# 通知設計書 5-zbell - デスクトップ通知

## 概要

本ドキュメントは、Oh My Zshのzbellプラグインにおけるデスクトップ通知機能について、その設計仕様を定義するものである。

### 本通知の処理概要

zbellプラグインは、コマンドの実行時間が指定したしきい値（デフォルト15秒）を超えた場合に、ベル音に加えてnotify-sendを使用したデスクトップ通知を表示する機能を提供する。この機能はzbell_use_notify_send変数で制御され、デフォルトで有効化されている。

**業務上の目的・背景**：ベル音だけでは、音声がミュートされている環境や、他の音声に紛れて気づかない場合がある。デスクトップ通知を併用することで、視覚的にもコマンド完了を確認でき、より確実にユーザーへ通知できる。特にLinuxデスクトップ環境では、notify-sendが標準的な通知手段として広く利用されている。

**通知の送信タイミング**：zbellプラグインがベル音を鳴らすタイミングと同時に、デスクトップ通知が送信される。具体的には、コマンド完了後、実行時間がzbell_duration（デフォルト15秒）以上であり、コマンドがzbell_ignoreリストに含まれておらず、かつzbell_use_notify_send=trueの場合に送信される。

**通知の受信者**：コマンドを実行したユーザー自身。Linuxのデスクトップ通知システムを通じて、現在ログインしているユーザーに通知が配信される。

**通知内容の概要**：通知にはタイトルとして「Command completed in Xs:」（Xは実行時間秒数）、メッセージとして実行されたコマンド文字列が含まれる。アイコンはターミナルアイコンが使用される。

**期待されるアクション**：受信者は通知を確認し、必要に応じてターミナルに戻って次のコマンドを実行したり、出力結果を確認したりする。

## 通知種別

デスクトップ通知（Linux notify-send）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（notify-send コマンド呼び出し） |
| 優先度 | 中 |
| リトライ | 無し |

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

ローカルユーザーのデスクトップセッションに対して通知を送信する。notify-sendコマンドが利用可能な場合のみ送信される。

## 通知テンプレート

### デスクトップ通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | `Command completed in {duration}s:` |
| メッセージ | `{command}` |
| アイコン | `-i terminal` |

### 本文テンプレート

