# 画面設計書 3-x (bunx)

## 概要

本ドキュメントは、Bun CLIの`x`（bunx）コマンドの設計仕様を記述する。`bun x`または`bunx`コマンドは、npmパッケージに含まれるCLIバイナリを実行し、未インストールの場合は自動的にインストールして実行する機能を提供する。

### 本画面の処理概要

`bun x`コマンドは、npxと同様の機能を提供し、パッケージのCLIツールを簡単に実行できる。必要に応じて一時的にパッケージをインストールし、バイナリを実行する。

**業務上の目的・背景**：開発ツール（vite、prisma、eslint等）を一時的に実行したい場合、グローバルインストールせずに最新版を実行できる。これにより、プロジェクト間でのバージョン競合を避け、常に最新のツールを使用可能にする。npxよりも高速な実行を実現。

**画面へのアクセス方法**：ターミナルから以下のコマンドで実行する。
- `bun x <package>` - パッケージのCLIバイナリを実行
- `bunx <package>` - bunxコマンドとして直接実行
- `bun x --package=<pkg> <binary>` - 特定パッケージから特定バイナリを実行

**主要な操作・処理内容**：
1. パッケージ名とバージョンの解析
2. ローカルnode_modules/.binでの既存バイナリ検索
3. bunxキャッシュディレクトリでの既存バイナリ検索
4. 未インストール時は一時ディレクトリにインストール
5. バイナリの実行
6. キャッシュの期限切れチェック（24時間）

**画面遷移**：
- エントリーポイント：`bun x` または `bunx` コマンドから直接実行
- 遷移先：バイナリ実行完了後はターミナルに制御を返す
- 関連コマンド：`bun add`（パッケージインストール）、`bun run`（スクリプト実行）

**権限による表示制御**：特になし。ファイルシステムの読み書き権限に依存。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | bunx | 主機能 | パッケージバイナリの実行と必要に応じた自動インストール |
| 39 | 依存関係解決 | 補助機能 | 未インストールパッケージの依存関係解決 |
| 41 | npmレジストリ | 補助機能 | パッケージ情報のnpmレジストリからの取得 |

## 画面種別

コマンドラインインターフェース（CLI）- パッケージバイナリ実行コマンド

## URL/ルーティング

コマンドラインパターン:
- `bun x [flags] <package>[@version] [args...]`
- `bunx [flags] <package>[@version] [args...]`

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| package | string | Yes | 実行するパッケージ名（@version指定可） |
| --bun / -b | flag | No | Bunランタイムを強制使用 |
| --silent | flag | No | インストール時の出力を抑制 |
| --verbose | flag | No | インストール時の詳細出力 |
| --no-install | flag | No | インストールをスキップ（既存バイナリのみ実行） |
| --package / -p | string | No | インストールするパッケージを明示的に指定 |
| [args...] | string[] | No | パッケージバイナリに渡す引数 |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| stdout | stream | バイナリの標準出力 |
| stderr | stream | バイナリの標準エラー出力 |
| exit code | number | バイナリの終了コード |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| インストールログ | --silent未指定かつインストール時 | パッケージインストールの進行状況 |
| エラーメッセージ | エラー発生時 | パッケージ名が見つからない等のエラー |
| 警告メッセージ | --no-install時にキャッシュが古い | 古いバージョンを使用している旨の警告 |

## イベント仕様

### 1-既存バイナリ実行

ローカルまたはキャッシュに既存バイナリが存在する場合の処理フロー：

1. コマンドライン引数を解析（Options.parse）
2. パッケージ名とバージョンを解析（UpdateRequest.parse）
3. ローカルnode_modules/.binでバイナリを検索
4. bunxキャッシュディレクトリでバイナリを検索
5. キャッシュの鮮度チェック（24時間以内か）
6. 見つかった場合はRunCommand.runBinaryで実行
7. 終了コードを返却

### 2-パッケージインストールと実行

バイナリが見つからない場合の処理フロー：

1. bunxキャッシュディレクトリを作成
2. 空のpackage.jsonを作成
3. `bun add <package>` を子プロセスとして実行
4. インストール完了後、バイナリを検索
5. RunCommand.runBinaryで実行
6. 終了コードを返却

### 3-キャッシュ更新

キャッシュが古い場合（24時間超過）の処理フロー：

1. キャッシュディレクトリの削除
2. 新規インストールの実行
3. バイナリの実行

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

