# Oh My Zsh コードリーディングガイドライン

## はじめに

このガイドラインは、Oh My Zshのコードベースを効率的に理解するための手引きです。
Zsh/シェルスクリプトに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、Zshの基本構文と概念を解説します。

### 1.1 プログラム構造

Oh My Zshは主にZsh（Z Shell）とPOSIX準拠のシェルスクリプト（sh）で構成されています。

**Zshスクリプトの基本構造:**
```zsh
# ファイル: oh-my-zsh.sh:50-55
[[ -n "$ZSH" ]] || export ZSH="${${(%):-%x}:a:h}"

# Set ZSH_CUSTOM to the path where your custom config files
# and plugins exists, or else we will use the default custom/
[[ -n "$ZSH_CUSTOM" ]] || ZSH_CUSTOM="$ZSH/custom"
```

- `[[ ]]`: Zsh固有の条件式（Bash互換の拡張テスト構文）
- `||`: 前のコマンドが失敗した場合に後続を実行
- `${...}`: パラメータ展開

### 1.2 データ型と変数

**変数宣言と代入:**
```zsh
# ファイル: lib/git.zsh:46-78
local -A prefix_constant_map
prefix_constant_map=(
  '\?\? '     'UNTRACKED'
  'A  '       'ADDED'
  'M  '       'MODIFIED'
)
```

- `local`: ローカル変数宣言
- `-A`: 連想配列フラグ
- `-a`: 通常の配列フラグ

**配列操作:**
```zsh
# ファイル: lib/git.zsh:82-86
local status_constants
status_constants=(
  UNTRACKED ADDED MODIFIED RENAMED DELETED
  STASHED UNMERGED AHEAD BEHIND DIVERGED
)
```

### 1.3 制御構造

**条件分岐:**
```zsh
# ファイル: lib/functions.zsh:20-34
case "$OSTYPE" in
  darwin*)  open_cmd='open' ;;
  cygwin*)  open_cmd='cygstart' ;;
  linux*)   [[ "$(uname -r)" != *icrosoft* ]] && open_cmd='nohup xdg-open' ;;
  msys*)    open_cmd='start ""' ;;
  *)        echo "Platform $OSTYPE not supported"
            return 1
            ;;
esac
```

**ループ:**
```zsh
# ファイル: oh-my-zsh.sh:90-98
for plugin ($plugins); do
  if is_plugin "$ZSH_CUSTOM" "$plugin"; then
    fpath=("$ZSH_CUSTOM/plugins/$plugin" $fpath)
  elif is_plugin "$ZSH" "$plugin"; then
    fpath=("$ZSH/plugins/$plugin" $fpath)
  else
    echo "[oh-my-zsh] plugin '$plugin' not found"
  fi
done
```

### 1.4 関数/メソッド定義

**関数定義の2つの形式:**
```zsh
# 形式1: function キーワード使用
# ファイル: lib/git.zsh:10-12
function __git_prompt_git() {
  GIT_OPTIONAL_LOCKS=0 command git "$@"
}

# 形式2: 関数名() 形式
# ファイル: oh-my-zsh.sh:81-86
is_plugin() {
  local base_dir=$1
  local name=$2
  builtin test -f $base_dir/plugins/$name/$name.plugin.zsh \
    || builtin test -f $base_dir/plugins/$name/_$name
}
```

### 1.5 モジュール/インポート

**sourceによるファイル読み込み:**
```zsh
# ファイル: oh-my-zsh.sh:197-199
for lib_file ("$ZSH"/lib/*.zsh); do
  _omz_source "lib/${lib_file:t}"
done
```

**autoloadによる関数の遅延ロード:**
```zsh
# ファイル: oh-my-zsh.sh:79
autoload -U compaudit compinit zrecompile
```

- `-U`: エイリアス展開を抑制
- `autoload`: 関数を必要時に読み込み

---

## 2. プロジェクト固有の概念

> このセクションでは、Oh My Zsh特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### プラグインシステム

プラグインは `plugins/プラグイン名/プラグイン名.plugin.zsh` の形式で配置されます。

```zsh
# ファイル: oh-my-zsh.sh:203-206
for plugin ($plugins); do
  _omz_source "plugins/$plugin/$plugin.plugin.zsh"
done
```

