# 画面設計書 17-pm

## 概要

本ドキュメントは、Bun CLIの `bun pm` コマンドの画面設計書です。パッケージマネージャーに関連する各種ユーティリティコマンドを提供するメタコマンドの仕様を定義します。

### 本画面の処理概要

`bun pm` コマンドは、パッケージマネージャー関連の様々なサブコマンドへのエントリーポイントを提供します。依存関係の一覧表示、キャッシュ管理、ロックファイル操作、パッケージメタデータ表示など、多様な機能を統合しています。

**業務上の目的・背景**：パッケージマネージャーの補助機能を統一されたインターフェースで提供し、開発者がプロジェクトの依存関係を効率的に管理できるようにします。npm/yarn/pnpmの類似コマンドとの互換性を考慮した設計になっています。

**画面へのアクセス方法**：`bun pm <subcommand>` の形式で実行します。サブコマンドなしで実行するとヘルプが表示されます。

**主要な操作・処理内容**：
- `bun pm ls`：依存関係ツリーの表示
- `bun pm bin`：binディレクトリパスの表示
- `bun pm hash`：ロックファイルハッシュの生成
- `bun pm cache`：キャッシュディレクトリの管理
- `bun pm migrate`：他パッケージマネージャーからの移行
- `bun pm trust`：信頼できる依存関係の管理
- その他多数のサブコマンド

**画面遷移**：各サブコマンドはそれぞれ独立した機能を実行し、結果をターミナルに表示して終了します。

**権限による表示制御**：特別な権限制御はありませんが、グローバル操作（-g）では適切なディレクトリ権限が必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | bun pm | 主機能 | パッケージマネージャーユーティリティ |
| 27 | bun pm scan | 補助機能 | セキュリティ脆弱性スキャン |
| 28 | bun pm pack | 補助機能 | tarball作成 |

## 画面種別

コマンド実行（サブコマンドに応じた出力）

## URL/ルーティング

```
bun pm [subcommand] [options]
```

## 入出力項目

### 入力項目（サブコマンド）

| サブコマンド | 必須 | 説明 |
|-------------|------|------|
| scan | いいえ | 全パッケージのセキュリティ脆弱性スキャン |
| pack | いいえ | 現在のワークスペースのtarball作成 |
| bin | いいえ | binディレクトリパスの表示 |
| ls / list | いいえ | 依存関係ツリーの表示 |
| why | いいえ | パッケージがインストールされている理由を表示 |
| whoami | いいえ | 現在のnpmユーザー名を表示 |
| view | いいえ | パッケージメタデータの表示 |
| version | いいえ | package.jsonのバージョンをバンプ |
| pkg | いいえ | package.jsonのデータ管理 |
| hash | いいえ | ロックファイルハッシュの生成・表示 |
| hash-string | いいえ | ハッシュ計算に使用される文字列を表示 |
| hash-print | いいえ | ロックファイルに保存されたハッシュを表示 |
| cache | いいえ | キャッシュディレクトリの表示・管理 |
| migrate | いいえ | 他パッケージマネージャーからの移行 |
| untrusted | いいえ | スクリプトを持つ未信頼依存関係の表示 |
| trust | いいえ | 未信頼依存関係のスクリプトを実行・信頼 |
| default-trusted | いいえ | デフォルト信頼リストの表示 |

### 共通オプション

| オプション | 型 | 説明 |
|-----------|-----|------|
| -g / --global | boolean | グローバルディレクトリで操作 |
| --all | boolean | 全依存関係を対象（ls等） |
| --json | boolean | JSON形式で出力（view等） |

## 表示項目

### ヘルプ表示（サブコマンドなし）

```
Usage: bun pm [flags] [<command>]

  Run package manager utilities.

Commands:

  bun pm scan                 scan all packages in lockfile for security vulnerabilities
  bun pm pack                 create a tarball of the current workspace
  bun pm bin                  print the path to bin folder
  bun list                    list the dependency tree according to the current lockfile
  bun pm why <pkg>            show dependency tree explaining why a package is installed
  bun pm whoami               print the current npm username
  bun pm view name[@version]  view package metadata from the registry
  bun pm version [increment]  bump the version in package.json and create a git tag
  bun pm pkg                  manage data in package.json
  bun pm hash                 generate & print the hash of the current lockfile
  bun pm hash-string          print the string used to hash the lockfile
  bun pm hash-print           print the hash stored in the current lockfile
  bun pm cache                print the path to the cache folder
  bun pm cache rm             clear the cache
  bun pm migrate              migrate another package manager's lockfile without installing anything
  bun pm untrusted            print current untrusted dependencies with scripts
  bun pm trust names ...      run scripts for untrusted dependencies and add to `trustedDependencies`
  bun pm default-trusted      print the default trusted dependencies list
```

## イベント仕様

