---
name: comment
description: ローカルの変更差分を分析し、実装意図 (Why) を説明するコメントをコードに追加する。Use when 変更にコメントを付けたい、Why コメントを追加したい、実装意図をコメントしたい際に使用する。
allowed-tools:
  - Bash
  - Read
  - Edit
  - Glob
  - Grep
  - AskUserQuestion
  - TaskCreate
  - TaskUpdate
  - TaskList
---

# コードコメント追加ワークフロー

ローカルの変更差分 (staged + unstaged) を分析し、「なぜそうしているのか (Why)」を説明するコメントをコードに直接追加する。

## 重要な原則

1. **Why のみコメントする** - 「何をしているか (What)」はコードが語る。コメントは「なぜそうしているか (Why)」のみ
2. **冗長なコメントは絶対に残さない** - 変数名や関数名から読み取れる情報は書かない
3. **既存コメントの言語に合わせる** - ファイル内の既存コメントが英語なら英語、日本語なら日本語
4. **意図が不明なら必ず確認する** - 推測でコメントを書かず、AskUserQuestion で実装者に確認する
5. **コメント形式は既存コードと言語のベストプラクティスに合わせる** - 既存コードのコメント形式を踏襲し、各言語の慣習に従う

## 作業開始前の準備

変更ファイルが 3 つ以上、または差分が大きい場合は TaskCreate ツールでステップを管理する。小規模な変更の場合はタスク登録なしで直接実行する。

タスク登録する場合は、まず TaskList で残存タスクを確認し、存在する場合は全て TaskUpdate({ status: "deleted" }) で削除する。

タスク登録する場合の例:

```
TaskCreate({ subject: "変更差分の取得", description: "git diff HEAD で全変更を取得し、変更ファイルを特定", activeForm: "差分を取得中" })
TaskCreate({ subject: "差分の分析とコメント箇所の特定", description: "各変更について Why コメントが必要な箇所を特定", activeForm: "差分を分析中" })
TaskCreate({ subject: "コメントの追加", description: "特定した箇所にコメントを追加", activeForm: "コメントを追加中" })
TaskCreate({ subject: "完了報告", description: "追加したコメントのサマリを報告", activeForm: "完了報告を作成中" })
```

各ステップの開始時に TaskUpdate で `in_progress` に、完了時に `completed` に更新する。

## 実行手順

### 1. 変更差分の取得

staged と unstaged の両方の変更を取得する:

```bash
# 変更ファイル一覧
git diff HEAD --name-only

# 全変更 (staged + unstaged)
git diff HEAD
```

変更がない場合は「変更がありません」と報告して終了する。

### 2. 差分の分析とコメント箇所の特定

各変更ファイルについて以下を行う:

1. **ファイル全体を Read ツールで読み込む** - 差分だけでなく前後のコンテキストが必要
2. **既存コメントのスタイルと言語を確認する** - 言語 (日本語/英語) とコメント形式を特定
3. **変更箇所ごとに Why コメントの必要性を判断する**

#### コメントが必要なケース

- **非自明なアルゴリズムやロジック** - なぜその手法を選んだか
- **ワークアラウンドやハック** - なぜ直接的な解決ではなくこの方法か
- **ビジネスルールに基づくロジック** - なぜこの条件なのか
- **パフォーマンス上の意図的な選択** - なぜこの実装パターンか
- **外部要因による制約** - ライブラリの制限、API の仕様等
- **将来の読者が「なぜ?」と思う箇所** - 一見不自然に見えるコード

#### コメントが不要なケース (絶対に追加しない)

- 変数宣言や代入の単純な説明 (`// ユーザー名を取得` 等)
- 関数名から明らかな処理内容 (`// リストをソートする` 等)
- 言語やフレームワークの標準的なパターン
- import 文や型定義
- 単純な条件分岐の説明
- テストコード (テスト名が説明になっている)

### 3. 意図が不明な場合の確認

変更の意図が差分やコンテキストから判断できない場合、推測でコメントを書かず AskUserQuestion で確認する。

確認の例:

- 質問: 「`src/api/handler.ts:42` でリトライ回数を 3 から 5 に変更していますが、この変更の意図を教えてください。」
- 選択肢を提示: タイムアウト対策 / 要件変更 / その他

