# 通知設計書 9-Workspaces disabled

## 概要

本ドキュメントは、OpenCodeアプリケーションにおける「Workspaces disabled（ワークスペース無効化）」トースト通知の設計を記述します。プロジェクトのワークスペース機能が無効化された際に、ユーザーに対してアプリ内トースト通知を表示する機能です。

### 本通知の処理概要

**業務上の目的・背景**：OpenCodeのワークスペース機能を無効化すると、サイドバーではメインのworktreeのみが表示されるようになります。複数のworktreeを管理する必要がない場合や、シンプルな表示を好む場合に無効化できます。この状態変更をユーザーに明確にフィードバックする必要があります。

**通知の送信タイミング**：ユーザーがワークスペース機能を無効化した時（workspace.toggleコマンドでオンからオフに切り替え時）に即座に送信されます。コマンドパレットからのトグル、またはプロジェクトメニューからの切り替えで発火します。

**通知の受信者**：ワークスペースを無効化したユーザー本人。設定による制御はなく、常に表示されます。

**通知内容の概要**：通知タイトル「Workspaces disabled」と、「Only the main worktree is shown in the sidebar」という説明が表示されます。

**期待されるアクション**：ユーザーはサイドバーでメインのworktreeのみが表示されるようになったことを認識します。再度ワークスペース機能が必要になった場合は、コマンドパレットやプロジェクトメニューから有効化できます。

## 通知種別

アプリ内トースト通知（一時的）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザーアクション直後） |
| 優先度 | 低 |
| リトライ | なし |

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

1. ユーザーがworkspace.toggleコマンドを実行
2. 現在の状態を確認
3. 状態がオン→オフに変わる場合、無効化通知を表示
4. layout.sidebar.toggleWorkspaces()でトグル実行
5. showToast()でトースト表示

## 通知テンプレート

### アプリ内トースト通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | `toast.workspace.disabled.title`（"Workspaces disabled"） |
| 説明 | `toast.workspace.disabled.description`（"Only the main worktree is shown in the sidebar"） |
| 永続性 | なし（自動消去） |
| アクション | なし |

### 本文テンプレート

```
タイトル: Workspaces disabled
説明: Only the main worktree is shown in the sidebar
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 添付ファイルは使用されません |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定テキスト | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザーアクション | workspace.toggleコマンド | オン→オフの場合 | ワークスペース無効化時 |
| ユーザーアクション | プロジェクトメニューから切り替え | オン→オフの場合 | ワークスペース無効化時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 既に無効な場合 | オフ→オフは発生しない |
| オフ→オンの場合 | Workspaces enabled通知が代わりに表示 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[workspace.toggleコマンド実行] --> B{VCS = git?}
    B -->|No| C[コマンド無効]
    B -->|Yes| D{現在有効?}
    D -->|No| E[Workspaces enabled通知]
    D -->|Yes| F[layout.sidebar.toggleWorkspaces]
    F --> G[showToast - disabled]
    G --> H[トースト表示]
    E --> H
    H --> I[サイドバー表示更新]
    C --> J[終了]
    I --> J
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| project | VCS種別の確認 | LocalProject |
| layout.sidebar.workspaces | 現在の有効状態 | LayoutContext |

### テーブル別参照項目詳細

#### project

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| vcs | VCS種別 | currentProject() |
| worktree | プロジェクトルート | - |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| layout.sidebar.workspaces | UPDATE | ワークスペース有効状態の更新 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| プロジェクト未選択 | currentProject()がundefined | コマンドがdisabledで発火しない |
| 非gitプロジェクト | project.vcs !== "git" | コマンドがdisabledで発火しない |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間配信可能）

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

- 固定テキストのためセキュリティリスクは低い
- ユーザー入力を含まない

## 備考

- Workspaces enabled通知と対になる通知
- 無効化してもworktree自体は削除されない（表示のみ変更）
- 無効化状態でも他のworktreeのセッションには直接URLでアクセス可能
- 非gitプロジェクトでワークスペースが有効になっている場合のみ、無効化のdisabled判定が緩和される

---

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

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

### 推奨読解順序

#### Step 1: コマンド定義を理解する

workspace.toggleコマンドの無効化分岐を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | layout.tsx | `packages/app/src/pages/layout.tsx` | workspace.toggleコマンド（981-1001行目）を理解 |

**読解のコツ**: wasEnabled = trueの場合に無効化通知が表示されることに注目。

**主要処理フロー**:
1. **989行目**: wasEnabled = layout.sidebar.workspaces(project.worktree)()で現在状態取得
2. **990行目**: layout.sidebar.toggleWorkspaces()でトグル
3. **997-999行目**: wasEnabledがtrueの場合、disabled通知を表示

#### Step 2: トースト表示ロジックを理解する

無効化通知の表示条件を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | layout.tsx | `packages/app/src/pages/layout.tsx` | 条件分岐（997-999行目）で無効化通知を確認 |

**主要処理フロー**:
- **997-999行目**: wasEnabled = true の場合、toast.workspace.disabled.*を使用

#### Step 3: i18nキーを理解する

通知テキストの定義を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | en.ts | `packages/app/src/i18n/en.ts` | toast.workspace.disabled.title/description（402-403行目）を確認 |

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

```
workspace.toggleコマンド (layout.tsx:981)
    │
    ├─ disabled判定
    │      ├─ !currentProject() → disabled
    │      └─ currentProject()?.vcs !== "git" → disabled（条件付き）
    │
    ├─ wasEnabled = layout.sidebar.workspaces(project.worktree)()
    │      └─ true の場合、無効化処理
    │
    ├─ layout.sidebar.toggleWorkspaces(project.worktree)
    │
    └─ showToast (layout.tsx:997)
           │
           └─ wasEnabled ? disabled通知 : enabled通知
                  │
                  ├─ title: "Workspaces disabled"
                  └─ description: "Only the main worktree..."
```

### データフロー図

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

ユーザーアクション          Layout - workspace.toggle
/workspace       ────▶    wasEnabled判定  ───────────────▶   トースト通知
                          toggleWorkspaces()                  サイドバー更新
                               │
                               ▼
                          wasEnabled = true
                               │
                          showToast({
                            title: "Workspaces disabled",
                            description: "Only the main worktree..."
                          })
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| layout.tsx | `packages/app/src/pages/layout.tsx` | ソース | コマンド定義・トースト表示 |
| layout.tsx | `packages/app/src/context/layout.tsx` | ソース | toggleWorkspaces実装 |
| toast.tsx | `packages/ui/src/components/toast.tsx` | ソース | showToast関数 |
| en.ts | `packages/app/src/i18n/en.ts` | 設定 | 翻訳キー定義 |