### 1-サブコマンドディスパッチ

コマンド実行時の処理フロー：

1. `PackageManagerCommand.exec()` がエントリーポイントとして呼び出される
2. コマンドライン引数を解析し、PackageManagerを初期化
3. `getSubcommand()` でサブコマンドを特定
4. サブコマンドに応じて対応する処理を実行：
   - scan → `ScanCommand.execWithManager()`
   - pack → `PackCommand.execWithManager()`
   - whoami → `Npm.whoami()`
   - view → `PmViewCommand.view()`
   - bin → binパスを出力
   - hash → ロックファイルハッシュを計算・出力
   - cache → キャッシュパスを出力、`rm`で削除
   - ls → 依存関係ツリーを出力
   - migrate → 他ロックファイルからの変換
   - version → `PmVersionCommand.exec()`
   - why → `PmWhyCommand.exec()`
   - pkg → `PmPkgCommand.exec()`
   - trust/untrusted → Trust関連コマンド
5. 該当なしの場合はヘルプを表示

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

### 操作別データベース影響一覧

サブコマンドによりファイルシステム操作が異なります。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| scan | なし | SELECT | ロックファイル読み取りのみ |
| pack | tarball | CREATE | パッケージtarballを生成 |
| bin | なし | SELECT | パス表示のみ |
| ls | なし | SELECT | ロックファイル読み取りのみ |
| hash | なし | SELECT | ロックファイル読み取りのみ |
| cache | キャッシュ | DELETE | rm時にキャッシュを削除 |
| migrate | bun.lock | CREATE | ロックファイルを変換・作成 |
| version | package.json | UPDATE | バージョン番号を更新 |
| pkg | package.json | UPDATE | package.jsonのデータを更新 |
| trust | package.json | UPDATE | trustedDependenciesを更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| PM_001 | エラー | No package.json was found for directory "{path}" | package.json未検出 |
| PM_002 | 注記 | Run "bun init" to initialize a project | package.json未検出時 |
| PM_003 | エラー | Lockfile not found | ロックファイル未検出 |
| PM_004 | エラー | Error loading lockfile: {error} | ロックファイル読み込みエラー |
| PM_005 | エラー | "{subcommand}" unknown command | 不明なサブコマンド |
| PM_006 | エラー | missing authentication (run `bunx npm login`) | 認証情報なし（whoami） |
| PM_007 | エラー | failed to authenticate with registry | レジストリ認証失敗 |
| PM_008 | 警告 | not in $PATH | グローバルbinがPATHにない |
| PM_009 | 情報 | Cleared 'bun install' cache | キャッシュ削除完了 |
| PM_010 | 情報 | Cleared {n} cached 'bunx' packages | bunxキャッシュ削除完了 |

## 例外処理

| 例外条件 | 処理内容 | エラーコード |
|---------|---------|------------|
| package.json未検出 | エラーメッセージとヒントを表示 | 1 |
| ロックファイル未検出 | エラーメッセージを表示して終了 | 1 |
| ロックファイル解析エラー | エラー詳細を表示して終了 | 1 |
| 不明なサブコマンド | ヘルプとエラーメッセージを表示 | 1 |
| 認証情報なし | `bunx npm login`の実行を案内 | 1 |

## 備考

- `bun list` は `bun pm ls` のエイリアス
- `bun whoami` は `bun pm whoami` のエイリアス
- ロックファイル操作（hash等）は読み取り専用
- キャッシュ削除はbun installキャッシュとbunxキャッシュの両方を対象
- migrateは他パッケージマネージャー（npm/yarn/pnpm）のロックファイルを検出して変換

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | package_manager_command.zig | `src/cli/package_manager_command.zig` | ByName構造体（L5-16）：依存関係のソート用コンパレータ |
| 1-2 | package_manager_command.zig | `src/cli/package_manager_command.zig` | NodeModulesFolder構造体（L1）：node_modulesツリー表現 |

**読解のコツ**: pmコマンドは多数のサブコマンドを持つディスパッチャーとして機能します。

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

処理の起点となるexec関数を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | package_manager_command.zig | `src/cli/package_manager_command.zig` | exec関数（L138-457）：メイン処理ロジック |

**主要処理フロー**:
1. **L139-140**: コマンドライン引数を取得
2. **L143**: 直接"bun whoami"呼び出しの検出
3. **L145-158**: PackageManagerを初期化（エラーハンドリング付き）
4. **L161-166**: サブコマンドを取得・正規化
5. **L172-445**: サブコマンドに応じた分岐処理

#### Step 3: サブコマンドディスパッチを理解する

