# 通知設計書 13-手動更新案内

## 概要

本ドキュメントは、Oh My Zshの更新プロンプトで更新をスキップした場合、またはreminderモードでの更新通知として表示される手動更新案内メッセージの設計を記載する。

### 本通知の処理概要

この通知は、ユーザーがOh My Zshの更新プロンプトで「No」を選択した場合、または何らかの理由で更新を行わなかった場合に、手動で更新を実行する方法を案内するメッセージを表示する機能である。

**業務上の目的・背景**：Oh My Zshは定期的な更新を推奨しているが、ユーザーが即座に更新を行えない状況（作業中、時間がない等）も考慮する必要がある。更新をスキップした場合でも、後で更新を行う方法を明確に伝えることで、ユーザーが都合の良いタイミングで更新できるようにサポートする。

**通知の送信タイミング**：更新プロンプト「[oh-my-zsh] Would you like to update? [Y/n]」に対してユーザーが「n」「N」またはその他のキー（Y/y/Enter以外）を入力した場合、またはユーザーが既に入力を開始している場合に送信される。

**通知の受信者**：ターミナル上でOh My Zshを使用しているユーザー。更新確認プロンプトに応答した本人に直接表示される。

**通知内容の概要**：「[oh-my-zsh] You can update manually by running `omz update`」というメッセージが表示され、手動更新コマンドが明示される。

**期待されるアクション**：ユーザーは通知を確認し、都合の良いタイミングで`omz update`コマンドを実行して手動で更新を行う。

## 通知種別

ターミナル標準出力（STDOUT）への直接表示

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（プロンプト応答後に即座に表示） |
| 優先度 | 低（情報提供のみ） |
| リトライ | なし（ターミナル出力のため） |

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

更新プロンプトに応答したターミナルセッションに直接出力する。

## 通知テンプレート

### ターミナル出力の場合

| 項目 | 内容 |
|-----|------|
| 送信元 | check_for_upgrade.sh |
| 表示色 | 標準色（色指定なし） |
| 形式 | プレーンテキスト |

### 本文テンプレート

```
[oh-my-zsh] You can update manually by running `omz update`
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | ターミナル出力のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定メッセージ | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| プロンプト応答 | 更新プロンプトで「n」「N」入力 | promptモードかつ拒否 | ユーザーが明示的に更新を拒否 |
| プロンプト応答 | 更新プロンプトでその他のキー入力 | promptモードかつY/y/Enter以外 | デフォルトケースとして案内 |
| 自動判定 | ユーザーが既に入力を開始している | has_typed_input()がtrue | 入力を中断させないための配慮 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ユーザーが「Y」「y」「Enter」を入力 | 更新を実行する場合は案内不要 |
| update_mode=auto | 自動更新モードではプロンプトを表示しない |
| update_mode=reminder | reminderモードでは別のメッセージを表示 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[更新確認時刻到達] --> B{update_mode?}
    B -->|prompt| C{has_typed_input?}
    B -->|reminder| D[リマインダーメッセージ表示]
    B -->|auto| E[自動更新実行]
    C -->|Yes| D
    C -->|No| F[更新プロンプト表示]
    F --> G{ユーザー入力}
    G -->|Y/y/Enter| H[update_ohmyzsh実行]
    G -->|n/N| I[update_last_updated_file]
    G -->|その他| J[手動更新案内表示]
    I --> J
    D --> K[終了]
    E --> K
    H --> K
    J --> K
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | データベースは使用しない |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | データベースは使用しない |

### ファイル更新

| ファイル | 操作 | 概要 |
|---------|------|------|
| .zsh-update | UPDATE | 「n/N」入力時のみLAST_EPOCHを更新（次回確認日を延期） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | 単純なecho出力のためエラーは発生しない |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | ターミナル出力のため制限不要 |

### 配信時間帯

制限なし

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

- メッセージには機密情報は含まれない
- 固定のコマンド案内のみ

## 備考

- 「n/N」入力時はLAST_EPOCHが更新され、次回の更新確認が延期される
- その他のキー入力時はLAST_EPOCHは更新されず、次回シェル起動時に再度プロンプトが表示される
- has_typed_input()関数により、ユーザーがコマンド入力中の場合はプロンプトを表示せずリマインダーモードと同様の動作となる

---

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

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

### 推奨読解順序

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

まず、更新モードの種類と判定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | update_modeの取得と種類（14-20行目） |

**読解のコツ**: `zstyle -s ':omz:update' mode`でユーザー設定を取得し、デフォルトは`prompt`モード。

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

処理の起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | handle_update関数（161-247行目） |

**主要処理フロー**:
1. **220-225行目**: reminderモードまたはhas_typed_inputの場合、リマインダーメッセージを表示
2. **233-242行目**: promptモードでの更新確認プロンプトとユーザー入力処理
3. **241行目**: `*)`パターンで手動更新案内を表示

#### Step 3: 入力判定ロジックを理解する

ユーザーが既に入力を開始しているかの判定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | check_for_upgrade.sh | `tools/check_for_upgrade.sh` | has_typed_input関数（136-159行目） |

**主要処理フロー**:
- **146行目**: sttyでターミナル設定を保存
- **150行目**: 正規モードを無効化
- **153行目**: zselectでstdin(fd 0)にデータがあるか確認

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

```
シェル起動
    │
    └─ tools/check_for_upgrade.sh (source)
           │
           ├─ handle_update (161行目)
           │      │
           │      ├─ is_update_available (215行目)
           │      │
           │      ├─ [reminder or has_typed_input]
           │      │      └─ echo "It's time to update!" (223行目)
           │      │
           │      └─ [prompt mode]
           │             │
           │             ├─ printf プロンプト (235行目)
           │             │
           │             ├─ read ユーザー入力 (236行目)
           │             │
           │             └─ case分岐
           │                    ├─ [yY] → update_ohmyzsh
           │                    ├─ [nN] → update_last_updated_file
           │                    │           └─ 手動更新案内 (241行目)
           │                    └─ [*]  → 手動更新案内 (241行目)
```

### データフロー図

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

update_mode ────▶ handle_update ─────────▶ プロンプト表示
                       │
                       ▼
ユーザー入力 ───▶ case分岐処理 ──────────▶ 手動更新案内
                       │                    "[oh-my-zsh] You can update..."
                       │
                       ▼
                 .zsh-update更新
                 (n/N入力時のみ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| check_for_upgrade.sh | `tools/check_for_upgrade.sh` | ソース | 更新確認とプロンプト表示の実装 |
| .zsh-update | `$ZSH_CACHE_DIR/.zsh-update` | データ | 最終更新確認日時の永続化 |