```
タイトル: Command completed in 45s:
メッセージ: npm run build
アイコン: terminal
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | - | - | 添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| duration | 実行時間（秒） | EPOCHSECONDS計算結果 | Yes |
| command | 実行されたコマンド | zbell_lastcmd | Yes |
| zbell_use_notify_send | 通知有効化フラグ | シェル変数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| シェルフック | precmd内のzbell_notify呼び出し | zbell_use_notify_send=true かつ notify-sendコマンドが存在 | ベル音と同時にデスクトップ通知を送信 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| zbell_use_notify_send=false | ユーザーがデスクトップ通知を無効化した場合 |
| notify-send未インストール | notify-sendコマンドが存在しない場合 |
| ベル音通知が抑止された場合 | zbell_end関数の条件チェックで抑止された場合、デスクトップ通知も送信されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[zbell_notify呼び出し] --> B[zbell_ui_notify呼び出し]
    B --> C{zbell_use_notify_send = true?}
    C -->|No| D[スキップ]
    C -->|Yes| E{notify-send コマンドが存在?}
    E -->|No| D
    E -->|Yes| F[notify-send実行]
    F --> G[デスクトップ通知表示]
    D --> H[print -n '\a' ベル音]
    G --> H
    H --> I[終了]
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。シェル変数のみで状態管理を行う。

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | - | データベース不使用 |

### シェル変数一覧

| 変数名 | 用途 | デフォルト値 |
|--------|------|-------------|
| zbell_use_notify_send | デスクトップ通知有効化フラグ | true |
| zbell_duration | 通知しきい値（秒） | 15 |
| zbell_lastcmd | 最後に実行したコマンド | preexec引数 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| notify-send未インストール | コマンドが存在しない | サイレントにスキップ |
| 通知デーモン未起動 | D-Busセッションが利用できない | notify-sendがエラーを返すが、プラグインは続行 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間対応）

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

- 通知にはユーザーが実行したコマンド文字列が含まれるため、機密性の高いコマンド（パスワード含むコマンド等）は通知に表示される可能性がある
- ローカル通知のみであり、ネットワーク経由での送信は行われない
- notify-sendは標準的なLinux通知機能であり、追加のセキュリティリスクはない

## 備考

- macOSではnotify-sendが標準で利用できないため、この機能は主にLinux環境向け
- notify-sendのアイコン指定は-i terminalで、システムのターミナルアイコンを使用
- zbell_use_notify_send=falseに設定すると、ベル音のみの通知となる
- bgnotifyプラグインとは異なり、zbellはシンプルな通知に特化している

---

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

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

### 推奨読解順序

#### Step 1: 設定変数を理解する

デスクトップ通知の有効/無効を制御する変数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | zbell.plugin.zsh | `plugins/zbell/zbell.plugin.zsh` | 33行目のzbell_use_notify_sendデフォルト値設定を確認 |

**読解のコツ**: `(( ${+var} ))` は変数が設定されているかをチェックする記法。

#### Step 2: UI通知関数を理解する

notify-sendを呼び出す関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | zbell.plugin.zsh | `plugins/zbell/zbell.plugin.zsh` | 44-50行目のzbell_ui_notify関数でデスクトップ通知の実装を確認 |

**主要処理フロー**:
- **45行目**: `[[ $zbell_use_notify_send != "true" ]] && return` - 有効化チェック
- **47行目**: `if type notify-send > /dev/null; then` - コマンド存在チェック
- **48行目**: `notify-send -i terminal "Command completed in ${2}s:" $1` - 通知送信

#### Step 3: 通知関数の呼び出しを理解する

zbell_notifyからzbell_ui_notifyの呼び出しを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | zbell.plugin.zsh | `plugins/zbell/zbell.plugin.zsh` | 55-58行目のzbell_notify関数で呼び出し順序を確認 |

**主要処理フロー**:
- **56行目**: `zbell_ui_notify "${@}"` - デスクトップ通知（先に実行）
- **57行目**: `print -n "\a"` - ベル音（後に実行）

#### Step 4: 引数の受け渡しを理解する

zbell_endからzbell_notifyへの引数の流れを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | zbell.plugin.zsh | `plugins/zbell/zbell.plugin.zsh` | 91行目のzbell_notify呼び出しで引数を確認 |

**主要処理フロー**:
- **91行目**: `zbell_notify $zbell_lastcmd $cmd_duration` - コマンドと実行時間を渡す

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

```
[コマンド完了]
    │
    └─ zbell_end (precmdフック)
           │
           └─ zbell_notify ($zbell_lastcmd, $cmd_duration)
                  │
                  ├─ zbell_ui_notify ($1=コマンド, $2=実行時間)
                  │      │
                  │      ├─ [zbell_use_notify_send=true?]
                  │      │      │
                  │      │      ├─ Yes ──▶ [notify-send存在?]
                  │      │      │                  │
                  │      │      │                  ├─ Yes ──▶ notify-send実行 ──▶ デスクトップ通知
                  │      │      │                  │
                  │      │      │                  └─ No ──▶ スキップ
                  │      │      │
                  │      │      └─ No ──▶ スキップ
                  │      │
                  │      └─ return
                  │
                  └─ print -n "\a" ──▶ ベル音
```

### データフロー図

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

zbell_lastcmd ────────▶ zbell_notify
cmd_duration ─────────▶       │
                              │
                              ├─ zbell_ui_notify
                              │      │
zbell_use_notify_send ───────▶│      ├─ 有効化チェック
                              │      │
                              │      └─ notify-send ────▶ デスクトップ通知
                              │           │                   │
                              │           ├─ タイトル: "Command completed in Xs:"
                              │           ├─ メッセージ: コマンド文字列
                              │           └─ アイコン: terminal
                              │
                              └─ print -n "\a" ─────────▶ ベル音
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| zbell.plugin.zsh | `plugins/zbell/zbell.plugin.zsh` | ソース | メインプラグインファイル、デスクトップ通知ロジックを含む |