本コマンドはデータベースを使用しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| ERR_NO_PACKAGE | error | --package requires a package name | --packageオプションに値がない |
| ERR_NO_BINARY | error | When using --package, you must specify the binary to run | --package使用時にバイナリ名がない |
| ERR_NO_BIN_FOUND | error | could not determine executable to run for package {name} | バイナリが見つからない |
| ERR_INSTALL_FAILED | error | bunx failed to install {package} due to error {error} | インストール失敗 |
| WARN_STALE | warning | Using a stale installation of {package} because --no-install was passed | 古いキャッシュを使用 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|----------|---------|
| パッケージ不在 | 指定パッケージがレジストリに存在しない | エラーメッセージを表示し終了コード1で終了 |
| バイナリ不在 | パッケージにbinフィールドがない | エラーメッセージを表示し終了コード1で終了 |
| インストール失敗 | ネットワークエラー等でインストールが失敗 | エラーメッセージを表示し終了コード1で終了 |
| キャッシュディレクトリ作成失敗 | 権限不足等 | エラーを返却 |

## 備考

- bunxキャッシュは `<temp_dir>/bunx-<uid>-<package>@<version>/` に保存される
- キャッシュの有効期限は24時間（86400秒）
- `tsc`は自動的に`typescript`パッケージから実行される
- `@org/pkg`形式のスコープ付きパッケージもサポート
- npx互換のコマンドライン引数をサポート

---

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

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

### 推奨読解順序

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

bunxコマンドに使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | bunx_command.zig | `src/cli/bunx_command.zig` | Options構造体の定義（行8-136） |

**読解のコツ**: Options構造体にはpackage_name、binary_name、verbose_install、silent_install、no_install等のフィールドが含まれる。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bunx_command.zig | `src/cli/bunx_command.zig` | BunxCommand.exec関数（行332-863） |

**主要処理フロー**:
1. **行336**: ctx.debug.silentをtrueに設定
2. **行338**: Options.parse()でCLI引数を解析
3. **行341-348**: UpdateRequest.parseでパッケージ名を解析
4. **行361-374**: tscの場合はtypescriptパッケージに変換
5. **行383-398**: configureEnvForRun/configurePathForRunで環境設定

#### Step 3: バイナリ検索処理を理解する

既存バイナリの検索処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | bunx_command.zig | `src/cli/bunx_command.zig` | try_run_existing ブロック（行551-686） |
| 3-2 | bunx_command.zig | `src/cli/bunx_command.zig` | getBinName/getBinNameFromTempDirectory関数 |

**主要処理フロー**:
- **行551-686**: 既存バイナリの検索とキャッシュ鮮度チェック
- **行556-572**: bun.which()でPATHからバイナリを検索
- **行578-617**: キャッシュの鮮度チェック（24時間 = 86400秒）
- **行620-630**: 見つかった場合はRunCommand.runBinaryで実行

#### Step 4: インストール処理を理解する

パッケージインストール処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | bunx_command.zig | `src/cli/bunx_command.zig` | インストール処理（行705-798） |

**主要処理フロー**:
- **行705**: bunxキャッシュディレクトリの作成
- **行707-711**: 空のpackage.jsonの作成
- **行713-741**: `bun add`コマンドの引数構築
- **行748-798**: spawnSyncでインストール実行

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

```
BunxCommand.exec()
    |
    +-- Options.parse() (CLI引数解析)
    |
    +-- UpdateRequest.parse() (パッケージ名解析)
    |
    +-- Run.configureEnvForRun() (環境設定)
    |
    +-- Run.configurePathForRun() (PATH設定)
    |
    +-- bun.which() (既存バイナリ検索)
    |       |
    |       +-- [見つかった場合]
    |       |       +-- キャッシュ鮮度チェック
    |       |       +-- Run.runBinary() (実行)
    |       |
    |       +-- [見つからない場合]
    |               +-- getBinName() (package.jsonからbin名取得)
    |
    +-- [インストール必要な場合]
    |       +-- bunxキャッシュディレクトリ作成
    |       +-- package.json作成
    |       +-- spawnSync("bun", "add", ...) (インストール)
    |
    +-- bun.which() (インストール後のバイナリ検索)
    |
    +-- Run.runBinary() (バイナリ実行)
```

### データフロー図

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

コマンドライン引数 -----> Options.parse() ---------> Options構造体
        |
        v
パッケージ名@version -----> UpdateRequest.parse() --> パッケージ情報
        |
        v
node_modules/.bin --------> bun.which() ------------> バイナリパス(あれば)
        |
        v
bunxキャッシュ -----------> bun.which() ------------> バイナリパス(あれば)
        |
        v
[未インストールの場合]
        |
npmレジストリ -----------> bun add --------------> インストール完了
        |
        v
                          Run.runBinary() --------> stdout/stderr/exit code
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bunx_command.zig | `src/cli/bunx_command.zig` | ソース | bunxコマンドのメイン実装 |
| run_command.zig | `src/cli/run_command.zig` | ソース | runBinary関数の実装 |
| which.zig | `src/which.zig` | ソース | PATHからバイナリを検索 |
| install/install.zig | `src/install/install.zig` | ソース | パッケージインストール処理 |
| resolver/package_json.zig | `src/resolver/package_json.zig` | ソース | package.jsonのbin解析 |