変更箇所ごとに個別に質問するのではなく、意図が不明な箇所をまとめて 1 回で確認する。確認結果を基にコメントを作成する。

### 4. コメントの追加

Edit ツールで対象ファイルにコメントを直接追加する。

**コメントの配置:**

- 該当コードの直前の行に配置する
- インデントは対象コードに合わせる
- 既存のコメントブロックがある場合はそこに追記する

**コメント形式の決定:**

1. **既存コードのコメント形式を最優先で踏襲する** - ファイル内で使われている形式に合わせる
2. **既存コメントがない場合は、各言語のベストプラクティスに従う:**

| 言語                  | 単行コメント | 複数行・補足  | 関数/クラスの説明                          |
| --------------------- | ------------ | ------------- | ------------------------------------------ |
| TypeScript/JavaScript | `//`         | `//` を複数行 | JSDoc (`/** */`) は既存に合わせる場合のみ  |
| Python                | `#`          | `#` を複数行  | docstring は既存に合わせる場合のみ         |
| Go                    | `//`         | `//` を複数行 | godoc 形式は既存に合わせる場合のみ         |
| Rust                  | `//`         | `//` を複数行 | `///` doc comment は既存に合わせる場合のみ |
| Ruby                  | `#`          | `#` を複数行  | YARD は既存に合わせる場合のみ              |
| Shell                 | `#`          | `#` を複数行  | -                                          |
| CSS                   | `/* */`      | `/* */`       | -                                          |
| SCSS                  | `//`         | `/* */`       | -                                          |
| HTML                  | `<!-- -->`   | `<!-- -->`    | -                                          |
| SQL                   | `--`         | `--` を複数行 | -                                          |
| Swift                 | `//`         | `//` を複数行 | `///` doc comment は既存に合わせる場合のみ |
| Dart                  | `//`         | `//` を複数行 | `///` doc comment は既存に合わせる場合のみ |
| Kotlin/Java           | `//`         | `//` を複数行 | KDoc/Javadoc は既存に合わせる場合のみ      |

3. **doc comment (JSDoc, docstring, godoc 等) は新規追加しない** - Why コメントは inline コメントで記述する。doc comment は既存パターンに追記する場合のみ使用する

**コメント例 (良い例):**

```typescript
// 外部 API が RFC 3339 形式を要求するため、Date ではなく文字列で保持
const createdAt: string = response.created_at;
```

```python
# バッチサイズを 100 に制限 - DB コネクションプールの上限が 100 のため
BATCH_SIZE = 100
```

```go
// nil チェックを先に行う - gRPC のレスポンスで nil が返るケースが本番で確認されたため
if resp == nil {
    return ErrNilResponse
}
```

```rust
// デフォルトの Ord 実装では NaN の比較で panic するため、partial_cmp を使用
items.sort_by(|a, b| a.score.partial_cmp(&b.score).unwrap_or(Ordering::Equal));
```

**コメント例 (悪い例 - 絶対に書かない):**

```typescript
// createdAt を文字列として宣言
const createdAt: string = response.created_at;
```

```python
# バッチサイズを定義
BATCH_SIZE = 100
```

### 5. 完了報告

追加したコメントのサマリを報告する:

```markdown
## コメント追加完了

| ファイル           | 追加数 | 内容                                             |
| ------------------ | ------ | ------------------------------------------------ |
| src/api/handler.ts | 2      | リトライポリシー変更理由、エラーハンドリング意図 |
| src/utils/date.ts  | 1      | 日付フォーマット選択理由                         |

**合計:** 3 件のコメントを追加
```

## エラーハンドリング

### 変更が大きすぎる場合

変更ファイルが多数の場合、主要なロジック変更に絞ってコメントを追加する。設定ファイルやテストファイル、自動生成コードは対象外とする。

### 既にコメントが十分な場合

差分を分析した結果、コメントが不要と判断した場合は:

```markdown
変更内容を分析しましたが、追加のコメントは不要です。

理由:

- 変更がコードから明確に読み取れる
- 既存のコメントで十分にカバーされている
```

### Git リポジトリ外で実行した場合

`git diff` が失敗した場合は「Git リポジトリ内で実行してください」と案内して終了する。

### ファイルの読み込みに失敗した場合

対象ファイルが読み込めない場合はスキップし、完了報告で明記する。
