# 画面設計書 22-create

## 概要

本ドキュメントは、Bun CLIの`bun create`コマンドの画面設計書です。`bun create`コマンドは、テンプレートから新規プロジェクトを作成するためのコマンドで、GitHubリポジトリ、npm パッケージ、ローカルフォルダなど様々なソースからプロジェクトを作成できます。

### 本画面の処理概要

`bun create`コマンドは、テンプレートベースの新規プロジェクト作成機能を提供します。NPMテンプレート、GitHubリポジトリ、ローカルフォルダなど複数のソースからプロジェクトのひな形を取得し、必要な変換を行って新規プロジェクトを構築します。

**業務上の目的・背景**：新規プロジェクトの立ち上げは、ボイラープレートコードの作成や依存関係の設定など多くの手順が必要です。`bun create`はこれらを自動化し、`create-react-app`や`create-next-app`などのNPMテンプレートエコシステムと互換性を持ちながら、Bunの高速なインストール機能と組み合わせて迅速なプロジェクト立ち上げを実現します。また、React JSX/TSXファイルを直接指定して即座に開発環境を構築する機能も提供します。

**画面へのアクセス方法**：ターミナルで`bun create <テンプレート> [出力先]`コマンドを実行します。`bun c`はエイリアスとして使用可能です。

**主要な操作・処理内容**：
1. コマンドライン引数の解析（テンプレート名、出力先、オプション）
2. テンプレートソースの判定（NPM/GitHub/ローカル/JSXファイル）
3. テンプレートのダウンロードまたはコピー
4. tarballの解凍とファイル展開
5. package.jsonの変換（プロジェクト名の更新等）
6. 依存関係の自動インストール（bun install）
7. postinstallスクリプトの実行

**画面遷移**：エントリーポイントの`bun`コマンドから直接アクセス。NPMテンプレートの場合は内部的に`bunx create-<template>`に委譲されることがあります。完了後はシェルに戻ります。

**権限による表示制御**：特にロールベースの権限制御はありません。ディレクトリへの書き込み権限が必要です。GitHubからのダウンロードにはレート制限があり、`GITHUB_TOKEN`環境変数で緩和できます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | bun create | 主機能 | テンプレートからの新規プロジェクト作成 |
| 41 | npmレジストリ | 補助機能 | テンプレートパッケージの取得 |
| 39 | 依存関係解決 | 補助機能 | テンプレート依存関係のインストール |

## 画面種別

コマンドライン / プロジェクト作成

## URL/ルーティング

- コマンド: `bun create <テンプレート> [出力先]`
- エイリアス: `bun c`

## 入出力項目

| 項目名 | 項目種別 | 型 | 必須 | 説明 |
|--------|----------|-----|------|------|
| template | 位置引数 | string | 必須 | テンプレート名（npm/GitHub/ローカル/JSXファイル） |
| destination | 位置引数 | string | 任意 | 出力先ディレクトリ（省略時はテンプレート名から推定） |
| --help, -h | フラグ | boolean | 任意 | ヘルプ表示 |
| --force | フラグ | boolean | 任意 | 既存ファイルを上書き |
| --no-install | フラグ | boolean | 任意 | node_modulesのインストールをスキップ |
| --no-git | フラグ | boolean | 任意 | Gitリポジトリの作成をスキップ |
| --verbose | フラグ | boolean | 任意 | 詳細ログを表示 |
| --no-package-json | フラグ | boolean | 任意 | package.jsonの変換を無効化 |
| --open | フラグ | boolean | 任意 | 完了後にbunを起動しブラウザで開く |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| 進捗バー | ダウンロード/解凍中 | Loading/Decompressing/Extractingの進捗表示 |
| コンフリクトファイル一覧 | --forceなしでファイル競合時 | 競合するファイル名の一覧 |
| 実行コマンド | postinstallスクリプト実行時 | `$ <コマンド>`形式で表示 |
| テンプレート一覧 | テンプレートが見つからない場合 | 使用可能なテンプレートの一覧 |

## イベント仕様

### 1-テンプレートソース判定

入力されたテンプレート名からソースタイプを判定します。

- **トリガー**: コマンド実行時
- **判定ロジック**:
  - `.jsx`/`.tsx`/`.mjs`/`.cjs`拡張子 → JSXファイルとして処理
  - `@org/repo`形式または`/`を含む → GitHubリポジトリ
  - ローカルパスが存在 → ローカルフォルダ
  - その他 → NPMテンプレート（`create-<template>`に変換）

### 2-GitHubリポジトリからダウンロード

GitHubからtarball形式でリポジトリをダウンロードします。

