# 通知設計書 10-ビルド完了メッセージ

## 概要

本ドキュメントは、Tailwind CSS CLIのbuildコマンド（`@tailwindcss/cli`）のCSS生成が完了した際に、処理時間を含む完了メッセージを出力する通知仕様を定義する。

### 本通知の処理概要

buildコマンドでCSSの生成・書き込みが完了した際に、経過時間を計測して「Done in {duration}」という完了メッセージを標準エラー出力に出力する通知処理である。初回ビルドとウォッチモードでの再ビルドの両方で出力される。

**業務上の目的・背景**：buildコマンドはCSSファイルの生成処理を行うが、プロジェクトの規模やオプション設定により処理時間が大きく異なる。完了メッセージに処理時間を含めることで、ユーザーはビルドのパフォーマンスを把握でき、最適化の必要性を判断できる。また、ウォッチモードでは各リビルドの完了を明示することで、変更が反映されたことを確認できる。

**通知の送信タイミング**：以下のタイミングで送信される。
1. 初回ビルド完了時（行413）：CSS生成と書き込みが全て完了した直後
2. ウォッチモード - インクリメンタルビルドで新候補なし（行351）：変更検出後、新しいCSS候補が見つからなかった場合の早期終了時
3. ウォッチモード - リビルド完了時（行369）：フル/インクリメンタルリビルドのCSS書き込み完了後

**通知の受信者**：CLIを実行した開発者。標準エラー出力（stderr）に出力される。

**通知内容の概要**：「Done in {duration}」というメッセージが出力される。{duration}は処理時間をナノ秒精度で計測し、人間が読みやすい形式（ミリ秒、秒など）に変換される。処理時間に応じて色が変化する（緑: 50ms以下、青: 300ms以下、黄: 1s以下、赤: 1s超）。

**期待されるアクション**：通常はアクション不要。処理時間が異常に長い場合は、入力CSSの最適化やプロジェクト構成の見直しを検討する。ウォッチモードでは、変更が正常にビルドされたことの確認として参照する。

## 通知種別

CLI標準エラー出力（stderr）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（プロセス内直接出力） |
| 優先度 | 低（情報通知、プロセスは継続） |
| リトライ | 無し（即時出力） |

### 送信先決定ロジック

CLIを実行したプロセスの標準エラー出力（`process.stderr`）に対して `eprintln()` 関数経由で出力する。

## 通知テンプレート

### メール通知の場合

該当なし（CLI出力のみ）

### 本文テンプレート

```
Done in {formattedDuration}
```

※ `eprintln()` による直接出力。`formatDuration()` 関数で処理時間に応じた色付け（picocolors）が適用される。

**色の凡例**:
- 緑色: 50ms以下（高速）
- 青色: 300ms以下（標準）
- 黄色: 1000ms以下（やや遅い）
- 赤色: 1000ms超（遅い）

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| formattedDuration | フォーマット済み処理時間 | `formatDuration(end - start)` （`process.hrtime.bigint()` の差分） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | 初回ビルド完了 | CSS生成と書き込みが成功 | 通常ビルド完了時 |
| 内部処理 | ウォッチ: 新候補なし | インクリメンタルスキャンで新候補が0件 | 変更は検出されたがCSS変更なし |
| 内部処理 | ウォッチ: リビルド完了 | フルまたはインクリメンタルリビルド成功 | ウォッチモードでのリビルド完了時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ビルドエラー発生時 | `handleError()` 関数でエラーがキャッチされた場合、`process.exit(1)` で終了するため完了メッセージは出力されない |
| ウォッチモードでのエラー | ウォッチモードのリビルドでエラーが発生した場合、catch節でエラーが出力され、完了メッセージは出力されない |
| 出力ファイルのみ変更された場合 | ウォッチモードで出力ファイルのみが変更された場合、無限ループ防止のためリビルドがスキップされる |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[buildコマンド実行] --> B[開始時刻記録<br>process.hrtime.bigint]
    B --> C{ウォッチモード?}
    C -->|No| D[CSS生成・書き込み]
    D --> E[終了時刻記録]
    E --> F[eprintln: Done in duration]
    C -->|Yes| G[ウォッチャー設定]
    G --> H[ファイル変更検出]
    H --> I{新候補あり?}
    I -->|なし| J[終了時刻記録]
    J --> K[eprintln: Done in duration]
    I -->|あり| L[CSS リビルド・書き込み]
    L --> M[終了時刻記録]
    M --> N[eprintln: Done in duration]
    K --> H
    N --> H
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースを使用しない）

