diff --git a/.claude/agents/coder.md b/.claude/agents/coder.md index 5f9bfc6..c85583c 100644 --- a/.claude/agents/coder.md +++ b/.claude/agents/coder.md @@ -8,7 +8,11 @@ - Grep - Edit - Write - - Bash(git *) + - Bash(git diff *) + - Bash(git status *) + - Bash(git log *) + - Bash(git stash *) + - Bash(git branch *) - Bash(npm *) - Bash(npx *) - Bash(pnpm *) diff --git a/.claude/agents/refactorer.md b/.claude/agents/refactorer.md index e8afe0b..000b45d 100644 --- a/.claude/agents/refactorer.md +++ b/.claude/agents/refactorer.md @@ -55,7 +55,7 @@ ## リファクタリングの判断基準 (Criteria) -以下に該当しない場合は「変更不要」と判断してよい(プロジェクト固有の基準が `docs/01_GUIDE/GUIDE_08_実装完了フロー.md` のリファクタリング方針にある場合はそちらを優先する): +以下に該当しない場合は「変更不要」と判断してよい: - 命名規則違反がある - 明らかなコード重複がある(3箇所以上の類似コード) diff --git a/.claude/agents/tester.md b/.claude/agents/tester.md index 3ea45d9..aad79ba 100644 --- a/.claude/agents/tester.md +++ b/.claude/agents/tester.md @@ -55,9 +55,8 @@ ## テスト作成の原則 (Testing Principles) - テスト対象の関数・クラスの**期待される振る舞い**をテストする(実装の詳細ではない) +- プロジェクトのテスト方針ガイド(存在する場合)に従う(テストの種類,カバレッジ基準,モック方針,ファイル配置等) - プロジェクトの既存テストのパターン・構造に合わせる -- テストファイルの配置はプロジェクトの規約に従う -- テスト名は何をテストしているかが明確にわかるようにする ## 出力フォーマット (Output Format) diff --git a/.claude/commands/commit.md b/.claude/commands/commit.md index de7a428..1610d69 100644 --- a/.claude/commands/commit.md +++ b/.claude/commands/commit.md @@ -18,45 +18,35 @@ **main ブランチにいる場合は自動でブランチを作成する:** -1. 変更内容から適切なプレフィックス(`feature/`/`fix/`/`docs/`/`chore/`)と英単語 2〜4 語のブランチ名を決定する +1. 変更内容から GUIDE_04 のブランチ命名規則に従い,適切なプレフィックスと英単語 2〜4 語のブランチ名を決定する 2. `git checkout -b {ブランチ名}` で作業ブランチを作成する 3. 以降のステップを続行する -## ステップ 2: docs/ 更新チェック +## ステップ 2: docs/ 更新漏れチェック -変更内容を確認し,以下に該当する場合は docs/ の更新が必要か確認する: +`.claude/commit-context.md` が存在し `docs_updated` が記録されている場合,このステップをスキップする. + +ファイルが存在しない場合(`/implement` を経由していない場合),変更内容を確認し,以下に該当するにもかかわらず docs/ が更新されていない場合は警告する: - API やデータ構造の変更 - 環境設定の変更 - 開発計画の進捗に関わる変更 - 規約やルールに関わる変更 -該当がある場合,ユーザーに docs/ の更新要否を確認する. +該当がある場合,「⚠ docs/ の更新が必要かもしれません.確認してください.」と警告する. +更新自体は行わず,ユーザーの判断に委ねる. ## ステップ 3: コミットメッセージの生成 -変更内容と $ARGUMENTS(指定がある場合)をもとに,GUIDE_04 に従ったコミットメッセージを生成する. +変更内容と $ARGUMENTS(指定がある場合)をもとに,GUIDE_04 の「コミットメッセージ」セクションに従ってコミットメッセージを生成する. -### タグの選定基準 +## ステップ 4: CLAUDE.md 更新漏れチェック -| タグ | 用途 | -| --- | --- | -| `[add]` | ファイルや機能の追加 | -| `[update]` | 機能やデータの更新・修正 | -| `[fix]` | バグ修正 | -| `[remove]` | 削除 | -| `[clean]` | 整理,リファクタリング | +`.claude/commit-context.md` が存在し `claude_md_updated` が記録されている場合,このステップをスキップする. -### メッセージの書式 - -- 書式: `[タグ] 内容` -- 言語: 日本語 -- 末尾に句点は不要 - -## ステップ 4: CLAUDE.md 更新 - -変更内容に応じて CLAUDE.md の「開発進捗」セクションの更新が必要か判断し, -必要であれば自動で更新する. +ファイルが存在しない場合(`/implement` を経由していない場合),変更内容に応じて CLAUDE.md の「開発進捗」セクションの更新が必要か判断し, +更新されていない場合は「⚠ CLAUDE.md の開発進捗の更新が必要かもしれません.確認してください.」と警告する. +更新自体は行わず,ユーザーの判断に委ねる. ## ステップ 5: コミット @@ -64,29 +54,29 @@ 1. `git add` で関連ファイルをステージングする(CLAUDE.md の変更がある場合はそれも含める) 2. `git commit -m "{コミットメッセージ}"` でコミットする +3. `.claude/commit-context.md` が存在する場合は削除する -## ステップ 6: プッシュ・PR・マージ($ARGUMENTS に指示がある場合のみ) +## ステップ 6: プッシュ・PR・マージ -$ARGUMENTS の指示に応じて,該当する操作のみ実行する. -指示がなければこのステップはすべてスキップする. +$ARGUMENTS に以下のキーワードが含まれる場合のみ,該当する操作を実行する. +**いずれも含まれない場合はこのステップ全体をスキップする.** + +| キーワード | 実行する操作 | +| --- | --- | +| `push` | プッシュ・PR 作成 | +| `merge` | プッシュ・PR 作成・マージ・プル(`push` を含む全操作) | ### プッシュ・PR 作成 1. `git push origin {ブランチ名}` でリモートにプッシュする 2. PR の状態を確認する: - **既存の PR がある場合**: PR の URL を表示して完了 - - **PR がない場合**: 以下で PR を作成する + - **PR がない場合**: GUIDE_04 の「プルリクエスト (PR) の作成」に従い PR を作成し,URL を表示する -```bash -gh pr create --title "{コミットメッセージ}" --body "概要" -``` +### マージ・プル(`merge` の場合のみ) -PR の URL を表示する. - -### マージ・プル - -1. `gh pr merge --merge --delete-branch` で PR をマージする -2. `git checkout main && git pull origin main` でローカルを最新化する +1. GUIDE_04 の「マージの実行」に従いマージする +2. GUIDE_04 の「ローカル環境のクリーンアップ」に従いローカルを最新化する ## 注意事項 diff --git a/.claude/commands/implement.md b/.claude/commands/implement.md index 59788f5..07f1c21 100644 --- a/.claude/commands/implement.md +++ b/.claude/commands/implement.md @@ -1,17 +1,18 @@ --- name: implement -description: "実装パイプラインを開始する.コーディング → テスト → リファクタリングの順で 3 つのエージェントを実行し,各フェーズ間で人間の確認を挟む." +model: opus +description: "実装パイプラインを開始する.コーディング → テスト → リファクタリングの順で 3 つのエージェントを実行し,必要に応じて人間の確認を挟む." argument-hint: "<タスク内容>" --- -あなたはオーケストレーターです.以下の実装パイプラインを管理してください. -各フェーズ間で必ず人間の確認を挟み,承認を得てから次のフェーズに進むこと. +あなたはオーケストレーターです. +GUIDE_05(エージェント運用ルール)を読み,パイプラインのルールを理解した上で以下の手順を実行してください. ## 前提確認 (Pre-check) 1. 現在のブランチを確認する(`git branch --show-current`) 2. `main` ブランチにいる場合,GUIDE_04 に従い作業ブランチを作成する - - ブランチ名: `feature/`/`fix/` + タスク内容を表す英単語 2〜4 語(kebab-case) + - GUIDE_04 のブランチ命名規則に従い,適切なプレフィックスとタスク内容を表す英単語 2〜4 語(kebab-case)でブランチ名を決定する 3. 実装対象のタスクを確認する: $ARGUMENTS ## Phase 1: コーディング (Coder) @@ -20,11 +21,7 @@ 「以下のタスクを実装してください: $ARGUMENTS」 -Coder の出力(実装サマリー)を記録する. - -### 人間の確認ポイント 1 - -Coder の実装サマリーをユーザーに提示し,以下を依頼する: +Coder の出力(実装サマリー)を記録し,ユーザーに提示する: 「**Phase 1(コーディング)が完了しました.** @@ -46,16 +43,10 @@ 実装サマリー: {Coder の出力}」 -Tester の出力(テストサマリー)を記録する. +Tester の出力(テストサマリー)を記録し,テスト結果に応じて分岐する: -### Phase 2 完了後の分岐 - -テスト結果に応じて自動で分岐する: - -- **全テスト成功**: ユーザーにテストサマリーを表示した上で,自動的に Phase 3 に進む. -- **テスト失敗あり**: ユーザーに報告し,判断を仰ぐ. - -テスト失敗時のみ,以下をユーザーに提示する: +- **全テスト成功**: テストサマリーを表示し,自動的に Phase 3 に進む. +- **テスト失敗あり**: ユーザーに以下を提示し,判断を仰ぐ. 「**Phase 2(テスト)でテスト失敗がありました.** @@ -80,33 +71,33 @@ テストサマリー: {Tester の出力}」 -Refactorer の出力(リファクタリングサマリー)を記録する. +Refactorer の出力(リファクタリングサマリー)を記録し,確認を挟まず Phase 4 に進む. -### 人間の確認ポイント 3 +## Phase 4: ドキュメント更新 (Documentation) -Refactorer のリファクタリングサマリーをユーザーに提示し,以下を依頼する: +GUIDE_05 の「Phase 4: ドキュメント更新」に記載されたチェック観点に従い,docs/ と CLAUDE.md を必要に応じて更新する. -「**Phase 3(リファクタリング)が完了しました.** +Phase 4 の結果を `.claude/commit-context.md` に書き出す: -{Refactorer のリファクタリングサマリー} +```markdown +# commit-context +- docs_updated: true/false +- claude_md_updated: true/false +- note: (更新不要の理由や更新内容の要約) +``` -全フェーズが完了しました.最終確認をお願いします. -- **OK** → コミット・push・PR 作成に進みます +ドキュメントを更新した場合のみ,ユーザーに提示する: + +「**Phase 4(ドキュメント更新)が完了しました.** + +{更新したドキュメントの一覧と変更内容の要約} + +確認をお願いします. +- **OK** → `/commit` でコミットできます - **NG** → 修正点を教えてください」 +更新不要と判断した場合は,確認を挟まず完了処理に進む. + ## 完了処理 (Finalization) -ユーザーの最終 OK を得た後: - -1. 全変更をステージングする(`git add` で関連ファイルを追加) -2. GUIDE_04 に従いコミットする(`[add]`/`[update]`/`[fix]` + 日本語メッセージ) -3. リモートにプッシュする(`git push origin {ブランチ名}`) -4. PR 作成を実行する(`gh pr create`) -5. CLAUDE.md の開発進捗の更新を提案する - -## 注意事項 (Notes) - -- 各フェーズは必ず順番に実行する(並列実行しない) -- フェーズをスキップしない.リファクタリング不要の判断は Refactorer エージェント自身が行う -- エージェントがエラーを報告した場合,ユーザーに報告して判断を仰ぐ -- 人間の確認なしに次のフェーズに進まない +「全フェーズが完了しました.`/commit` でコミットしてください.」 diff --git a/.claude/commands/setup.md b/.claude/commands/setup.md index beb2433..9e42dde 100644 --- a/.claude/commands/setup.md +++ b/.claude/commands/setup.md @@ -1,11 +1,12 @@ --- name: setup +model: opus description: "GUIDE_01 に従い,プロジェクトの立ち上げを対話的に進める.各フェーズでユーザーの確認を挟む." argument-hint: "<プロジェクト名>" --- あなたはプロジェクト立ち上げのファシリテーターです. -GUIDE_01(プロジェクト立ち上げフロー)に従い,以下のフェーズを **1つずつ対話的に** 進めてください. +GUIDE_01(プロジェクト立ち上げフロー)を読み,各フェーズのルールを理解した上で以下の手順を実行してください. ## 基本ルール @@ -16,134 +17,41 @@ ## 前提確認 (Pre-check) -1. CLAUDE.md の「開発進捗」を確認し,どのフェーズから再開するか判断する -2. 初回の場合はフェーズ 1 から開始する -3. プロジェクト名を確認する: $ARGUMENTS +1. CLAUDE.md がテンプレート初期状態(タイトルが `# プロジェクト名` のまま)か確認する +2. **初期状態の場合(新規プロジェクト立ち上げ):** + - プロジェクト名を確定する(引数 `$ARGUMENTS` があればそれを使用,なければユーザーに確認) + - プロジェクト概要(1〜2 行)をユーザーに確認する + - CLAUDE.md の以下を書き換える: + - 1 行目の `# プロジェクト名` → `# {確定したプロジェクト名}` + - 3 行目の `` → 概要テキスト +3. CLAUDE.md の「開発進捗」を確認し,どのフェーズから再開するか判断する +4. 初回の場合はフェーズ 1 から開始する -## フェーズ 1: 方針決定 +## フェーズ 1〜6: 各フェーズの実行 -**目的**: プロジェクトの全体像を明確にする +GUIDE_01 に定義された各フェーズを順番に実行する. +各フェーズで以下の手順を繰り返す: -ユーザーに以下を質問し,要件を整理する: +1. GUIDE_01 の該当フェーズを参照し,目的・成果物・役割分担を確認する +2. ユーザーとの対話で情報を収集する +3. 成果物のドラフトを作成し,ユーザーに提示する +4. 承認を得てから GUIDE_01 に記載された保存先に書き出す -- プロジェクトの目的は何か -- 対象ユーザーは誰か -- スコープ(やること・やらないこと) +### 台詞テンプレート -回答をもとに `PLAN_01_要件定義書.md` のドラフトを作成し,ユーザーに提示する. - -「**フェーズ 1(方針決定)のドラフトです.** +「**フェーズ {N}({フェーズ名})のドラフトです.** {ドラフト内容} -修正点があれば指示してください.OKであれば docs/03_PLAN/ に保存して次のフェーズに進みます.」 +修正点があれば指示してください.OKであれば {保存先} に保存して次のフェーズに進みます.」 -## フェーズ 2: 技術選定 +### フェーズ 3(環境構築)の注意 -**目的**: 要件に基づいて技術スタックを決定する - -PLAN_01 の要件をもとに: - -1. 要件に適した技術の候補を提案する(言語・フレームワーク・インフラ) -2. 各候補のメリット・デメリットを比較する -3. ユーザーの判断を仰ぐ - -決定後,`ENV_01_技術スタック.md` のドラフトを作成し,ユーザーに提示する. - -「**フェーズ 2(技術選定)のドラフトです.** - -{ドラフト内容} - -修正点があれば指示してください.OKであれば docs/02_ENV/ に保存して次のフェーズに進みます.」 - -## フェーズ 3: 環境構築 - -**目的**: 開発環境を構築し,手順をドキュメント化する - -ENV_01 の技術スタックに基づき: - -1. 環境構築手順書のドラフトを作成する -2. 必要な設定ファイル(`.gitignore`,Dockerfile 等)を提案する -3. 管理者用の初期設定手順を整理する - -成果物: -- `ENV_02_環境構築手順.md` -- `ENV_03_管理者用環境構築手順.md` - -**注意**: 外部サービスの設定(アカウント作成,コンソール操作等)はユーザー自身が行う.手順書に記載するが,AI が実行しないこと. - -「**フェーズ 3(環境構築)のドラフトです.** - -{ドラフト内容} - -修正点があれば指示してください. -⚠ 外部サービスの設定が必要な場合は,ご自身で実施をお願いします. -OKであれば docs/02_ENV/ に保存して次のフェーズに進みます.」 - -## フェーズ 4: 仕様設計 - -**目的**: アーキテクチャ・データモデル・画面設計を決める - -要件と技術スタックに基づき: - -1. アーキテクチャ設計をドラフトする -2. データモデルを定義する -3. 画面遷移・UI フローを整理する - -成果物: `SPEC_01_*.md`(規模に応じて複数ファイルに分割) - -「**フェーズ 4(仕様設計)のドラフトです.** - -{ドラフト内容} - -修正点があれば指示してください.OKであれば docs/04_SPEC/ に保存して次のフェーズに進みます.」 - -## フェーズ 5: 規約整備 - -**目的**: 技術スタックに応じたプロジェクト固有の規約を作成する - -汎用ガイド(GUIDE_01〜05)は本テンプレートに含まれている.ここでは以下のプロジェクト固有ガイドを作成する: - -- コーディング規約(命名規則,フォーマット,import 順序等) -- ディレクトリ構造規則 -- テスト方針 -- エラーハンドリング方針 -- リファクタリング方針 -- 機能実装完了フロー - -**基本方針**: 言語・フレームワークの公式ガイドラインに則り,プロジェクト固有のルールは標準と異なる部分のみ定義する. - -各ガイドのドラフトを 1 つずつ提示し,ユーザーの承認を得てから保存する. - -「**フェーズ 5(規約整備)のドラフトです.** - -{ガイド名}: {ドラフト内容} - -修正点があれば指示してください.OKであれば docs/01_GUIDE/ に保存します.」 - -## フェーズ 6: 開発計画 - -**目的**: 実装の順序とステップを決定する - -仕様をもとに: - -1. ステップ分割を提案する -2. 依存関係を整理する -3. ユーザーに優先度とリリース計画を確認する - -成果物: `PLAN_02_開発ステップ.md` - -「**フェーズ 6(開発計画)のドラフトです.** - -{ドラフト内容} - -修正点があれば指示してください.OKであれば docs/03_PLAN/ に保存して次のフェーズに進みます.」 +外部サービスの設定(アカウント作成,コンソール操作等)はユーザー自身が行う.手順書に記載するが,AI が実行しないこと. ## フェーズ 7: 実装開始 -**目的**: 開発の準備が整ったことを確認する - -1. CLAUDE.md を最終更新する(プロジェクト概要,技術スタック要約,必須ルール,ドキュメント一覧) +1. GUIDE_01 の「CLAUDE.md の管理」セクションに従い,CLAUDE.md を最終更新する 2. 作成した全ドキュメントの一覧を表示する 3. 最初の実装ステップを確認する diff --git a/.claude/commands/sync-template.md b/.claude/commands/sync-template.md index 59733a8..0372706 100644 --- a/.claude/commands/sync-template.md +++ b/.claude/commands/sync-template.md @@ -12,6 +12,18 @@ テンプレート URL: `https://github.com/rintoHasegawa/programming-template.git` +## マージ必須ファイル (Merge-required Files) + +以下のファイルは「プロジェクト固有の内容 + テンプレートの共通ルール」のハイブリッドのため,**上書きせずマージする**.コピー処理(ステップ 5.3)に入る前に対象ファイルかを判定し,該当する場合はステップ 5.4 のマージ手順に分岐させる. + +| ファイル | 理由 | マージ方針 | +| --- | --- | --- | +| `.gitignore` | フレームワーク固有ルール(Flutter/Node 等)を保持する必要がある | テンプレート側の実効行で既存に含まれないもののみを追記.既存行は触らない | +| `CLAUDE.md` | プロジェクト名・開発進捗・固有規約を保持する必要がある | テンプレートで変更された共通セクション(必須ルール,エージェントチーム,ドキュメント構成等)のみを Edit で更新.プロジェクト固有セクションは触らない | +| `.gitattributes` | プロジェクトによって設定が異なる可能性がある | 差分を表示し,ユーザーに「上書き / マージ / スキップ」を問う | + +マージ処理の対象は **既存ファイルが存在する場合のみ**.初回同期(`.claude/template-sync-sha` がない状態)では全ファイルが A 扱いとなるが,これらのファイルはフレームワーク初期化(`flutter create` / `npm init` 等)や `/init` で既にプロジェクトに存在するのが通常なので,そのままマージ処理に入る.既存ファイルがない稀なケースに限り通常の `cp` で配置する. + ## ステップ 1: 事前確認 `git status` でワーキングツリーがクリーンか確認する. @@ -64,7 +76,7 @@ ## ステップ 4: 変更一覧をユーザーに提示 -取り込み対象のファイル一覧を種別ごとに整理してユーザーに提示する: +取り込み対象のファイル一覧を種別ごとに整理してユーザーに提示する.マージ必須ファイル(`.gitignore`, `CLAUDE.md`, `.gitattributes`)に変更がある場合は,**ユーザーが取り込み前に影響範囲を把握できるよう差分サマリーを先出しする**: 「**テンプレートに以下の変更があります:** @@ -73,54 +85,154 @@ - 削除 (D): {ファイル一覧} - リネーム (R): {旧名 → 新名} +**⚠ マージ必須ファイル(上書きせず差分マージします):** + +- `.gitignore`(既存 {N} 行 / テンプレート {M} 行.既存の固有ルールを保持し,テンプレート側で追加されている {K} 行を追記) +- `CLAUDE.md`(既存にプロジェクト固有セクションが {L} 行.テンプレート更新セクションのみマージ) +- `.gitattributes`(差分 {D} 行.処理方針をユーザーに確認) + 取り込みを開始します.」 +差分サマリーは以下で取得する(該当ファイルがマージ対象かつ既存ファイルがある場合のみ出力): + +```bash +# 既存ファイル行数 +wc -l .gitignore CLAUDE.md .gitattributes 2>/dev/null + +# テンプレート側の実効行数(.gitignore) +grep -vE '^\s*(#|$)' "$TEMP_DIR/.gitignore" | wc -l + +# 既存ファイルとテンプレート最新版の差分プレビュー +diff -u .gitignore "$TEMP_DIR/.gitignore" | head -30 +diff -u CLAUDE.md "$TEMP_DIR/CLAUDE.md" | head -50 +diff -u .gitattributes "$TEMP_DIR/.gitattributes" | head -30 +``` + ## ステップ 5: ブランチ作成とファイル反映 -1. `git checkout -b chore/sync-template` でブランチを作成する - - 既に同名のブランチが存在する場合は削除してから作り直す +### 5.1 ブランチ作成 -2. 追加・変更・リネーム先を反映する: +`git checkout -b chore/sync-template` でブランチを作成する.既に同名のブランチが存在する場合は削除してから作り直す. +### 5.2 マージ必須ファイル判定ヘルパー + +以降の処理で利用する判定関数を定義する: + +```bash +MERGE_FILES=(".gitignore" "CLAUDE.md" ".gitattributes") + +is_merge_file() { + local t="$1" + for f in "${MERGE_FILES[@]}"; do + [ "$f" = "$t" ] && return 0 + done + return 1 +} +``` + +### 5.3 通常コピー対象の反映(マージ必須ファイル以外) + +マージ必須ファイルは後段(5.4)で個別処理するため,このループではスキップする.既存ファイルがない場合は通常どおり `cp` で配置する: + +```bash +echo "$CHANGED_ENTRIES" | while IFS=$'\t' read -r status file newfile; do + [ -z "$status" ] && continue + case "$status" in + A|M) + # マージ必須ファイルで既存ファイルがある場合は 5.4 で処理 + if is_merge_file "$file" && [ -f "$file" ]; then + continue + fi + mkdir -p "$(dirname "$file")" + cp "$TEMP_DIR/$file" "$file" + ;; + R*) + # file=旧パス, newfile=新パス + if is_merge_file "$newfile" && [ -f "$newfile" ]; then + continue + fi + mkdir -p "$(dirname "$newfile")" + cp "$TEMP_DIR/$newfile" "$newfile" + ;; + esac +done +``` + +### 5.4 マージ必須ファイルの個別処理 + +`$CHANGED_ENTRIES` に A/M/R* で含まれ,かつ既存ファイルが存在するマージ必須ファイルについて,以下の手順で処理する. + +**`.gitignore` のマージ手順** + +1. 既存 `.gitignore` とテンプレート `$TEMP_DIR/.gitignore` を読む +2. テンプレート側の**実効行**(コメント `#` 行・空行を除く)を抽出する: ```bash - echo "$CHANGED_ENTRIES" | while IFS=$'\t' read -r status file newfile; do - [ -z "$status" ] && continue - case "$status" in - A|M) - mkdir -p "$(dirname "$file")" - cp "$TEMP_DIR/$file" "$file" - ;; - R*) - # file=旧パス, newfile=新パス - mkdir -p "$(dirname "$newfile")" - cp "$TEMP_DIR/$newfile" "$newfile" - ;; - esac - done + grep -vE '^\s*(#|$)' "$TEMP_DIR/.gitignore" ``` +3. 抽出した各行について,既存ファイルに完全一致で含まれていないものだけを収集する +4. 収集した行がある場合,既存ファイル末尾に以下のマーカー付きブロックで追記する: + ``` + + # --- from template (sync-template) --- + {追加行} + ``` + - 既存ファイル末尾に同じマーカーが既にある場合は,マーカー以降に追記して重複マーカーを作らない +5. `git diff .gitignore` で結果を表示しユーザーに確認する -3. 削除候補(D およびリネーム元)を抽出する: +**`CLAUDE.md` のマージ手順** +同期担当エージェント(= あなた)が Read と Edit ツールを使ってセクション単位でマージする: + +1. 既存 `CLAUDE.md` とテンプレート版 `$TEMP_DIR/CLAUDE.md` を Read する +2. テンプレート側の変更箇所を特定する(初回同期は LAST_SHA がないためテンプレート全体を「更新候補」として扱う): ```bash - DELETIONS=$(echo "$CHANGED_ENTRIES" | awk -F'\t' '$1 == "D" {print $2} $1 ~ /^R/ {print $2}') + if [ -n "$LAST_SHA" ]; then + git -C "$TEMP_DIR" show "$LAST_SHA:CLAUDE.md" 2>/dev/null > /tmp/claude_md_old || true + diff -u /tmp/claude_md_old "$TEMP_DIR/CLAUDE.md" + fi ``` +3. セクションを以下の基準で分類する: + - **共通セクション(テンプレート管理,更新対象)**: 「必須ルール」「エージェントチーム」「Git 運用」「ドキュメント」節など,テンプレートに由来する節 + - **プロジェクト固有セクション(保持対象)**: 「プロジェクト名」「開発進捗」や,プロジェクトが追加した固有規約の節 +4. テンプレート側で変更があった共通セクションのみを Edit で既存ファイルに反映する.プロジェクト固有セクションは一切触らない +5. `git diff CLAUDE.md` で結果を表示しユーザーに確認する -4. `$DELETIONS` が空でない場合,ユーザーに確認を求める: +**`.gitattributes` のマージ手順** - 「**以下のファイルはテンプレートから削除されています:** - - {削除候補一覧} - - プロジェクトからも削除してよいですか?(残したいファイルがあれば指定してください)」 - - ユーザー確認後,対象ファイルを `rm` で削除する.プロジェクトが独自に残したいファイルは削除対象から除外する. - -5. 同期済み SHA を記録し,一時ディレクトリを削除する: - +1. 既存ファイルとテンプレート版の差分を表示する: ```bash - echo "$NEW_SHA" > .claude/template-sync-sha - rm -rf "$TEMP_DIR" + diff -u .gitattributes "$TEMP_DIR/.gitattributes" ``` +2. ユーザーに以下のいずれかを選ばせる: + - **上書き**: テンプレート版で既存を置換 + - **マージ**: 両者のルールを統合(具体的な統合内容は対話で決定) + - **スキップ**: 既存ファイルを維持 +3. 選択に応じて処理する + +### 5.5 削除候補の確認 + +削除候補(D およびリネーム元)を抽出する: + +```bash +DELETIONS=$(echo "$CHANGED_ENTRIES" | awk -F'\t' '$1 == "D" {print $2} $1 ~ /^R/ {print $2}') +``` + +`$DELETIONS` が空でない場合,ユーザーに確認を求める: + +「**以下のファイルはテンプレートから削除されています:** + +{削除候補一覧} + +プロジェクトからも削除してよいですか?(残したいファイルがあれば指定してください)」 + +ユーザー確認後,対象ファイルを `rm` で削除する.プロジェクトが独自に残したいファイルは削除対象から除外する. + +### 5.6 同期済み SHA の記録とクリーンアップ + +```bash +echo "$NEW_SHA" > .claude/template-sync-sha +rm -rf "$TEMP_DIR" +``` ## ステップ 6: 変更内容の分析 @@ -160,5 +272,7 @@ - テンプレートリポジトリへの push は行わない - コード修正はユーザーの確認なしに実行しない -- ファイルコピーによりプロジェクト固有の変更が上書きされる場合は,`git diff` で確認してユーザーに報告する +- マージ必須ファイル(`.gitignore`, `CLAUDE.md`, `.gitattributes`)は必ずステップ 5.4 の手順でマージする.盲目的な `cp` で上書きしない(フレームワーク固有の除外ルールやプロジェクト固有セクションが失われる) +- 通常コピー対象でもプロジェクト固有の変更が上書きされうる場合は,`git diff` で確認してユーザーに報告する +- テンプレートが管理するのは `.claude/` 配下のうち `agents/`,`commands/`,`hooks/`,`settings.json`,`template-sync-sha` のみ.`.claude/plans/` や `.claude/commit-context.md` 等のプロジェクト固有ファイルはテンプレートに含まれないため同期対象外 - `chore/sync-template` ブランチは他の作業ブランチと混ぜず,作成後は速やかにマージすること.複数の作業ブランチで `/sync-template` を実行すると `.claude/template-sync-sha` がコンフリクトする.コンフリクト時は新しい(HEAD 側の)SHA を採用すること. diff --git a/.claude/hooks/restrict_repo_access.py b/.claude/hooks/restrict_repo_access.py index e2f8733..36bfe96 100644 --- a/.claude/hooks/restrict_repo_access.py +++ b/.claude/hooks/restrict_repo_access.py @@ -2,8 +2,13 @@ import json import os +import re +import shlex import sys +# Bash で検出する破壊的コマンド +DESTRUCTIVE_COMMANDS = {"rm", "rmdir", "mv", "cp", "chmod", "chown", "unlink"} + def get_target_path(tool_name: str, tool_input: dict) -> str | None: """ツールの種類に応じてチェック対象のパスを取得する.""" @@ -22,6 +27,49 @@ return real_target == real_base or real_target.startswith(real_base + os.sep) +def check_bash_command(command: str, cwd: str) -> str | None: + """Bash コマンド内の破壊的操作がリポジトリ外を対象としていないかチェックする. + + リポジトリ外のパスに対する破壊的コマンドを検出した場合、理由文字列を返す。 + 問題なければ None を返す。 + """ + # セミコロン、&&、|| やパイプで分割された各部分をチェック + parts = re.split(r"[;&|]+", command) + for part in parts: + part = part.strip() + if not part: + continue + try: + tokens = shlex.split(part) + except ValueError: + # クォートが閉じていない等のパースエラーは無視して続行 + continue + if not tokens: + continue + # コマンド名を取得(env, sudo 等のプレフィックスをスキップ) + cmd_name = None + for token in tokens: + if token in ("sudo", "env") or "=" in token: + continue + cmd_name = os.path.basename(token) + break + if cmd_name not in DESTRUCTIVE_COMMANDS: + continue + # 破壊的コマンドの引数からパスを抽出してチェック + for token in tokens[1:]: + if token.startswith("-"): + continue + # 絶対パスまたは .. を含むパスをチェック + if os.path.isabs(token) or ".." in token: + resolved = os.path.realpath(os.path.join(cwd, token)) + if not is_within_directory(resolved, cwd): + return ( + f"リポジトリ外への破壊的操作をブロックしました: " + f"`{cmd_name}` が `{token}` を対象としています" + ) + return None + + def deny(reason: str) -> None: """ブロック用の JSON を出力して終了する.""" result = { @@ -41,6 +89,15 @@ tool_input = data.get("tool_input", {}) cwd = data.get("cwd", os.getcwd()) + # Bash ツールの破壊的コマンドチェック + if tool_name == "Bash": + command = tool_input.get("command", "") + reason = check_bash_command(command, cwd) + if reason: + deny(reason) + sys.exit(0) + + # Read/Write/Edit/Glob/Grep のパスチェック target_path = get_target_path(tool_name, tool_input) # パスが指定されていない場合は許可(Glob/Grep の path 省略時など) diff --git a/.claude/settings.json b/.claude/settings.json index 548c175..3b0ffd7 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -2,7 +2,7 @@ "hooks": { "PreToolUse": [ { - "matcher": "Read|Write|Edit|Glob|Grep", + "matcher": "Read|Write|Edit|Glob|Grep|Bash", "hooks": [ { "type": "command", diff --git a/.claude/template-sync-sha b/.claude/template-sync-sha new file mode 100644 index 0000000..49722ad --- /dev/null +++ b/.claude/template-sync-sha @@ -0,0 +1 @@ +edf620587f1798319fa8412e55e7b99bf17528a4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.gitignore b/.gitignore index 4fddf76..77310e6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Claude Code working files .claude/plans/ +.claude/commit-context.md # Python __pycache__/ diff --git a/CLAUDE.md b/CLAUDE.md index 9634673..6afd396 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,11 +19,10 @@ ### エージェントチーム(GUIDE_05 準拠) -- 実装は `/implement <タスク>` で開始する(コーディング → テスト → リファクタリング) -- 各フェーズ間で人間が動作確認・方針判断を行う -- 個別実行: coder → tester → refactorer を順に実行 -- テスト・リファクタリングをスキップしない(Stop Hook が警告) -- Phase 3 完了後,コミット前に docs/ の更新要否を確認する +- 実装は `/implement <タスク>` で開始する(コーディング → テスト → リファクタリング → ドキュメント更新) +- Phase 1 後に人間が動作確認,Phase 2 でテスト失敗時のみ方針判断 +- Phase 2 成功後は Phase 3 → Phase 4 まで自動で進む(Phase 4 で更新がある場合のみ確認) +- テスト・リファクタリングをスキップしない ### 手動確認が必要な作業(自分で完了させないこと) @@ -49,8 +48,6 @@ - ディレクトリ構造規則: docs/01_GUIDE/GUIDE_07_ディレクトリ構造規則.md - テスト方針: docs/01_GUIDE/GUIDE_08_テスト方針.md - エラーハンドリング方針: docs/01_GUIDE/GUIDE_09_エラーハンドリング方針.md -- リファクタリング方針: docs/01_GUIDE/GUIDE_10_リファクタリング方針.md -- 機能実装完了フロー: docs/01_GUIDE/GUIDE_11_機能実装完了フロー.md ### 02_ENV(環境) diff --git "a/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" index f9aa80e..b3b8893 100644 --- "a/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" +++ "b/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" @@ -38,6 +38,26 @@ - **前提条件**: 以下のツールは全プロジェクト共通で導入する. - `git` — バージョン管理([GUIDE_04](GUIDE_04_Git運用ルール.md) で運用ルールを定義) - `gh` — GitHub CLI(PR 作成・マージ等に使用) +- **テンプレートからのプロジェクト作成**: + 以下の手順でテンプレートをコピーし,履歴を引き継がない新規リポジトリとして初期化する. + + ```bash + # 1. プロジェクトディレクトリを作成して移動 + mkdir + cd + + # 2. カレントディレクトリにテンプレートをクローン(末尾の . に注意) + git clone https://github.com/rintoHasegawa/programming-template.git . + + # 3. 現在のテンプレート SHA を記録(以降の /sync-template で差分同期するため) + git rev-parse HEAD > .claude/template-sync-sha + + # 4. テンプレートの git 履歴を削除し,新しいリポジトリとして初期化 + rm -rf .git + git init -b main + ``` + + 以降,テンプレートの更新を取り込むときは `/sync-template` を実行する. - **基本方針**: 環境の再現性を重視し,手順書だけに頼らず構築を自動化・コード化できる方法を優先する(例: Docker,Dev Containers,Windows Sandbox,IaC ツール等). - **人間が決めること**: 開発マシンの選定,クラウドサービスのアカウント作成,環境構築方法の選択 - **AI に依頼できること**: 環境構築手順書の作成,設定ファイルの生成,`.gitignore` の作成,Dockerfile や devcontainer.json 等の構築用ファイルの作成 @@ -56,18 +76,18 @@ ## 規約整備 (Coding Standards) 技術スタックに応じたコーディング規約やプロジェクト固有のガイドを作成する. -汎用ガイド(GUIDE_01〜04)は本テンプレートに含まれている.ここではプロジェクト固有の規約を追加する. +汎用ガイド(GUIDE_01〜05)は本テンプレートに含まれている.ここではプロジェクト固有の規約を追加する. - **基本方針**: 言語・フレームワークの公式ガイドラインや広く採用されている標準規約に則る(例: Effective Dart,PEP 8,Google Style Guide 等).プロジェクト固有のルールは標準と異なる部分のみ定義する. - **人間が決めること**: 標準規約でカバーされない判断(アーキテクチャパターンの選択等) - **AI に依頼できること**: 標準規約を踏まえた規約のドラフト作成,参照元ガイドラインの調査 -- **作成すべきガイド**: - - コーディング規約 — 命名規則,フォーマット,import 順序,型の使い方,コメントの書き方,コード内ドキュメントの規則 - - ディレクトリ構造規則 — プロジェクトのディレクトリ構成とファイル配置ルール - - テスト方針 — テストの種類,粒度,実行タイミング,カバレッジ基準 - - エラーハンドリング方針 — エラーの分類,処理方法,ログ出力の方針 - - リファクタリング方針 — リファクタリングの判断基準,実施タイミング - - 機能実装完了フロー — コミット前のチェックリスト(フォーマット,静的解析,テスト,レビュー等) +- **作成すべきガイド**(推奨番号は GUIDE_03 に準拠): + - `GUIDE_06` コーディング規約 — 命名規則,フォーマット,import 順序,型の使い方,コメントの書き方,コード内ドキュメントの規則 + - `GUIDE_07` ディレクトリ構造規則 — プロジェクトのディレクトリ構成とファイル配置ルール + - `GUIDE_08` テスト方針 — テストの種類,粒度,実行タイミング,カバレッジ基準,モック方針,テストファイルの配置規則 + - `GUIDE_09` エラーハンドリング方針 — エラーの分類,処理方法,ログ出力の方針 + - ※ リファクタリング方針は言語に依存しないため,`.claude/agents/refactorer.md` の判断基準を共通ルールとして使用する + - ※ 機能実装完了フローは GUIDE_05 と `/implement` で定義済みのため,別途作成しない ## 開発計画 (Development Plan) @@ -84,11 +104,6 @@ - 各ステップの完了時に [GUIDE_02_ドキュメント作成ガイド](GUIDE_02_ドキュメント作成ガイド.md) と [GUIDE_04_Git運用ルール](GUIDE_04_Git運用ルール.md) に従ってコミット・PR を作成する. - 仕様変更が発生した場合は,先にドキュメントを更新してから実装に反映する. -### ドキュメントの書き方 - -- コード内ドキュメント(JSDoc・コメント)と docs/ ドキュメントの書き方は [GUIDE_05_コーディング規約](GUIDE_05_コーディング規約.md) の「ドキュメント」セクションを参照 -- 仕様・設計の変更がある場合は `docs/` を先に更新してから実装に反映する - ## CLAUDE.md の管理 (CLAUDE.md Management) `CLAUDE.md` は AI が会話開始時に最初に読むファイルであり,プロジェクトの引継ぎ情報を一元管理する. diff --git "a/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" "b/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" index 63ec124..9a30190 100644 --- "a/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" +++ "b/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" @@ -50,15 +50,12 @@ │ テストを安全網としてリファクタリング │ テスト再実行で挙動が変わっていないことを保証 │ - ├─ ドキュメント更新チェック - │ 変更内容に関連する docs/ の更新要否を確認 - │ 必要なら更新してからコミットへ進む + ├─ Phase 4 ──▶ ドキュメント更新 + │ docs/ と CLAUDE.md を必要に応じて更新 + │ 更新がある場合のみ人間の確認を挟む + │ 結果を .claude/commit-context.md に書き出す │ - ├─ 人間の確認ポイント 3 - │ 最終確認 - │ OK → コミット・push・PR 作成 - │ - └─ CLAUDE.md 進捗更新 + └─ 完了 → /commit でコミット ``` ### Phase 1: コーディング (Coding) @@ -94,9 +91,9 @@ - リファクタリング後にテストを再実行し,全テストが通ることを確認する. - リファクタリング不要と判断した場合は,理由を明示して終了する. -### ドキュメント更新チェック (Documentation Update Check) +### Phase 4: ドキュメント更新 (Documentation) -Phase 3 完了後,コミット前に `docs/` 配下のドキュメント更新が必要かを確認する.エージェントが更新候補を提示し,人間が最終判断する. +Phase 3 完了後,実装内容に応じて `docs/` と `CLAUDE.md` を更新する. - **チェック観点**: - API・データ構造の変更 → `docs/04_SPEC/` の該当仕様を更新 @@ -104,11 +101,13 @@ - 開発ステップの進捗 → `docs/03_PLAN/` や `CLAUDE.md` の進捗欄を更新 - 規約・運用ルールの変更 → `docs/01_GUIDE/` を更新 - **該当なし**: ドキュメント更新が不要な変更(軽微なバグ修正,リファクタリングのみ等)はスキップ可. -- **実行者**: エージェントが `git diff` を基に更新候補を提示し,人間が更新要否を判断する. +- **更新がある場合のみ**人間の確認を挟む.更新不要の場合は確認なしで完了処理に進む. +- **コミットコンテキストの書き出し**: Phase 4 の結果(更新の有無と理由)を `.claude/commit-context.md` に書き出す.このファイルは `/commit` が参照し,docs/CLAUDE.md の更新漏れチェックをスキップするために使う(`.gitignore` 対象). -### 人間の確認ポイント 3 +### 完了処理 -- 最終確認を行い,OK ならコミット・push・PR 作成を指示する. +- `/implement` はコミットを行わない.完了後は `/commit` でコミットする. +- `/commit` は `.claude/commit-context.md` が存在する場合,docs/CLAUDE.md の更新漏れチェックをスキップする.存在しない場合(`/implement` を経由していない場合)は警告のみ行う. ## コンテキスト受け渡し (Context Passing) @@ -127,36 +126,12 @@ | 開始時 | タスクの指示(`/implement <何をするか>`) | | Phase 1 後 | 動作確認(ブラウザ・実機など AI にできない確認) | | Phase 2 後 | テスト失敗時のみ方針判断(全成功なら自動で Phase 3 へ) | -| Phase 3 後 | ドキュメント更新の要否判断 + 最終確認 → コミット・PR 作成の指示 | +| Phase 4 後 | ドキュメント更新がある場合のみ確認 → `/commit` でコミット | 人間の本質的な役割は「AI にできない判断と確認」であり,各フェーズの品質のゲートキーパーとなる. -## 個別実行 (Manual Execution) - -パイプラインを使わず個別にエージェントを実行することも可能だが,3 フェーズすべてを順番に実行すること. - -```bash -# 個別実行の場合 -/coder # Phase 1 -# → 人間が動作確認 -/tester # Phase 2 -# → 人間がテスト結果確認 -/refactorer # Phase 3 -# → 人間が最終確認 → コミット -``` - -## 安全装置 (Safety Net) - -Stop Hook により,実装を含む会話の終了時にテスト・リファクタリングの実施状況を確認する.未実施の場合は警告が表示される.これはアドバイザリー(助言)であり,ブロッキング(強制)ではない. - ## コミットルール (Commit Rules) -パイプライン完了後のコミットは [GUIDE_04](GUIDE_04_Git運用ルール.md) に従う. - -| 内容 | コミットタグ | -| --- | --- | -| 機能追加 | `[add]` | -| 機能更新 | `[update]` | -| バグ修正 | `[fix]` | +パイプライン完了後は `/commit` でコミットする.コミットメッセージのタグ等は [GUIDE_04](GUIDE_04_Git運用ルール.md) に従う. ※ リファクタリングとテストは実装と一体の成果物として,まとめてコミットする.必要に応じて分割コミットも可. diff --git "a/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" deleted file mode 100644 index eaa15b3..0000000 --- "a/docs/01_GUIDE/GUIDE_10_\343\203\252\343\203\225\343\202\241\343\202\257\343\202\277\343\203\252\343\203\263\343\202\260\346\226\271\351\207\235.md" +++ /dev/null @@ -1,27 +0,0 @@ -# リファクタリング方針 (Refactoring Policy) - -## 判断基準 (When to Refactor) - -以下に該当する場合にリファクタリングを検討する. - -- 同じ処理が 3 箇所以上に重複している -- 1 つの関数が複数の責務を持っている -- 関数の引数が 5 つ以上になっている -- テストが書きにくい構造になっている - -## 実施タイミング (Timing) - -- 機能実装の完了後(`/implement` の Phase 3)に行う -- 機能追加とリファクタリングは同一コミットに混ぜない - -## 方針 (Approach) - -- テストが通っている状態を維持しながら変更する -- 外部から見た振る舞い(入出力)を変えない -- 変更前にテストを実行し,変更後にも同じテストが通ることを確認する - -## やらないこと (Out of Scope) - -- 動いているコードの「見た目だけ」の書き換え(Ruff が自動で対応する範囲) -- 将来の要件を見越した過度な抽象化 -- 使われていないコードの温存(不要なら削除する) diff --git "a/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" deleted file mode 100644 index 75b7151..0000000 --- "a/docs/01_GUIDE/GUIDE_11_\346\251\237\350\203\275\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" +++ /dev/null @@ -1,35 +0,0 @@ -# 機能実装完了フロー (Implementation Completion Flow) - -## 概要 (Overview) - -機能実装からコミットまでに実施するチェックリスト.`/implement` の全フェーズ完了後に確認する. - -## チェックリスト (Checklist) - -### コード品質 - -- [ ] Ruff でフォーマット・リントを実行しエラーがないこと - -```bash -ruff check src/ tests/ -ruff format --check src/ tests/ -``` - -### テスト - -- [ ] pytest で全テストが通ること - -```bash -pytest -``` - -### ドキュメント - -- [ ] 公開関数に docstring があること -- [ ] API やデータ構造を変更した場合,`docs/` を更新したこと - -### コミット前の最終確認 - -- [ ] `git diff` で意図しない変更が含まれていないこと -- [ ] `.env` やクレデンシャルがステージングされていないこと -- [ ] コミットメッセージが GUIDE_04 の書式に従っていること