- **トリガー**: テンプレートがGitHubリポジトリと判定された場合
- **処理内容**:
  - GitHub APIを使用してリポジトリ情報を取得
  - tarball URLからアーカイブをダウンロード
  - gzip解凍後、tar展開

### 3-ローカルフォルダからコピー

ローカルテンプレートフォルダからファイルをコピーします。

- **トリガー**: テンプレートがローカルフォルダと判定された場合
- **処理内容**:
  - テンプレートディレクトリを再帰的に走査
  - `node_modules`、`.git`等のスキップ対象を除外
  - ファイルを出力先にコピー

### 4-ファイル競合チェック

出力先に既存ファイルがないかチェックします。

- **トリガー**: `--force`オプションなしで出力先が存在する場合
- **処理内容**:
  - 展開予定ファイルと既存ファイルを比較
  - `README.md`、`.gitignore`等は競合対象外
  - 競合がある場合はエラー終了

### 5-package.json変換

package.jsonの内容を新規プロジェクト用に変換します。

- **トリガー**: `--no-package-json`オプションなしの場合
- **処理内容**:
  - `name`フィールドを出力先ディレクトリ名に更新
  - 不要なロックファイル（package-lock.json等）を削除
  - `gitignore`を`.gitignore`にリネーム

### 6-依存関係インストール

変換後のpackage.jsonに基づき依存関係をインストールします。

- **トリガー**: `--no-install`オプションなしで依存関係がある場合
- **処理内容**: `bun install`を実行

## データベース更新仕様

本コマンドはデータベースを使用しません。ファイルシステムへの書き込みとHTTPリクエストを行います。

### 操作別ファイル影響一覧

| 操作（イベント） | 対象ファイル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| テンプレート展開 | 各種プロジェクトファイル | CREATE | テンプレートファイルの展開 |
| package.json変換 | package.json | UPDATE | プロジェクト名の更新 |
| gitignore変換 | .gitignore | CREATE/RENAME | gitignoreから.gitignoreへ |
| 不要ファイル削除 | .npmignore | DELETE | npm専用ファイルの削除 |
| 依存関係インストール | node_modules/ | CREATE | パッケージのインストール |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|---------------|----------|
| 進捗 | `Loading <template>` | ダウンロード開始時 |
| 進捗 | `Decompressing <template>` | gzip解凍時 |
| 進捗 | `Extracting <template>` | tar展開時 |
| 進捗 | `Copying files` | ローカルコピー時 |
| エラー | `error: "<template>" was not found. Here are templates you can use:` | テンプレートが見つからない場合 |
| エラー | `error: GitHub returned 403. This usually means GitHub is rate limiting your requests.` | GitHubレート制限時 |
| エラー | `error: The directory <dir>/ contains files that could conflict:` | ファイル競合時 |
| 情報 | `To download <template> anyway, use --force` | ファイル競合時の案内 |
| 警告 | `warn: "<package>" won't work in bun yet` | 非対応パッケージ検出時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| テンプレートが見つからない | 使用可能なテンプレート一覧を表示し終了コード1で終了 |
| GitHubレート制限 (403) | GITHUB_ACCESS_TOKEN設定の案内を表示し終了 |
| GitHubリポジトリが存在しない (404) | 使用可能なテンプレート一覧を表示し終了 |
| 出力先ディレクトリ作成失敗 | エラーメッセージを表示し終了コード1で終了 |
| ファイルコピー失敗 | エラーメッセージを表示し終了 |
| package.jsonパースエラー | package.json変換をスキップし処理続行 |

## 備考

- `react`テンプレートは非推奨で、`react-app`または`vite`の使用が推奨されます
- `next`テンプレートは`next-app`にリダイレクトされます
- 環境変数`GITHUB_TOKEN`または`GITHUB_ACCESS_TOKEN`でGitHubレート制限を緩和できます
- 環境変数`GITHUB_API_DOMAIN`でGitHub APIドメインをカスタマイズ可能（企業プロキシ対応）
- 環境変数`BUN_CREATE_DIR`でカスタムテンプレートディレクトリを指定可能

---

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

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

### 推奨読解順序

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

まず、createコマンドで使用される主要なデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | create_command.zig | `src/cli/create_command.zig` | CreateOptions構造体（142-190行目）でコマンドオプションを定義 |
| 1-2 | create_command.zig | `src/cli/create_command.zig` | Example.Tag列挙型でテンプレートソースタイプを定義 |
| 1-3 | create_command.zig | `src/cli/create_command.zig` | skip_dirs/skip_files配列（12-20行目）で除外対象を定義 |

**読解のコツ**: CreateOptionsのparamsフィールドでclapライブラリを使ったCLI引数定義が行われています。

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

