# 通知設計書 20-ターミナル不完全警告

## 概要

本ドキュメントは、Juliaのターミナルが完全に機能していない場合に発行される警告通知（`@warn "Terminal not fully functional"`）の設計仕様を記述する。

### 本通知の処理概要

本通知は、`run_std_repl`関数においてターミナルの種別が「dumb」と判定された場合に、フル機能のREPL（LineEditREPL）ではなく基本REPL（BasicREPL）が使用されることをユーザーに警告する処理である。

**業務上の目的・背景**：JuliaのREPLは、ターミナルの機能レベルに応じて異なるモードで動作する。行編集（LineEdit）モードは、カーソル移動、タブ補完、シンタックスハイライト、履歴ナビゲーションなどの高度な機能を提供するが、これらの機能は「dumb」ターミナル（機能が限定的なターミナル）では正しく動作しない。本警告は、BasicREPLへの自動フォールバックが発生したことをユーザーに通知し、ターミナル環境の改善（TERM環境変数の設定、より高機能なターミナルエミュレータの使用等）を促すために存在する。

**通知の送信タイミング**：`run_std_repl`関数内で、`REPL.Terminals.TTYTerminal`のterm_typeが「dumb」と判定された場合に送信される。ただし`quiet`フラグが`true`の場合は抑止される。

**通知の受信者**：Juliaの対話型セッションを開始したユーザー。標準エラー出力を通じてログ表示される。

**通知内容の概要**：「Terminal not fully functional」という固定メッセージが出力される。付加的な変数やコンテキスト情報は含まれない。

**期待されるアクション**：ユーザーは、TERM環境変数の設定を確認する（例：`export TERM=xterm-256color`）。「dumb」ターミナルの原因として、SSH経由の接続、IDE内のターミナル、またはTERM環境変数が未設定もしくは不正な値に設定されているケースが考えられる。より高機能なターミナルエミュレータを使用するか、TERM変数を適切に設定することで解消される。

## 通知種別

ログ（Warn） - Juliaの標準ログシステム（`@warn`マクロ）を通じたコンソール警告出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（`@warn`マクロによる即座のログ出力） |
| 優先度 | 中（ユーザー体験に影響するがプロセス自体は正常に動作） |
| リトライ | なし |

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

Juliaの標準ロギングフレームワーク（`CoreLogging`）を通じて、現在アクティブなロガーに送信される。デフォルトでは標準エラー出力（`stderr`）に出力される。

## 通知テンプレート

### メール通知の場合

該当なし（コンソールログ出力のみ）

### 本文テンプレート

```
Warning: Terminal not fully functional
```

### 添付ファイル

該当なし

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| REPL起動 | `run_std_repl`の実行 | `term.term_type == "dumb"` かつ `!quiet` | ターミナルが「dumb」と判定され、quiet モードでない場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `quiet == true` | quietモード（`-q`/`--quiet`オプション）が指定されている場合 |
| term_type != "dumb" | ターミナルが「dumb」以外の場合（正常なターミナル） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[run_std_repl呼出し] --> B[TERM環境変数取得]
    B --> C[TTYTerminal生成]
    C --> D{term_type == 'dumb'?}
    D -->|Yes| E[BasicREPL生成]
    E --> F{quiet?}
    F -->|No| G["@warn 'Terminal not fully functional'"]
    F -->|Yes| H[警告スキップ]
    D -->|No| I[LineEditREPL生成]
    G --> J[REPL実行]
    H --> J
    I --> J
