# 通知設計書 19-coded/changedSelectedWorkspace

## 概要

本ドキュメントは、カスタム通知 `coded/changedSelectedWorkspace` の設計仕様を定義する。この通知はサーバー（serve-d）からクライアント（エディタ）に送信され、選択中のワークスペースが変更されたことをクライアントに通知する。

### 本通知の処理概要

`coded/changedSelectedWorkspace` 通知は、ユーザーの操作（ファイルを開く、コマンド実行など）により、serve-d内部でアクティブワークスペースが切り替わった際にクライアントへ送信する通知である。`Workspace.describeState()` の結果（WorkspaceState構造体）が送信される。

**業務上の目的・背景**：serve-dはマルチワークスペース環境に対応しており、ユーザーがファイルを開いたりコマンドを実行すると、そのファイルが属するワークスペースが「選択状態」になる。この変更をクライアントに通知することで、エディタ側のステータスバーやUIがアクティブワークスペースを正しく表示できる。

**通知の送信タイミング**：`handleThings` 関数（types.d）内で、ユーザー操作により異なるワークスペースが選択された場合、または初めてワークスペースが選択された場合に送信される。

**通知の受信者**：LSPクライアント（エディタ拡張機能）が受信する。

**通知内容の概要**：`WorkspaceState` 構造体が送信され、ワークスペースのURI、名前、初期化状態、選択状態、および保留中のエラー情報が含まれる。

**期待されるアクション**：クライアントはアクティブワークスペースの表示を更新し、関連する設定やコンテキスト情報を切り替える。

## 通知種別

LSPカスタム通知（JSON-RPC notification）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（handleThings実行中に即座送信） |
| 優先度 | 中 |
| リトライ | 無し |

### 送信先決定ロジック

サーバーからクライアントへの一方向通知。LSP接続で確立されたクライアントプロセスに固定。

## 通知テンプレート

### JSON-RPC通知メッセージ

| 項目 | 内容 |
|-----|------|
| メソッド名 | `coded/changedSelectedWorkspace` |
| パラメータ型 | `WorkspaceState`（Workspace.describeState()の戻り値型） |
| レスポンス | なし（通知） |

### メッセージ構造

```json
{
  "jsonrpc": "2.0",
  "method": "coded/changedSelectedWorkspace",
  "params": {
    "uri": "file:///path/to/workspace",
    "name": "my-workspace",
    "initialized": true,
    "selected": true,
    "pendingErrors": {}
  }
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| uri | ワークスペースフォルダのURI | workspace.folder.uri | Yes |
| name | ワークスペースフォルダの名前 | workspace.folder.name | Yes |
| initialized | 初期化完了フラグ | workspace.initialized | Yes |
| selected | 選択状態フラグ | workspace.selected（常にtrue） | Yes |
| pendingErrors | 保留中のスタートアップエラー | workspace.startupErrorNotifications | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | handleThings実行（ユーザー操作） | notifyChange==true（前回と異なるワークスペース）または changedOne==false（初回選択） | types.d L376-411のhandleThings関数内 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| userExecuted==false | ユーザー操作ではない内部的なワークスペース参照の場合、handleThingsのワークスペース選択処理自体がスキップされる |
| 同一ワークスペース | 既に選択中のワークスペースと同じ場合（notifyChange==falseかつchangedOne==true） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[workspace関数呼び出し: userExecuted=true] --> B[handleThings関数]
    B --> C{前回選択されたワークスペースと異なる?}
    C -->|Yes: notifyChange=true| D[全ワークスペースのselected=false]
    C -->|No| E{初回選択?}
    E -->|Yes: changedOne=false| D
    E -->|No| F[送信スキップ]
    D --> G[新ワークスペースのselected=true]
    G --> H[coded/changedSelectedWorkspace送信]
    H --> I[終了]
    F --> I
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースを使用しない）。

### 更新テーブル一覧

該当なし。`workspaces` 配列の `selected` フィールドがインメモリで更新される。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| クライアント未対応 | クライアントがcoded/changedSelectedWorkspaceをハンドリングしない | 通知は無視される |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

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

- ワークスペースのURIとフォルダ名が含まれる
- スタートアップエラーの詳細メッセージが含まれる可能性がある

## 備考

- `handleThings` は `workspace(uri, userExecuted)` 関数経由で呼ばれる。`userExecuted` パラメータはデフォルトで `true` であり、ユーザー操作由来のワークスペース参照で呼ばれる
- `describeState()` はWorkspace構造体のプロパティとして定義されている（types.d L301-317）
- `handleThings` 内ではスタートアップエラーの表示処理も行われている（types.d L381-395）

---

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

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

### 推奨読解順序

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

送信されるWorkspaceState構造体を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | Workspace構造体（L270-327）内の `describeState` プロパティ（L301-317） |

**読解のコツ**: `describeState` は `@property` として定義された関数で、内部に `WorkspaceState` 構造体を定義して返す。この構造体が通知パラメータとなる。

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

handleThings関数でのワークスペース切り替え・通知処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | types.d | `source/served/types.d` | `handleThings` 関数（L376-413）のワークスペース選択・通知ロジック |

**主要処理フロー**:
1. **L379**: `userExecuted` が `true` かチェック
2. **L381-395**: スタートアップエラーの表示処理
3. **L397-406**: 全ワークスペースの `selected` フラグをクリアし、切り替え検出
4. **L408**: 新ワークスペースの `selected = true` に設定
5. **L409-410**: `notifyChange` または `!changedOne` の場合に `coded/changedSelectedWorkspace` を送信

#### Step 3: 呼び出し元を理解する

workspace関数からhandleThingsへの呼び出しフローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | types.d | `source/served/types.d` | `workspace` 関数（L415-425）がhandleThingsを呼び出す仕組み |

**主要処理フロー**:
- **L421-424**: workspaceIndex でベストマッチのワークスペースを検索し、`handleThings` を呼び出す

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

```
[ユーザー操作: ファイルを開く等]
    |
    +-- workspace(uri, userExecuted=true) (types.d:415)
            |
            +-- workspaceIndex(uri) (types.d:356)
            +-- handleThings(workspace, uri, true) (types.d:376)
                    |
                    +-- [スタートアップエラー表示] (L381-395)
                    +-- [ワークスペース選択切り替え] (L397-408)
                    +-- [切り替えが発生した場合]
                            |
                            +-- rpc.notifyMethod("coded/changedSelectedWorkspace",
                                    workspace.describeState) (L410)
```

### データフロー図

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

ファイルURI             handleThings()                coded/changedSelectedWorkspace
(ユーザー操作)      --> (types.d:376-413)          --> WorkspaceState {
                        |                                uri,
                        +-- ワークスペース選択判定        name,
                        +-- describeState()生成          initialized,
                            (types.d:301-317)            selected,
                                                         pendingErrors
                                                       }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| types.d | `source/served/types.d` | ソース | Workspace/WorkspaceState構造体定義、handleThings関数、workspace関数 |