処理の起点となるファイル・関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cli.zig | `src/cli.zig` | `bun create`コマンドの判定（600行目: `RootCommandMatcher.case("c"), RootCommandMatcher.case("create")`) |
| 2-2 | cli.zig | `src/cli.zig` | extractInfo()でテンプレート情報抽出（1682-1684行目） |
| 2-3 | create_command.zig | `src/cli/create_command.zig` | CreateCommand.exec()関数（195行目〜）がメイン処理 |

**主要処理フロー**:
1. **163-189行目**: CreateOptions.parse()でコマンドライン引数解析
2. **253-614行目**: テンプレートソースタイプ別の処理分岐
3. **651-1000行目以降**: package.json変換処理
4. **依存関係インストールとpostinstallスクリプト実行**

#### Step 3: テンプレートソース判定

テンプレートの種類判定ロジックを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cli.zig | `src/cli.zig` | extractInfo()関数でテンプレートタイプを判定 |
| 3-2 | create_command.zig | `src/cli/create_command.zig` | Example.Tag列挙型（github_repository, official, local_folder, jslike_file） |

#### Step 4: ダウンロードと展開処理

GitHubからのダウンロードと展開処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create_command.zig | `src/cli/create_command.zig` | Example.fetch/fetchFromGitHub（257-317行目）でダウンロード |
| 4-2 | create_command.zig | `src/cli/create_command.zig` | Zlib.ZlibReaderArrayList（329行目）でgzip解凍 |
| 4-3 | create_command.zig | `src/cli/create_command.zig` | Archiver.extractToDisk（389-398行目）でtar展開 |

#### Step 5: ローカルコピー処理

ローカルテンプレートのコピー処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | create_command.zig | `src/cli/create_command.zig` | local_folder分岐（412-613行目） |
| 5-2 | create_command.zig | `src/cli/create_command.zig` | Walker.walk（453行目）でディレクトリ走査 |
| 5-3 | create_command.zig | `src/cli/create_command.zig` | FileCopier.copy（456-549行目）でファイルコピー |

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

```
bun create <template> [destination]
    │
    ├─ cli.zig: Command.which()
    │      └─ "create"/"c"を検出 → CreateCommand
    │
    ├─ cli.zig: extractInfo()
    │      └─ テンプレートタイプ判定
    │
    ├─ [NPMテンプレートの場合]
    │      └─ BunxCommand.exec() に委譲
    │          └─ bunx create-<template>
    │
    └─ CreateCommand.exec()
           │
           ├─ CreateOptions.parse() [引数解析]
           │
           ├─ [GitHubリポジトリの場合]
           │      ├─ Example.fetchFromGitHub()
           │      │      └─ HTTP.AsyncHTTP (tarball取得)
           │      ├─ Zlib.ZlibReaderArrayList (gzip解凍)
           │      └─ Archiver.extractToDisk (tar展開)
           │
           ├─ [ローカルフォルダの場合]
           │      ├─ Walker.walk() (ディレクトリ走査)
           │      └─ FileCopier.copy() (ファイルコピー)
           │
           ├─ package.json変換
           │      └─ JSON.parseUTF8 → 変換 → JSPrinter
           │
           └─ bun install [依存関係インストール]
```

### データフロー図

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

コマンドライン引数        ───▶ CreateOptions.parse()      ───▶ CreateOptions構造体
(template, destination)

テンプレートソース判定    ───▶ Example.Tag判定            ───▶ ソースタイプ
(GitHub/Local/NPM)

[GitHubの場合]
GitHub API              ───▶ HTTP.AsyncHTTP             ───▶ tarball (gzip)
                        ───▶ Zlib解凍                    ───▶ tarball (raw)
                        ───▶ Archiver.extractToDisk     ───▶ プロジェクトファイル群

[ローカルの場合]
テンプレートディレクトリ ───▶ Walker.walk                ───▶ ファイル一覧
                        ───▶ FileCopier.copy            ───▶ プロジェクトファイル群

package.json            ───▶ JSON.parseUTF8             ───▶ 更新済みpackage.json
(name更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| create_command.zig | `src/cli/create_command.zig` | ソース | createコマンドのメイン実装 |
| cli.zig | `src/cli.zig` | ソース | CLIコマンドルーター、テンプレート判定 |
| bunx_command.zig | `src/cli/bunx_command.zig` | ソース | NPMテンプレート委譲先 |
| libarchive.zig | `src/libarchive/libarchive.zig` | ソース | tarアーカイブ処理 |
| walker_skippable.zig | `src/walker_skippable.zig` | ソース | ディレクトリ走査 |
| http.zig | `src/http.zig` | ソース | HTTPクライアント |
| zlib.zig | `src/zlib.zig` | ソース | gzip解凍処理 |
