# 通知設計書 26-served/installDependency

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるカスタム通知「served/installDependency」の設計仕様を定義する。本通知はクライアント(エディタ)からサーバーに送信され、DUBの依存パッケージのインストールを実行する。

### 本通知の処理概要

本通知は、DUBプロジェクトに新しい依存パッケージを追加し、ダウンロード・インポートパスの更新を行うものである。

**業務上の目的・背景**：D言語プロジェクト開発においてサードパーティパッケージを導入する場合、dub.json/dub.sdlに依存関係を追記し、パッケージをダウンロードする必要がある。本通知によりエディタUI上から直接パッケージの追加が可能となり、手動でのレシピファイル編集を不要にする。

**通知の送信タイミング**：ユーザーがエディタの依存関係管理UI（DUBツリービュー等）から「Add Dependency」を実行し、パッケージ名とバージョンを指定したときに送信される。

**通知の受信者**：serve-d LSPサーバープロセスが受信者である。

**通知内容の概要**：InstallRequest（name, version）をパラメータとして受け取る。パッケージ名とバージョン文字列を含む。

**期待されるアクション**：サーバーはdub.json/dub.sdlに依存関係を追記し、DUBで不足パッケージをダウンロードし、インポートパスを更新する。進捗はreportProgress経由でクライアントに通知される。

## 通知種別

LSPカスタム通知（JSON-RPC Notification）。クライアントからサーバーへの方向（C->S）。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（JSON-RPC notification） |
| 優先度 | 高 |
| リトライ | なし |

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

クライアントがserve-d LSPサーバーに直接送信する。処理はactiveInstanceに対して行われる。

## 通知テンプレート

### メール通知の場合

該当なし。本通知はLSPプロトコル上のJSON-RPCメッセージである。

### 本文テンプレート

```json
{
  "jsonrpc": "2.0",
  "method": "served/installDependency",
  "params": {
    "name": "vibe-d",
    "version": "0.9.5"
  }
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| name | インストール対象のパッケージ名 | ユーザー入力 | Yes |
| version | パッケージのバージョン指定 | ユーザー入力 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | ユーザーが「Add Dependency」コマンドを実行 | アクティブインスタンスがDUBプロジェクト | 依存パッケージのインストール |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| アクティブインスタンスなし | activeInstanceが未設定の場合は処理不可 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[served/installDependency通知受信] --> B[activeInstance取得]
    B --> C[reportProgress: importUpgrades 0/10]
    C --> D[injectDependency: レシピファイルに追記]
    D --> E{DubComponentあり?}
    E -->|Yes| F[selectAndDownloadMissing: パッケージダウンロード]
    E -->|No| G[スキップ]
    F --> H[reportProgress: dubReload 7/10]
    G --> H
    H --> I[updateImports: インポートパス更新]
    I --> J[reportProgress: dubReload 10/10]
    J --> K[終了]
```

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

### 参照テーブル一覧

該当なし。

### 更新テーブル一覧

該当なし。ファイルシステム上のdub.json/dub.sdlが更新される。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| レシピファイル未発見 | dub.json/dub.sdl/package.jsonが存在しない | injectDependencyが処理をスキップ |
| パッケージダウンロード失敗 | ネットワークエラー等 | DubComponentの例外処理に依存 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし。

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

- DUBパッケージレジストリからネットワーク経由でパッケージがダウンロードされる
- ファイルシステム上のレシピファイル（dub.json/dub.sdl）が直接編集される

## 備考

- injectDependency関数はSDL形式とJSON形式の両方に対応している
- SDL形式の場合は`dependency "name" version="~>ver"`形式で追記
- JSON形式の場合はdependenciesブロック内に`"name": "~>ver"`形式で追記
- バージョン指定は`~>`プレフィックス（互換バージョン指定）で追記される
- updateImportsの呼び出しでDCDのインポートパスも更新される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | InstallRequest（name, version）の定義 |

**読解のコツ**: InstallRequestはname（パッケージ名）とversion_（バージョン文字列）の2フィールドを持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dub.d | `source/served/commands/dub.d` | installDependency関数（L574-586） |

**主要処理フロー**:
1. **L574**: `@protocolNotification("served/installDependency")` アノテーション
2. **L575**: `void installDependency(InstallRequest req)` シグネチャ
3. **L577-578**: activeInstance取得とURI生成
4. **L579**: reportProgress開始
5. **L580**: injectDependency呼び出し
6. **L581-582**: DubComponent.selectAndDownloadMissing実行
7. **L584**: updateImports呼び出し
8. **L585**: reportProgress完了

#### Step 3: レシピファイル編集処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `source/served/commands/dub.d` | injectDependency関数（L623-725） |

**主要処理フロー**:
- **L625-649**: SDL形式（dub.sdl）への追記処理
- **L651-724**: JSON形式（dub.json/package.json）への追記処理

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

```
[クライアント] served/installDependency通知
    |
    +-- RPCProcessor
          |
          +-- installDependency() [dub.d L575]
                |
                +-- injectDependency() [L623]
                |     |
                |     +-- dub.sdl編集 / dub.json編集
                |
                +-- DubComponent.selectAndDownloadMissing()
                |
                +-- updateImports() [L212]
                      |
                      +-- DubComponent.update()
                      +-- DCDComponent.refreshImports()
```

### データフロー図

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

InstallRequest            installDependency()               レシピファイル更新
(name, version) -------> injectDependency()             --> パッケージダウンロード
                         selectAndDownloadMissing()      --> インポートパス更新
                         updateImports()                 --> 進捗通知($/progress)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | installDependency通知ハンドラ（L574-586）、injectDependency（L623-725） |
| types.d | `source/served/types.d` | ソース | InstallRequestの型定義 |
| progress.d | `source/served/utils/progress.d` | ソース | reportProgress関数 |
| extension.d | `source/served/extension.d` | ソース | モジュール登録 |