```

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

### 参照テーブル一覧

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

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | dumbターミナルはエラーではなく、BasicREPLへの正常なフォールバック | 警告を出力し、BasicREPLで処理を続行 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（REPL起動時に1回のみ発行）

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

本通知には固定メッセージのみが含まれ、個人情報やシステム構成情報は一切含まれない。セキュリティ上の考慮事項は特にない。

## 備考

- TERM環境変数はWindowsでは空文字列（`""`）、その他のOSでは`"dumb"`がデフォルト値として使用される
- BasicREPLは行編集機能を持たないが、基本的なJuliaの評価は可能
- LineEditREPLはカラー出力、タブ補完、履歴管理など多くの機能を提供する
- `run_std_repl`は`run_main_repl`から、REPLモジュールのロードが成功した場合にのみ呼び出される
- banner表示（`REPL.banner(term, ...)`）はterm_type判定の前に実行される

---

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

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

### 推奨読解順序

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

ターミナル種別の判定に使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | client.jl | `base/client.jl` | `run_std_repl`の引数（484行目）- `REPL::Module`, `quiet::Bool`, `banner::Symbol`, `history_file::Bool` |

**読解のコツ**: `REPL.Terminals.TTYTerminal`はREPLモジュール内のターミナル抽象化で、`term_type`フィールドにTERM環境変数の値が格納される。

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

`run_std_repl`関数のターミナル判定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | client.jl | `base/client.jl` | `run_std_repl`（484-512行目）- ターミナル種別判定とREPL種別の選択 |

**主要処理フロー**:
1. **485行目**: `term_env = get(ENV, "TERM", ...)` - TERM環境変数の取得（OS別デフォルト値）
2. **486行目**: `term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr)` - ターミナルオブジェクト生成
3. **487行目**: `banner == :no || REPL.banner(term, short=banner==:short)` - バナー表示
4. **488行目**: `if term.term_type == "dumb"` - dumbターミナル判定
5. **489行目**: `repl = REPL.BasicREPL(term)` - BasicREPL生成
6. **490行目**: `quiet || @warn "Terminal not fully functional"` - 本通知の発行
7. **492行目**: `repl = REPL.LineEditREPL(term, get(stdout, :color, false), true)` - 正常時のLineEditREPL生成

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

`run_std_repl`がどのように呼び出されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | client.jl | `base/client.jl` | `run_main_repl`（515-534行目）- REPLロードの成功/失敗に基づく分岐 |

**主要処理フロー**:
- **525行目**: `if !fallback_repl && interactive && REPL !== Base` - REPLロード成功の確認
- **526行目**: `invokelatest(run_std_repl, REPL, quiet, banner, history_file)` - run_std_repl呼出し

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

```
run_main_repl(interactive, quiet, banner, history_file) [base/client.jl:515]
    |
    +-- load_InteractiveUtils()                          [base/client.jl:413]
    +-- load_REPL()                                      [base/client.jl:429]
    |
    +-- [REPL !== Base?]
        |
        +-- run_std_repl(REPL, quiet, banner, history_file) [base/client.jl:484]
                |
                +-- get(ENV, "TERM", ...)                [環境変数取得]
                +-- REPL.Terminals.TTYTerminal(...)      [ターミナル生成]
                +-- REPL.banner(term, ...)               [バナー表示]
                |
                +-- [term_type == "dumb"?]
                    |
                    +-- REPL.BasicREPL(term)             [dumb時]
                    |   +-- @warn (条件付き)              [CoreLogging]
                    |
                    +-- REPL.LineEditREPL(term, ...)     [正常時]
                |
                +-- REPL.run_repl(repl, ...)
```

### データフロー図

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

ENV["TERM"]                --> get(ENV, "TERM", default) --> term_env文字列
                                [client.jl:485]

term_env, stdin,           --> TTYTerminal(...)          --> termオブジェクト
stdout, stderr                  [client.jl:486]

term.term_type             --> "dumb"判定                --> BasicREPL or LineEditREPL
                                [client.jl:488]

quiet                      --> 抑止判定                  --> @warn or スキップ
                                [client.jl:490]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| client.jl | `base/client.jl` | ソース | `run_std_repl`関数とターミナル判定ロジック |
| REPL.jl | `stdlib/REPL/src/REPL.jl` | ソース | REPL本体（BasicREPL、LineEditREPL） |
| Terminals.jl | `stdlib/REPL/src/Terminals.jl` | ソース | TTYTerminal型の定義 |
| logging.jl | `base/logging.jl` | ソース | `@warn`マクロの定義 |