**プラグインの構造例（gitプラグイン）:**
```
plugins/git/
  git.plugin.zsh    # メインのプラグインファイル
  README.md         # ドキュメント
```

#### テーマシステム

テーマは `themes/テーマ名.zsh-theme` の形式で配置されます。

```zsh
# ファイル: oh-my-zsh.sh:221-230
if [[ -n "$ZSH_THEME" ]]; then
  if is_theme "$ZSH_CUSTOM" "$ZSH_THEME"; then
    source "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme"
  elif is_theme "$ZSH_CUSTOM/themes" "$ZSH_THEME"; then
    source "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme"
  elif is_theme "$ZSH/themes" "$ZSH_THEME"; then
    source "$ZSH/themes/$ZSH_THEME.zsh-theme"
  fi
fi
```

#### omz CLIコマンド

`omz` コマンドはOh My Zshの管理用CLIツールです。

```zsh
# ファイル: lib/cli.zsh:3-21
function omz {
  setopt localoptions noksharrays
  [[ $# -gt 0 ]] || {
    _omz::help
    return 1
  }

  local command="$1"
  shift

  (( ${+functions[_omz::$command]} )) || {
    _omz::help
    return 1
  }

  _omz::$command "$@"
}
```

### 2.2 プロジェクト独自のパターン

#### _omz_sourceパターン

エイリアスの有効/無効を制御しながらファイルを読み込むパターン:

```zsh
# ファイル: oh-my-zsh.sh:154-193
_omz_source() {
  local context filepath="$1"

  # Construct zstyle context based on path
  case "$filepath" in
  lib/*) context="lib:${filepath:t:r}" ;;
  plugins/*) context="plugins:${filepath:h:t}" ;;
  esac

  local disable_aliases=0
  zstyle -T ":omz:${context}" aliases || disable_aliases=1
  # ...
}
```

#### 非同期プロンプトパターン

Gitステータスなどの重い処理を非同期で実行するパターン:

