From 815d39bf46d8b61bc97e553237a4e4d56b56e333 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 13:53:07 +0900
Subject: [PATCH 1/7] [fix] readme
---
README-en.md | 4 ++--
README.md | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README-en.md b/README-en.md
index 4888a14..a26f852 100644
--- a/README-en.md
+++ b/README-en.md
@@ -6,7 +6,7 @@
[](https://dotnet.microsoft.com/)
[](LICENSE)
-[](Clawleash.Tests)
+[](Clawleash.Tests)
*Semantic Kernel × Playwright × PowerShell × MCP × Sandbox Architecture × Multi-Interface*
@@ -216,7 +216,7 @@ Use tools from external MCP servers within Clawleash.
**Transport Support:**
- **stdio**: Local NPX packages, Docker containers
-- **SSE**: Remote MCP servers (coming soon)
+- **SSE**: Remote MCP servers (HTTP Server-Sent Events)
---
diff --git a/README.md b/README.md
index df094c9..0b02c22 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
[](https://dotnet.microsoft.com/)
[](LICENSE)
-[](Clawleash.Tests)
+[](Clawleash.Tests)
*Semantic Kernel × Playwright × PowerShell × MCP × Sandbox Architecture × Multi-Interface*
@@ -216,7 +216,7 @@ prompt: |
**トランスポート対応:**
- **stdio**: ローカルNPXパッケージ、Dockerコンテナ
-- **SSE**: リモートMCPサーバー(今後対応)
+- **SSE**: リモートMCPサーバー(HTTP Server-Sent Events)
---
From b62d4d83b19227cc852ba96f48d56681ceecb4ba Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 13:53:20 +0900
Subject: [PATCH 2/7] [add] readme
---
Clawleash.Interfaces.Discord/README.md | 163 ++++++++++++++++++
Clawleash.Interfaces.Slack/README.md | 165 ++++++++++++++++++
Clawleash.Interfaces.WebSocket/README.md | 200 ++++++++++++++++++++++
Clawleash.Server/README.md | 208 +++++++++++++++++++++++
Clawleash.Shell/README.md | 199 ++++++++++++++++++++++
5 files changed, 935 insertions(+)
create mode 100644 Clawleash.Interfaces.Discord/README.md
create mode 100644 Clawleash.Interfaces.Slack/README.md
create mode 100644 Clawleash.Interfaces.WebSocket/README.md
create mode 100644 Clawleash.Server/README.md
create mode 100644 Clawleash.Shell/README.md
diff --git a/Clawleash.Interfaces.Discord/README.md b/Clawleash.Interfaces.Discord/README.md
new file mode 100644
index 0000000..ff785b1
--- /dev/null
+++ b/Clawleash.Interfaces.Discord/README.md
@@ -0,0 +1,163 @@
+# Clawleash.Interfaces.Discord
+
+Discord Bot チャットインターフェースの完全実装。Discord.NET を使用して Discord サーバーおよび DM からメッセージを受信し、AI エージェントと連携します。
+
+## 機能
+
+- **リアルタイムメッセージ受信**: Gateway Intents を使用したリアルタイムメッセージ監視
+- **コマンドプレフィックス対応**: `!` などのプレフィックスでコマンドを識別
+- **スレッド返信**: 元のメッセージに対する返信形式で応答
+- **DM 対応**: ダイレクトメッセージでも動作(プレフィックス不要)
+- **ストリーミング送信**: 長いメッセージの一括送信対応
+
+## アーキテクチャ
+
+```
+┌──────────────────────────────────────────────────┐
+│ DiscordChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ DiscordSocketClient (Discord.NET) │ │
+│ │ - Gateway Intents │ │
+│ │ - Message Received Events │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Discord Gateway │
+ │ (WebSocket) │
+ └───────────────────────┘
+```
+
+## 使用方法
+
+### 設定
+
+```csharp
+var settings = new DiscordSettings
+{
+ Token = "YOUR_BOT_TOKEN",
+ CommandPrefix = "!",
+ UseThreads = false,
+ UseEmbeds = true
+};
+```
+
+### 基本的な使用
+
+```csharp
+var chatInterface = new DiscordChatInterface(settings, logger);
+
+// イベントハンドラー
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Guild: {args.Metadata["GuildName"]}");
+ Console.WriteLine($"Channel: {args.Metadata["ChannelName"]}");
+ Console.WriteLine($"Is DM: {args.Metadata["IsDirectMessage"]}");
+};
+
+// 開始
+await chatInterface.StartAsync(cancellationToken);
+
+// メッセージ送信(返信形式)
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// 終了
+await chatInterface.DisposeAsync();
+```
+
+## 設定オプション
+
+| プロパティ | 説明 | デフォルト |
+|-----------|------|-----------|
+| `Token` | Discord Bot Token | (必須) |
+| `CommandPrefix` | コマンドプレフィックス(DM では無視) | `!` |
+| `UseThreads` | 返信をスレッドで行うかどうか | `false` |
+| `UseEmbeds` | Embed メッセージを使用するかどうか | `true` |
+
+## イベント
+
+### MessageReceived
+
+メッセージ受信時に発生するイベント。
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - メッセージ ID
+ // args.SenderId - 送信者 Discord ID
+ // args.SenderName - 送信者名(グローバル名優先)
+ // args.Content - メッセージ内容(プレフィックス削除済み)
+ // args.ChannelId - チャンネル ID
+ // args.Timestamp - タイムスタンプ
+ // args.Metadata["GuildId"] - サーバー ID
+ // args.Metadata["GuildName"] - サーバー名
+ // args.Metadata["ChannelName"] - チャンネル名
+ // args.Metadata["IsDirectMessage"] - DM かどうか
+ // args.Metadata["IsThread"] - スレッドかどうか
+};
+```
+
+## Bot 設定
+
+### 必要な権限
+
+- **Read Messages**: メッセージの読み取り
+- **Send Messages**: メッセージの送信
+- **Read Message History**: メッセージ履歴の読み取り(返信用)
+- **View Channels**: チャンネルの表示
+
+### Gateway Intents
+
+以下の Intents が必要です:
+
+- `MessageContent` - メッセージ内容の読み取り
+- `GuildMessages` - サーバーメッセージの受信
+- `DirectMessages` - DM の受信
+
+## トラブルシューティング
+
+### "Privileged intent provided is not enabled"
+
+Bot 設定で Message Content Intent を有効にしてください:
+1. Discord Developer Portal を開く
+2. 対象のアプリケーションを選択
+3. Bot タブ → Privileged Gateway Intents
+4. "Message Content Intent" を有効化
+
+### "Discord token is not configured"
+
+`appsettings.json` で Token が正しく設定されているか確認してください:
+
+```json
+{
+ "ChatInterface": {
+ "Discord": {
+ "Enabled": true,
+ "Token": "${DISCORD_BOT_TOKEN}"
+ }
+ }
+}
+```
+
+### コマンドが反応しない
+
+- コマンドプレフィックスが正しいか確認
+- Bot がチャンネルにアクセス権を持っているか確認
+- DM ではプレフィックスなしで送信
+
+## ビルド
+
+```bash
+cd Clawleash.Interfaces.Discord
+dotnet build
+```
+
+## 依存関係
+
+- Discord.NET (最新安定版)
+- Clawleash.Abstractions
+
+## ライセンス
+
+MIT
diff --git a/Clawleash.Interfaces.Slack/README.md b/Clawleash.Interfaces.Slack/README.md
new file mode 100644
index 0000000..abae070
--- /dev/null
+++ b/Clawleash.Interfaces.Slack/README.md
@@ -0,0 +1,165 @@
+# Clawleash.Interfaces.Slack
+
+Slack Bot チャットインターフェースの完全実装。HTTP API + ポーリング方式で Slack からメッセージを受信し、AI エージェントと連携します。
+
+## 機能
+
+- **HTTP API ポーリング**: conversations.history API を使用したメッセージ取得
+- **スレッド返信**: 元のメッセージに対するスレッド形式で応答
+- **DM 対応**: ダイレクトメッセージの送受信
+- **チャンネル管理**: チャンネル一覧取得・参加・離脱
+- **ストリーミング送信**: 長いメッセージの一括送信対応
+
+## アーキテクチャ
+
+```
+┌──────────────────────────────────────────────────┐
+│ SlackChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ HTTP Client + Polling Thread │ │
+│ │ - conversations.history polling │ │
+│ │ - Message deduplication │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Slack Web API │
+ │ (HTTPS) │
+ └───────────────────────┘
+```
+
+## 使用方法
+
+### 設定
+
+```csharp
+var settings = new SlackSettings
+{
+ BotToken = "xoxb-...",
+ AppToken = "xapp-...",
+ UseThreads = true,
+ UseBlockKit = false
+};
+```
+
+### 基本的な使用
+
+```csharp
+var chatInterface = new SlackChatInterface(settings, logger);
+
+// イベントハンドラー
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Thread: {args.Metadata["ThreadTs"]}");
+ Console.WriteLine($"Is Thread: {args.Metadata["IsThread"]}");
+};
+
+// 開始
+await chatInterface.StartAsync(cancellationToken);
+
+// チャンネルに参加
+await chatInterface.JoinChannelAsync("C12345678");
+
+// メッセージ送信(スレッド返信)
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// DM 送信
+await chatInterface.SendDirectMessageAsync("U12345678", "Hello!");
+
+// 終了
+await chatInterface.DisposeAsync();
+```
+
+## 設定オプション
+
+| プロパティ | 説明 | デフォルト |
+|-----------|------|-----------|
+| `BotToken` | Bot User OAuth Token (`xoxb-...`) | (必須) |
+| `AppToken` | App-Level Token (`xapp-...`) | (空) |
+| `SigningSecret` | HTTP リクエスト検証用 | `null` |
+| `UseThreads` | スレッドで返信するかどうか | `true` |
+| `UseBlockKit` | Block Kit を使用するかどうか | `false` |
+
+## イベント
+
+### MessageReceived
+
+メッセージ受信時に発生するイベント。
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - メッセージタイムスタンプ (ts)
+ // args.SenderId - 送信者 Slack ID
+ // args.SenderName - 送信者表示名
+ // args.Content - メッセージ内容
+ // args.ChannelId - チャンネル ID
+ // args.Timestamp - タイムスタンプ
+ // args.Metadata["ThreadTs"] - スレッドの親 ts
+ // args.Metadata["IsThread"] - スレッド内かどうか
+};
+```
+
+## Slack App 設定
+
+### 必要な OAuth Scopes
+
+- `channels:history` - パブリックチャンネルのメッセージ読み取り
+- `groups:history` - プライベートチャンネルのメッセージ読み取り
+- `im:history` - DM のメッセージ読み取り
+- `mpim:history` - グループ DM のメッセージ読み取り
+- `channels:read` - チャンネル一覧取得
+- `groups:read` - プライベートチャンネル一覧取得
+- `im:read` - DM 一覧取得
+- `im:write` - DM 送信
+- `chat:write` - メッセージ送信
+
+### App 設定手順
+
+1. [Slack API](https://api.slack.com/apps) でアプリを作成
+2. OAuth & Permissions で上記 Scopes を追加
+3. Install to Workspace でインストール
+4. Bot User OAuth Token (`xoxb-...`) をコピー
+
+## ポーリング動作
+
+- **ポーリング間隔**: 5 秒
+- **取得期間**: 過去 5 分間のメッセージ
+- **重複排除**: 処理済みメッセージ ID を 10 分間保持
+
+## トラブルシューティング
+
+### "Failed to authenticate with Slack"
+
+Bot Token が正しいか確認してください:
+- `xoxb-` で始まるトークン
+- 適切な Scopes が付与されている
+
+### メッセージが受信されない
+
+1. Bot がチャンネルに招待されているか確認
+2. `JoinChannelAsync` でチャンネルを監視対象に追加
+3. 必要な Scopes が付与されているか確認
+
+### "rate_limited"
+
+Slack API のレート制限に達しました:
+- ポーリング間隔を増やしてください
+- 監視チャンネル数を減らしてください
+
+## ビルド
+
+```bash
+cd Clawleash.Interfaces.Slack
+dotnet build
+```
+
+## 依存関係
+
+- System.Text.Json
+- Clawleash.Abstractions
+
+## ライセンス
+
+MIT
diff --git a/Clawleash.Interfaces.WebSocket/README.md b/Clawleash.Interfaces.WebSocket/README.md
new file mode 100644
index 0000000..a13a444
--- /dev/null
+++ b/Clawleash.Interfaces.WebSocket/README.md
@@ -0,0 +1,200 @@
+# Clawleash.Interfaces.WebSocket
+
+WebSocket チャットインターフェースの完全実装。SignalR クライアントを使用してサーバーとリアルタイム通信を行い、E2EE(エンドツーエンド暗号化)に対応しています。
+
+## 機能
+
+- **SignalR 通信**: ASP.NET Core SignalR によるリアルタイム双方向通信
+- **E2EE 対応**: X25519 鍵交換 + AES-256-GCM によるエンドツーエンド暗号化
+- **チャンネル鍵**: チャンネルごとの暗号化鍵管理
+- **自動再接続**: 指数バックオフによる自動再接続
+- **ストリーミング送信**: 長いメッセージの一括送信対応
+
+## アーキテクチャ
+
+```
+┌──────────────────────────────────────────────────┐
+│ WebSocketChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ HubConnection (SignalR Client) │ │
+│ │ - Automatic Reconnect │ │
+│ │ - Message/Channel Key Handling │ │
+│ └────────────────────────────────────────────┘ │
+│ ┌────────────────────────────────────────────┐ │
+│ │ AesGcmE2eeProvider │ │
+│ │ - X25519 Key Exchange │ │
+│ │ - AES-256-GCM Encryption/Decryption │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Clawleash.Server │
+ │ ChatHub (/chat) │
+ └───────────────────────┘
+```
+
+## E2EE 暗号化フロー
+
+```
+┌──────────────┐ ┌──────────────┐
+│ Client │ │ Server │
+│ │ │ │
+│ 1. 鍵交換 │ ◄─── X25519 ────────► │ │
+│ │ │ │
+│ 2. 暗号化 │ │ │
+│ Plaintext │ │ │
+│ │ │ │ │
+│ ▼ │ │ │
+│ AES-256-GCM │ │ │
+│ │ │ │ │
+│ ▼ │ │ │
+│ Ciphertext │ ──── wss:// ────────► │ 3. 復号化 │
+│ │ │ AES-256-GCM │
+│ │ │ │ │
+│ │ │ ▼ │
+│ │ │ Plaintext │
+└──────────────┘ └──────────────┘
+```
+
+## 使用方法
+
+### 設定
+
+```csharp
+var settings = new WebSocketSettings
+{
+ ServerUrl = "wss://localhost:8080/chat",
+ EnableE2ee = true,
+ ReconnectIntervalMs = 5000,
+ MaxReconnectAttempts = 10,
+ HeartbeatIntervalMs = 30000,
+ ConnectionTimeoutMs = 10000
+};
+```
+
+### 基本的な使用
+
+```csharp
+var chatInterface = new WebSocketChatInterface(settings, logger);
+
+// イベントハンドラー
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Encrypted: {args.Metadata["encrypted"]}");
+};
+
+// 開始(E2EE 有効時は鍵交換も実行)
+await chatInterface.StartAsync(cancellationToken);
+
+// チャンネルに参加
+await chatInterface.JoinChannelAsync("general");
+
+// メッセージ送信
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// チャンネルから離脱
+await chatInterface.LeaveChannelAsync("general");
+
+// 終了
+await chatInterface.DisposeAsync();
+```
+
+## 設定オプション
+
+| プロパティ | 説明 | デフォルト |
+|-----------|------|-----------|
+| `ServerUrl` | SignalR サーバー URL | `ws://localhost:8080/chat` |
+| `EnableE2ee` | E2EE 有効化(親設定から継承) | `false` |
+| `ReconnectIntervalMs` | 再接続間隔 | `5000` |
+| `MaxReconnectAttempts` | 最大再接続試行回数 | `10` |
+| `HeartbeatIntervalMs` | ハートビート間隔 | `30000` |
+| `ConnectionTimeoutMs` | 接続タイムアウト | `10000` |
+
+## イベント
+
+### MessageReceived
+
+メッセージ受信時に発生するイベント。
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - メッセージ ID
+ // args.SenderId - 送信者 ID
+ // args.SenderName - 送信者名
+ // args.Content - メッセージ内容(復号化済み)
+ // args.ChannelId - チャンネル ID
+ // args.Timestamp - タイムスタンプ
+ // args.Metadata["encrypted"] - 暗号化されていたか
+};
+```
+
+## 再接続ポリシー
+
+指数バックオフを使用した自動再接続:
+
+```
+試行 1: 5 秒後
+試行 2: 10 秒後
+試行 3: 20 秒後
+...
+最大 60 秒間隔
+```
+
+最大試行回数に達すると再接続を停止します。
+
+## トラブルシューティング
+
+### "WebSocket server URL is not configured"
+
+`appsettings.json` で URL が設定されているか確認:
+
+```json
+{
+ "ChatInterface": {
+ "WebSocket": {
+ "Enabled": true,
+ "ServerUrl": "wss://localhost:8080/chat",
+ "EnableE2ee": true
+ }
+ }
+}
+```
+
+### "Failed to connect to SignalR hub"
+
+1. Clawleash.Server が起動しているか確認
+2. URL が正しいか確認(`ws://` または `wss://`)
+3. ファイアウォール設定を確認
+
+### "Key exchange failed"
+
+1. サーバー側でも E2EE が有効か確認
+2. サーバーの時刻が正しいか確認
+
+### メッセージが暗号化されない
+
+- `EnableE2ee` が `true` に設定されているか確認
+- チャンネル鍵が設定されているか確認(`HasChannelKey`)
+
+## ビルド
+
+```bash
+cd Clawleash.Interfaces.WebSocket
+dotnet build
+```
+
+## 依存関係
+
+- Microsoft.AspNetCore.SignalR.Client
+- Clawleash.Abstractions
+
+## 関連プロジェクト
+
+- [Clawleash.Server](../Clawleash.Server) - SignalR サーバー
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC インターフェース
+
+## ライセンス
+
+MIT
diff --git a/Clawleash.Server/README.md b/Clawleash.Server/README.md
new file mode 100644
index 0000000..a1b0b59
--- /dev/null
+++ b/Clawleash.Server/README.md
@@ -0,0 +1,208 @@
+# Clawleash.Server
+
+Clawleash の SignalR サーバーコンポーネント。WebSocket および WebRTC クライアントとのリアルタイム通信を提供し、E2EE(エンドツーエンド暗号化)に対応しています。
+
+## 機能
+
+- **SignalR Hub**: リアルタイム双方向通信
+- **ChatHub**: WebSocket クライアント用チャットハブ(E2EE 対応)
+- **SignalingHub**: WebRTC シグナリングサーバー
+- **E2EE 鍵管理**: X25519 鍵交換・チャンネル鍵配布
+- **Svelte クライアント配信**: 静的ファイルとして SPA を配信
+
+## アーキテクチャ
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash.Server │
+│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
+│ │ ChatHub │ │ SignalingHub │ │
+│ │ (/chat) │ │ (/signaling) │ │
+│ │ - E2EE 対応 │ │ - SDP/ICE 候補交換 │ │
+│ │ - チャンネル管理 │ │ - ピア接続管理 │ │
+│ └─────────────────────┘ └─────────────────────────────┘ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ Security │ │
+│ │ ┌───────────────────┐ ┌─────────────────────────────┐ │ │
+│ │ │ KeyManager │ │ E2eeMiddleware │ │ │
+│ │ │ - 鍵ペア生成 │ │ - チャンネル鍵管理 │ │ │
+│ │ │ - セッション管理 │ │ │ │ │
+│ │ └───────────────────┘ └─────────────────────────────┘ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ Svelte Client (Static Files) │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## 使用方法
+
+### 起動
+
+```bash
+cd Clawleash.Server
+dotnet run
+
+# または
+dotnet run --project Clawleash.Server
+```
+
+### エンドポイント
+
+| パス | 説明 |
+|------|------|
+| `/` | Svelte SPA クライアント |
+| `/chat` | WebSocket ChatHub |
+| `/signaling` | WebRTC シグナリングハブ |
+
+### 設定
+
+`appsettings.json`:
+
+```json
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information"
+ }
+ },
+ "AllowedOrigins": "https://yourdomain.com"
+}
+```
+
+## ChatHub API
+
+### クライアント → サーバー
+
+| メソッド | 説明 |
+|----------|------|
+| `StartKeyExchange()` | E2EE 鍵交換開始 |
+| `CompleteKeyExchange(sessionId, publicKey)` | 鍵交換完了 |
+| `SendMessage(content, channelId, senderName, encrypted, ciphertext)` | メッセージ送信 |
+| `JoinChannel(channelId)` | チャンネル参加 |
+| `LeaveChannel(channelId)` | チャンネル離脱 |
+
+### サーバー → クライアント
+
+| イベント | 説明 |
+|----------|------|
+| `MessageReceived` | メッセージ受信 |
+| `ChannelKey` | チャンネル鍵配布 |
+| `KeyExchangeCompleted` | 鍵交換完了通知 |
+
+## SignalingHub API
+
+### クライアント → サーバー
+
+| メソッド | 説明 |
+|----------|------|
+| `Register(peerId, metadata)` | ピア登録 |
+| `Offer(targetPeerId, sdp)` | SDP オファー送信 |
+| `Answer(targetPeerId, sdp)` | SDP アンサー送信 |
+| `IceCandidate(targetPeerId, candidate)` | ICE 候補送信 |
+
+### サーバー → クライアント
+
+| イベント | 説明 |
+|----------|------|
+| `PeerConnected` | ピー接続通知 |
+| `PeerDisconnected` | ピー切断通知 |
+| `Offer` | SDP オファー受信 |
+| `Answer` | SDP アンサー受信 |
+| `IceCandidate` | ICE 候補受信 |
+
+## CORS 設定
+
+### 開発環境
+
+```csharp
+policy.WithOrigins("http://localhost:5173", "http://localhost:4173")
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ .AllowCredentials();
+```
+
+### 本番環境
+
+`AllowedOrigins` 設定で許可するオリジンを指定:
+
+```json
+{
+ "AllowedOrigins": "https://app.yourdomain.com"
+}
+```
+
+## E2EE 鍵交換フロー
+
+```
+Client Server
+ │ │
+ │ ─── StartKeyExchange ──────► │
+ │ │ 1. 鍵ペア生成
+ │ │ セッション ID 発行
+ │ ◄── ServerPublicKey ─────── │
+ │ SessionId │
+ │ │
+ │ 2. 共有秘密生成 │
+ │ チャンネル鍵生成 │
+ │ │
+ │ ─── ClientPublicKey ───────► │
+ │ SessionId │ 3. 共有秘密生成
+ │ │
+ │ ◄── KeyExchangeCompleted ── │
+ │ │
+ │ ◄── ChannelKey ───────────── │
+ │ (暗号化済み) │
+```
+
+## Svelte クライアント
+
+`Client/` ディレクトリに Svelte アプリケーションを配置:
+
+```
+Client/
+├── index.html
+├── _framework/
+│ └── blazor.webassembly.js
+└── ...
+```
+
+ビルド時に `wwwroot/` にコピーされます。
+
+## トラブルシューティング
+
+### "CORS policy blocked"
+
+1. 開発環境では `localhost:5173` が許可されています
+2. 本番環境では `AllowedOrigins` を設定してください
+
+### WebSocket 接続が切れる
+
+1. プロキシサーバーで WebSocket が許可されているか確認
+2. Keep-Alive 設定を確認
+
+### E2EE が動作しない
+
+1. クライアントとサーバーで `EnableE2ee` が `true` に設定されているか確認
+2. 時刻同期が正しいか確認
+
+## ビルド
+
+```bash
+cd Clawleash.Server
+dotnet build
+```
+
+## 依存関係
+
+- Microsoft.AspNetCore.SignalR
+- Clawleash.Abstractions
+
+## 関連プロジェクト
+
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket) - WebSocket クライアント
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC クライアント
+
+## ライセンス
+
+MIT
diff --git a/Clawleash.Shell/README.md b/Clawleash.Shell/README.md
new file mode 100644
index 0000000..4d1f0e6
--- /dev/null
+++ b/Clawleash.Shell/README.md
@@ -0,0 +1,199 @@
+# Clawleash.Shell
+
+Clawleash のサンドボックス実行プロセス。ZeroMQ + MessagePack による IPC でメインアプリケーションと通信し、制約付き PowerShell 環境でコマンドを実行します。
+
+## 概要
+
+Clawleash.Shell は分離されたプロセスとして動作し、以下の役割を持ちます:
+
+- **IPC クライアント**: ZeroMQ (DealerSocket) でメインアプリに接続
+- **PowerShell 実行**: 制約付き PowerShell Runspace でコマンド実行
+- **サンドボックス**: AppContainer (Windows) / Bubblewrap (Linux) で分離実行
+
+## アーキテクチャ
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash (Main) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ ShellServer (RouterSocket) │ │
+│ └──────────────────────────┬──────────────────────────────┘ │
+└─────────────────────────────┼───────────────────────────────┘
+ │
+ │ ZeroMQ + MessagePack
+ │
+┌─────────────────────────────┼───────────────────────────────┐
+│ Clawleash.Shell (Sandboxed) │
+│ ┌──────────────────────────┴──────────────────────────────┐ │
+│ │ IpcClient (DealerSocket) │ │
+│ └──────────────────────────┬──────────────────────────────┘ │
+│ │ │
+│ ┌──────────────────────────┴──────────────────────────────┐ │
+│ │ ConstrainedRunspaceHost │ │
+│ │ (PowerShell SDK) │ │
+│ │ ┌─────────────────────────────────────────────────────┐ │ │
+│ │ │ ConstrainedLanguage Mode │ │ │
+│ │ │ - Command Whitelist │ │ │
+│ │ │ - Path Restrictions │ │ │
+│ │ │ - Folder Policies │ │ │
+│ │ └─────────────────────────────────────────────────────┘ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## 使用方法
+
+### 起動
+
+Clawleash.Shell は通常、メインアプリケーションから自動的に起動されます:
+
+```bash
+# 手動起動(デバッグ用)
+Clawleash.Shell --server tcp://localhost:5555
+
+# 詳細ログ有効
+Clawleash.Shell --server tcp://localhost:5555 --verbose
+```
+
+### コマンドライン引数
+
+| 引数 | 短縮 | 説明 |
+|------|------|------|
+| `--server
` | `-s` | ZeroMQ サーバーアドレス (必須) |
+| `--verbose` | `-v` | 詳細ログ出力 |
+
+## IPC プロトコル
+
+### 通信仕様
+
+| 項目 | 仕様 |
+|------|------|
+| プロトコル | ZeroMQ (Router/Dealer) |
+| シリアライズ | MessagePack |
+| 方向 | Main (Server) ← Shell (Client) |
+
+### メッセージ種別
+
+| メッセージ | 方向 | 説明 |
+|-----------|------|------|
+| `ShellInitializeRequest` | S → M | 初期化要求 |
+| `ShellInitializeResponse` | M → S | 初期化応答 |
+| `ShellExecuteRequest` | M → S | コマンド実行要求 |
+| `ShellExecuteResponse` | S → M | 実行結果 |
+| `ToolInvokeRequest` | M → S | ツール呼び出し要求 |
+| `ToolInvokeResponse` | S → M | ツール実行結果 |
+| `ShellPingRequest` | M → S | 死活監視 |
+| `ShellPingResponse` | S → M | 応答 |
+
+## PowerShell 制約
+
+### ConstrainedLanguage モード
+
+デフォルトで ConstrainedLanguage モードで動作:
+
+- **許可**: 基本的なコマンド、パイプライン、変数
+- **禁止**: .NET メソッド呼び出し、Add-Type、スクリプトブロック
+
+### コマンドホワイトリスト
+
+許可されたコマンドのみ実行可能:
+
+```powershell
+# 許可されるコマンド例
+Get-Content, Set-Content, Get-ChildItem
+New-Item, Remove-Item, Copy-Item, Move-Item
+Write-Output, Write-Error
+```
+
+### パス制限
+
+フォルダーポリシーに基づくアクセス制御:
+
+```json
+{
+ "FolderPolicies": [
+ {
+ "Path": "C:\\Projects",
+ "Access": "ReadWrite",
+ "Network": "Allow",
+ "Execute": "Allow"
+ },
+ {
+ "Path": "C:\\Projects\\Secrets",
+ "Access": "Deny"
+ }
+ ]
+}
+```
+
+## サンドボックス
+
+### Windows (AppContainer)
+
+- ケーパビリティベースのアクセス制御
+- ファイルシステム、ネットワーク、レジストリの分離
+- 低い整合性レベルで実行
+
+### Linux (Bubblewrap)
+
+- 名前空間分離 (PID, Network, Mount, User)
+- cgroups によるリソース制限
+- seccomp フィルタ
+
+## プロジェクト構成
+
+```
+Clawleash.Shell/
+├── Program.cs # エントリーポイント
+├── IPC/
+│ └── IpcClient.cs # ZeroMQ クライアント
+├── Hosting/
+│ └── ConstrainedRunspaceHost.cs # PowerShell ホスト
+└── Cmdlets/
+ └── ... # カスタムコマンドレット
+```
+
+## トラブルシューティング
+
+### "サーバーアドレスが指定されていません"
+
+`--server` 引数を指定してください:
+
+```bash
+Clawleash.Shell --server tcp://localhost:5555
+```
+
+### "Main アプリへの接続に失敗しました"
+
+1. メインアプリケーションが起動しているか確認
+2. サーバーアドレスが正しいか確認
+3. ファイアウォール設定を確認
+
+### PowerShell コマンドが失敗する
+
+1. コマンドがホワイトリストに含まれているか確認
+2. パスがフォルダーポリシーで許可されているか確認
+3. ConstrainedLanguage モードの制限を確認
+
+## ビルド
+
+```bash
+cd Clawleash.Shell
+dotnet build
+```
+
+## 依存関係
+
+- NetMQ (ZeroMQ)
+- MessagePack
+- PowerShell SDK
+- Clawleash.Contracts
+
+## 関連プロジェクト
+
+- [Clawleash](../Clawleash) - メインアプリケーション
+- [Clawleash.Contracts](../Clawleash.Contracts) - IPC メッセージ定義
+
+## ライセンス
+
+MIT
From ae5731ea1e51eb506e07fdde9e72acf72d4b3575 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 14:09:22 +0900
Subject: [PATCH 3/7] [add] functions docs
---
Clawleash.Abstractions/README.md | 433 +++++++++++++++++++++++++++++++
README-en.md | 254 ++++++++++++++++++
README.md | 283 ++++++++++++++++++++
3 files changed, 970 insertions(+)
create mode 100644 Clawleash.Abstractions/README.md
diff --git a/Clawleash.Abstractions/README.md b/Clawleash.Abstractions/README.md
new file mode 100644
index 0000000..888ce0a
--- /dev/null
+++ b/Clawleash.Abstractions/README.md
@@ -0,0 +1,433 @@
+# Clawleash.Abstractions
+
+Clawleash の共有インターフェースと抽象化を定義するライブラリ。カスタムチャットインターフェースプロバイダーを作成するための基盤を提供します。
+
+## 概要
+
+このライブラリは以下を提供します:
+
+- **IChatInterface**: チャットインターフェースの抽象化
+- **ChatMessageReceivedEventArgs**: メッセージ受信イベントの引数
+- **IStreamingMessageWriter**: ストリーミングメッセージ送信用
+- **ChatInterfaceSettingsBase**: 設定のベースクラス
+- **IE2eeProvider**: E2EE 暗号化プロバイダー
+
+---
+
+## カスタムプロバイダーの作成
+
+### 1. プロジェクト作成
+
+新しいクラスライブラリプロジェクトを作成し、`Clawleash.Abstractions` を参照します:
+
+```xml
+
+
+ net10.0
+
+
+
+
+
+
+```
+
+### 2. 設定クラスの作成
+
+`ChatInterfaceSettingsBase` を継承して設定クラスを作成します:
+
+```csharp
+using Clawleash.Abstractions.Configuration;
+
+namespace Clawleash.Interfaces.MyProvider;
+
+public class MyProviderSettings : ChatInterfaceSettingsBase
+{
+ ///
+ /// 接続先のサーバーURL
+ ///
+ public string ServerUrl { get; set; } = "https://api.example.com";
+
+ ///
+ /// API キー
+ ///
+ public string ApiKey { get; set; } = string.Empty;
+
+ ///
+ /// 再接続間隔(ミリ秒)
+ ///
+ public int ReconnectIntervalMs { get; set; } = 5000;
+}
+```
+
+### 3. IChatInterface の実装
+
+```csharp
+using System.Text;
+using Clawleash.Abstractions.Services;
+using Microsoft.Extensions.Logging;
+
+namespace Clawleash.Interfaces.MyProvider;
+
+public class MyProviderChatInterface : IChatInterface
+{
+ private readonly MyProviderSettings _settings;
+ private readonly ILogger? _logger;
+ private bool _isConnected;
+ private bool _disposed;
+
+ // 必須プロパティ
+ public string Name => "MyProvider";
+ public bool IsConnected => _isConnected;
+
+ // 必須イベント
+ public event EventHandler? MessageReceived;
+
+ public MyProviderChatInterface(
+ MyProviderSettings settings,
+ ILogger? logger = null)
+ {
+ _settings = settings ?? throw new ArgumentNullException(nameof(settings));
+ _logger = logger;
+ }
+
+ // 必須メソッド: インターフェース開始
+ public async Task StartAsync(CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(_settings.ApiKey))
+ {
+ _logger?.LogWarning("API key is not configured");
+ return;
+ }
+
+ try
+ {
+ // 接続処理を実装
+ await ConnectAsync(cancellationToken);
+ _isConnected = true;
+ _logger?.LogInformation("{Name} connected", Name);
+ }
+ catch (Exception ex)
+ {
+ _logger?.LogError(ex, "Failed to start {Name}", Name);
+ throw;
+ }
+ }
+
+ // 必須メソッド: インターフェース停止
+ public async Task StopAsync(CancellationToken cancellationToken = default)
+ {
+ _isConnected = false;
+ // 切断処理を実装
+ await Task.CompletedTask;
+ _logger?.LogInformation("{Name} stopped", Name);
+ }
+
+ // 必須メソッド: メッセージ送信
+ public async Task SendMessageAsync(
+ string message,
+ string? replyToMessageId = null,
+ CancellationToken cancellationToken = default)
+ {
+ if (!IsConnected)
+ {
+ _logger?.LogWarning("{Name} is not connected", Name);
+ return;
+ }
+
+ // メッセージ送信処理を実装
+ // replyToMessageId がある場合は返信として送信
+ await Task.CompletedTask;
+ }
+
+ // 必須メソッド: ストリーミング送信
+ public IStreamingMessageWriter StartStreamingMessage(CancellationToken cancellationToken = default)
+ {
+ return new MyStreamingWriter(this);
+ }
+
+ // 必須メソッド: リソース解放
+ public async ValueTask DisposeAsync()
+ {
+ if (_disposed) return;
+ _disposed = true;
+
+ await StopAsync();
+ }
+
+ // 内部メソッド: メッセージ受信時に呼び出す
+ protected virtual void OnMessageReceived(string content, string senderId, string senderName)
+ {
+ var args = new ChatMessageReceivedEventArgs
+ {
+ MessageId = Guid.NewGuid().ToString(),
+ SenderId = senderId,
+ SenderName = senderName,
+ Content = content,
+ ChannelId = "default",
+ Timestamp = DateTime.UtcNow,
+ InterfaceName = Name,
+ RequiresReply = true,
+ Metadata = new Dictionary
+ {
+ // プロバイダー固有のメタデータ
+ ["custom_field"] = "value"
+ }
+ };
+
+ MessageReceived?.Invoke(this, args);
+ }
+
+ private async Task ConnectAsync(CancellationToken ct)
+ {
+ // 実際の接続処理
+ await Task.CompletedTask;
+ }
+}
+
+// ストリーミングライターの実装
+internal class MyStreamingWriter : IStreamingMessageWriter
+{
+ private readonly StringBuilder _content = new();
+ private readonly MyProviderChatInterface _interface;
+
+ public string MessageId { get; } = Guid.NewGuid().ToString();
+
+ public MyStreamingWriter(MyProviderChatInterface iface)
+ {
+ _interface = iface;
+ }
+
+ public Task AppendTextAsync(string text, CancellationToken cancellationToken = default)
+ {
+ _content.Append(text);
+ return Task.CompletedTask;
+ }
+
+ public async Task CompleteAsync(CancellationToken cancellationToken = default)
+ {
+ var message = _content.ToString();
+ if (!string.IsNullOrEmpty(message))
+ {
+ await _interface.SendMessageAsync(message, null, cancellationToken);
+ }
+ }
+
+ public ValueTask DisposeAsync() => ValueTask.CompletedTask;
+}
+```
+
+---
+
+## プロバイダーのデプロイ
+
+### ビルド
+
+```bash
+cd Clawleash.Interfaces.MyProvider
+dotnet build -c Release
+```
+
+### 配置
+
+DLL と依存ファイルをインターフェースディレクトリにコピー:
+
+```
+%LocalAppData%\Clawleash\Interfaces\MyProvider\
+├── Clawleash.Interfaces.MyProvider.dll
+├── Clawleash.Abstractions.dll
+└── (その他の依存DLL)
+```
+
+### 自動認識
+
+アプリケーション実行中にファイルを配置すると、自動的にロードされます(ホットリロード有効時)。
+
+---
+
+## 設定の統合
+
+### appsettings.json への追加
+
+```json
+{
+ "ChatInterface": {
+ "EnableHotReload": true,
+ "MyProvider": {
+ "Enabled": true,
+ "ServerUrl": "https://api.example.com",
+ "ApiKey": "${MY_PROVIDER_API_KEY}",
+ "EnableE2ee": false
+ }
+ }
+}
+```
+
+### DI への登録
+
+プロバイダーは `ActivatorUtilities.CreateInstance` でインスタンス化されるため、設定とロガーを DI に登録します:
+
+```csharp
+// Program.cs で設定を登録
+services.Configure(
+ configuration.GetSection("ChatInterface:MyProvider"));
+```
+
+---
+
+## ChatMessageReceivedEventArgs プロパティ
+
+| プロパティ | 型 | 説明 |
+|-----------|-----|------|
+| `MessageId` | `string` | メッセージの一意識別子 |
+| `SenderId` | `string` | 送信者の一意識別子 |
+| `SenderName` | `string` | 送信者の表示名 |
+| `Content` | `string` | メッセージの内容 |
+| `ChannelId` | `string` | チャンネル/ルーム ID |
+| `Timestamp` | `DateTime` | メッセージのタイムスタンプ (UTC) |
+| `ReplyToMessageId` | `string?` | 返信先メッセージ ID |
+| `RequiresReply` | `bool` | 返信が必要かどうか |
+| `InterfaceName` | `string` | インターフェース名 |
+| `Metadata` | `Dictionary` | プロバイダー固有のメタデータ |
+
+---
+
+## IChatInterface メンバー一覧
+
+### プロパティ
+
+| プロパティ | 型 | 説明 |
+|-----------|-----|------|
+| `Name` | `string` | インターフェース名(一意) |
+| `IsConnected` | `bool` | 接続状態 |
+
+### イベント
+
+| イベント | 説明 |
+|----------|------|
+| `MessageReceived` | メッセージ受信時に発生 |
+
+### メソッド
+
+| メソッド | 説明 |
+|----------|------|
+| `StartAsync(CancellationToken)` | インターフェース開始 |
+| `StopAsync(CancellationToken)` | インターフェース停止 |
+| `SendMessageAsync(message, replyToMessageId?, CancellationToken)` | メッセージ送信 |
+| `StartStreamingMessage(CancellationToken)` | ストリーミング送信開始 |
+| `DisposeAsync()` | リソース解放 |
+
+---
+
+## E2EE 対応
+
+E2EE(エンドツーエンド暗号化)をサポートする場合:
+
+### 1. IE2eeProvider の使用
+
+```csharp
+using Clawleash.Abstractions.Security;
+
+public class MySecureProvider : IChatInterface
+{
+ private readonly IE2eeProvider _e2eeProvider;
+
+ public MySecureProvider(MyProviderSettings settings, IE2eeProvider e2eeProvider)
+ {
+ _e2eeProvider = e2eeProvider;
+ }
+
+ public async Task SendMessageAsync(string message, ...)
+ {
+ if (_settings.EnableE2ee && _e2eeProvider.IsEncrypted)
+ {
+ var ciphertext = await _e2eeProvider.EncryptAsync(message, channelId);
+ // 暗号化されたデータを送信
+ }
+ else
+ {
+ // 平文で送信
+ }
+ }
+}
+```
+
+### 2. 設定での有効化
+
+```json
+{
+ "ChatInterface": {
+ "MyProvider": {
+ "Enabled": true,
+ "EnableE2ee": true
+ }
+ }
+}
+```
+
+---
+
+## ベストプラクティス
+
+### エラーハンドリング
+
+```csharp
+public async Task StartAsync(CancellationToken cancellationToken = default)
+{
+ try
+ {
+ await ConnectAsync(cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger?.LogError(ex, "Connection failed");
+ // 接続状態を更新
+ _isConnected = false;
+ throw;
+ }
+}
+```
+
+### ログ出力
+
+```csharp
+// 構造化ログを使用
+_logger?.LogInformation("{Name} starting with server: {ServerUrl}", Name, _settings.ServerUrl);
+_logger?.LogDebug("Message received: {MessageId} from {SenderName}", args.MessageId, args.SenderName);
+```
+
+### リソース管理
+
+```csharp
+public async ValueTask DisposeAsync()
+{
+ if (_disposed) return;
+ _disposed = true;
+
+ // イベントの購読解除
+ // _client.OnMessage -= OnMessage;
+
+ // 接続の切断
+ await StopAsync();
+
+ // その他のリソース解放
+ _httpClient?.Dispose();
+}
+```
+
+---
+
+## 既存プロバイダーの参照
+
+実装の参考として、以下のプロバイダーを参照してください:
+
+- [Clawleash.Interfaces.Discord](../Clawleash.Interfaces.Discord) - Discord Bot
+- [Clawleash.Interfaces.Slack](../Clawleash.Interfaces.Slack) - Slack Bot
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+
+---
+
+## ライセンス
+
+MIT
diff --git a/README-en.md b/README-en.md
index a26f852..e855ba4 100644
--- a/README-en.md
+++ b/README-en.md
@@ -586,6 +586,23 @@ dotnet run --project Clawleash.Server
Hot-reload enabled: New DLLs are automatically loaded when placed in the directory.
+### Creating Custom Providers
+
+You can create and add your own chat interfaces.
+
+**Steps:**
+1. Create a class library project referencing `Clawleash.Abstractions`
+2. Implement `IChatInterface`
+3. Build and place in `%LocalAppData%\Clawleash\Interfaces\`
+
+See [Clawleash.Abstractions/README.md](Clawleash.Abstractions/README.md) for detailed development guide.
+
+**Example Implementations:**
+- [Discord](Clawleash.Interfaces.Discord) - Discord Bot
+- [Slack](Clawleash.Interfaces.Slack) - Slack Bot
+- [WebSocket](Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
+- [WebRTC](Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+
### Adding Skills
```
@@ -612,6 +629,243 @@ Hot-reload enabled: New DLLs are automatically loaded when placed in the directo
---
+## Developing Extensions
+
+### Adding MCP Servers
+
+Add external MCP servers to use their tools within Clawleash.
+
+**appsettings.json:**
+
+```json
+{
+ "Mcp": {
+ "Enabled": true,
+ "Servers": [
+ {
+ "name": "filesystem",
+ "transport": "stdio",
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
+ "enabled": true,
+ "timeoutMs": 30000,
+ "useSandbox": true
+ },
+ {
+ "name": "github",
+ "transport": "stdio",
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-github"],
+ "environment": {
+ "GITHUB_TOKEN": "${GITHUB_TOKEN}"
+ },
+ "enabled": true
+ },
+ {
+ "name": "remote-server",
+ "transport": "sse",
+ "url": "https://api.example.com/mcp/sse",
+ "headers": {
+ "Authorization": "Bearer ${API_KEY}"
+ },
+ "enabled": true,
+ "timeoutMs": 60000
+ }
+ ]
+ }
+}
+```
+
+**MCP Configuration Properties:**
+
+| Property | Description | Required |
+|----------|-------------|----------|
+| `name` | Server name (unique identifier) | ✅ |
+| `transport` | `stdio` or `sse` | ✅ |
+| `command` | Command to execute (stdio) | stdio |
+| `args` | Command arguments | No |
+| `environment` | Environment variables | No |
+| `url` | Server URL (SSE) | sse |
+| `headers` | HTTP headers (SSE) | No |
+| `enabled` | Enable/disable server | No |
+| `timeoutMs` | Timeout in milliseconds | No |
+| `useSandbox` | Run in sandbox | No |
+
+### Adding Tool Packages (Native Function Calling)
+
+Create custom tools using Semantic Kernel's `[KernelFunction]` attribute.
+
+**Project Structure:**
+
+```
+MyToolPackage/
+├── MyToolPackage.csproj
+├── WeatherTools.cs
+└── tool-manifest.json (optional)
+```
+
+**tool-manifest.json:**
+
+```json
+{
+ "name": "WeatherTools",
+ "version": "1.0.0",
+ "description": "Weather information tools",
+ "mainAssembly": "MyToolPackage.dll"
+}
+```
+
+**WeatherTools.cs:**
+
+```csharp
+using System.ComponentModel;
+using Microsoft.SemanticKernel;
+
+namespace MyToolPackage;
+
+public class WeatherTools
+{
+ [KernelFunction("get_weather")]
+ [Description("Get weather for specified city")]
+ public async Task GetWeatherAsync(
+ [Description("City name")] string city,
+ [Description("Unit (celsius/fahrenheit)")] string unit = "celsius")
+ {
+ // Weather retrieval logic
+ return $"Weather in {city}: Sunny, Temperature: 25{unit}";
+ }
+}
+```
+
+**Deployment:**
+
+```bash
+# Create ZIP package
+cd MyToolPackage/bin/Release/net10.0
+zip -r ../../weather-tools.zip .
+
+# Copy to packages directory
+cp ../../weather-tools.zip "%LocalAppData%/Clawleash/Packages/"
+```
+
+**Tool Package Directory:** `%LocalAppData%\Clawleash\Packages\`
+
+Hot-reload enabled: New ZIP files are automatically loaded when placed in the directory.
+
+#### Native Tool Packages vs MCP
+
+| Aspect | Native Tool Packages | MCP |
+|--------|---------------------|-----|
+| **Execution** | Direct execution in sandbox | External process |
+| **Access Control** | AppContainer + Folder policies | Controlled by MCP server |
+| **Network** | Capability-based control | Depends on MCP server |
+| **Process Isolation** | Isolated within Shell process | Completely separate process |
+| **Auditing** | Detailed logging available | MCP server dependent |
+| **Deployment** | Simple ZIP deployment | MCP server setup required |
+
+**Use Native Tool Packages when:**
+- Internal tools or handling sensitive data
+- Strict access control is required
+- Audit logging is mandatory
+- Network access should be restricted
+
+**Use MCP when:**
+- Using existing MCP servers
+- Integrating with external services
+- Using community-provided tools
+
+### Sandbox Execution Architecture
+
+Tools are executed in a sandboxed environment for security.
+
+**Architecture:**
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash (Main Process) │
+│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
+│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
+│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
+│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
+│ │ │ │ IPC │
+└─────────┼────────────────┼─────────────────────┼─────────────┘
+ │ │ │
+ │ ┌─────────────┴─────────────────────┘
+ │ │
+ ▼ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash.Shell (Sandboxed Process) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ AppContainer (Windows) / Bubblewrap (Linux) │ │
+│ │ - File system access control │ │
+│ │ - Network access control │ │
+│ │ - Process execution control │ │
+│ │ - Folder policy enforcement │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ AssemblyLoadContext (isCollectible: true) │ │
+│ │ - Tool DLLs loaded in isolated context │ │
+│ │ - Can be unloaded when tool is removed │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+**Execution Flow:**
+
+1. **Tool Invocation:**
+ - Kernel → ToolProxy → ShellServer (IPC)
+ - ShellServer → Shell (inside sandbox)
+ - Shell → AssemblyLoadContext → Tool DLL
+ - Results returned in reverse order
+
+2. **Isolation Mechanism:**
+ - Each tool package is loaded in a separate `AssemblyLoadContext`
+ - Unloadable (`isCollectible: true`)
+ - Memory released when tool is removed
+
+3. **Security Boundaries:**
+ - **Process Isolation**: Main ↔ Shell are separate processes
+ - **OS-level Isolation**: AppContainer/Bubblewrap restricts resources
+ - **Folder Policies**: Path-based access control
+
+**AppContainer Capabilities (Windows):**
+
+```json
+{
+ "Sandbox": {
+ "Type": "AppContainer",
+ "AppContainerName": "Clawleash.Sandbox",
+ "Capabilities": "InternetClient, PrivateNetworkClientServer"
+ }
+}
+```
+
+| Capability | Allowed Operations |
+|------------|-------------------|
+| `InternetClient` | Outbound internet connections |
+| `PrivateNetworkClientServer` | Private network connections |
+| None | No network access |
+
+**Folder Policy Control:**
+
+```json
+{
+ "Sandbox": {
+ "FolderPolicies": [
+ {
+ "Path": "C:\\Work",
+ "Access": "ReadWrite",
+ "Execute": "Deny",
+ "DeniedExtensions": [".exe", ".bat", ".ps1"]
+ }
+ ]
+ }
+}
+```
+
+---
+
## Development
```bash
diff --git a/README.md b/README.md
index 0b02c22..d667c52 100644
--- a/README.md
+++ b/README.md
@@ -586,6 +586,23 @@ dotnet run --project Clawleash.Server
ホットリロード対応:新しいDLLを配置すると自動的に読み込まれます。
+### カスタムプロバイダーの作成
+
+独自のチャットインターフェースを作成して追加できます。
+
+**手順:**
+1. `Clawleash.Abstractions` を参照したクラスライブラリプロジェクトを作成
+2. `IChatInterface` を実装
+3. ビルドして `%LocalAppData%\Clawleash\Interfaces\` に配置
+
+詳細な開発ガイドは [Clawleash.Abstractions/README.md](Clawleash.Abstractions/README.md) を参照してください。
+
+**実装例:**
+- [Discord](Clawleash.Interfaces.Discord) - Discord Bot
+- [Slack](Clawleash.Interfaces.Slack) - Slack Bot
+- [WebSocket](Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
+- [WebRTC](Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+
### スキルの追加
```
@@ -612,6 +629,272 @@ dotnet run --project Clawleash.Server
---
+## 拡張機能の開発
+
+### MCPサーバーの追加
+
+外部MCPサーバーを追加して、そのツールをClawleash内で使用できます。
+
+**appsettings.json:**
+
+```json
+{
+ "Mcp": {
+ "Enabled": true,
+ "Servers": [
+ {
+ "name": "filesystem",
+ "transport": "stdio",
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
+ "enabled": true,
+ "timeoutMs": 30000,
+ "useSandbox": true
+ },
+ {
+ "name": "github",
+ "transport": "stdio",
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-github"],
+ "environment": {
+ "GITHUB_TOKEN": "${GITHUB_TOKEN}"
+ },
+ "enabled": true
+ },
+ {
+ "name": "remote-server",
+ "transport": "sse",
+ "url": "https://api.example.com/mcp/sse",
+ "headers": {
+ "Authorization": "Bearer ${API_KEY}"
+ },
+ "enabled": true,
+ "timeoutMs": 60000
+ }
+ ]
+ }
+}
+```
+
+**MCP設定プロパティ:**
+
+| プロパティ | 説明 | 必須 |
+|-----------|------|------|
+| `name` | サーバー名(一意識別子) | ✅ |
+| `transport` | `stdio` または `sse` | ✅ |
+| `command` | 実行コマンド(stdio用) | stdio時 |
+| `args` | コマンド引数 | |
+| `environment` | 環境変数 | |
+| `url` | サーバーURL(SSE用) | SSE時 |
+| `headers` | HTTPヘッダー(SSE用) | |
+| `enabled` | 有効/無効 | |
+| `timeoutMs` | タイムアウト(ミリ秒) | |
+| `useSandbox` | サンドボックスで実行 | |
+
+**使用可能なツールの確認:**
+
+```
+ユーザー: MCPサーバーのツール一覧を表示して
+AI: list_tools ツールを実行してツール一覧を表示
+```
+
+### ツールパッケージの作成
+
+ネイティブなFunction CallingライブラリをZIPパッケージとして追加できます。
+
+**1. プロジェクト作成**
+
+```xml
+
+
+ net10.0
+
+
+
+
+
+
+```
+
+**2. ツールクラスの実装**
+
+```csharp
+using Microsoft.SemanticKernel;
+
+namespace MyTools;
+
+public class WeatherTools
+{
+ [KernelFunction("get_weather")]
+ [Description("指定した都市の天気を取得します")]
+ public async Task GetWeatherAsync(
+ [Description("都市名")] string city,
+ [Description("単位(celsius/fahrenheit)")] string unit = "celsius")
+ {
+ // 天気取得ロジック
+ return $"{city}の天気: 晴れ, 気温: 25{unit}";
+ }
+
+ [KernelFunction("get_forecast")]
+ [Description("天気予報を取得します")]
+ public async Task GetForecastAsync(
+ [Description("都市名")] string city,
+ [Description("予報日数(1-7)")] int days = 3)
+ {
+ return $"{city}の{days}日間予報: 晴れ→曇り→雨";
+ }
+}
+```
+
+**3. マニフェスト作成(tool-manifest.json)**
+
+```json
+{
+ "name": "WeatherTools",
+ "version": "1.0.0",
+ "description": "天気情報ツール",
+ "mainAssembly": "MyTools.dll",
+ "dependencies": []
+}
+```
+
+**4. パッケージ作成**
+
+```bash
+# ZIPパッケージを作成
+zip -r WeatherTools.zip MyTools.dll tool-manifest.json
+
+# 配置
+cp WeatherTools.zip "%LocalAppData%\Clawleash\Packages\"
+```
+
+**パッケージ構成:**
+
+```
+WeatherTools.zip
+├── tool-manifest.json # マニフェスト
+├── MyTools.dll # メインアセンブリ
+└── (依存DLL) # 必要に応じて
+```
+
+**ホットリロード:** PackagesディレクトリにZIPを配置すると自動的にロードされます。
+
+#### ネイティブツールパッケージ vs MCP
+
+| 項目 | ネイティブツールパッケージ | MCP |
+|------|--------------------------|-----|
+| **実行環境** | サンドボックス内で直接実行 | 外部プロセス |
+| **アクセス制御** | AppContainer + フォルダーポリシー | MCPサーバー側で制御 |
+| **ネットワーク** | ケーパビリティで制御 | MCPサーバー次第 |
+| **プロセス分離** | Shellプロセス内で分離 | 完全に別プロセス |
+| **監査** | 詳細ログ可能 | MCPサーバー依存 |
+| **デプロイ** | ZIPで簡単配置 | MCPサーバー構築必要 |
+
+**ネイティブツールパッケージが推奨されるケース:**
+- 社内ツール・機密データを扱うツール
+- 厳密なアクセス制御が必要な場合
+- 監査ログが必須な環境
+- ネットワークアクセスを制限したい場合
+
+**MCPが推奨されるケース:**
+- 既存のMCPサーバーを利用したい場合
+- 外部サービスとの連携
+- コミュニティ提供のツールを使用したい場合
+
+### サンドボックス実行の仕組み
+
+ツールパッケージとシェルコマンドは、サンドボックス環境内で安全に実行されます。
+
+**アーキテクチャ:**
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash (Main Process) │
+│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
+│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
+│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
+│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
+│ │ │ │ │
+│ │ ToolProxy │ │ IPC │
+│ │ (経由で呼出) │ │ │
+└─────────┼────────────────┼─────────────────────┼─────────────┘
+ │ │ │
+ ▼ ▼ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash.Shell (Sandboxed Process) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ AssemblyLoadContext (分離ロード) │ │
+│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
+│ │ │ Tool DLL │ │ Tool DLL │ │ PowerShell │ │ │
+│ │ │ (分離済み) │ │ (分離済み) │ │ Constrained │ │ │
+│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ AppContainer (Windows) / Bubblewrap (Linux) │ │
+│ │ - ファイルシステムアクセス制御 │ │
+│ │ - ネットワークアクセス制御 │ │
+│ │ - プロセス実行制御 │ │
+│ │ - フォルダーポリシー適用 │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+**実行フロー:**
+
+1. **ツール呼び出し時:**
+ - Kernel → ToolProxy → ShellServer (IPC)
+ - ShellServer → Shell (サンドボックス内)
+ - Shell → AssemblyLoadContext → Tool DLL
+ - 結果を逆順で返却
+
+2. **分離の仕組み:**
+ - 各ツールパッケージは独立した`AssemblyLoadContext`でロード
+ - アンロード可能(`isCollectible: true`)
+ - ツール削除時にメモリ解放
+
+3. **セキュリティ境界:**
+ - **プロセス分離**: Main ↔ Shell は別プロセス
+ - **OSレベル分離**: AppContainer/Bubblewrap でリソース制限
+ - **フォルダーポリシー**: パスごとのアクセス制御
+
+**AppContainerケーパビリティ(Windows):**
+
+```json
+{
+ "Sandbox": {
+ "Type": "AppContainer",
+ "AppContainerName": "Clawleash.Sandbox",
+ "Capabilities": "InternetClient, PrivateNetworkClientServer"
+ }
+}
+```
+
+| ケーパビリティ | 許可される操作 |
+|--------------|---------------|
+| `InternetClient` | インターネットへの送信接続 |
+| `PrivateNetworkClientServer` | プライベートネットワークへの接続 |
+| なし | ネットワークアクセス禁止 |
+
+**フォルダーポリシーによる制御:**
+
+```json
+{
+ "Sandbox": {
+ "FolderPolicies": [
+ {
+ "Path": "C:\\Work",
+ "Access": "ReadWrite",
+ "Execute": "Deny",
+ "DeniedExtensions": [".exe", ".bat", ".ps1"]
+ }
+ ]
+ }
+}
+```
+
+---
+
## 開発
```bash
From 49b7dc051d1f33115fa4458045ce72f3b798a9a2 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 14:10:24 +0900
Subject: [PATCH 4/7] [add] ipc
---
README.md | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 255 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index d667c52..a4ff579 100644
--- a/README.md
+++ b/README.md
@@ -615,17 +615,263 @@ dotnet run --project Clawleash.Server
## IPC通信
+Main プロセスと Shell プロセス間の通信には ZeroMQ + MessagePack を使用します。
+
+### 通信仕様
+
| 項目 | 仕様 |
|------|------|
-| プロトコル | ZeroMQ (Router/Dealer) |
-| シリアライズ | MessagePack |
-| 方向 | Main (Server) ← Shell (Client) |
-
-**メッセージ種別:**
-- `ShellExecuteRequest/Response` - コマンド実行
-- `ToolInvokeRequest/Response` - ツール呼び出し
-- `ShellInitializeRequest/Response` - 初期化
-- `ShellPingRequest/Response` - 死活監視
+| ライブラリ | NetMQ (ZeroMQ .NET実装) |
+| パターン | Router/Dealer |
+| シリアライズ | MessagePack (Union属性によるポリモーフィズム) |
+| トランスポート | TCP (localhost) |
+| 方向 | Main (Router/Server) ↔ Shell (Dealer/Client) |
+
+### アーキテクチャ
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Main プロセス │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ RouterSocket (Server) │ │
+│ │ - ランダムポートでバインド │ │
+│ │ - 複数クライアント接続可能 │ │
+│ │ - Identity でクライアント識別 │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+ │
+ ZeroMQ (TCP)
+ │
+┌─────────────────────────────────────────────────────────────┐
+│ Shell プロセス (Sandboxed) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ DealerSocket (Client) │ │
+│ │ - 動的に割り当てられたIdentity │ │
+│ │ - 非同期リクエスト/レスポンス │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+### 接続フロー
+
+```
+Main Shell
+ │ │
+ │ 1. RouterSocket.BindRandomPort │
+ │ (例: tcp://127.0.0.1:5555) │
+ │ │
+ │ 2. プロセス起動 --server "tcp://..."
+ │ │
+ │ 3. DealerSocket.Connect()
+ │ │
+ │ ◄─────── ShellReadyMessage ───── │
+ │ (ProcessId, Runtime, OS) │
+ │ │
+ │ ──── ShellInitializeRequest ────►│
+ │ (AllowedCommands, Paths) │
+ │ │
+ │ ◄─── ShellInitializeResponse ───│
+ │ (Success, Version) │
+ │ │
+ │ 準備完了 │
+```
+
+### メッセージ一覧
+
+#### 基本メッセージ(全メッセージ共通)
+
+```csharp
+public abstract class ShellMessage
+{
+ public string MessageId { get; set; } // 一意識別子
+ public DateTime Timestamp { get; set; } // UTC タイムスタンプ
+}
+```
+
+#### 1. ShellReadyMessage (Shell → Main)
+
+接続完了時に送信される準備完了通知。
+
+```csharp
+public class ShellReadyMessage : ShellMessage
+{
+ public int ProcessId { get; set; } // Shell プロセス ID
+ public string Runtime { get; set; } // .NET ランタイム情報
+ public string OS { get; set; } // OS 情報
+}
+```
+
+#### 2. ShellInitializeRequest/Response (Main ↔ Shell)
+
+Shell 実行環境の初期化。
+
+**Request:**
+```csharp
+public class ShellInitializeRequest : ShellMessage
+{
+ public string[] AllowedCommands { get; set; } // 許可コマンド
+ public string[] AllowedPaths { get; set; } // 読み書き許可パス
+ public string[] ReadOnlyPaths { get; set; } // 読み取り専用パス
+ public ShellLanguageMode LanguageMode { get; set; } // ConstrainedLanguage
+}
+```
+
+**Response:**
+```csharp
+public class ShellInitializeResponse : ShellMessage
+{
+ public bool Success { get; set; }
+ public string? Error { get; set; }
+ public string Version { get; set; }
+ public string Runtime { get; set; }
+}
+```
+
+#### 3. ShellExecuteRequest/Response (Main ↔ Shell)
+
+PowerShell コマンドの実行。
+
+**Request:**
+```csharp
+public class ShellExecuteRequest : ShellMessage
+{
+ public string Command { get; set; } // 実行コマンド
+ public Dictionary Parameters { get; set; }
+ public string? WorkingDirectory { get; set; }
+ public int TimeoutMs { get; set; } = 30000;
+ public ShellExecutionMode Mode { get; set; }
+}
+```
+
+**Response:**
+```csharp
+public class ShellExecuteResponse : ShellMessage
+{
+ public string RequestId { get; set; }
+ public bool Success { get; set; }
+ public string Output { get; set; } // 標準出力
+ public string? Error { get; set; } // エラーメッセージ
+ public int ExitCode { get; set; }
+ public Dictionary Metadata { get; set; }
+}
+```
+
+#### 4. ToolInvokeRequest/Response (Main ↔ Shell)
+
+ツールパッケージのメソッド呼び出し。
+
+**Request:**
+```csharp
+public class ToolInvokeRequest : ShellMessage
+{
+ public string ToolName { get; set; } // ツール名
+ public string MethodName { get; set; } // メソッド名
+ public object?[] Arguments { get; set; } // 引数
+}
+```
+
+**Response:**
+```csharp
+public class ToolInvokeResponse : ShellMessage
+{
+ public string RequestId { get; set; }
+ public bool Success { get; set; }
+ public object? Result { get; set; } // 戻り値
+ public string? Error { get; set; }
+}
+```
+
+#### 5. ShellPingRequest/Response (Main ↔ Shell)
+
+死活監視・レイテンシ測定。
+
+**Request:**
+```csharp
+public class ShellPingRequest : ShellMessage
+{
+ public string Payload { get; set; } = "ping";
+}
+```
+
+**Response:**
+```csharp
+public class ShellPingResponse : ShellMessage
+{
+ public string Payload { get; set; } = "pong";
+ public long ProcessingTimeMs { get; set; } // 処理時間
+}
+```
+
+#### 6. ShellShutdownRequest/Response (Main ↔ Shell)
+
+Shell プロセスのシャットダウン。
+
+**Request:**
+```csharp
+public class ShellShutdownRequest : ShellMessage
+{
+ public bool Force { get; set; } // 強制終了フラグ
+}
+```
+
+**Response:**
+```csharp
+public class ShellShutdownResponse : ShellMessage
+{
+ public bool Success { get; set; }
+}
+```
+
+### MessagePack シリアライズ
+
+```csharp
+// Union 属性でポリモーフィック デシリアライズ
+[MessagePackObject]
+[Union(0, typeof(ShellExecuteRequest))]
+[Union(1, typeof(ShellExecuteResponse))]
+[Union(2, typeof(ShellInitializeRequest))]
+// ...
+public abstract class ShellMessage { ... }
+
+// シリアライズ
+var data = MessagePackSerializer.Serialize(request);
+
+// デシリアライズ
+var message = MessagePackSerializer.Deserialize(data);
+```
+
+### エラーハンドリング
+
+```csharp
+try
+{
+ var response = await shellServer.ExecuteAsync(request);
+ if (!response.Success)
+ {
+ // コマンド実行失敗
+ Console.WriteLine($"Error: {response.Error}");
+ }
+}
+catch (TimeoutException)
+{
+ // Shell からの応答なし
+}
+catch (InvalidOperationException)
+{
+ // Shell に接続されていない
+}
+```
+
+### タイムアウト設定
+
+```csharp
+var options = new ShellServerOptions
+{
+ StartTimeoutMs = 10000, // 起動タイムアウト
+ CommunicationTimeoutMs = 30000, // 通信タイムアウト
+ Verbose = true // 詳細ログ
+};
+```
---
From ee76a6f01de3c1c637ae16ddd7cc119fc3a4c0a1 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 14:10:49 +0900
Subject: [PATCH 5/7] [add] ipc en
---
README-en.md | 264 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 255 insertions(+), 9 deletions(-)
diff --git a/README-en.md b/README-en.md
index e855ba4..c2187ee 100644
--- a/README-en.md
+++ b/README-en.md
@@ -615,17 +615,263 @@ See [Clawleash.Abstractions/README.md](Clawleash.Abstractions/README.md) for det
## IPC Communication
+Communication between Main and Shell processes uses ZeroMQ + MessagePack.
+
+### Communication Specification
+
| Item | Specification |
|------|---------------|
-| Protocol | ZeroMQ (Router/Dealer) |
-| Serialization | MessagePack |
-| Direction | Main (Server) ← Shell (Client) |
-
-**Message Types:**
-- `ShellExecuteRequest/Response` - Command execution
-- `ToolInvokeRequest/Response` - Tool invocation
-- `ShellInitializeRequest/Response` - Initialization
-- `ShellPingRequest/Response` - Health check
+| Library | NetMQ (ZeroMQ .NET implementation) |
+| Pattern | Router/Dealer |
+| Serialization | MessagePack (Union attribute for polymorphism) |
+| Transport | TCP (localhost) |
+| Direction | Main (Router/Server) ↔ Shell (Dealer/Client) |
+
+### Architecture
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Main Process │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ RouterSocket (Server) │ │
+│ │ - Bind to random port │ │
+│ │ - Multiple client connections supported │ │
+│ │ - Client identification via Identity │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+ │
+ ZeroMQ (TCP)
+ │
+┌─────────────────────────────────────────────────────────────┐
+│ Shell Process (Sandboxed) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ DealerSocket (Client) │ │
+│ │ - Dynamically assigned Identity │ │
+│ │ - Async request/response │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+### Connection Flow
+
+```
+Main Shell
+ │ │
+ │ 1. RouterSocket.BindRandomPort │
+ │ (e.g., tcp://127.0.0.1:5555) │
+ │ │
+ │ 2. Process start --server "tcp://..."
+ │ │
+ │ 3. DealerSocket.Connect()
+ │ │
+ │ ◄─────── ShellReadyMessage ───── │
+ │ (ProcessId, Runtime, OS) │
+ │ │
+ │ ──── ShellInitializeRequest ────►│
+ │ (AllowedCommands, Paths) │
+ │ │
+ │ ◄─── ShellInitializeResponse ───│
+ │ (Success, Version) │
+ │ │
+ │ Ready │
+```
+
+### Message Types
+
+#### Base Message (Common to All Messages)
+
+```csharp
+public abstract class ShellMessage
+{
+ public string MessageId { get; set; } // Unique identifier
+ public DateTime Timestamp { get; set; } // UTC timestamp
+}
+```
+
+#### 1. ShellReadyMessage (Shell → Main)
+
+Ready notification sent on connection completion.
+
+```csharp
+public class ShellReadyMessage : ShellMessage
+{
+ public int ProcessId { get; set; } // Shell process ID
+ public string Runtime { get; set; } // .NET runtime info
+ public string OS { get; set; } // OS information
+}
+```
+
+#### 2. ShellInitializeRequest/Response (Main ↔ Shell)
+
+Initialize the Shell execution environment.
+
+**Request:**
+```csharp
+public class ShellInitializeRequest : ShellMessage
+{
+ public string[] AllowedCommands { get; set; } // Permitted commands
+ public string[] AllowedPaths { get; set; } // Read/write allowed paths
+ public string[] ReadOnlyPaths { get; set; } // Read-only paths
+ public ShellLanguageMode LanguageMode { get; set; } // ConstrainedLanguage
+}
+```
+
+**Response:**
+```csharp
+public class ShellInitializeResponse : ShellMessage
+{
+ public bool Success { get; set; }
+ public string? Error { get; set; }
+ public string Version { get; set; }
+ public string Runtime { get; set; }
+}
+```
+
+#### 3. ShellExecuteRequest/Response (Main ↔ Shell)
+
+Execute PowerShell commands.
+
+**Request:**
+```csharp
+public class ShellExecuteRequest : ShellMessage
+{
+ public string Command { get; set; } // Command to execute
+ public Dictionary Parameters { get; set; }
+ public string? WorkingDirectory { get; set; }
+ public int TimeoutMs { get; set; } = 30000;
+ public ShellExecutionMode Mode { get; set; }
+}
+```
+
+**Response:**
+```csharp
+public class ShellExecuteResponse : ShellMessage
+{
+ public string RequestId { get; set; }
+ public bool Success { get; set; }
+ public string Output { get; set; } // Standard output
+ public string? Error { get; set; } // Error message
+ public int ExitCode { get; set; }
+ public Dictionary Metadata { get; set; }
+}
+```
+
+#### 4. ToolInvokeRequest/Response (Main ↔ Shell)
+
+Invoke methods from tool packages.
+
+**Request:**
+```csharp
+public class ToolInvokeRequest : ShellMessage
+{
+ public string ToolName { get; set; } // Tool name
+ public string MethodName { get; set; } // Method name
+ public object?[] Arguments { get; set; } // Arguments
+}
+```
+
+**Response:**
+```csharp
+public class ToolInvokeResponse : ShellMessage
+{
+ public string RequestId { get; set; }
+ public bool Success { get; set; }
+ public object? Result { get; set; } // Return value
+ public string? Error { get; set; }
+}
+```
+
+#### 5. ShellPingRequest/Response (Main ↔ Shell)
+
+Health monitoring and latency measurement.
+
+**Request:**
+```csharp
+public class ShellPingRequest : ShellMessage
+{
+ public string Payload { get; set; } = "ping";
+}
+```
+
+**Response:**
+```csharp
+public class ShellPingResponse : ShellMessage
+{
+ public string Payload { get; set; } = "pong";
+ public long ProcessingTimeMs { get; set; } // Processing time
+}
+```
+
+#### 6. ShellShutdownRequest/Response (Main ↔ Shell)
+
+Shutdown the Shell process.
+
+**Request:**
+```csharp
+public class ShellShutdownRequest : ShellMessage
+{
+ public bool Force { get; set; } // Force shutdown flag
+}
+```
+
+**Response:**
+```csharp
+public class ShellShutdownResponse : ShellMessage
+{
+ public bool Success { get; set; }
+}
+```
+
+### MessagePack Serialization
+
+```csharp
+// Union attribute for polymorphic deserialization
+[MessagePackObject]
+[Union(0, typeof(ShellExecuteRequest))]
+[Union(1, typeof(ShellExecuteResponse))]
+[Union(2, typeof(ShellInitializeRequest))]
+// ...
+public abstract class ShellMessage { ... }
+
+// Serialize
+var data = MessagePackSerializer.Serialize(request);
+
+// Deserialize
+var message = MessagePackSerializer.Deserialize(data);
+```
+
+### Error Handling
+
+```csharp
+try
+{
+ var response = await shellServer.ExecuteAsync(request);
+ if (!response.Success)
+ {
+ // Command execution failed
+ Console.WriteLine($"Error: {response.Error}");
+ }
+}
+catch (TimeoutException)
+{
+ // No response from Shell
+}
+catch (InvalidOperationException)
+{
+ // Shell not connected
+}
+```
+
+### Timeout Configuration
+
+```csharp
+var options = new ShellServerOptions
+{
+ StartTimeoutMs = 10000, // Startup timeout
+ CommunicationTimeoutMs = 30000, // Communication timeout
+ Verbose = true // Verbose logging
+};
+```
---
From e376a6569c810c310e653a6c7fa4d6ee023b7279 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 14:20:06 +0900
Subject: [PATCH 6/7] [add] en docs
---
Clawleash.Abstractions/README-en.md | 433 ++++++++++++++++++++
Clawleash.Abstractions/README.md | 8 +-
Clawleash.Interfaces.Discord/README-en.md | 167 ++++++++
Clawleash.Interfaces.Discord/README.md | 4 +
Clawleash.Interfaces.Slack/README-en.md | 169 ++++++++
Clawleash.Interfaces.Slack/README.md | 4 +
Clawleash.Interfaces.WebRTC/README-en.md | 197 +++++++++
Clawleash.Interfaces.WebRTC/README.md | 6 +
Clawleash.Interfaces.WebSocket/README-en.md | 201 +++++++++
Clawleash.Interfaces.WebSocket/README.md | 5 +-
Clawleash.Server/README-en.md | 209 ++++++++++
Clawleash.Server/README.md | 5 +-
Clawleash.Shell/README-en.md | 199 +++++++++
Clawleash.Shell/README.md | 3 +-
README-en.md | 10 +-
README.md | 10 +-
16 files changed, 1611 insertions(+), 19 deletions(-)
create mode 100644 Clawleash.Abstractions/README-en.md
create mode 100644 Clawleash.Interfaces.Discord/README-en.md
create mode 100644 Clawleash.Interfaces.Slack/README-en.md
create mode 100644 Clawleash.Interfaces.WebRTC/README-en.md
create mode 100644 Clawleash.Interfaces.WebSocket/README-en.md
create mode 100644 Clawleash.Server/README-en.md
create mode 100644 Clawleash.Shell/README-en.md
diff --git a/Clawleash.Abstractions/README-en.md b/Clawleash.Abstractions/README-en.md
new file mode 100644
index 0000000..721a0e6
--- /dev/null
+++ b/Clawleash.Abstractions/README-en.md
@@ -0,0 +1,433 @@
+# Clawleash.Abstractions
+
+A library defining shared interfaces and abstractions for Clawleash. Provides the foundation for creating custom chat interface providers.
+
+## Overview
+
+This library provides:
+
+- **IChatInterface**: Chat interface abstraction
+- **ChatMessageReceivedEventArgs**: Message received event arguments
+- **IStreamingMessageWriter**: For streaming message sending
+- **ChatInterfaceSettingsBase**: Base class for settings
+- **IE2eeProvider**: E2EE encryption provider
+
+---
+
+## Creating Custom Providers
+
+### 1. Project Creation
+
+Create a new class library project and reference `Clawleash.Abstractions`:
+
+```xml
+
+
+ net10.0
+
+
+
+
+
+
+```
+
+### 2. Creating Settings Class
+
+Create a settings class inheriting from `ChatInterfaceSettingsBase`:
+
+```csharp
+using Clawleash.Abstractions.Configuration;
+
+namespace Clawleash.Interfaces.MyProvider;
+
+public class MyProviderSettings : ChatInterfaceSettingsBase
+{
+ ///
+ /// Server URL to connect to
+ ///
+ public string ServerUrl { get; set; } = "https://api.example.com";
+
+ ///
+ /// API Key
+ ///
+ public string ApiKey { get; set; } = string.Empty;
+
+ ///
+ /// Reconnection interval (milliseconds)
+ ///
+ public int ReconnectIntervalMs { get; set; } = 5000;
+}
+```
+
+### 3. Implementing IChatInterface
+
+```csharp
+using System.Text;
+using Clawleash.Abstractions.Services;
+using Microsoft.Extensions.Logging;
+
+namespace Clawleash.Interfaces.MyProvider;
+
+public class MyProviderChatInterface : IChatInterface
+{
+ private readonly MyProviderSettings _settings;
+ private readonly ILogger? _logger;
+ private bool _isConnected;
+ private bool _disposed;
+
+ // Required properties
+ public string Name => "MyProvider";
+ public bool IsConnected => _isConnected;
+
+ // Required event
+ public event EventHandler? MessageReceived;
+
+ public MyProviderChatInterface(
+ MyProviderSettings settings,
+ ILogger? logger = null)
+ {
+ _settings = settings ?? throw new ArgumentNullException(nameof(settings));
+ _logger = logger;
+ }
+
+ // Required method: Start interface
+ public async Task StartAsync(CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(_settings.ApiKey))
+ {
+ _logger?.LogWarning("API key is not configured");
+ return;
+ }
+
+ try
+ {
+ // Implement connection logic
+ await ConnectAsync(cancellationToken);
+ _isConnected = true;
+ _logger?.LogInformation("{Name} connected", Name);
+ }
+ catch (Exception ex)
+ {
+ _logger?.LogError(ex, "Failed to start {Name}", Name);
+ throw;
+ }
+ }
+
+ // Required method: Stop interface
+ public async Task StopAsync(CancellationToken cancellationToken = default)
+ {
+ _isConnected = false;
+ // Implement disconnection logic
+ await Task.CompletedTask;
+ _logger?.LogInformation("{Name} stopped", Name);
+ }
+
+ // Required method: Send message
+ public async Task SendMessageAsync(
+ string message,
+ string? replyToMessageId = null,
+ CancellationToken cancellationToken = default)
+ {
+ if (!IsConnected)
+ {
+ _logger?.LogWarning("{Name} is not connected", Name);
+ return;
+ }
+
+ // Implement message sending logic
+ // If replyToMessageId is present, send as a reply
+ await Task.CompletedTask;
+ }
+
+ // Required method: Start streaming message
+ public IStreamingMessageWriter StartStreamingMessage(CancellationToken cancellationToken = default)
+ {
+ return new MyStreamingWriter(this);
+ }
+
+ // Required method: Dispose resources
+ public async ValueTask DisposeAsync()
+ {
+ if (_disposed) return;
+ _disposed = true;
+
+ await StopAsync();
+ }
+
+ // Internal method: Call when message is received
+ protected virtual void OnMessageReceived(string content, string senderId, string senderName)
+ {
+ var args = new ChatMessageReceivedEventArgs
+ {
+ MessageId = Guid.NewGuid().ToString(),
+ SenderId = senderId,
+ SenderName = senderName,
+ Content = content,
+ ChannelId = "default",
+ Timestamp = DateTime.UtcNow,
+ InterfaceName = Name,
+ RequiresReply = true,
+ Metadata = new Dictionary
+ {
+ // Provider-specific metadata
+ ["custom_field"] = "value"
+ }
+ };
+
+ MessageReceived?.Invoke(this, args);
+ }
+
+ private async Task ConnectAsync(CancellationToken ct)
+ {
+ // Actual connection logic
+ await Task.CompletedTask;
+ }
+}
+
+// Streaming writer implementation
+internal class MyStreamingWriter : IStreamingMessageWriter
+{
+ private readonly StringBuilder _content = new();
+ private readonly MyProviderChatInterface _interface;
+
+ public string MessageId { get; } = Guid.NewGuid().ToString();
+
+ public MyStreamingWriter(MyProviderChatInterface iface)
+ {
+ _interface = iface;
+ }
+
+ public Task AppendTextAsync(string text, CancellationToken cancellationToken = default)
+ {
+ _content.Append(text);
+ return Task.CompletedTask;
+ }
+
+ public async Task CompleteAsync(CancellationToken cancellationToken = default)
+ {
+ var message = _content.ToString();
+ if (!string.IsNullOrEmpty(message))
+ {
+ await _interface.SendMessageAsync(message, null, cancellationToken);
+ }
+ }
+
+ public ValueTask DisposeAsync() => ValueTask.CompletedTask;
+}
+```
+
+---
+
+## Provider Deployment
+
+### Build
+
+```bash
+cd Clawleash.Interfaces.MyProvider
+dotnet build -c Release
+```
+
+### Installation
+
+Copy DLL and dependencies to the interfaces directory:
+
+```
+%LocalAppData%\Clawleash\Interfaces\MyProvider\
+├── Clawleash.Interfaces.MyProvider.dll
+├── Clawleash.Abstractions.dll
+└── (other dependency DLLs)
+```
+
+### Auto-Recognition
+
+When files are placed while the application is running, they are automatically loaded (when hot-reload is enabled).
+
+---
+
+## Settings Integration
+
+### Adding to appsettings.json
+
+```json
+{
+ "ChatInterface": {
+ "EnableHotReload": true,
+ "MyProvider": {
+ "Enabled": true,
+ "ServerUrl": "https://api.example.com",
+ "ApiKey": "${MY_PROVIDER_API_KEY}",
+ "EnableE2ee": false
+ }
+ }
+}
+```
+
+### DI Registration
+
+Providers are instantiated using `ActivatorUtilities.CreateInstance`, so register settings and logger in DI:
+
+```csharp
+// Register settings in Program.cs
+services.Configure(
+ configuration.GetSection("ChatInterface:MyProvider"));
+```
+
+---
+
+## ChatMessageReceivedEventArgs Properties
+
+| Property | Type | Description |
+|-----------|-----|------|
+| `MessageId` | `string` | Unique message identifier |
+| `SenderId` | `string` | Unique sender identifier |
+| `SenderName` | `string` | Sender display name |
+| `Content` | `string` | Message content |
+| `ChannelId` | `string` | Channel/Room ID |
+| `Timestamp` | `DateTime` | Message timestamp (UTC) |
+| `ReplyToMessageId` | `string?` | Reply target message ID |
+| `RequiresReply` | `bool` | Whether reply is required |
+| `InterfaceName` | `string` | Interface name |
+| `Metadata` | `Dictionary` | Provider-specific metadata |
+
+---
+
+## IChatInterface Members
+
+### Properties
+
+| Property | Type | Description |
+|-----------|-----|------|
+| `Name` | `string` | Interface name (unique) |
+| `IsConnected` | `bool` | Connection state |
+
+### Events
+
+| Event | Description |
+|----------|------|
+| `MessageReceived` | Raised when message is received |
+
+### Methods
+
+| Method | Description |
+|----------|------|
+| `StartAsync(CancellationToken)` | Start interface |
+| `StopAsync(CancellationToken)` | Stop interface |
+| `SendMessageAsync(message, replyToMessageId?, CancellationToken)` | Send message |
+| `StartStreamingMessage(CancellationToken)` | Start streaming message |
+| `DisposeAsync()` | Release resources |
+
+---
+
+## E2EE Support
+
+To support E2EE (End-to-End Encryption):
+
+### 1. Using IE2eeProvider
+
+```csharp
+using Clawleash.Abstractions.Security;
+
+public class MySecureProvider : IChatInterface
+{
+ private readonly IE2eeProvider _e2eeProvider;
+
+ public MySecureProvider(MyProviderSettings settings, IE2eeProvider e2eeProvider)
+ {
+ _e2eeProvider = e2eeProvider;
+ }
+
+ public async Task SendMessageAsync(string message, ...)
+ {
+ if (_settings.EnableE2ee && _e2eeProvider.IsEncrypted)
+ {
+ var ciphertext = await _e2eeProvider.EncryptAsync(message, channelId);
+ // Send encrypted data
+ }
+ else
+ {
+ // Send plaintext
+ }
+ }
+}
+```
+
+### 2. Enable in Settings
+
+```json
+{
+ "ChatInterface": {
+ "MyProvider": {
+ "Enabled": true,
+ "EnableE2ee": true
+ }
+ }
+}
+```
+
+---
+
+## Best Practices
+
+### Error Handling
+
+```csharp
+public async Task StartAsync(CancellationToken cancellationToken = default)
+{
+ try
+ {
+ await ConnectAsync(cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger?.LogError(ex, "Connection failed");
+ // Update connection state
+ _isConnected = false;
+ throw;
+ }
+}
+```
+
+### Logging
+
+```csharp
+// Use structured logging
+_logger?.LogInformation("{Name} starting with server: {ServerUrl}", Name, _settings.ServerUrl);
+_logger?.LogDebug("Message received: {MessageId} from {SenderName}", args.MessageId, args.SenderName);
+```
+
+### Resource Management
+
+```csharp
+public async ValueTask DisposeAsync()
+{
+ if (_disposed) return;
+ _disposed = true;
+
+ // Unsubscribe from events
+ // _client.OnMessage -= OnMessage;
+
+ // Disconnect
+ await StopAsync();
+
+ // Release other resources
+ _httpClient?.Dispose();
+}
+```
+
+---
+
+## Reference Implementations
+
+For implementation reference, see these providers:
+
+- [Clawleash.Interfaces.Discord](../Clawleash.Interfaces.Discord/README-en.md) - Discord Bot
+- [Clawleash.Interfaces.Slack](../Clawleash.Interfaces.Slack/README-en.md) - Slack Bot
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README-en.md) - WebSocket (E2EE)
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README-en.md) - WebRTC (E2EE)
+
+---
+
+## License
+
+MIT
diff --git a/Clawleash.Abstractions/README.md b/Clawleash.Abstractions/README.md
index 888ce0a..e92efca 100644
--- a/Clawleash.Abstractions/README.md
+++ b/Clawleash.Abstractions/README.md
@@ -421,10 +421,10 @@ public async ValueTask DisposeAsync()
実装の参考として、以下のプロバイダーを参照してください:
-- [Clawleash.Interfaces.Discord](../Clawleash.Interfaces.Discord) - Discord Bot
-- [Clawleash.Interfaces.Slack](../Clawleash.Interfaces.Slack) - Slack Bot
-- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
-- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+- [Clawleash.Interfaces.Discord](../Clawleash.Interfaces.Discord/README.md) - Discord Bot
+- [Clawleash.Interfaces.Slack](../Clawleash.Interfaces.Slack/README.md) - Slack Bot
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README.md) - WebSocket (E2EE)
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README.md) - WebRTC (E2EE)
---
diff --git a/Clawleash.Interfaces.Discord/README-en.md b/Clawleash.Interfaces.Discord/README-en.md
new file mode 100644
index 0000000..7d0bb58
--- /dev/null
+++ b/Clawleash.Interfaces.Discord/README-en.md
@@ -0,0 +1,167 @@
+# Clawleash.Interfaces.Discord
+
+A complete implementation of Discord Bot chat interface. Uses Discord.NET to receive messages from Discord servers and DMs, integrating with the AI agent.
+
+## Features
+
+- **Real-time Message Reception**: Real-time message monitoring using Gateway Intents
+- **Command Prefix Support**: Identify commands with prefixes like `!`
+- **Thread Replies**: Respond in reply format to original messages
+- **DM Support**: Works in direct messages (no prefix required)
+- **Streaming Send**: Support for batch sending of long messages
+
+## Architecture
+
+```
+┌──────────────────────────────────────────────────┐
+│ DiscordChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ DiscordSocketClient (Discord.NET) │ │
+│ │ - Gateway Intents │ │
+│ │ - Message Received Events │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Discord Gateway │
+ │ (WebSocket) │
+ └───────────────────────┘
+```
+
+## Usage
+
+### Settings
+
+```csharp
+var settings = new DiscordSettings
+{
+ Token = "YOUR_BOT_TOKEN",
+ CommandPrefix = "!",
+ UseThreads = false,
+ UseEmbeds = true
+};
+```
+
+### Basic Usage
+
+```csharp
+var chatInterface = new DiscordChatInterface(settings, logger);
+
+// Event handler
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Guild: {args.Metadata["GuildName"]}");
+ Console.WriteLine($"Channel: {args.Metadata["ChannelName"]}");
+ Console.WriteLine($"Is DM: {args.Metadata["IsDirectMessage"]}");
+};
+
+// Start
+await chatInterface.StartAsync(cancellationToken);
+
+// Send message (reply format)
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// Dispose
+await chatInterface.DisposeAsync();
+```
+
+## Configuration Options
+
+| Property | Description | Default |
+|-----------|------|-----------|
+| `Token` | Discord Bot Token | (Required) |
+| `CommandPrefix` | Command prefix (ignored in DMs) | `!` |
+| `UseThreads` | Whether to reply in threads | `false` |
+| `UseEmbeds` | Whether to use embed messages | `true` |
+
+## Events
+
+### MessageReceived
+
+Event raised when a message is received.
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - Message ID
+ // args.SenderId - Sender Discord ID
+ // args.SenderName - Sender name (global name preferred)
+ // args.Content - Message content (prefix removed)
+ // args.ChannelId - Channel ID
+ // args.Timestamp - Timestamp
+ // args.Metadata["GuildId"] - Server ID
+ // args.Metadata["GuildName"] - Server name
+ // args.Metadata["ChannelName"] - Channel name
+ // args.Metadata["IsDirectMessage"] - Whether it's a DM
+ // args.Metadata["IsThread"] - Whether it's a thread
+};
+```
+
+## Bot Setup
+
+### Required Permissions
+
+- **Read Messages**: Read messages
+- **Send Messages**: Send messages
+- **Read Message History**: Read message history (for replies)
+- **View Channels**: View channels
+
+### Gateway Intents
+
+The following Intents are required:
+
+- `MessageContent` - Read message content
+- `GuildMessages` - Receive server messages
+- `DirectMessages` - Receive DMs
+
+## Troubleshooting
+
+### "Privileged intent provided is not enabled"
+
+Enable Message Content Intent in Bot settings:
+1. Open Discord Developer Portal
+2. Select the target application
+3. Bot tab → Privileged Gateway Intents
+4. Enable "Message Content Intent"
+
+### "Discord token is not configured"
+
+Verify Token is correctly set in `appsettings.json`:
+
+```json
+{
+ "ChatInterface": {
+ "Discord": {
+ "Enabled": true,
+ "Token": "${DISCORD_BOT_TOKEN}"
+ }
+ }
+}
+```
+
+### Commands Not Responding
+
+- Verify command prefix is correct
+- Check if bot has access to the channel
+- In DMs, send without prefix
+
+## Build
+
+```bash
+cd Clawleash.Interfaces.Discord
+dotnet build
+```
+
+## Dependencies
+
+- Discord.NET (latest stable)
+- Clawleash.Abstractions
+
+## Related Projects
+
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README-en.md) - Shared interfaces
+
+## License
+
+MIT
diff --git a/Clawleash.Interfaces.Discord/README.md b/Clawleash.Interfaces.Discord/README.md
index ff785b1..2341143 100644
--- a/Clawleash.Interfaces.Discord/README.md
+++ b/Clawleash.Interfaces.Discord/README.md
@@ -158,6 +158,10 @@ dotnet build
- Discord.NET (最新安定版)
- Clawleash.Abstractions
+## 関連プロジェクト
+
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
+
## ライセンス
MIT
diff --git a/Clawleash.Interfaces.Slack/README-en.md b/Clawleash.Interfaces.Slack/README-en.md
new file mode 100644
index 0000000..e110a6c
--- /dev/null
+++ b/Clawleash.Interfaces.Slack/README-en.md
@@ -0,0 +1,169 @@
+# Clawleash.Interfaces.Slack
+
+A complete implementation of Slack Bot chat interface. Uses HTTP API + polling to receive messages from Slack, integrating with the AI agent.
+
+## Features
+
+- **HTTP API Polling**: Message retrieval using conversations.history API
+- **Thread Replies**: Respond in thread format to original messages
+- **DM Support**: Send and receive direct messages
+- **Channel Management**: List, join, and leave channels
+- **Streaming Send**: Support for batch sending of long messages
+
+## Architecture
+
+```
+┌──────────────────────────────────────────────────┐
+│ SlackChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ HTTP Client + Polling Thread │ │
+│ │ - conversations.history polling │ │
+│ │ - Message deduplication │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Slack Web API │
+ │ (HTTPS) │
+ └───────────────────────┘
+```
+
+## Usage
+
+### Settings
+
+```csharp
+var settings = new SlackSettings
+{
+ BotToken = "xoxb-...",
+ AppToken = "xapp-...",
+ UseThreads = true,
+ UseBlockKit = false
+};
+```
+
+### Basic Usage
+
+```csharp
+var chatInterface = new SlackChatInterface(settings, logger);
+
+// Event handler
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Thread: {args.Metadata["ThreadTs"]}");
+ Console.WriteLine($"Is Thread: {args.Metadata["IsThread"]}");
+};
+
+// Start
+await chatInterface.StartAsync(cancellationToken);
+
+// Join channel
+await chatInterface.JoinChannelAsync("C12345678");
+
+// Send message (thread reply)
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// Send DM
+await chatInterface.SendDirectMessageAsync("U12345678", "Hello!");
+
+// Dispose
+await chatInterface.DisposeAsync();
+```
+
+## Configuration Options
+
+| Property | Description | Default |
+|-----------|------|-----------|
+| `BotToken` | Bot User OAuth Token (`xoxb-...`) | (Required) |
+| `AppToken` | App-Level Token (`xapp-...`) | (Empty) |
+| `SigningSecret` | For HTTP request validation | `null` |
+| `UseThreads` | Whether to reply in threads | `true` |
+| `UseBlockKit` | Whether to use Block Kit | `false` |
+
+## Events
+
+### MessageReceived
+
+Event raised when a message is received.
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - Message timestamp (ts)
+ // args.SenderId - Sender Slack ID
+ // args.SenderName - Sender display name
+ // args.Content - Message content
+ // args.ChannelId - Channel ID
+ // args.Timestamp - Timestamp
+ // args.Metadata["ThreadTs"] - Parent thread ts
+ // args.Metadata["IsThread"] - Whether in thread
+};
+```
+
+## Slack App Setup
+
+### Required OAuth Scopes
+
+- `channels:history` - Read public channel messages
+- `groups:history` - Read private channel messages
+- `im:history` - Read DM messages
+- `mpim:history` - Read group DM messages
+- `channels:read` - Get channel list
+- `groups:read` - Get private channel list
+- `im:read` - Get DM list
+- `im:write` - Send DMs
+- `chat:write` - Send messages
+
+### App Setup Steps
+
+1. Create an app at [Slack API](https://api.slack.com/apps)
+2. Add the above Scopes in OAuth & Permissions
+3. Install to Workspace
+4. Copy the Bot User OAuth Token (`xoxb-...`)
+
+## Polling Behavior
+
+- **Polling Interval**: 5 seconds
+- **Fetch Period**: Messages from the past 5 minutes
+- **Deduplication**: Processed message IDs retained for 10 minutes
+
+## Troubleshooting
+
+### "Failed to authenticate with Slack"
+
+Verify Bot Token is correct:
+- Token starts with `xoxb-`
+- Appropriate Scopes are granted
+
+### Messages Not Received
+
+1. Verify bot is invited to the channel
+2. Add channel to monitoring with `JoinChannelAsync`
+3. Verify required Scopes are granted
+
+### "rate_limited"
+
+Slack API rate limit reached:
+- Increase polling interval
+- Reduce number of monitored channels
+
+## Build
+
+```bash
+cd Clawleash.Interfaces.Slack
+dotnet build
+```
+
+## Dependencies
+
+- System.Text.Json
+- Clawleash.Abstractions
+
+## Related Projects
+
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README-en.md) - Shared interfaces
+
+## License
+
+MIT
diff --git a/Clawleash.Interfaces.Slack/README.md b/Clawleash.Interfaces.Slack/README.md
index abae070..7d608a2 100644
--- a/Clawleash.Interfaces.Slack/README.md
+++ b/Clawleash.Interfaces.Slack/README.md
@@ -160,6 +160,10 @@ dotnet build
- System.Text.Json
- Clawleash.Abstractions
+## 関連プロジェクト
+
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
+
## ライセンス
MIT
diff --git a/Clawleash.Interfaces.WebRTC/README-en.md b/Clawleash.Interfaces.WebRTC/README-en.md
new file mode 100644
index 0000000..3a9416f
--- /dev/null
+++ b/Clawleash.Interfaces.WebRTC/README-en.md
@@ -0,0 +1,197 @@
+# Clawleash.Interfaces.WebRTC
+
+A complete implementation of WebRTC chat interface. Establishes WebRTC P2P connections via SignalR signaling server and performs real-time communication through DataChannel.
+
+## Features
+
+- **Native WebRTC**: High-speed P2P communication using Rust (webrtc-rs) based native library
+- **Fallback Support**: Works in simulation mode when native library is unavailable
+- **E2EE Support**: End-to-end encryption for DataChannel communication
+- **STUN/TURN**: NAT traversal support (configurable STUN/TURN servers)
+- **Auto-Reconnect**: SignalR auto-reconnect and automatic peer connection recovery
+
+## Architecture
+
+```
+┌──────────────────────────────────────────────────┐
+│ WebRtcChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ WebRtcNativeClient (P/Invoke wrapper) │ │
+│ │ - Event polling thread │ │
+│ │ - Message serialization │ │
+│ └────────────────────────────────────────────┘ │
+│ │ P/Invoke │
+│ ▼ │
+│ ┌────────────────────────────────────────────┐ │
+│ │ webrtc_client.dll (Rust cdylib) │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ SignalR Server │
+ │ (Signaling) │
+ └───────────────────────┘
+```
+
+## Building Native Library
+
+### Prerequisites
+
+- Rust 1.70 or later
+- Cargo
+
+### Build Steps
+
+```bash
+# Navigate to webrtc-client repository
+cd ../webrtc-client
+
+# Release build
+cargo build --release -p webrtc-client-sys
+
+# Copy output files to Clowleash
+# Windows x64:
+copy target\release\webrtc_client.dll ..\Clowleash\Clawleash.Interfaces.WebRTC\Native\win-x64\
+
+# Linux x64:
+cp target/release/libwebrtc_client.so ../Clowleash/Clawleash.Interfaces.WebRTC/Native/linux-x64/
+
+# macOS x64:
+cp target/release/libwebrtc_client.dylib ../Clowleash/Clawleash.Interfaces.WebRTC/Native/osx-x64/
+```
+
+## Usage
+
+### Settings
+
+```csharp
+var settings = new WebRtcSettings
+{
+ SignalingServerUrl = "http://localhost:8080/signaling",
+ StunServers = new List
+ {
+ "stun:stun.l.google.com:19302",
+ "stun:stun1.l.google.com:19302"
+ },
+ TurnServerUrl = "turn:turn.example.com:3478", // Optional
+ TurnUsername = "user",
+ TurnPassword = "password",
+ EnableE2ee = true,
+ IceConnectionTimeoutMs = 30000,
+ MaxReconnectAttempts = 5
+};
+```
+
+### Basic Usage
+
+```csharp
+var chatInterface = new WebRtcChatInterface(settings, logger);
+
+// Event handler
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+};
+
+// Start
+await chatInterface.StartAsync(cancellationToken);
+
+// Send message
+await chatInterface.SendMessageAsync("Hello, World!");
+
+// Dispose
+await chatInterface.DisposeAsync();
+```
+
+## Configuration Options
+
+| Property | Description | Default |
+|-----------|------|-----------|
+| `SignalingServerUrl` | SignalR signaling server URL | `ws://localhost:8080/signaling` |
+| `StunServers` | STUN server URL list | Google STUN servers |
+| `TurnServerUrl` | TURN server URL | `null` |
+| `TurnUsername` | TURN username | `null` |
+| `TurnPassword` | TURN password | `null` |
+| `EnableE2ee` | Enable E2EE | `false` |
+| `IceConnectionTimeoutMs` | ICE connection timeout | `30000` |
+| `MaxReconnectAttempts` | Maximum reconnection attempts | `5` |
+| `ReconnectIntervalMs` | Reconnection interval | `5000` |
+| `TryUseNativeClient` | Try using native client | `true` |
+| `DataChannelReliable` | DataChannel reliability mode | `true` |
+| `HeartbeatIntervalMs` | Heartbeat interval | `30000` |
+
+## Events
+
+### MessageReceived
+
+Event raised when a message is received.
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - Message ID
+ // args.SenderId - Sender peer ID
+ // args.SenderName - Sender name
+ // args.Content - Message content
+ // args.Timestamp - Timestamp
+ // args.Metadata["native"] - Native client usage flag
+ // args.Metadata["encrypted"] - Encryption flag
+};
+```
+
+## Simulation Mode
+
+When native library is unavailable, the interface operates in simulation mode:
+
+- Messages relayed via SignalR
+- No actual P2P communication
+- Suitable for development and testing environments
+
+## Troubleshooting
+
+### "Native WebRTC library not found"
+
+When native library is not found:
+1. Build the `webrtc-client` Rust project
+2. Copy DLL/SO/DYLIB to appropriate platform folder
+3. Or use simulation mode with `TryUseNativeClient = false`
+
+### "Architecture mismatch"
+
+When application and library architectures don't match:
+- x64 application → x64 library
+- arm64 application → arm64 library
+
+### ICE Connection Timeout
+
+When NAT traversal fails:
+- Verify STUN servers are configured correctly
+- Consider using TURN server
+- Increase `IceConnectionTimeoutMs`
+
+## Testing
+
+```bash
+# Unit tests
+dotnet test Clawleash.Interfaces.WebRTC.Tests
+
+# Integration tests
+# Terminal 1: Signaling Server
+cd Clawleash.Server && dotnet run
+
+# Terminal 2: Client 1
+cd Clawleash && dotnet run
+
+# Terminal 3: Client 2
+cd Clawleash && dotnet run
+```
+
+## Related Projects
+
+- [Clawleash.Server](../Clawleash.Server/README-en.md) - Signaling server
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README-en.md) - WebSocket interface
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README-en.md) - Shared interfaces
+
+## License
+
+MIT
diff --git a/Clawleash.Interfaces.WebRTC/README.md b/Clawleash.Interfaces.WebRTC/README.md
index a2fee14..3d9f528 100644
--- a/Clawleash.Interfaces.WebRTC/README.md
+++ b/Clawleash.Interfaces.WebRTC/README.md
@@ -186,6 +186,12 @@ cd Clawleash && dotnet run
cd Clawleash && dotnet run
```
+## 関連プロジェクト
+
+- [Clawleash.Server](../Clawleash.Server/README.md) - シグナリングサーバー
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README.md) - WebSocket インターフェース
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
+
## ライセンス
MIT
diff --git a/Clawleash.Interfaces.WebSocket/README-en.md b/Clawleash.Interfaces.WebSocket/README-en.md
new file mode 100644
index 0000000..868a28a
--- /dev/null
+++ b/Clawleash.Interfaces.WebSocket/README-en.md
@@ -0,0 +1,201 @@
+# Clawleash.Interfaces.WebSocket
+
+A complete implementation of WebSocket chat interface. Uses SignalR client for real-time communication with the server, supporting E2EE (End-to-End Encryption).
+
+## Features
+
+- **SignalR Communication**: Real-time bidirectional communication via ASP.NET Core SignalR
+- **E2EE Support**: End-to-end encryption using X25519 key exchange + AES-256-GCM
+- **Channel Keys**: Per-channel encryption key management
+- **Auto-Reconnect**: Automatic reconnection with exponential backoff
+- **Streaming Send**: Support for batch sending of long messages
+
+## Architecture
+
+```
+┌──────────────────────────────────────────────────┐
+│ WebSocketChatInterface (C#) │
+│ ┌────────────────────────────────────────────┐ │
+│ │ HubConnection (SignalR Client) │ │
+│ │ - Automatic Reconnect │ │
+│ │ - Message/Channel Key Handling │ │
+│ └────────────────────────────────────────────┘ │
+│ ┌────────────────────────────────────────────┐ │
+│ │ AesGcmE2eeProvider │ │
+│ │ - X25519 Key Exchange │ │
+│ │ - AES-256-GCM Encryption/Decryption │ │
+│ └────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────┘
+ │
+ ┌───────────────────────┐
+ │ Clawleash.Server │
+ │ ChatHub (/chat) │
+ └───────────────────────┘
+```
+
+## E2EE Encryption Flow
+
+```
+┌──────────────┐ ┌──────────────┐
+│ Client │ │ Server │
+│ │ │ │
+│ 1. Exchange │ ◄─── X25519 ────────► │ │
+│ │ │ │
+│ 2. Encrypt │ │ │
+│ Plaintext │ │ │
+│ │ │ │ │
+│ ▼ │ │ │
+│ AES-256-GCM │ │ │
+│ │ │ │ │
+│ ▼ │ │ │
+│ Ciphertext │ ──── wss:// ────────► │ 3. Decrypt │
+│ │ │ AES-256-GCM │
+│ │ │ │ │
+│ │ │ ▼ │
+│ │ │ Plaintext │
+└──────────────┘ └──────────────┘
+```
+
+## Usage
+
+### Settings
+
+```csharp
+var settings = new WebSocketSettings
+{
+ ServerUrl = "wss://localhost:8080/chat",
+ EnableE2ee = true,
+ ReconnectIntervalMs = 5000,
+ MaxReconnectAttempts = 10,
+ HeartbeatIntervalMs = 30000,
+ ConnectionTimeoutMs = 10000
+};
+```
+
+### Basic Usage
+
+```csharp
+var chatInterface = new WebSocketChatInterface(settings, logger);
+
+// Event handler
+chatInterface.MessageReceived += (sender, args) =>
+{
+ Console.WriteLine($"Message from {args.SenderName}: {args.Content}");
+ Console.WriteLine($"Encrypted: {args.Metadata["encrypted"]}");
+};
+
+// Start (also performs key exchange if E2EE enabled)
+await chatInterface.StartAsync(cancellationToken);
+
+// Join channel
+await chatInterface.JoinChannelAsync("general");
+
+// Send message
+await chatInterface.SendMessageAsync("Hello!", replyToMessageId);
+
+// Leave channel
+await chatInterface.LeaveChannelAsync("general");
+
+// Dispose
+await chatInterface.DisposeAsync();
+```
+
+## Configuration Options
+
+| Property | Description | Default |
+|-----------|------|-----------|
+| `ServerUrl` | SignalR server URL | `ws://localhost:8080/chat` |
+| `EnableE2ee` | Enable E2EE (inherited from parent settings) | `false` |
+| `ReconnectIntervalMs` | Reconnection interval | `5000` |
+| `MaxReconnectAttempts` | Maximum reconnection attempts | `10` |
+| `HeartbeatIntervalMs` | Heartbeat interval | `30000` |
+| `ConnectionTimeoutMs` | Connection timeout | `10000` |
+
+## Events
+
+### MessageReceived
+
+Event raised when a message is received.
+
+```csharp
+chatInterface.MessageReceived += (sender, args) =>
+{
+ // args.MessageId - Message ID
+ // args.SenderId - Sender ID
+ // args.SenderName - Sender name
+ // args.Content - Message content (decrypted)
+ // args.ChannelId - Channel ID
+ // args.Timestamp - Timestamp
+ // args.Metadata["encrypted"] - Whether it was encrypted
+};
+```
+
+## Reconnection Policy
+
+Automatic reconnection using exponential backoff:
+
+```
+Attempt 1: After 5 seconds
+Attempt 2: After 10 seconds
+Attempt 3: After 20 seconds
+...
+Maximum 60 second interval
+```
+
+Stops reconnecting after maximum attempts reached.
+
+## Troubleshooting
+
+### "WebSocket server URL is not configured"
+
+Verify URL is set in `appsettings.json`:
+
+```json
+{
+ "ChatInterface": {
+ "WebSocket": {
+ "Enabled": true,
+ "ServerUrl": "wss://localhost:8080/chat",
+ "EnableE2ee": true
+ }
+ }
+}
+```
+
+### "Failed to connect to SignalR hub"
+
+1. Verify Clawleash.Server is running
+2. Verify URL is correct (`ws://` or `wss://`)
+3. Check firewall settings
+
+### "Key exchange failed"
+
+1. Verify E2EE is enabled on server side
+2. Verify server time is correct
+
+### Messages Not Encrypted
+
+- Verify `EnableE2ee` is set to `true`
+- Verify channel key is set (`HasChannelKey`)
+
+## Build
+
+```bash
+cd Clawleash.Interfaces.WebSocket
+dotnet build
+```
+
+## Dependencies
+
+- Microsoft.AspNetCore.SignalR.Client
+- Clawleash.Abstractions
+
+## Related Projects
+
+- [Clawleash.Server](../Clawleash.Server/README-en.md) - SignalR server
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README-en.md) - WebRTC interface
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README-en.md) - Shared interfaces
+
+## License
+
+MIT
diff --git a/Clawleash.Interfaces.WebSocket/README.md b/Clawleash.Interfaces.WebSocket/README.md
index a13a444..d712096 100644
--- a/Clawleash.Interfaces.WebSocket/README.md
+++ b/Clawleash.Interfaces.WebSocket/README.md
@@ -192,8 +192,9 @@ dotnet build
## 関連プロジェクト
-- [Clawleash.Server](../Clawleash.Server) - SignalR サーバー
-- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC インターフェース
+- [Clawleash.Server](../Clawleash.Server/README.md) - SignalR サーバー
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README.md) - WebRTC インターフェース
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
## ライセンス
diff --git a/Clawleash.Server/README-en.md b/Clawleash.Server/README-en.md
new file mode 100644
index 0000000..3fe20be
--- /dev/null
+++ b/Clawleash.Server/README-en.md
@@ -0,0 +1,209 @@
+# Clawleash.Server
+
+Clawleash's SignalR server component. Provides real-time communication with WebSocket and WebRTC clients, supporting E2EE (End-to-End Encryption).
+
+## Features
+
+- **SignalR Hub**: Real-time bidirectional communication
+- **ChatHub**: Chat hub for WebSocket clients (E2EE support)
+- **SignalingHub**: WebRTC signaling server
+- **E2EE Key Management**: X25519 key exchange and channel key distribution
+- **Svelte Client Delivery**: Serves SPA as static files
+
+## Architecture
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash.Server │
+│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
+│ │ ChatHub │ │ SignalingHub │ │
+│ │ (/chat) │ │ (/signaling) │ │
+│ │ - E2EE Support │ │ - SDP/ICE candidate exchange│ │
+│ │ - Channel Mgmt │ │ - Peer connection mgmt │ │
+│ └─────────────────────┘ └─────────────────────────────┘ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ Security │ │
+│ │ ┌───────────────────┐ ┌─────────────────────────────┐ │ │
+│ │ │ KeyManager │ │ E2eeMiddleware │ │ │
+│ │ │ - Key pair gen │ │ - Channel key management │ │ │
+│ │ │ - Session mgmt │ │ │ │ │
+│ │ └───────────────────┘ └─────────────────────────────┘ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ Svelte Client (Static Files) │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Usage
+
+### Starting
+
+```bash
+cd Clawleash.Server
+dotnet run
+
+# Or
+dotnet run --project Clawleash.Server
+```
+
+### Endpoints
+
+| Path | Description |
+|------|-------------|
+| `/` | Svelte SPA client |
+| `/chat` | WebSocket ChatHub |
+| `/signaling` | WebRTC signaling hub |
+
+### Configuration
+
+`appsettings.json`:
+
+```json
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information"
+ }
+ },
+ "AllowedOrigins": "https://yourdomain.com"
+}
+```
+
+## ChatHub API
+
+### Client → Server
+
+| Method | Description |
+|----------|------|
+| `StartKeyExchange()` | Start E2EE key exchange |
+| `CompleteKeyExchange(sessionId, publicKey)` | Complete key exchange |
+| `SendMessage(content, channelId, senderName, encrypted, ciphertext)` | Send message |
+| `JoinChannel(channelId)` | Join channel |
+| `LeaveChannel(channelId)` | Leave channel |
+
+### Server → Client
+
+| Event | Description |
+|----------|------|
+| `MessageReceived` | Message received |
+| `ChannelKey` | Channel key distribution |
+| `KeyExchangeCompleted` | Key exchange completion notification |
+
+## SignalingHub API
+
+### Client → Server
+
+| Method | Description |
+|----------|------|
+| `Register(peerId, metadata)` | Register peer |
+| `Offer(targetPeerId, sdp)` | Send SDP offer |
+| `Answer(targetPeerId, sdp)` | Send SDP answer |
+| `IceCandidate(targetPeerId, candidate)` | Send ICE candidate |
+
+### Server → Client
+
+| Event | Description |
+|----------|------|
+| `PeerConnected` | Peer connection notification |
+| `PeerDisconnected` | Peer disconnection notification |
+| `Offer` | SDP offer received |
+| `Answer` | SDP answer received |
+| `IceCandidate` | ICE candidate received |
+
+## CORS Configuration
+
+### Development
+
+```csharp
+policy.WithOrigins("http://localhost:5173", "http://localhost:4173")
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ .AllowCredentials();
+```
+
+### Production
+
+Specify allowed origins in `AllowedOrigins` setting:
+
+```json
+{
+ "AllowedOrigins": "https://app.yourdomain.com"
+}
+```
+
+## E2EE Key Exchange Flow
+
+```
+Client Server
+ │ │
+ │ ─── StartKeyExchange ──────► │
+ │ │ 1. Generate key pair
+ │ │ Issue session ID
+ │ ◄── ServerPublicKey ─────── │
+ │ SessionId │
+ │ │
+ │ 2. Generate shared secret │
+ │ Generate channel key │
+ │ │
+ │ ─── ClientPublicKey ───────► │
+ │ SessionId │ 3. Generate shared secret
+ │ │
+ │ ◄── KeyExchangeCompleted ── │
+ │ │
+ │ ◄── ChannelKey ───────────── │
+ │ (encrypted) │
+```
+
+## Svelte Client
+
+Place Svelte application in `Client/` directory:
+
+```
+Client/
+├── index.html
+├── _framework/
+│ └── blazor.webassembly.js
+└── ...
+```
+
+Copied to `wwwroot/` during build.
+
+## Troubleshooting
+
+### "CORS policy blocked"
+
+1. `localhost:5173` is allowed in development
+2. Configure `AllowedOrigins` in production
+
+### WebSocket Connection Drops
+
+1. Verify WebSocket is allowed on proxy server
+2. Check Keep-Alive settings
+
+### E2EE Not Working
+
+1. Verify `EnableE2ee` is set to `true` on both client and server
+2. Verify time synchronization is correct
+
+## Build
+
+```bash
+cd Clawleash.Server
+dotnet build
+```
+
+## Dependencies
+
+- Microsoft.AspNetCore.SignalR
+- Clawleash.Abstractions
+
+## Related Projects
+
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README-en.md) - WebSocket client
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README-en.md) - WebRTC client
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README-en.md) - Shared interfaces
+
+## License
+
+MIT
diff --git a/Clawleash.Server/README.md b/Clawleash.Server/README.md
index a1b0b59..760c6dc 100644
--- a/Clawleash.Server/README.md
+++ b/Clawleash.Server/README.md
@@ -200,8 +200,9 @@ dotnet build
## 関連プロジェクト
-- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket) - WebSocket クライアント
-- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC) - WebRTC クライアント
+- [Clawleash.Interfaces.WebSocket](../Clawleash.Interfaces.WebSocket/README.md) - WebSocket クライアント
+- [Clawleash.Interfaces.WebRTC](../Clawleash.Interfaces.WebRTC/README.md) - WebRTC クライアント
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
## ライセンス
diff --git a/Clawleash.Shell/README-en.md b/Clawleash.Shell/README-en.md
new file mode 100644
index 0000000..c0daf6a
--- /dev/null
+++ b/Clawleash.Shell/README-en.md
@@ -0,0 +1,199 @@
+# Clawleash.Shell
+
+Clawleash's sandbox execution process. Communicates with the main application via IPC using ZeroMQ + MessagePack, executing commands in a constrained PowerShell environment.
+
+## Overview
+
+Clawleash.Shell operates as an isolated process with the following responsibilities:
+
+- **IPC Client**: Connects to main app via ZeroMQ (DealerSocket)
+- **PowerShell Execution**: Executes commands in constrained PowerShell Runspace
+- **Sandbox**: Runs isolated in AppContainer (Windows) / Bubblewrap (Linux)
+
+## Architecture
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Clawleash (Main) │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ ShellServer (RouterSocket) │ │
+│ └──────────────────────────┬──────────────────────────────┘ │
+└─────────────────────────────┼───────────────────────────────┘
+ │
+ │ ZeroMQ + MessagePack
+ │
+┌─────────────────────────────┼───────────────────────────────┐
+│ Clawleash.Shell (Sandboxed) │
+│ ┌──────────────────────────┴──────────────────────────────┐ │
+│ │ IpcClient (DealerSocket) │ │
+│ └──────────────────────────┬──────────────────────────────┘ │
+│ │ │
+│ ┌──────────────────────────┴──────────────────────────────┐ │
+│ │ ConstrainedRunspaceHost │ │
+│ │ (PowerShell SDK) │ │
+│ │ ┌─────────────────────────────────────────────────────┐ │ │
+│ │ │ ConstrainedLanguage Mode │ │ │
+│ │ │ - Command Whitelist │ │ │
+│ │ │ - Path Restrictions │ │ │
+│ │ │ - Folder Policies │ │ │
+│ │ └─────────────────────────────────────────────────────┘ │ │
+│ └─────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Usage
+
+### Starting
+
+Clawleash.Shell is typically started automatically from the main application:
+
+```bash
+# Manual start (for debugging)
+Clawleash.Shell --server tcp://localhost:5555
+
+# Verbose logging enabled
+Clawleash.Shell --server tcp://localhost:5555 --verbose
+```
+
+### Command Line Arguments
+
+| Argument | Short | Description |
+|------|------|------|
+| `--server ` | `-s` | ZeroMQ server address (required) |
+| `--verbose` | `-v` | Verbose logging output |
+
+## IPC Protocol
+
+### Communication Specification
+
+| Item | Specification |
+|------|---------------|
+| Protocol | ZeroMQ (Router/Dealer) |
+| Serialization | MessagePack |
+| Direction | Main (Server) ← Shell (Client) |
+
+### Message Types
+
+| Message | Direction | Description |
+|-----------|------|------|
+| `ShellInitializeRequest` | S → M | Initialization request |
+| `ShellInitializeResponse` | M → S | Initialization response |
+| `ShellExecuteRequest` | M → S | Command execution request |
+| `ShellExecuteResponse` | S → M | Execution result |
+| `ToolInvokeRequest` | M → S | Tool invocation request |
+| `ToolInvokeResponse` | S → M | Tool execution result |
+| `ShellPingRequest` | M → S | Health check |
+| `ShellPingResponse` | S → M | Response |
+
+## PowerShell Constraints
+
+### ConstrainedLanguage Mode
+
+Operates in ConstrainedLanguage mode by default:
+
+- **Allowed**: Basic commands, pipelines, variables
+- **Prohibited**: .NET method calls, Add-Type, script blocks
+
+### Command Whitelist
+
+Only allowed commands can be executed:
+
+```powershell
+# Example allowed commands
+Get-Content, Set-Content, Get-ChildItem
+New-Item, Remove-Item, Copy-Item, Move-Item
+Write-Output, Write-Error
+```
+
+### Path Restrictions
+
+Access control based on folder policies:
+
+```json
+{
+ "FolderPolicies": [
+ {
+ "Path": "C:\\Projects",
+ "Access": "ReadWrite",
+ "Network": "Allow",
+ "Execute": "Allow"
+ },
+ {
+ "Path": "C:\\Projects\\Secrets",
+ "Access": "Deny"
+ }
+ ]
+}
+```
+
+## Sandbox
+
+### Windows (AppContainer)
+
+- Capability-based access control
+- File system, network, registry isolation
+- Runs at low integrity level
+
+### Linux (Bubblewrap)
+
+- Namespace isolation (PID, Network, Mount, User)
+- Resource limits via cgroups
+- seccomp filter
+
+## Project Structure
+
+```
+Clawleash.Shell/
+├── Program.cs # Entry point
+├── IPC/
+│ └── IpcClient.cs # ZeroMQ client
+├── Hosting/
+│ └── ConstrainedRunspaceHost.cs # PowerShell host
+└── Cmdlets/
+ └── ... # Custom cmdlets
+```
+
+## Troubleshooting
+
+### "Server address not specified"
+
+Specify the `--server` argument:
+
+```bash
+Clawleash.Shell --server tcp://localhost:5555
+```
+
+### "Failed to connect to Main app"
+
+1. Verify main application is running
+2. Verify server address is correct
+3. Check firewall settings
+
+### PowerShell Command Fails
+
+1. Verify command is in whitelist
+2. Verify path is allowed by folder policies
+3. Check ConstrainedLanguage mode restrictions
+
+## Build
+
+```bash
+cd Clawleash.Shell
+dotnet build
+```
+
+## Dependencies
+
+- NetMQ (ZeroMQ)
+- MessagePack
+- PowerShell SDK
+- Clawleash.Contracts
+
+## Related Projects
+
+- [Clawleash](../README-en.md) - Main application
+- [Clawleash.Contracts](../Clawleash.Contracts) - IPC message definitions
+
+## License
+
+MIT
diff --git a/Clawleash.Shell/README.md b/Clawleash.Shell/README.md
index 4d1f0e6..d3beb9c 100644
--- a/Clawleash.Shell/README.md
+++ b/Clawleash.Shell/README.md
@@ -191,8 +191,9 @@ dotnet build
## 関連プロジェクト
-- [Clawleash](../Clawleash) - メインアプリケーション
+- [Clawleash](../README.md) - メインアプリケーション
- [Clawleash.Contracts](../Clawleash.Contracts) - IPC メッセージ定義
+- [Clawleash.Abstractions](../Clawleash.Abstractions/README.md) - 共有インターフェース
## ライセンス
diff --git a/README-en.md b/README-en.md
index c2187ee..d0dbec7 100644
--- a/README-en.md
+++ b/README-en.md
@@ -595,13 +595,13 @@ You can create and add your own chat interfaces.
2. Implement `IChatInterface`
3. Build and place in `%LocalAppData%\Clawleash\Interfaces\`
-See [Clawleash.Abstractions/README.md](Clawleash.Abstractions/README.md) for detailed development guide.
+See [Clawleash.Abstractions](Clawleash.Abstractions/README-en.md) for detailed development guide.
**Example Implementations:**
-- [Discord](Clawleash.Interfaces.Discord) - Discord Bot
-- [Slack](Clawleash.Interfaces.Slack) - Slack Bot
-- [WebSocket](Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
-- [WebRTC](Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+- [Discord](Clawleash.Interfaces.Discord/README-en.md) - Discord Bot
+- [Slack](Clawleash.Interfaces.Slack/README-en.md) - Slack Bot
+- [WebSocket](Clawleash.Interfaces.WebSocket/README-en.md) - WebSocket (E2EE)
+- [WebRTC](Clawleash.Interfaces.WebRTC/README-en.md) - WebRTC (E2EE)
### Adding Skills
diff --git a/README.md b/README.md
index a4ff579..8d1e704 100644
--- a/README.md
+++ b/README.md
@@ -595,13 +595,13 @@ dotnet run --project Clawleash.Server
2. `IChatInterface` を実装
3. ビルドして `%LocalAppData%\Clawleash\Interfaces\` に配置
-詳細な開発ガイドは [Clawleash.Abstractions/README.md](Clawleash.Abstractions/README.md) を参照してください。
+詳細な開発ガイドは [Clawleash.Abstractions](Clawleash.Abstractions/README.md) を参照してください。
**実装例:**
-- [Discord](Clawleash.Interfaces.Discord) - Discord Bot
-- [Slack](Clawleash.Interfaces.Slack) - Slack Bot
-- [WebSocket](Clawleash.Interfaces.WebSocket) - WebSocket (E2EE)
-- [WebRTC](Clawleash.Interfaces.WebRTC) - WebRTC (E2EE)
+- [Discord](Clawleash.Interfaces.Discord/README.md) - Discord Bot
+- [Slack](Clawleash.Interfaces.Slack/README.md) - Slack Bot
+- [WebSocket](Clawleash.Interfaces.WebSocket/README.md) - WebSocket (E2EE)
+- [WebRTC](Clawleash.Interfaces.WebRTC/README.md) - WebRTC (E2EE)
### スキルの追加
From ff0bc5b6f3d056c9015a085a14ed470b11cc50e6 Mon Sep 17 00:00:00 2001
From: actbit <57023457+actbit@users.noreply.github.com>
Date: Sat, 28 Feb 2026 14:37:04 +0900
Subject: [PATCH 7/7] [fix] figure
---
Clawleash.Interfaces.Discord/README-en.md | 23 +-
Clawleash.Interfaces.Discord/README.md | 23 +-
Clawleash.Interfaces.Slack/README-en.md | 23 +-
Clawleash.Interfaces.Slack/README.md | 23 +-
Clawleash.Interfaces.WebRTC/README-en.md | 30 +--
Clawleash.Interfaces.WebRTC/README.md | 30 +--
Clawleash.Interfaces.WebSocket/README-en.md | 63 ++---
Clawleash.Interfaces.WebSocket/README.md | 63 ++---
Clawleash.Server/README-en.md | 65 ++---
Clawleash.Server/README.md | 65 ++---
Clawleash.Shell/README-en.md | 43 ++--
Clawleash.Shell/README.md | 43 ++--
README-en.md | 254 ++++++++-----------
README.md | 259 +++++++++-----------
14 files changed, 409 insertions(+), 598 deletions(-)
diff --git a/Clawleash.Interfaces.Discord/README-en.md b/Clawleash.Interfaces.Discord/README-en.md
index 7d0bb58..ef458af 100644
--- a/Clawleash.Interfaces.Discord/README-en.md
+++ b/Clawleash.Interfaces.Discord/README-en.md
@@ -12,20 +12,15 @@ A complete implementation of Discord Bot chat interface. Uses Discord.NET to rec
## Architecture
-```
-┌──────────────────────────────────────────────────┐
-│ DiscordChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ DiscordSocketClient (Discord.NET) │ │
-│ │ - Gateway Intents │ │
-│ │ - Message Received Events │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Discord Gateway │
- │ (WebSocket) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["DiscordChatInterface (C#)"]
+ subgraph Client["DiscordSocketClient (Discord.NET)"]
+ Intent["Gateway Intents"]
+ Events["Message Received Events"]
+ end
+ end
+ Client -->|WebSocket| Gateway["Discord Gateway
(WebSocket)"]
```
## Usage
diff --git a/Clawleash.Interfaces.Discord/README.md b/Clawleash.Interfaces.Discord/README.md
index 2341143..511c02a 100644
--- a/Clawleash.Interfaces.Discord/README.md
+++ b/Clawleash.Interfaces.Discord/README.md
@@ -12,20 +12,15 @@ Discord Bot チャットインターフェースの完全実装。Discord.NET
## アーキテクチャ
-```
-┌──────────────────────────────────────────────────┐
-│ DiscordChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ DiscordSocketClient (Discord.NET) │ │
-│ │ - Gateway Intents │ │
-│ │ - Message Received Events │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Discord Gateway │
- │ (WebSocket) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["DiscordChatInterface (C#)"]
+ subgraph Client["DiscordSocketClient (Discord.NET)"]
+ Intent["Gateway Intents"]
+ Events["Message Received Events"]
+ end
+ end
+ Client -->|WebSocket| Gateway["Discord Gateway
(WebSocket)"]
```
## 使用方法
diff --git a/Clawleash.Interfaces.Slack/README-en.md b/Clawleash.Interfaces.Slack/README-en.md
index e110a6c..c55db4d 100644
--- a/Clawleash.Interfaces.Slack/README-en.md
+++ b/Clawleash.Interfaces.Slack/README-en.md
@@ -12,20 +12,15 @@ A complete implementation of Slack Bot chat interface. Uses HTTP API + polling t
## Architecture
-```
-┌──────────────────────────────────────────────────┐
-│ SlackChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ HTTP Client + Polling Thread │ │
-│ │ - conversations.history polling │ │
-│ │ - Message deduplication │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Slack Web API │
- │ (HTTPS) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["SlackChatInterface (C#)"]
+ subgraph Client["HTTP Client + Polling Thread"]
+ Poll["conversations.history polling"]
+ Dedup["Message deduplication"]
+ end
+ end
+ Client -->|HTTPS| API["Slack Web API
(HTTPS)"]
```
## Usage
diff --git a/Clawleash.Interfaces.Slack/README.md b/Clawleash.Interfaces.Slack/README.md
index 7d608a2..ea75c6c 100644
--- a/Clawleash.Interfaces.Slack/README.md
+++ b/Clawleash.Interfaces.Slack/README.md
@@ -12,20 +12,15 @@ Slack Bot チャットインターフェースの完全実装。HTTP API + ポ
## アーキテクチャ
-```
-┌──────────────────────────────────────────────────┐
-│ SlackChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ HTTP Client + Polling Thread │ │
-│ │ - conversations.history polling │ │
-│ │ - Message deduplication │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Slack Web API │
- │ (HTTPS) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["SlackChatInterface (C#)"]
+ subgraph Client["HTTP Client + Polling Thread"]
+ Poll["conversations.history polling"]
+ Dedup["Message deduplication"]
+ end
+ end
+ Client -->|HTTPS| API["Slack Web API
(HTTPS)"]
```
## 使用方法
diff --git a/Clawleash.Interfaces.WebRTC/README-en.md b/Clawleash.Interfaces.WebRTC/README-en.md
index 3a9416f..e56a062 100644
--- a/Clawleash.Interfaces.WebRTC/README-en.md
+++ b/Clawleash.Interfaces.WebRTC/README-en.md
@@ -12,25 +12,17 @@ A complete implementation of WebRTC chat interface. Establishes WebRTC P2P conne
## Architecture
-```
-┌──────────────────────────────────────────────────┐
-│ WebRtcChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ WebRtcNativeClient (P/Invoke wrapper) │ │
-│ │ - Event polling thread │ │
-│ │ - Message serialization │ │
-│ └────────────────────────────────────────────┘ │
-│ │ P/Invoke │
-│ ▼ │
-│ ┌────────────────────────────────────────────┐ │
-│ │ webrtc_client.dll (Rust cdylib) │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ SignalR Server │
- │ (Signaling) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["WebRtcChatInterface (C#)"]
+ subgraph Native["WebRtcNativeClient (P/Invoke wrapper)"]
+ Poll["Event polling thread"]
+ Ser["Message serialization"]
+ end
+ DLL["webrtc_client.dll
(Rust cdylib)"]
+ end
+ Native -->|P/Invoke| DLL
+ DLL --> SignalR["SignalR Server
(Signaling)"]
```
## Building Native Library
diff --git a/Clawleash.Interfaces.WebRTC/README.md b/Clawleash.Interfaces.WebRTC/README.md
index 3d9f528..aa91586 100644
--- a/Clawleash.Interfaces.WebRTC/README.md
+++ b/Clawleash.Interfaces.WebRTC/README.md
@@ -12,25 +12,17 @@ WebRTC チャットインターフェースの完全実装。SignalR シグナ
## アーキテクチャ
-```
-┌──────────────────────────────────────────────────┐
-│ WebRtcChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ WebRtcNativeClient (P/Invoke wrapper) │ │
-│ │ - Event polling thread │ │
-│ │ - Message serialization │ │
-│ └────────────────────────────────────────────┘ │
-│ │ P/Invoke │
-│ ▼ │
-│ ┌────────────────────────────────────────────┐ │
-│ │ webrtc_client.dll (Rust cdylib) │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ SignalR Server │
- │ (Signaling) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["WebRtcChatInterface (C#)"]
+ subgraph Native["WebRtcNativeClient (P/Invoke wrapper)"]
+ Poll["Event polling thread"]
+ Ser["Message serialization"]
+ end
+ DLL["webrtc_client.dll
(Rust cdylib)"]
+ end
+ Native -->|P/Invoke| DLL
+ DLL --> SignalR["SignalR Server
(Signaling)"]
```
## ネイティブライブラリのビルド
diff --git a/Clawleash.Interfaces.WebSocket/README-en.md b/Clawleash.Interfaces.WebSocket/README-en.md
index 868a28a..241fb41 100644
--- a/Clawleash.Interfaces.WebSocket/README-en.md
+++ b/Clawleash.Interfaces.WebSocket/README-en.md
@@ -12,48 +12,35 @@ A complete implementation of WebSocket chat interface. Uses SignalR client for r
## Architecture
-```
-┌──────────────────────────────────────────────────┐
-│ WebSocketChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ HubConnection (SignalR Client) │ │
-│ │ - Automatic Reconnect │ │
-│ │ - Message/Channel Key Handling │ │
-│ └────────────────────────────────────────────┘ │
-│ ┌────────────────────────────────────────────┐ │
-│ │ AesGcmE2eeProvider │ │
-│ │ - X25519 Key Exchange │ │
-│ │ - AES-256-GCM Encryption/Decryption │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Clawleash.Server │
- │ ChatHub (/chat) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["WebSocketChatInterface (C#)"]
+ subgraph Hub["HubConnection (SignalR Client)"]
+ Reconnect["Automatic Reconnect"]
+ Keys["Message/Channel Key Handling"]
+ end
+ subgraph E2EE["AesGcmE2eeProvider"]
+ X25519["X25519 Key Exchange"]
+ AES["AES-256-GCM Encryption/Decryption"]
+ end
+ end
+ Hub --> Server["Clawleash.Server
ChatHub (/chat)"]
```
## E2EE Encryption Flow
-```
-┌──────────────┐ ┌──────────────┐
-│ Client │ │ Server │
-│ │ │ │
-│ 1. Exchange │ ◄─── X25519 ────────► │ │
-│ │ │ │
-│ 2. Encrypt │ │ │
-│ Plaintext │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ AES-256-GCM │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ Ciphertext │ ──── wss:// ────────► │ 3. Decrypt │
-│ │ │ AES-256-GCM │
-│ │ │ │ │
-│ │ │ ▼ │
-│ │ │ Plaintext │
-└──────────────┘ └──────────────┘
+```mermaid
+flowchart LR
+ subgraph Client["Client"]
+ KX1["1. Key Exchange
X25519"]
+ ENC["2. Encrypt
Plaintext → AES-256-GCM → Ciphertext"]
+ end
+ subgraph Server["Server"]
+ KX2["Key Exchange"]
+ DEC["3. Decrypt
AES-256-GCM → Plaintext"]
+ end
+ KX1 <-.->|X25519| KX2
+ ENC -->|wss://| DEC
```
## Usage
diff --git a/Clawleash.Interfaces.WebSocket/README.md b/Clawleash.Interfaces.WebSocket/README.md
index d712096..95bac9d 100644
--- a/Clawleash.Interfaces.WebSocket/README.md
+++ b/Clawleash.Interfaces.WebSocket/README.md
@@ -12,48 +12,35 @@ WebSocket チャットインターフェースの完全実装。SignalR クラ
## アーキテクチャ
-```
-┌──────────────────────────────────────────────────┐
-│ WebSocketChatInterface (C#) │
-│ ┌────────────────────────────────────────────┐ │
-│ │ HubConnection (SignalR Client) │ │
-│ │ - Automatic Reconnect │ │
-│ │ - Message/Channel Key Handling │ │
-│ └────────────────────────────────────────────┘ │
-│ ┌────────────────────────────────────────────┐ │
-│ │ AesGcmE2eeProvider │ │
-│ │ - X25519 Key Exchange │ │
-│ │ - AES-256-GCM Encryption/Decryption │ │
-│ └────────────────────────────────────────────┘ │
-└──────────────────────────────────────────────────┘
- │
- ┌───────────────────────┐
- │ Clawleash.Server │
- │ ChatHub (/chat) │
- └───────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Interface["WebSocketChatInterface (C#)"]
+ subgraph Hub["HubConnection (SignalR Client)"]
+ Reconnect["Automatic Reconnect"]
+ Keys["Message/Channel Key Handling"]
+ end
+ subgraph E2EE["AesGcmE2eeProvider"]
+ X25519["X25519 Key Exchange"]
+ AES["AES-256-GCM Encryption/Decryption"]
+ end
+ end
+ Hub --> Server["Clawleash.Server
ChatHub (/chat)"]
```
## E2EE 暗号化フロー
-```
-┌──────────────┐ ┌──────────────┐
-│ Client │ │ Server │
-│ │ │ │
-│ 1. 鍵交換 │ ◄─── X25519 ────────► │ │
-│ │ │ │
-│ 2. 暗号化 │ │ │
-│ Plaintext │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ AES-256-GCM │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ Ciphertext │ ──── wss:// ────────► │ 3. 復号化 │
-│ │ │ AES-256-GCM │
-│ │ │ │ │
-│ │ │ ▼ │
-│ │ │ Plaintext │
-└──────────────┘ └──────────────┘
+```mermaid
+flowchart LR
+ subgraph Client["Client"]
+ KX1["1. 鍵交換
X25519"]
+ ENC["2. 暗号化
Plaintext → AES-256-GCM → Ciphertext"]
+ end
+ subgraph Server["Server"]
+ KX2["鍵交換"]
+ DEC["3. 復号化
AES-256-GCM → Plaintext"]
+ end
+ KX1 <-.->|X25519| KX2
+ ENC -->|wss://| DEC
```
## 使用方法
diff --git a/Clawleash.Server/README-en.md b/Clawleash.Server/README-en.md
index 3fe20be..931db8c 100644
--- a/Clawleash.Server/README-en.md
+++ b/Clawleash.Server/README-en.md
@@ -12,27 +12,19 @@ Clawleash's SignalR server component. Provides real-time communication with WebS
## Architecture
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Server │
-│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
-│ │ ChatHub │ │ SignalingHub │ │
-│ │ (/chat) │ │ (/signaling) │ │
-│ │ - E2EE Support │ │ - SDP/ICE candidate exchange│ │
-│ │ - Channel Mgmt │ │ - Peer connection mgmt │ │
-│ └─────────────────────┘ └─────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Security │ │
-│ │ ┌───────────────────┐ ┌─────────────────────────────┐ │ │
-│ │ │ KeyManager │ │ E2eeMiddleware │ │ │
-│ │ │ - Key pair gen │ │ - Channel key management │ │ │
-│ │ │ - Session mgmt │ │ │ │ │
-│ │ └───────────────────┘ └─────────────────────────────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Svelte Client (Static Files) │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Server["Clawleash.Server"]
+ subgraph Hubs["Hubs"]
+ ChatHub["ChatHub
(/chat)
- E2EE Support
- Channel Mgmt"]
+ SignalingHub["SignalingHub
(/signaling)
- SDP/ICE candidate exchange
- Peer connection mgmt"]
+ end
+ subgraph Security["Security"]
+ KeyManager["KeyManager
- Key pair gen
- Session mgmt"]
+ Middleware["E2eeMiddleware
- Channel key management"]
+ end
+ Svelte["Svelte Client (Static Files)"]
+ end
```
## Usage
@@ -134,25 +126,18 @@ Specify allowed origins in `AllowedOrigins` setting:
## E2EE Key Exchange Flow
-```
-Client Server
- │ │
- │ ─── StartKeyExchange ──────► │
- │ │ 1. Generate key pair
- │ │ Issue session ID
- │ ◄── ServerPublicKey ─────── │
- │ SessionId │
- │ │
- │ 2. Generate shared secret │
- │ Generate channel key │
- │ │
- │ ─── ClientPublicKey ───────► │
- │ SessionId │ 3. Generate shared secret
- │ │
- │ ◄── KeyExchangeCompleted ── │
- │ │
- │ ◄── ChannelKey ───────────── │
- │ (encrypted) │
+```mermaid
+sequenceDiagram
+ participant Client
+ participant Server
+ Client->>Server: StartKeyExchange
+ Server->>Server: 1. Generate key pair
Issue session ID
+ Server->>Client: ServerPublicKey + SessionId
+ Client->>Client: 2. Generate shared secret
Generate channel key
+ Client->>Server: ClientPublicKey + SessionId
+ Server->>Server: 3. Generate shared secret
+ Server->>Client: KeyExchangeCompleted
+ Server->>Client: ChannelKey (encrypted)
```
## Svelte Client
diff --git a/Clawleash.Server/README.md b/Clawleash.Server/README.md
index 760c6dc..5469745 100644
--- a/Clawleash.Server/README.md
+++ b/Clawleash.Server/README.md
@@ -12,27 +12,19 @@ Clawleash の SignalR サーバーコンポーネント。WebSocket および We
## アーキテクチャ
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Server │
-│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
-│ │ ChatHub │ │ SignalingHub │ │
-│ │ (/chat) │ │ (/signaling) │ │
-│ │ - E2EE 対応 │ │ - SDP/ICE 候補交換 │ │
-│ │ - チャンネル管理 │ │ - ピア接続管理 │ │
-│ └─────────────────────┘ └─────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Security │ │
-│ │ ┌───────────────────┐ ┌─────────────────────────────┐ │ │
-│ │ │ KeyManager │ │ E2eeMiddleware │ │ │
-│ │ │ - 鍵ペア生成 │ │ - チャンネル鍵管理 │ │ │
-│ │ │ - セッション管理 │ │ │ │ │
-│ │ └───────────────────┘ └─────────────────────────────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Svelte Client (Static Files) │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Server["Clawleash.Server"]
+ subgraph Hubs["Hubs"]
+ ChatHub["ChatHub
(/chat)
- E2EE 対応
- チャンネル管理"]
+ SignalingHub["SignalingHub
(/signaling)
- SDP/ICE 候補交換
- ピア接続管理"]
+ end
+ subgraph Security["Security"]
+ KeyManager["KeyManager
- 鍵ペア生成
- セッション管理"]
+ Middleware["E2eeMiddleware
- チャンネル鍵管理"]
+ end
+ Svelte["Svelte Client (Static Files)"]
+ end
```
## 使用方法
@@ -134,25 +126,18 @@ policy.WithOrigins("http://localhost:5173", "http://localhost:4173")
## E2EE 鍵交換フロー
-```
-Client Server
- │ │
- │ ─── StartKeyExchange ──────► │
- │ │ 1. 鍵ペア生成
- │ │ セッション ID 発行
- │ ◄── ServerPublicKey ─────── │
- │ SessionId │
- │ │
- │ 2. 共有秘密生成 │
- │ チャンネル鍵生成 │
- │ │
- │ ─── ClientPublicKey ───────► │
- │ SessionId │ 3. 共有秘密生成
- │ │
- │ ◄── KeyExchangeCompleted ── │
- │ │
- │ ◄── ChannelKey ───────────── │
- │ (暗号化済み) │
+```mermaid
+sequenceDiagram
+ participant Client
+ participant Server
+ Client->>Server: StartKeyExchange
+ Server->>Server: 1. 鍵ペア生成
セッション ID 発行
+ Server->>Client: ServerPublicKey + SessionId
+ Client->>Client: 2. 共有秘密生成
チャンネル鍵生成
+ Client->>Server: ClientPublicKey + SessionId
+ Server->>Server: 3. 共有秘密生成
+ Server->>Client: KeyExchangeCompleted
+ Server->>Client: ChannelKey (暗号化済み)
```
## Svelte クライアント
diff --git a/Clawleash.Shell/README-en.md b/Clawleash.Shell/README-en.md
index c0daf6a..b0e542c 100644
--- a/Clawleash.Shell/README-en.md
+++ b/Clawleash.Shell/README-en.md
@@ -12,33 +12,22 @@ Clawleash.Shell operates as an isolated process with the following responsibilit
## Architecture
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ ShellServer (RouterSocket) │ │
-│ └──────────────────────────┬──────────────────────────────┘ │
-└─────────────────────────────┼───────────────────────────────┘
- │
- │ ZeroMQ + MessagePack
- │
-┌─────────────────────────────┼───────────────────────────────┐
-│ Clawleash.Shell (Sandboxed) │
-│ ┌──────────────────────────┴──────────────────────────────┐ │
-│ │ IpcClient (DealerSocket) │ │
-│ └──────────────────────────┬──────────────────────────────┘ │
-│ │ │
-│ ┌──────────────────────────┴──────────────────────────────┐ │
-│ │ ConstrainedRunspaceHost │ │
-│ │ (PowerShell SDK) │ │
-│ │ ┌─────────────────────────────────────────────────────┐ │ │
-│ │ │ ConstrainedLanguage Mode │ │ │
-│ │ │ - Command Whitelist │ │ │
-│ │ │ - Path Restrictions │ │ │
-│ │ │ - Folder Policies │ │ │
-│ │ └─────────────────────────────────────────────────────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main)"]
+ Server["ShellServer
(RouterSocket)"]
+ end
+ subgraph Shell["Clawleash.Shell (Sandboxed)"]
+ Client["IpcClient
(DealerSocket)"]
+ subgraph Runspace["ConstrainedRunspaceHost (PowerShell SDK)"]
+ Mode["ConstrainedLanguage Mode"]
+ Whitelist["- Command Whitelist"]
+ Path["- Path Restrictions"]
+ Policy["- Folder Policies"]
+ end
+ end
+ Server <-.->|ZeroMQ + MessagePack| Client
+ Client --> Runspace
```
## Usage
diff --git a/Clawleash.Shell/README.md b/Clawleash.Shell/README.md
index d3beb9c..24fb1b0 100644
--- a/Clawleash.Shell/README.md
+++ b/Clawleash.Shell/README.md
@@ -12,33 +12,22 @@ Clawleash.Shell は分離されたプロセスとして動作し、以下の役
## アーキテクチャ
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ ShellServer (RouterSocket) │ │
-│ └──────────────────────────┬──────────────────────────────┘ │
-└─────────────────────────────┼───────────────────────────────┘
- │
- │ ZeroMQ + MessagePack
- │
-┌─────────────────────────────┼───────────────────────────────┐
-│ Clawleash.Shell (Sandboxed) │
-│ ┌──────────────────────────┴──────────────────────────────┐ │
-│ │ IpcClient (DealerSocket) │ │
-│ └──────────────────────────┬──────────────────────────────┘ │
-│ │ │
-│ ┌──────────────────────────┴──────────────────────────────┐ │
-│ │ ConstrainedRunspaceHost │ │
-│ │ (PowerShell SDK) │ │
-│ │ ┌─────────────────────────────────────────────────────┐ │ │
-│ │ │ ConstrainedLanguage Mode │ │ │
-│ │ │ - Command Whitelist │ │ │
-│ │ │ - Path Restrictions │ │ │
-│ │ │ - Folder Policies │ │ │
-│ │ └─────────────────────────────────────────────────────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main)"]
+ Server["ShellServer
(RouterSocket)"]
+ end
+ subgraph Shell["Clawleash.Shell (Sandboxed)"]
+ Client["IpcClient
(DealerSocket)"]
+ subgraph Runspace["ConstrainedRunspaceHost (PowerShell SDK)"]
+ Mode["ConstrainedLanguage Mode"]
+ Whitelist["- Command Whitelist"]
+ Path["- Path Restrictions"]
+ Policy["- Folder Policies"]
+ end
+ end
+ Server <-.->|ZeroMQ + MessagePack| Client
+ Client --> Runspace
```
## 使用方法
diff --git a/README-en.md b/README-en.md
index d0dbec7..cfbc1c3 100644
--- a/README-en.md
+++ b/README-en.md
@@ -48,23 +48,23 @@ Clawleash supports multiple input interfaces simultaneously.
| **WebRTC** | P2P communication via DataChannel | ✅ DTLS-SRTP |
**Architecture:**
-```
-┌─────────────────────────────────────────────────────────────────────┐
-│ Clawleash (Main Application) │
-│ ┌─────────────────────────────────────────────────────────────────┐ │
-│ │ InterfaceLoader + FileSystemWatcher (Hot Reload) │ │
-│ │ %LocalAppData%\Clawleash\Interfaces\ monitored │ │
-│ │ New DLL → Auto-load → Register with ChatInterfaceManager │ │
-│ └──────────────────────────┬──────────────────────────────────────┘ │
-│ │ │
-│ ┌──────────────────────────┴──────────────────────────────────────┐ │
-│ │ ChatInterfaceManager │ │
-│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
-│ │ │ CLI │ │ Discord │ │ Slack │ │ WebSocket│ │ WebRTC │ │ │
-│ │ │(Built-in)│ │ (DLL) │ │ (DLL) │ │ (DLL) │ │ (DLL) │ │ │
-│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
-│ └───────────────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────────────────┘
+
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main Application)"]
+ subgraph IL["InterfaceLoader + FileSystemWatcher (Hot Reload)"]
+ D1["%LocalAppData%\Clawleash\Interfaces\ monitored"]
+ D2["New DLL → Auto-load → Register with ChatInterfaceManager"]
+ end
+ subgraph CIM["ChatInterfaceManager"]
+ CLI["CLI
(Built-in)"]
+ DISC["Discord
(DLL)"]
+ SLK["Slack
(DLL)"]
+ WS["WebSocket
(DLL)"]
+ WRTC["WebRTC
(DLL)"]
+ end
+ IL --> CIM
+ end
```
**Configuration Example (appsettings.json):**
@@ -101,25 +101,18 @@ Clawleash supports multiple input interfaces simultaneously.
Enable E2EE for WebSocket and WebRTC communications.
-```
-┌──────────────┐ ┌──────────────┐
-│ Client │ │ Server │
-│ │ │ │
-│ 1. Exchange │ ◄─── X25519 ────────► │ │
-│ │ │ │
-│ 2. Encrypt │ │ │
-│ Plaintext │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ AES-256-GCM │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ Ciphertext │ ──── wss:// ────────► │ 3. Decrypt │
-│ │ │ AES-256-GCM │
-│ │ │ │ │
-│ │ │ ▼ │
-│ │ │ Plaintext │
-└──────────────┘ └──────────────┘
+```mermaid
+flowchart LR
+ subgraph Client["Client"]
+ KX1["1. Key Exchange
X25519"]
+ ENC["2. Encrypt
Plaintext → AES-256-GCM → Ciphertext"]
+ end
+ subgraph Server["Server"]
+ KX2["Key Exchange"]
+ DEC["3. Decrypt
AES-256-GCM → Plaintext"]
+ end
+ KX1 <-.->|X25519| KX2
+ ENC -->|wss://| DEC
```
### Web Crawler (Firecrawl-style)
@@ -349,46 +342,42 @@ services.AddSilentApprovalHandler(config);
## Architecture
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main) │
-│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
-│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
-│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
-│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
-│ │ │ │ IPC │
-│ ├────────────────┼─────────────────────┤ │
-│ │ SkillLoader │ McpClientManager │ │
-│ │ (YAML/JSON) │ (stdio/SSE) │ │
-│ └────────────────┴─────────────────────┘ │
-│ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ ChatInterfaceManager │ │
-│ │ ┌─────┐ ┌─────────┐ ┌────────┐ ┌──────────┐ ┌───────┐ │ │
-│ │ │ CLI │ │ Discord │ │ Slack │ │ WebSocket│ │ WebRTC│ │ │
-│ │ └─────┘ └─────────┘ └────────┘ └──────────┘ └───────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
- │
- ▼ MessagePack over ZeroMQ
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Shell (Sandboxed) │
-│ ┌─────────────┐ ┌─────────────────────────────────────┐ │
-│ │ IpcClient │ │ ConstrainedRunspaceHost │ │
-│ │ (Dealer) │ │ (PowerShell SDK) │ │
-│ └─────────────┘ └─────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
-
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Server (Optional) │
-│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
-│ │ ChatHub │ │ SignalingHub │ │
-│ │ (WebSocket/E2EE) │ │ (WebRTC Signaling) │ │
-│ └─────────────────────┘ └─────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Svelte Client (Static Files) │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main)"]
+ Kernel["Kernel
(AI Agent)"]
+ ToolLoader["ToolLoader
(ZIP/DLL)"]
+ ShellServer["ShellServer
(ZeroMQ Router)"]
+ SkillLoader["SkillLoader
(YAML/JSON)"]
+ McpClient["McpClientManager
(stdio/SSE)"]
+ subgraph CIM["ChatInterfaceManager"]
+ CLI["CLI"]
+ DISC["Discord"]
+ SLK["Slack"]
+ WS["WebSocket"]
+ WRTC["WebRTC"]
+ end
+ end
+ Kernel --> SkillLoader
+ Kernel --> ToolLoader
+ Kernel --> McpClient
+ Kernel --> CIM
+ ToolLoader --> ShellServer
+
+ subgraph Shell["Clawleash.Shell (Sandboxed)"]
+ IpcClient["IpcClient
(Dealer)"]
+ Runspace["ConstrainedRunspaceHost
(PowerShell SDK)"]
+ end
+ ShellServer <-.->|MessagePack over ZeroMQ| IpcClient
+ IpcClient --> Runspace
+
+ subgraph Server["Clawleash.Server (Optional)"]
+ ChatHub["ChatHub
(WebSocket/E2EE)"]
+ Signaling["SignalingHub
(WebRTC Signaling)"]
+ Svelte["Svelte Client (Static Files)"]
+ end
+ WS --> ChatHub
+ WRTC --> Signaling
```
## Project Structure
@@ -629,51 +618,30 @@ Communication between Main and Shell processes uses ZeroMQ + MessagePack.
### Architecture
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Main Process │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ RouterSocket (Server) │ │
-│ │ - Bind to random port │ │
-│ │ - Multiple client connections supported │ │
-│ │ - Client identification via Identity │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
- │
- ZeroMQ (TCP)
- │
-┌─────────────────────────────────────────────────────────────┐
-│ Shell Process (Sandboxed) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ DealerSocket (Client) │ │
-│ │ - Dynamically assigned Identity │ │
-│ │ - Async request/response │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Main Process"]
+ Router["RouterSocket (Server)
- Bind to random port
- Multiple client connections supported
- Client identification via Identity"]
+ end
+ subgraph Shell["Shell Process (Sandboxed)"]
+ Dealer["DealerSocket (Client)
- Dynamically assigned Identity
- Async request/response"]
+ end
+ Router <-.->|ZeroMQ TCP| Dealer
```
### Connection Flow
-```
-Main Shell
- │ │
- │ 1. RouterSocket.BindRandomPort │
- │ (e.g., tcp://127.0.0.1:5555) │
- │ │
- │ 2. Process start --server "tcp://..."
- │ │
- │ 3. DealerSocket.Connect()
- │ │
- │ ◄─────── ShellReadyMessage ───── │
- │ (ProcessId, Runtime, OS) │
- │ │
- │ ──── ShellInitializeRequest ────►│
- │ (AllowedCommands, Paths) │
- │ │
- │ ◄─── ShellInitializeResponse ───│
- │ (Success, Version) │
- │ │
- │ Ready │
+```mermaid
+sequenceDiagram
+ participant Main
+ participant Shell
+ Main->>Main: 1. RouterSocket.BindRandomPort
(e.g., tcp://127.0.0.1:5555)
+ Main->>Shell: 2. Process start --server "tcp://..."
+ Shell->>Shell: 3. DealerSocket.Connect()
+ Shell->>Main: ShellReadyMessage
(ProcessId, Runtime, OS)
+ Main->>Shell: ShellInitializeRequest
(AllowedCommands, Paths)
+ Shell->>Main: ShellInitializeResponse
(Success, Version)
+ Note over Main,Shell: Ready
```
### Message Types
@@ -1026,35 +994,29 @@ Tools are executed in a sandboxed environment for security.
**Architecture:**
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main Process) │
-│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
-│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
-│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
-│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
-│ │ │ │ IPC │
-└─────────┼────────────────┼─────────────────────┼─────────────┘
- │ │ │
- │ ┌─────────────┴─────────────────────┘
- │ │
- ▼ ▼
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Shell (Sandboxed Process) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ AppContainer (Windows) / Bubblewrap (Linux) │ │
-│ │ - File system access control │ │
-│ │ - Network access control │ │
-│ │ - Process execution control │ │
-│ │ - Folder policy enforcement │ │
-│ └─────────────────────────────────────────────────────────┘ │
-│ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ AssemblyLoadContext (isCollectible: true) │ │
-│ │ - Tool DLLs loaded in isolated context │ │
-│ │ - Can be unloaded when tool is removed │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main Process)"]
+ Kernel["Kernel
(AI Agent)"]
+ ToolLoader["ToolLoader
(ZIP/DLL)"]
+ ShellServer["ShellServer
(ZeroMQ Router)"]
+ end
+ Kernel --> ToolLoader
+ Kernel --> ShellServer
+
+ subgraph Shell["Clawleash.Shell (Sandboxed Process)"]
+ subgraph Sandbox["AppContainer (Windows) / Bubblewrap (Linux)"]
+ ACL["- File system access control"]
+ NET["- Network access control"]
+ EXEC["- Process execution control"]
+ POL["- Folder policy enforcement"]
+ end
+ subgraph ALC["AssemblyLoadContext (isCollectible: true)"]
+ DLL1["Tool DLLs
(isolated context)"]
+ DLL2["Can be unloaded
when tool is removed"]
+ end
+ end
+ ShellServer <-.->|IPC| ALC
```
**Execution Flow:**
diff --git a/README.md b/README.md
index 8d1e704..07dd642 100644
--- a/README.md
+++ b/README.md
@@ -48,23 +48,23 @@ Clawleashは複数の入力インターフェースを同時にサポートし
| **WebRTC** | DataChannel経由のP2P通信 | ✅ DTLS-SRTP |
**アーキテクチャ:**
-```
-┌─────────────────────────────────────────────────────────────────────┐
-│ Clawleash (Main Application) │
-│ ┌─────────────────────────────────────────────────────────────────┐ │
-│ │ InterfaceLoader + FileSystemWatcher (Hot Reload) │ │
-│ │ %LocalAppData%\Clawleash\Interfaces\ を監視 │ │
-│ │ 新規DLL追加 → 自動ロード → ChatInterfaceManagerに登録 │ │
-│ └──────────────────────────┬──────────────────────────────────────┘ │
-│ │ │
-│ ┌──────────────────────────┴──────────────────────────────────────┐ │
-│ │ ChatInterfaceManager │ │
-│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
-│ │ │ CLI │ │ Discord │ │ Slack │ │ WebSocket│ │ WebRTC │ │ │
-│ │ │(Built-in)│ │ (DLL) │ │ (DLL) │ │ (DLL) │ │ (DLL) │ │ │
-│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
-│ └───────────────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────────────────┘
+
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main Application)"]
+ subgraph IL["InterfaceLoader + FileSystemWatcher (Hot Reload)"]
+ D1["%LocalAppData%\Clawleash\Interfaces\ を監視"]
+ D2["新規DLL追加 → 自動ロード → ChatInterfaceManagerに登録"]
+ end
+ subgraph CIM["ChatInterfaceManager"]
+ CLI["CLI
(Built-in)"]
+ DISC["Discord
(DLL)"]
+ SLK["Slack
(DLL)"]
+ WS["WebSocket
(DLL)"]
+ WRTC["WebRTC
(DLL)"]
+ end
+ IL --> CIM
+ end
```
**設定例 (appsettings.json):**
@@ -101,25 +101,18 @@ Clawleashは複数の入力インターフェースを同時にサポートし
WebSocket・WebRTC通信でE2EEを有効にできます。
-```
-┌──────────────┐ ┌──────────────┐
-│ Client │ │ Server │
-│ │ │ │
-│ 1. 鍵交換 │ ◄─── X25519 ────────► │ │
-│ │ │ │
-│ 2. 暗号化 │ │ │
-│ Plaintext │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ AES-256-GCM │ │ │
-│ │ │ │ │
-│ ▼ │ │ │
-│ Ciphertext │ ──── wss:// ────────► │ 3. 復号化 │
-│ │ │ AES-256-GCM │
-│ │ │ │ │
-│ │ │ ▼ │
-│ │ │ Plaintext │
-└──────────────┘ └──────────────┘
+```mermaid
+flowchart LR
+ subgraph Client["Client"]
+ KX1["1. 鍵交換
X25519"]
+ ENC["2. 暗号化
Plaintext → AES-256-GCM → Ciphertext"]
+ end
+ subgraph Server["Server"]
+ KX2["鍵交換"]
+ DEC["3. 復号化
AES-256-GCM → Plaintext"]
+ end
+ KX1 <-.->|X25519| KX2
+ ENC -->|wss://| DEC
```
### Webクローラー(Firecrawl風)
@@ -349,46 +342,42 @@ services.AddSilentApprovalHandler(config);
## アーキテクチャ
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main) │
-│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
-│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
-│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
-│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
-│ │ │ │ IPC │
-│ ├────────────────┼─────────────────────┤ │
-│ │ SkillLoader │ McpClientManager │ │
-│ │ (YAML/JSON) │ (stdio/SSE) │ │
-│ └────────────────┴─────────────────────┘ │
-│ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ ChatInterfaceManager │ │
-│ │ ┌─────┐ ┌─────────┐ ┌────────┐ ┌──────────┐ ┌───────┐ │ │
-│ │ │ CLI │ │ Discord │ │ Slack │ │ WebSocket│ │ WebRTC│ │ │
-│ │ └─────┘ └─────────┘ └────────┘ └──────────┘ └───────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
- │
- ▼ MessagePack over ZeroMQ
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Shell (Sandboxed) │
-│ ┌─────────────┐ ┌─────────────────────────────────────┐ │
-│ │ IpcClient │ │ ConstrainedRunspaceHost │ │
-│ │ (Dealer) │ │ (PowerShell SDK) │ │
-│ └─────────────┘ └─────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
-
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Server (Optional) │
-│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
-│ │ ChatHub │ │ SignalingHub │ │
-│ │ (WebSocket/E2EE) │ │ (WebRTC Signaling) │ │
-│ └─────────────────────┘ └─────────────────────────────┘ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ Svelte Client (Static Files) │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main)"]
+ Kernel["Kernel
(AI Agent)"]
+ ToolLoader["ToolLoader
(ZIP/DLL)"]
+ ShellServer["ShellServer
(ZeroMQ Router)"]
+ SkillLoader["SkillLoader
(YAML/JSON)"]
+ McpClient["McpClientManager
(stdio/SSE)"]
+ subgraph CIM["ChatInterfaceManager"]
+ CLI["CLI"]
+ DISC["Discord"]
+ SLK["Slack"]
+ WS["WebSocket"]
+ WRTC["WebRTC"]
+ end
+ end
+ Kernel --> SkillLoader
+ Kernel --> ToolLoader
+ Kernel --> McpClient
+ Kernel --> CIM
+ ToolLoader --> ShellServer
+
+ subgraph Shell["Clawleash.Shell (Sandboxed)"]
+ IpcClient["IpcClient
(Dealer)"]
+ Runspace["ConstrainedRunspaceHost
(PowerShell SDK)"]
+ end
+ ShellServer <-.->|MessagePack over ZeroMQ| IpcClient
+ IpcClient --> Runspace
+
+ subgraph Server["Clawleash.Server (Optional)"]
+ ChatHub["ChatHub
(WebSocket/E2EE)"]
+ Signaling["SignalingHub
(WebRTC Signaling)"]
+ Svelte["Svelte Client (Static Files)"]
+ end
+ WS --> ChatHub
+ WRTC --> Signaling
```
## プロジェクト構成
@@ -629,51 +618,30 @@ Main プロセスと Shell プロセス間の通信には ZeroMQ + MessagePack
### アーキテクチャ
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Main プロセス │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ RouterSocket (Server) │ │
-│ │ - ランダムポートでバインド │ │
-│ │ - 複数クライアント接続可能 │ │
-│ │ - Identity でクライアント識別 │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
- │
- ZeroMQ (TCP)
- │
-┌─────────────────────────────────────────────────────────────┐
-│ Shell プロセス (Sandboxed) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ DealerSocket (Client) │ │
-│ │ - 動的に割り当てられたIdentity │ │
-│ │ - 非同期リクエスト/レスポンス │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Main プロセス"]
+ Router["RouterSocket (Server)
- ランダムポートでバインド
- 複数クライアント接続可能
- Identity でクライアント識別"]
+ end
+ subgraph Shell["Shell プロセス (Sandboxed)"]
+ Dealer["DealerSocket (Client)
- 動的に割り当てられたIdentity
- 非同期リクエスト/レスポンス"]
+ end
+ Router <-.->|ZeroMQ TCP| Dealer
```
### 接続フロー
-```
-Main Shell
- │ │
- │ 1. RouterSocket.BindRandomPort │
- │ (例: tcp://127.0.0.1:5555) │
- │ │
- │ 2. プロセス起動 --server "tcp://..."
- │ │
- │ 3. DealerSocket.Connect()
- │ │
- │ ◄─────── ShellReadyMessage ───── │
- │ (ProcessId, Runtime, OS) │
- │ │
- │ ──── ShellInitializeRequest ────►│
- │ (AllowedCommands, Paths) │
- │ │
- │ ◄─── ShellInitializeResponse ───│
- │ (Success, Version) │
- │ │
- │ 準備完了 │
+```mermaid
+sequenceDiagram
+ participant Main
+ participant Shell
+ Main->>Main: 1. RouterSocket.BindRandomPort
(例: tcp://127.0.0.1:5555)
+ Main->>Shell: 2. プロセス起動 --server "tcp://..."
+ Shell->>Shell: 3. DealerSocket.Connect()
+ Shell->>Main: ShellReadyMessage
(ProcessId, Runtime, OS)
+ Main->>Shell: ShellInitializeRequest
(AllowedCommands, Paths)
+ Shell->>Main: ShellInitializeResponse
(Success, Version)
+ Note over Main,Shell: 準備完了
```
### メッセージ一覧
@@ -1053,37 +1021,32 @@ WeatherTools.zip
**アーキテクチャ:**
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash (Main Process) │
-│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
-│ │ Kernel │ │ ToolLoader │ │ ShellServer │ │
-│ │ (AI Agent) │ │ (ZIP/DLL) │ │ (ZeroMQ Router) │ │
-│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
-│ │ │ │ │
-│ │ ToolProxy │ │ IPC │
-│ │ (経由で呼出) │ │ │
-└─────────┼────────────────┼─────────────────────┼─────────────┘
- │ │ │
- ▼ ▼ ▼
-┌─────────────────────────────────────────────────────────────┐
-│ Clawleash.Shell (Sandboxed Process) │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ AssemblyLoadContext (分離ロード) │ │
-│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
-│ │ │ Tool DLL │ │ Tool DLL │ │ PowerShell │ │ │
-│ │ │ (分離済み) │ │ (分離済み) │ │ Constrained │ │ │
-│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
-│ └─────────────────────────────────────────────────────────┘ │
-│ │
-│ ┌─────────────────────────────────────────────────────────┐ │
-│ │ AppContainer (Windows) / Bubblewrap (Linux) │ │
-│ │ - ファイルシステムアクセス制御 │ │
-│ │ - ネットワークアクセス制御 │ │
-│ │ - プロセス実行制御 │ │
-│ │ - フォルダーポリシー適用 │ │
-│ └─────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
+```mermaid
+flowchart TB
+ subgraph Main["Clawleash (Main Process)"]
+ Kernel["Kernel
(AI Agent)"]
+ ToolLoader["ToolLoader
(ZIP/DLL)"]
+ ShellServer["ShellServer
(ZeroMQ Router)"]
+ Proxy["ToolProxy
(経由で呼出)"]
+ end
+ Kernel --> Proxy
+ Proxy --> ToolLoader
+ Proxy --> ShellServer
+
+ subgraph Shell["Clawleash.Shell (Sandboxed Process)"]
+ subgraph ALC["AssemblyLoadContext (分離ロード)"]
+ DLL1["Tool DLL
(分離済み)"]
+ DLL2["Tool DLL
(分離済み)"]
+ PS["PowerShell
Constrained"]
+ end
+ subgraph Sandbox["AppContainer (Windows) / Bubblewrap (Linux)"]
+ ACL["- ファイルシステムアクセス制御"]
+ NET["- ネットワークアクセス制御"]
+ EXEC["- プロセス実行制御"]
+ POL["- フォルダーポリシー適用"]
+ end
+ end
+ ShellServer <-.->|IPC| ALC
```
**実行フロー:**