# 機能設計書 73-$シェル

## 概要

本ドキュメントは、Bunの$シェル機能（タグ付きテンプレートリテラルによるシェル実行）の機能設計を記述する。$シェルは、JavaScriptコード内でシェルコマンドを直感的かつ安全に実行するためのAPIである。

### 本機能の処理概要

$シェルは、タグ付きテンプレートリテラル構文を使用してシェルコマンドを実行し、結果をPromiseで返す機能である。クロスプラットフォーム対応の組み込みシェルインタプリタを持ち、多くの基本コマンドをネイティブ実装している。

**業務上の目的・背景**：ビルドスクリプト、タスクランナー、自動化スクリプトなど、シェルコマンドの実行が必要な場面で使用される。従来のchild_process.execと比較して、より直感的な構文、安全なパラメータ展開、クロスプラットフォーム互換性を提供する。Node.jsのスクリプトやnpm scriptsの代替として利用可能。

**機能の利用シーン**：
- ビルドプロセスの自動化
- ファイル操作（コピー、移動、削除）
- Git操作の自動化
- テスト実行スクリプト
- デプロイメントスクリプト

**主要な処理内容**：
1. タグ付きテンプレートリテラルからシェルスクリプトをパース
2. 変数展開とパラメータ置換
3. パイプライン、リダイレクト、条件実行の処理
4. 組み込みコマンドの実行または外部コマンドの起動
5. 標準出力/エラー出力の収集と返却

**関連システム・外部連携**：OSのシェル環境、ファイルシステム、環境変数と連携。組み込みコマンドはBunのファイルシステムAPIを内部で使用。

**権限による制御**：シェルコマンドはOS権限に従う。ファイルシステム操作は実行ユーザーの権限で制限される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | exec | 主機能 | シェルスクリプトのBunによる直接実行 |

## 機能種別

コマンド実行 / 外部プロセス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| template | TemplateStringsArray | Yes | シェルコマンドテンプレート | タグ付きテンプレートリテラル必須 |
| ...args | any[] | No | 埋め込み変数 | 自動エスケープ |

### 設定オプション

| オプション | 型 | 説明 |
|-----------|-----|------|
| cwd | string | 作業ディレクトリ |
| env | Record<string, string> | 環境変数 |
| quiet | boolean | 出力を抑制 |
| nothrow | boolean | エラー時に例外を投げない |

### 入力データソース

タグ付きテンプレートリテラルとして直接記述。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| stdout | Buffer | 標準出力 |
| stderr | Buffer | 標準エラー出力 |
| exitCode | number | 終了コード |

### 出力先

ShellPromiseとして返却。await時にShellOutputオブジェクトを取得。

## 処理フロー

### 処理シーケンス

```
1. テンプレートリテラルのパース
   └─ ParsedShellScriptオブジェクトを生成
2. 設定の適用
   └─ cwd、env、quiet、throwsを設定
3. インタプリタの起動
   └─ ShellInterpreterを生成してrun()
4. 状態マシンによる実行
   └─ 非同期IOを状態マシンで管理
5. 結果の収集
   └─ stdout、stderr、exitCodeを返却
```

### フローチャート