各サブコマンドへの分岐処理を読み解きます。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | package_manager_command.zig | `src/cli/package_manager_command.zig` | scan分岐（L172-174）：ScanCommand呼び出し |
| 3-2 | package_manager_command.zig | `src/cli/package_manager_command.zig` | pack分岐（L175-177）：PackCommand呼び出し |
| 3-3 | package_manager_command.zig | `src/cli/package_manager_command.zig` | whoami分岐（L178-194）：Npm.whoami呼び出し |
| 3-4 | package_manager_command.zig | `src/cli/package_manager_command.zig` | view分岐（L195-198）：PmViewCommand.view呼び出し |
| 3-5 | package_manager_command.zig | `src/cli/package_manager_command.zig` | bin分岐（L199-224）：binパス出力 |
| 3-6 | package_manager_command.zig | `src/cli/package_manager_command.zig` | hash分岐（L225-235）：ハッシュ計算・出力 |
| 3-7 | package_manager_command.zig | `src/cli/package_manager_command.zig` | cache分岐（L251-308）：キャッシュ管理 |
| 3-8 | package_manager_command.zig | `src/cli/package_manager_command.zig` | ls分岐（L318-397）：依存関係ツリー表示 |
| 3-9 | package_manager_command.zig | `src/cli/package_manager_command.zig` | migrate分岐（L400-435）：ロックファイル移行 |

#### Step 4: ヘルプ表示を理解する

printHelp関数でヘルプメッセージを出力します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | package_manager_command.zig | `src/cli/package_manager_command.zig` | printHelp関数（L78-136）：ヘルプテキスト定義と出力 |

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

```
PackageManagerCommand.exec()
    │
    ├─ PackageManager.CommandLineArguments.parse(.pm)
    │
    ├─ PackageManager.init()
    │
    ├─ getSubcommand() ─────────────────────────────────────┐
    │                                                       │
    │   ┌───────────────────────────────────────────────────┘
    │   ▼
    ├─ [scan]    → ScanCommand.execWithManager()
    ├─ [pack]    → PackCommand.execWithManager()
    ├─ [whoami]  → Npm.whoami()
    ├─ [view]    → PmViewCommand.view()
    ├─ [bin]     → Path.joinAbs() → 出力
    ├─ [hash]    → lockfile.loadFromCwd() → hasMetaHashChanged() → 出力
    ├─ [hash-print] → lockfile.loadFromCwd() → fmtMetaHash() → 出力
    ├─ [hash-string] → lockfile.loadFromCwd() → hasMetaHashChanged(print=true)
    ├─ [cache]   → getCacheDirectory() → 出力 or deleteTreeAbsolute()
    ├─ [ls]      → lockfile.loadFromCwd() → Tree.Iterator → 出力
    ├─ [migrate] → detectAndLoadOtherLockfile() → saveToDisk()
    ├─ [version] → PmVersionCommand.exec()
    ├─ [why]     → PmWhyCommand.exec()
    ├─ [pkg]     → PmPkgCommand.exec()
    ├─ [trust]   → TrustCommand.exec()
    ├─ [untrusted] → UntrustedCommand.exec()
    ├─ [default-trusted] → DefaultTrustedCommand.exec()
    │
    └─ [該当なし] → printHelp()
```

### データフロー図

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

bun pm <subcommand> ──────▶ getSubcommand() ───────────────────┐
                                  │                            │
                                  ▼                            │
                           ┌─────────────────┐                 │
                           │ サブコマンド判定 │                  │
                           └─────────────────┘                 │
                                  │                            │
        ┌──────┬──────┬──────┬───┴───┬──────┬──────┐          │
        ▼      ▼      ▼      ▼       ▼      ▼      ▼          ▼
      scan   pack  whoami  view    bin   hash   ls   ...   [ヘルプ]
        │      │      │      │       │      │      │
        ▼      ▼      ▼      ▼       ▼      ▼      ▼
    [脆弱性] [tar] [ユーザー名] [メタ] [パス] [ハッシュ] [ツリー]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| package_manager_command.zig | `src/cli/package_manager_command.zig` | ソース | pmコマンドのメイン実装 |
| scan_command.zig | `src/cli/scan_command.zig` | ソース | セキュリティスキャン |
| pack_command.zig | `src/cli/pack_command.zig` | ソース | tarball作成 |
| pm_view_command.zig | `src/cli/pm_view_command.zig` | ソース | パッケージ情報表示 |
| pm_version_command.zig | `src/cli/pm_version_command.zig` | ソース | バージョン管理 |
| pm_why_command.zig | `src/cli/pm_why_command.zig` | ソース | 依存関係理由表示 |
| pm_pkg_command.zig | `src/cli/pm_pkg_command.zig` | ソース | package.jsonデータ管理 |
| pm_trusted_command.zig | `src/cli/pm_trusted_command.zig` | ソース | 信頼依存関係管理 |
| lockfile.zig | `src/install/lockfile.zig` | ソース | ロックファイル操作 |
| migration.zig | `src/install/migration.zig` | ソース | ロックファイル移行 |
