# 機能設計書 54-クラッシュレポート

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータのクラッシュレポート機能(`+crash-report`コマンド)の設計仕様を記載する。

### 本機能の処理概要

クラッシュレポート機能は、Ghosttyのクラッシュレポートを一覧表示および管理するCLIコマンドである。アプリケーションがクラッシュした際に生成されるレポートを確認し、デバッグやバグ報告に役立てることができる。

**業務上の目的・背景**：アプリケーションのクラッシュは予期せず発生する可能性があり、その原因を特定するためにはクラッシュ時の情報が重要である。本機能により、ユーザーは過去のクラッシュレポートを確認でき、開発者への報告や問題の診断に活用できる。将来的にはクラッシュレポートの送信機能も追加予定。

**機能の利用シーン**：
- クラッシュ発生後に原因を調査したい場合
- 開発者にバグ報告を行う際のクラッシュ情報収集
- 過去のクラッシュ履歴を確認したい場合
- システムの安定性を監視したい場合

**主要な処理内容**：
1. コマンドライン引数の解析
2. クラッシュレポートディレクトリの取得
3. レポートファイルの一覧取得と時間順ソート
4. レポート一覧の出力（ファイル名と経過時間）

**関連システム・外部連携**：ファイルシステム（XDG_STATE_HOME配下のクラッシュディレクトリ）

**権限による制御**：特になし。全ユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI | 主機能 | コマンドライン実行によるクラッシュレポート一覧表示 |

## 機能種別

CLI操作 / 情報表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | 現在は引数なしで動作 | - |

### 入力データソース

- クラッシュレポートディレクトリ（`${XDG_STATE_HOME}/ghostty/crash/`）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| レポート名 | テキスト | クラッシュレポートのファイル名 |
| 経過時間 | テキスト | クラッシュからの経過時間（例: "5 minutes ago"） |

### 出力先

- 標準出力（stdout）: レポート一覧
- 終了コード: 0

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ Options構造体を初期化（現在は空）
2. アリーナアロケータの初期化
   └─ コマンド全体のメモリ管理
3. クラッシュディレクトリの取得
   └─ crash.defaultDir()でデフォルトパスを取得
4. レポートイテレータの取得
   └─ ディレクトリ内のファイルをイテレート
5. レポートの収集
   └─ 各レポートの名前と更新時間を収集
6. 時間順でソート
   └─ 新しいものが先頭になるようソート
7. 結果の出力
   └─ レポートがない場合は「No crash reports! 👻」
   └─ ある場合はファイル名と経過時間を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C[アリーナアロケータ初期化]
    C --> D[crash.defaultDir取得]
    D --> E[ディレクトリイテレータ取得]
    E --> F{レポートあり?}
    F -->|No| G{TTY接続?}
    G -->|Yes| H["No crash reports! 👻" 出力]
    G -->|No| I[何も出力せず終了]
    H --> J[終了コード0]
    I --> J
    F -->|Yes| K[レポートリスト収集]
    K --> L[時間順ソート]
    L --> M[各レポートを出力]
    M --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-1 | デフォルトディレクトリ | XDG_STATE_HOME/ghostty/crash/がデフォルトのクラッシュレポートディレクトリ | 常時 |
| BR-54-2 | ソート順序 | 新しいレポートが先頭になるよう更新時間の降順でソート | 常時 |
| BR-54-3 | TTY判定出力 | TTYに接続されていない場合、レポートなし時は何も出力しない | レポートなし時 |

### 計算ロジック

経過時間の計算:
- 現在時刻 - レポートの更新時刻（mtime）
- Duration型を使用して人間が読みやすい形式に変換（例: "5 minutes ago"）

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

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

データベース操作なし（ファイルシステムの読み取りのみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ不存在 | クラッシュディレクトリが存在しない | 空のイテレータを返す（エラーにはならない） |

### リトライ仕様

リトライなし

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

該当なし

## パフォーマンス要件

即座にレスポンスが返ること（通常1秒未満）

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

クラッシュレポートには機密情報が含まれる可能性があるため、適切なファイルパーミッションを維持すること

## 備考

- 現在は一覧表示のみ実装。閲覧・送信機能は将来実装予定
- クラッシュレポートはSentry形式のエンベロープファイル

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dir.zig | `src/crash/dir.zig` | Report構造体（63-66行目）でレポートデータを定義 |
| 1-2 | dir.zig | `src/crash/dir.zig` | Dir構造体（14-34行目）でディレクトリ操作を定義 |

**読解のコツ**: Report構造体はnameとmtimeのみを持つシンプルな構造で、ファイル名と更新時刻を表す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | crash_report.zig | `src/cli/crash_report.zig` | run関数（26-49行目）がエントリーポイント |

**主要処理フロー**:
1. **28-30行目**: アリーナアロケータの初期化
2. **32-39行目**: Options解析
3. **41-44行目**: stdout writerの準備
4. **46行目**: runInner関数の呼び出し

#### Step 3: 一覧取得ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | crash_report.zig | `src/cli/crash_report.zig` | runInner関数（51-89行目）でメイン処理 |

**主要処理フロー**:
- **56行目**: crash.defaultDir()でクラッシュディレクトリ取得
- **60-64行目**: ディレクトリイテレートしてレポート収集
- **68-73行目**: レポートがない場合の処理（TTY判定あり）
- **75行目**: 時間順（降順）でソート
- **77-86行目**: 各レポートの出力

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

```
ghostty +crash-report
    │
    └─ crash_report.run()
           │
           ├─ args.parse() ─ オプション解析
           │
           └─ runInner()
                  │
                  ├─ crash.defaultDir() ─ クラッシュディレクトリ取得
                  │      └─ xdg.state() ─ XDGパス解決
                  │
                  ├─ crash_dir.iterator() ─ ファイルイテレータ取得
                  │
                  ├─ std.mem.sort() ─ 時間順ソート
                  │
                  └─ stdout.print() ─ 結果出力
```

### データフロー図

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

XDG_STATE_HOME ───▶ crash.defaultDir() ──▶ クラッシュディレクトリパス
                         │
                         ▼
クラッシュファイル ───▶ iterator()
                         │
                         ▼
                  Report配列収集
                         │
                         ▼
                  時間順ソート
                         │
                         ▼
                  stdout.print() ─────▶ 「filename (X ago)」形式
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| crash_report.zig | `src/cli/crash_report.zig` | ソース | メインエントリーポイント |
| main.zig | `src/crash/main.zig` | ソース | クラッシュモジュールエントリー |
| dir.zig | `src/crash/dir.zig` | ソース | ディレクトリ操作とReport構造体 |
| sentry.zig | `src/crash/sentry.zig` | ソース | Sentryクライアント（レポート生成） |
| args.zig | `src/cli/args.zig` | ソース | コマンドライン引数解析 |