```mermaid
flowchart TD
    A["$`command`"] --> B[ParsedShellScript生成]
    B --> C{設定オプション?}
    C -->|cwd/env/quiet| D[設定適用]
    C -->|なし| E[ShellPromise生成]
    D --> E
    E --> F[await/then呼び出し]
    F --> G[ShellInterpreter起動]
    G --> H{コマンド種別}
    H -->|組み込み| I[Builtin実行]
    H -->|外部| J[Subprocess起動]
    I --> K[結果収集]
    J --> K
    K --> L{exitCode == 0?}
    L -->|Yes| M[ShellOutput返却]
    L -->|No| N{throws?}
    N -->|Yes| O[ShellError投げる]
    N -->|No| M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | タグ付きテンプレート必須 | `$`は必ずタグ付きテンプレートリテラルで使用 | 常時 |
| BR-73-02 | 変数エスケープ | 埋め込み変数は自動的にエスケープ | 常時 |
| BR-73-03 | デフォルトthrows | exitCode !== 0でShellErrorを投げる | nothrow未指定時 |
| BR-73-04 | 組み込みコマンド優先 | 組み込みコマンドは外部コマンドより優先 | 常時 |

### 計算ロジック

なし

## データベース操作仕様

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

なし（データベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ShellError | Error | コマンドが非0終了 | nothrow()で抑制可能 |
| TypeError | Error | タグ付きテンプレート以外で呼び出し | `$\`cmd\`形式で使用 |
| SyntaxError | Error | シェル構文エラー | 構文を修正 |

### リトライ仕様

なし（呼び出し側で制御）

## トランザクション仕様

なし

## パフォーマンス要件

- 組み込みコマンドはサブプロセス生成をスキップして高速実行
- 非同期IOで主スレッドをブロックしない
- 状態マシンベースのインタプリタで効率的なメモリ使用

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

- 埋め込み変数は自動エスケープでインジェクション防止
- 環境変数の継承は明示的に制御可能
- サンドボックス機能は提供されない（OS権限に依存）

## 備考

組み込みコマンド一覧：
- `cat` - ファイル内容の表示（POSIXでは無効）
- `cd` - ディレクトリ変更
- `cp` - ファイルコピー（POSIXでは無効）
- `echo` - 文字列出力
- `exit` - シェル終了
- `export` - 環境変数設定
- `false` - 常に失敗
- `ls` - ディレクトリ一覧
- `mkdir` - ディレクトリ作成
- `mv` - ファイル移動
- `pwd` - 現在ディレクトリ表示
- `rm` - ファイル削除
- `touch` - ファイル作成/更新
- `true` - 常に成功
- `which` - コマンドパス表示
- `yes` - 文字列繰り返し出力
- `seq` - 数列生成
- `dirname` - ディレクトリ名取得
- `basename` - ファイル名取得

---

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

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

### 推奨読解順序

#### Step 1: JavaScript APIを理解する

シェルのJavaScript側インターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | shell.ts | `src/js/builtins/shell.ts` | ShellPromise、ShellOutput、ShellErrorクラス定義 |

**読解のコツ**: TypeScriptのクラス構造とPromise拡張を理解する。cwdSymbol、envSymbol等のSymbolによるプライベートプロパティ管理に注目。

**主要処理フロー**:
1. **302-315行目**: BunShell関数 - タグ付きテンプレートの処理
2. **106-250行目**: ShellPromiseクラス - Promise拡張と設定メソッド
3. **74-104行目**: ShellOutputクラス - 結果オブジェクト
4. **16-72行目**: ShellErrorクラス - エラーオブジェクト

#### Step 2: シェルモジュール構造を理解する

Zigのシェルモジュール全体構造を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | shell.zig | `src/shell/shell.zig` | モジュールエクスポート、定数定義 |

**主要処理フロー**:
- **1-18行目**: 各サブモジュールのインポートとエクスポート
- **26-28行目**: 標準入出力のファイルディスクリプタ定義
- **34-119行目**: ShellErr union型 - エラー表現

#### Step 3: インタプリタアーキテクチャを理解する

状態マシンベースのインタプリタ設計を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | interpreter.zig | `src/shell/interpreter.zig` | インタプリタの全体設計（コメント1-59行目） |

**読解のコツ**: 「state-machine based tree-walking, trampoline-driven continuation-passing style interpreter」という設計思想を理解する。非同期IOを状態マシンで管理する仕組みに注目。

#### Step 4: 組み込みコマンドを理解する

組み込みコマンドの実装パターンを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Builtin.zig | `src/shell/Builtin.zig` | 組み込みコマンドの共通構造（1-100行目） |
| 4-2 | echo.zig | `src/shell/builtin/echo.zig` | echoコマンドの実装例 |

**主要処理フロー**:
- **38-58行目**: Impl union型 - 各コマンド実装の格納
- **63-82行目**: Kind enum - コマンド種別定義

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

```
$`command args`  (JavaScript)
    │
    ├─ createParsedShellScript()
    │      └─ ParsedShellScript.zig
    │
    └─ ShellPromise
           │
           └─ ShellInterpreter.run()
                  │
                  ├─ interpret.Interpreter
                  │      ├─ states/Script.zig
                  │      ├─ states/Stmt.zig
                  │      ├─ states/Pipeline.zig
                  │      └─ states/Cmd.zig
                  │
                  ├─ Builtin (組み込みコマンド)
                  │      ├─ builtin/echo.zig
                  │      ├─ builtin/ls.zig
                  │      ├─ builtin/cd.zig
                  │      └─ ... etc
                  │
                  └─ subproc.zig (外部コマンド)
                         └─ ShellSubprocess
```

### データフロー図

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

$`echo ${var}`     ───▶  createParsedShellScript()
                         ├─ テンプレートパース
                         └─ 変数展開

ShellPromise       ───▶  ShellInterpreter.run()
.cwd()                   ├─ 状態マシン実行
.env()                   ├─ IO処理
.quiet()                 └─ コマンド実行
                                │
                                ▼
                         ShellOutput              ───▶   stdout: Buffer
                         ├─ stdout収集                    stderr: Buffer
                         ├─ stderr収集                    exitCode: number
                         └─ exitCode取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| shell.ts | `src/js/builtins/shell.ts` | ソース | JavaScript API定義 |
| shell.zig | `src/shell/shell.zig` | ソース | シェルモジュールエントリ |
| interpreter.zig | `src/shell/interpreter.zig` | ソース | インタプリタ本体 |
| Builtin.zig | `src/shell/Builtin.zig` | ソース | 組み込みコマンド管理 |
| ParsedShellScript.zig | `src/shell/ParsedShellScript.zig` | ソース | パース結果表現 |
| subproc.zig | `src/shell/subproc.zig` | ソース | サブプロセス管理 |
| Yield.zig | `src/shell/Yield.zig` | ソース | 継続渡しスタイル実装 |
| states/ | `src/shell/states/` | ソース | 状態マシン各状態 |
| builtin/ | `src/shell/builtin/` | ソース | 組み込みコマンド実装 |
| braces.zig | `src/shell/braces.zig` | ソース | ブレース展開 |
| EnvMap.zig | `src/shell/EnvMap.zig` | ソース | 環境変数マップ |
| IOReader.zig | `src/shell/IOReader.zig` | ソース | 入力IO管理 |
| IOWriter.zig | `src/shell/IOWriter.zig` | ソース | 出力IO管理 |