```zsh
# ファイル: lib/async_prompt.zsh:28-43
function _omz_register_handler {
  setopt localoptions noksharrays unset
  typeset -ga _omz_async_functions
  if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \
    || (( ${_omz_async_functions[(Ie)$1]} )); then
    return
  fi
  _omz_async_functions+=("$1")
  # ...
}
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `*.zsh` | Zshスクリプトファイル | `git.zsh`, `functions.zsh` |
| `*.zsh-theme` | テーマファイル | `robbyrussell.zsh-theme` |
| `*.plugin.zsh` | プラグインメインファイル | `git.plugin.zsh` |
| `_*` | 補完定義ファイル | `_git` |
| `*.sh` | POSIX互換シェルスクリプト | `install.sh`, `upgrade.sh` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `_omz_*` | Oh My Zsh内部関数 | `_omz_source`, `_omz_register_handler` |
| `_omz::*` | omz CLIサブコマンド | `_omz::plugin`, `_omz::theme` |
| `__*` | プライベートヘルパー関数 | `__git_prompt_git` |
| `ZSH_*` | グローバル設定変数 | `ZSH_THEME`, `ZSH_CUSTOM` |
| `ZSH_THEME_*` | テーマ設定変数 | `ZSH_THEME_GIT_PROMPT_PREFIX` |
| `AGNOSTER_*` | Agnosterテーマ固有変数 | `AGNOSTER_DIR_FG` |

### 3.3 プログラム分類一覧

| 分類 | 場所 | 説明 |
|-----|------|------|
| コアライブラリ | `lib/*.zsh` | 基本機能を提供 |
| プラグイン | `plugins/*/` | 拡張機能を提供 |
| テーマ | `themes/*.zsh-theme` | プロンプト表示をカスタマイズ |
| ツール | `tools/*.sh` | インストール/アップグレード等 |
| カスタム | `custom/` | ユーザー独自の設定 |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
oh-my-zsh/
  oh-my-zsh.sh          # メインエントリーポイント
  lib/                   # コアライブラリ
    cli.zsh             # omzコマンドの実装
    git.zsh             # Git関連関数
    functions.zsh       # 汎用ユーティリティ関数
    completion.zsh      # 補完設定
    async_prompt.zsh    # 非同期プロンプト処理
    ...
  plugins/               # プラグイン群（355以上）
    git/                # Gitエイリアス・関数
    docker/             # Dockerサポート
    ...
  themes/                # テーマ群（143以上）
    robbyrussell.zsh-theme  # デフォルトテーマ
    agnoster.zsh-theme      # 人気テーマ
    ...
  tools/                 # 管理ツール
    install.sh          # インストーラー
    upgrade.sh          # アップグレードスクリプト
    uninstall.sh        # アンインストーラー
    ...
  custom/                # ユーザーカスタマイズ用
    plugins/            # カスタムプラグイン
    themes/             # カスタムテーマ
    example.zsh         # 設定例
  templates/             # テンプレート
    zshrc.zsh-template  # .zshrcテンプレート
  cache/                 # キャッシュディレクトリ
  log/                   # ログディレクトリ
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `/` | プロジェクトルート | `oh-my-zsh.sh` |
| `lib/` | コアライブラリ | `cli.zsh`, `git.zsh`, `functions.zsh` |
| `plugins/` | プラグイン | 各プラグイン固有の `.plugin.zsh` |
| `themes/` | テーマ | 各テーマ固有の `.zsh-theme` |
| `tools/` | 管理ツール | `install.sh`, `upgrade.sh` |
| `custom/` | ユーザーカスタマイズ | ユーザー作成ファイル |
| `templates/` | テンプレート | `zshrc.zsh-template` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Oh My Zshは**プラグインアーキテクチャ**を採用しています。コアシステムが最小限の機能を提供し、追加機能はプラグインとして分離されています。

```
                    +------------------+
                    |    .zshrc        |
                    |  (ユーザー設定)   |
                    +--------+---------+
                             |
                             v
                    +------------------+
                    |  oh-my-zsh.sh    |
                    |  (メインローダー) |
                    +--------+---------+
                             |
          +------------------+------------------+
          |                  |                  |
          v                  v                  v
    +----------+      +-----------+      +-----------+
    | lib/*.zsh|      | plugins/* |      | themes/*  |
    | (コア)   |      | (拡張)    |      | (表示)    |
    +----------+      +-----------+      +-----------+
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| 設定 | ユーザー設定の読み込み | `.zshrc`, `templates/zshrc.zsh-template` |
| ローダー | コンポーネントの初期化と読み込み | `oh-my-zsh.sh` |
| コア | 基本機能の提供 | `lib/cli.zsh`, `lib/functions.zsh` |
| プラグイン | 拡張機能の提供 | `plugins/git/git.plugin.zsh` |
| テーマ | プロンプト表示 | `themes/robbyrussell.zsh-theme` |

### 5.3 データフロー

1. **起動フロー:**
   - zshが `.zshrc` を読み込み
   - `ZSH_THEME`, `plugins` 変数を設定
   - `oh-my-zsh.sh` をsource
   - lib配下のファイルを順次読み込み
   - 設定されたプラグインを読み込み
   - テーマを読み込み

2. **プロンプト表示フロー:**
   - 非同期ハンドラが登録されている場合、バックグラウンドで処理開始
   - `PROMPT` 変数内の関数が評価される
   - Git情報などが動的に表示される

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**oh-my-zsh.sh**

```zsh
# ファイル: oh-my-zsh.sh:71
source "$ZSH/tools/check_for_upgrade.sh"

# ファイル: oh-my-zsh.sh:79
autoload -U compaudit compinit zrecompile

# ファイル: oh-my-zsh.sh:197-199
for lib_file ("$ZSH"/lib/*.zsh); do
  _omz_source "lib/${lib_file:t}"
done

# ファイル: oh-my-zsh.sh:203-206
for plugin ($plugins); do
  _omz_source "plugins/$plugin/$plugin.plugin.zsh"
done
```

### 6.2 ビジネスロジック

**lib/cli.zsh - omzコマンド管理:**

```zsh
# ファイル: lib/cli.zsh:205-226
function _omz::plugin {
  (( $# > 0 && $+functions[$0::$1] )) || {
    # ヘルプ表示
    return 1
  }

  local command="$1"
  shift

  $0::$command "$@"
}
```

**lib/git.zsh - Git情報の取得:**

```zsh
# ファイル: lib/git.zsh:14-40
function _omz_git_prompt_info() {
  if ! __git_prompt_git rev-parse --git-dir &> /dev/null; then
    return 0
  fi

  local ref
  ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \
  || ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \
  || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \
  || return 0

  echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
}
```

### 6.3 データアクセス

Oh My Zshは直接的なデータベースアクセスは行いませんが、以下のようなファイルシステムアクセスを行います:

**キャッシュ管理:**
```zsh
# ファイル: oh-my-zsh.sh:57-68
[[ -n "$ZSH_CACHE_DIR" ]] || ZSH_CACHE_DIR="$ZSH/cache"

if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
  ZSH_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh"
fi

mkdir -p "$ZSH_CACHE_DIR/completions"
```

### 6.4 ユーティリティ/共通機能

**lib/functions.zsh:**

```zsh
# ファイル: lib/functions.zsh:16-44
function open_command() {
  local open_cmd

  case "$OSTYPE" in
    darwin*)  open_cmd='open' ;;
    cygwin*)  open_cmd='cygstart' ;;
    linux*)   open_cmd='nohup xdg-open' ;;
    msys*)    open_cmd='start ""' ;;
  esac

  ${=open_cmd} "$@" &>/dev/null
}
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| エイリアス定義 | コマンドの短縮形を定義 | 高 | `plugins/git/git.plugin.zsh` |
| 関数ラッパー | コマンドをラップして機能追加 | 高 | `lib/git.zsh` |
| 条件付き設定 | OS/環境に応じた設定切り替え | 中 | `lib/functions.zsh` |
| zstyle設定 | Zsh固有の設定管理 | 中 | `lib/completion.zsh` |
| プロンプトセグメント | モジュール化されたプロンプト構築 | 中 | `themes/agnoster.zsh-theme` |

### 各パターンの詳細

#### パターン1: エイリアス定義パターン

**目的:** 頻繁に使用するコマンドを短縮して入力効率を向上させる

**実装例:**
```zsh
# ファイル: plugins/git/git.plugin.zsh:106-112
alias g='git'
alias ga='git add'
alias gaa='git add --all'
alias gapa='git add --patch'
alias gau='git add --update'
alias gav='git add --verbose'
```

**解説:** Gitの一般的なコマンドを1-3文字のエイリアスに短縮しています。

#### パターン2: 関数ラッパーパターン

**目的:** 既存コマンドに追加機能や環境設定を付与する

**実装例:**
```zsh
# ファイル: lib/git.zsh:10-12
function __git_prompt_git() {
  GIT_OPTIONAL_LOCKS=0 command git "$@"
}
```

**解説:** `GIT_OPTIONAL_LOCKS=0` を設定してgitコマンドを実行することで、ロックファイルによる競合を防いでいます。

#### パターン3: プロンプトセグメントパターン

**目的:** プロンプトを再利用可能なパーツに分割する

**実装例:**
```zsh
# ファイル: themes/agnoster.zsh-theme:126-137
prompt_segment() {
  local bg fg
  [[ -n $1 ]] && bg="%K{$1}" || bg="%k"
  [[ -n $2 ]] && fg="%F{$2}" || fg="%f"
  if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
    echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
  else
    echo -n "%{$bg%}%{$fg%} "
  fi
  CURRENT_BG=$1
  [[ -n $3 ]] && echo -n $3
}
```

**解説:** 背景色と前景色を引数として受け取り、セグメントの区切り文字を適切に挿入します。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: プラグイン有効化フロー

**概要:** `omz plugin enable` コマンドでプラグインを有効化する処理

**処理フロー:**
```
omz → _omz::plugin → _omz::plugin::enable → .zshrc編集 → reload
```

**詳細な追跡:**

1. **omzコマンド呼び出し** (`lib/cli.zsh:3-21`)
   ```zsh
   function omz {
     local command="$1"
     shift
     _omz::$command "$@"
   }
   ```

2. **pluginサブコマンド処理** (`lib/cli.zsh:205-226`)
   ```zsh
   function _omz::plugin {
     local command="$1"
     shift
     $0::$command "$@"
   }
   ```

3. **enable処理** (`lib/cli.zsh:324-416`)
   ```zsh
   function _omz::plugin::enable {
     # AWKスクリプトで.zshrcを編集
     awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new"
     command mv -f "$zdot/.zshrc.new" "$zshrc"

     # シェルをリロード
     [[ ! -o interactive ]] || _omz::reload
   }
   ```

#### 例2: Git情報のプロンプト表示フロー

**概要:** プロンプトにGitブランチ情報を表示する処理

**処理フロー:**
```
PROMPT評価 → git_prompt_info() → _omz_git_prompt_info() → __git_prompt_git → 出力
```

**詳細な追跡:**

1. **PROMPTでの関数呼び出し** (`themes/robbyrussell.zsh-theme:1-2`)
   ```zsh
   PROMPT="%(?:%{$fg_bold[green]%}%1{➜%} :%{$fg_bold[red]%}%1{➜%} )"
   PROMPT+=' $(git_prompt_info)'
   ```

2. **git_prompt_info関数** (`lib/git.zsh:149-153`)
   ```zsh
   function git_prompt_info() {
     if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
       echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
     fi
   }
   ```

3. **非同期処理結果の取得** (`lib/git.zsh:14-40`)
   ```zsh
   function _omz_git_prompt_info() {
     local ref
     ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null)
     echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
   }
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `oh-my-zsh.sh` - メインエントリーポイント
3. `lib/` ディレクトリ - コア機能

#### 特定機能を理解したい場合
1. 対象プラグインの `README.md`
2. 対象プラグインの `*.plugin.zsh`
3. 関連する `lib/*.zsh`

#### 改修作業を行う場合
1. `CONTRIBUTING.md` - 貢献ガイドライン
2. 対象コンポーネントのソースコード
3. 関連する既存プラグインの実装例

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要・インストール方法 | 初回・導入時 |
| `CONTRIBUTING.md` | 貢献方法・開発ガイド | 開発時 |
| `CODE_OF_CONDUCT.md` | 行動規範 | コミュニティ参加時 |
| `SECURITY.md` | セキュリティポリシー | 脆弱性報告時 |
| `plugins/*/README.md` | 各プラグインの使い方 | プラグイン利用時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: プラグインがどこで読み込まれているか分からない
A: `oh-my-zsh.sh:203-206` で `plugins` 変数に設定されたプラグインが順次読み込まれます。

#### Q: テーマ変数の意味が分からない
A: `ZSH_THEME_*` で始まる変数はテーマ固有の設定です。各テーマファイル冒頭のコメントを確認してください。

#### Q: 関数の定義場所を特定したい
A: `which 関数名` または `type 関数名` コマンドで定義場所を確認できます。

#### Q: エイリアスの一覧を確認したい
A: `alias` コマンドで現在定義されているエイリアス一覧を表示できます。`plugins/aliases` プラグインの `als` コマンドも便利です。

### デバッグのヒント

1. **関数の定義確認:**
   ```zsh
   which git_prompt_info
   type git_prompt_info
   ```

2. **変数の値確認:**
   ```zsh
   echo $ZSH
   echo $ZSH_CUSTOM
   echo $plugins
   ```

3. **ソースファイルのトレース:**
   ```zsh
   setopt SOURCE_TRACE
   source ~/.zshrc
   unsetopt SOURCE_TRACE
   ```

4. **デバッグ出力の有効化:**
   ```zsh
   _OMZ_DEBUG=1 omz update
   ```

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| fpath | 関数パス。関数定義ファイルの検索パス |
| compdef | 補完関数の定義コマンド |
| autoload | 関数の遅延ロード機構 |
| zstyle | Zsh固有のスタイル設定システム |
| precmd | コマンド実行前に呼ばれるフック |
| PROMPT | プライマリプロンプト文字列 |
| RPROMPT | 右側プロンプト文字列 |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `oh-my-zsh.sh` | メインローダー | 初期化処理、プラグイン/テーマの読み込み |
| `lib/cli.zsh` | CLIコマンド | `omz` コマンドの実装 |
| `lib/git.zsh` | Git機能 | Git情報取得関数群 |
| `lib/functions.zsh` | ユーティリティ | 汎用関数群 |
| `lib/completion.zsh` | 補完設定 | タブ補完の設定 |
| `lib/async_prompt.zsh` | 非同期処理 | 非同期プロンプト機構 |
| `tools/install.sh` | インストーラー | 初回インストールスクリプト |
| `tools/upgrade.sh` | アップグレーダー | 更新スクリプト |

### C. 参考資料

- [Zsh公式ドキュメント](https://zsh.sourceforge.io/Doc/)
- [Oh My Zsh Wiki](https://github.com/ohmyzsh/ohmyzsh/wiki)
- [Zsh Plugin Standard](https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html)