### 更新テーブル一覧

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ビルドエラー | CSS生成中にエラー | `handleError()` でキャッチされ、`process.exit(1)` で終了。完了メッセージは出力されない |
| ウォッチリビルドエラー | ウォッチモードのリビルドでエラー | catch節で `eprintln(err.toString())` が出力される。完了メッセージは出力されず、ウォッチは継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ウォッチモードでは変更頻度に依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（CLI実行時に即時出力）

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

本通知は処理時間のみを出力するため、個人情報や機密情報の漏洩リスクはない。

## 備考

- 処理時間は `process.hrtime.bigint()` で高精度（ナノ秒）計測される
- `formatDuration()` は内部で `formatNanoseconds()` を呼び出し、適切な単位（ms、s等）に変換する
- ウォッチモードでのリビルドは、パフォーマンスデバッグ用の `DEBUG` モード計測（`Instrumentation` クラス）とは独立して処理時間が記録される
- ウォッチモードでインクリメンタルビルドの新候補が0件の場合も処理時間は出力される（変更検出からスキャン完了までの時間）

---

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

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

### 推奨読解順序

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

処理時間計測とフォーマットの仕組みを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | renderer.ts | `packages/@tailwindcss-cli/src/utils/renderer.ts` | 行72-80の `formatDuration()` 関数が処理時間に応じて色を変える仕組みを理解する |

**読解のコツ**: `formatDuration()` は `bigint` 型のナノ秒値を受け取る。内部で `formatNanoseconds()` を呼び出して人間が読みやすい文字列に変換し、閾値に応じて `pc.green()`, `pc.blue()`, `pc.yellow()`, `pc.red()` で色付けする。

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

完了メッセージの出力箇所を網羅的に確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts（handle関数） | `packages/@tailwindcss-cli/src/commands/build/index.ts` | 行134で `start` が記録され、行413で初回ビルド完了メッセージが出力される流れを理解する |
| 2-2 | index.ts（ウォッチコールバック） | `packages/@tailwindcss-cli/src/commands/build/index.ts` | 行266で `start` が記録され、行351と行369でウォッチモードの完了メッセージが出力される流れを理解する |

**主要処理フロー（初回ビルド）**:
1. **行134**: `let start = process.hrtime.bigint()` で開始時刻を記録
2. **行395-410**: CSS生成、ソースマップ生成、出力書き込みを実行
3. **行412**: `let end = process.hrtime.bigint()` で終了時刻を記録
4. **行413**: `eprintln(`Done in ${formatDuration(end - start)}`)` で完了メッセージを出力

**主要処理フロー（ウォッチモード）**:
1. **行266**: `let start = process.hrtime.bigint()` で開始時刻を記録（リビルドごと）
2. **行349-352**: 新候補がない場合、終了時刻を記録して完了メッセージを出力
3. **行366-369**: リビルド完了後、終了時刻を記録して完了メッセージを出力

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

```
index.ts :: handle(args)
    │
    ├─ [初回ビルド]
    │      ├─ process.hrtime.bigint() ... 開始
    │      ├─ compiler.build(candidates)
    │      ├─ write(output, map, args, I)
    │      ├─ process.hrtime.bigint() ... 終了
    │      └─ eprintln(`Done in ${formatDuration(end - start)}`)
    │
    └─ [ウォッチモード]
           └─ createWatchers(dirs, callback)
                  ├─ process.hrtime.bigint() ... 開始
                  ├─ scanner.scanFiles() or scanner.scan()
                  ├─ compiler.build()
                  ├─ write()
                  ├─ process.hrtime.bigint() ... 終了
                  └─ eprintln(`Done in ${formatDuration(end - start)}`)
```

### データフロー図

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

process.hrtime ──────▶ start（開始時刻）
                           │
CSS入力 ──────────▶ compile() → build() → write()
                           │
process.hrtime ──────▶ end（終了時刻）
                           │
                           ▼
                     end - start
                           │
                           ▼
                     formatDuration() ──▶ formatNanoseconds()
                           │               + 色付け
                           ▼
                     eprintln() ──────────▶ stderr（Done in ...）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/@tailwindcss-cli/src/commands/build/index.ts` | ソース | buildコマンドのエントリーポイント。行351, 369, 413で完了メッセージを出力 |
| renderer.ts | `packages/@tailwindcss-cli/src/utils/renderer.ts` | ソース | `formatDuration()`, `eprintln()` 等のCLI出力ユーティリティ |
| format-ns.ts | `packages/@tailwindcss-cli/src/utils/format-ns.ts` | ソース | `formatNanoseconds()` 関数。ナノ秒を人間が読みやすい時間表現に変換 |
