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 2ad606c..1610d69 100644 --- a/.claude/commands/commit.md +++ b/.claude/commands/commit.md @@ -18,75 +18,65 @@ **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` が記録されている場合,このステップをスキップする. -### メッセージの書式 +ファイルが存在しない場合(`/implement` を経由していない場合),変更内容に応じて CLAUDE.md の「開発進捗」セクションの更新が必要か判断し, +更新されていない場合は「⚠ CLAUDE.md の開発進捗の更新が必要かもしれません.確認してください.」と警告する. +更新自体は行わず,ユーザーの判断に委ねる. -- 書式: `[タグ] 内容` -- 言語: 日本語 -- 末尾に句点は不要 - -## ステップ 4: コミット +## ステップ 5: コミット 以下を実行する: -1. `git add` で関連ファイルをステージングする +1. `git add` で関連ファイルをステージングする(CLAUDE.md の変更がある場合はそれも含める) 2. `git commit -m "{コミットメッセージ}"` でコミットする +3. `.claude/commit-context.md` が存在する場合は削除する -## ステップ 5: プッシュ・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 master && git pull origin master` でローカルを最新化する - -## ステップ 6: CLAUDE.md 更新提案 - -変更内容に応じて CLAUDE.md の「開発進捗」セクションの更新が必要か判断し, -必要であれば更新内容を提案する. +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 new file mode 100644 index 0000000..59733a8 --- /dev/null +++ b/.claude/commands/sync-template.md @@ -0,0 +1,164 @@ +--- +name: sync-template +model: sonnet +description: "テンプレートリポジトリから最新の変更を取り込み,ルール変更に伴うコード修正を行う." +argument-hint: "" +--- + +あなたはテンプレート同期の担当者です. +テンプレートリポジトリから最新の変更を取り込み,必要に応じてプロジェクトのコードを修正してください. + +実行環境: bash(Git Bash または Unix シェル)が必要.`mktemp`, `rm -rf`, `cat`, シェル変数展開を使用する. + +テンプレート URL: `https://github.com/rintoHasegawa/programming-template.git` + +## ステップ 1: 事前確認 + +`git status` でワーキングツリーがクリーンか確認する. + +**コミットされていない変更がある場合:** + +「⚠ コミットされていない変更があります. +先に変更をコミットするか,stash してから再度 `/sync-template` を実行してください.」 + +→ ここで処理を中断する. + +## ステップ 2: テンプレートを一時ディレクトリにクローン + +以下を実行する: + +```bash +TEMPLATE_URL="https://github.com/rintoHasegawa/programming-template.git" +TEMP_DIR=$(mktemp -d) +git clone "$TEMPLATE_URL" "$TEMP_DIR" +NEW_SHA=$(git -C "$TEMP_DIR" rev-parse HEAD) +``` + +## ステップ 3: 変更ファイルの特定 + +`.claude/template-sync-sha` の有無で処理を分岐する: + +**ファイルが存在する場合(2 回目以降の同期):** + +```bash +LAST_SHA=$(cat .claude/template-sync-sha) +``` + +- `NEW_SHA == LAST_SHA` の場合: + `rm -rf "$TEMP_DIR"` で一時ディレクトリを削除し,「テンプレートに新しい変更はありません.既に最新です.」と報告して終了する. + +- `NEW_SHA != LAST_SHA` の場合: + ```bash + # A=追加, M=変更, D=削除, R=リネーム の種別付きで取得 + CHANGED_ENTRIES=$(git -C "$TEMP_DIR" diff --name-status "$LAST_SHA" HEAD) + ``` + で変更されたファイルを種別付きで取得する. + +**ファイルが存在しない場合(初回同期):** + +テンプレートの全ファイルを「追加(A)」として対象に含める: + +```bash +CHANGED_ENTRIES=$(cd "$TEMP_DIR" && find . -type f -not -path "./.git/*" | sed 's|^\./||' | awk -v OFS='\t' '{print "A", $0}') +``` + +## ステップ 4: 変更一覧をユーザーに提示 + +取り込み対象のファイル一覧を種別ごとに整理してユーザーに提示する: + +「**テンプレートに以下の変更があります:** + +- 追加 (A): {ファイル一覧} +- 変更 (M): {ファイル一覧} +- 削除 (D): {ファイル一覧} +- リネーム (R): {旧名 → 新名} + +取り込みを開始します.」 + +## ステップ 5: ブランチ作成とファイル反映 + +1. `git checkout -b chore/sync-template` でブランチを作成する + - 既に同名のブランチが存在する場合は削除してから作り直す + +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 + ``` + +3. 削除候補(D およびリネーム元)を抽出する: + + ```bash + DELETIONS=$(echo "$CHANGED_ENTRIES" | awk -F'\t' '$1 == "D" {print $2} $1 ~ /^R/ {print $2}') + ``` + +4. `$DELETIONS` が空でない場合,ユーザーに確認を求める: + + 「**以下のファイルはテンプレートから削除されています:** + + {削除候補一覧} + + プロジェクトからも削除してよいですか?(残したいファイルがあれば指定してください)」 + + ユーザー確認後,対象ファイルを `rm` で削除する.プロジェクトが独自に残したいファイルは削除対象から除外する. + +5. 同期済み SHA を記録し,一時ディレクトリを削除する: + + ```bash + echo "$NEW_SHA" > .claude/template-sync-sha + rm -rf "$TEMP_DIR" + ``` + +## ステップ 6: 変更内容の分析 + +コピーされた変更を以下のカテゴリに分類する: + +- **ルール変更**: コーディング規約,Git 運用ルール,テスト方針等の変更 +- **ドキュメント更新**: 手順書やガイドの改善 +- **設定変更**: CLAUDE.md や .claude/ 配下の変更 +- **その他**: 上記に該当しない変更 + +## ステップ 7: ルール変更に伴うコード修正 + +ステップ 6 で「ルール変更」に該当するものがある場合: + +1. 変更されたルールの内容を要約してユーザーに報告する +2. そのルール変更がプロジェクトの既存コードに影響するか分析する +3. 影響がある場合,修正が必要な箇所と修正内容を提示する +4. ユーザーの確認を得てから修正を実行する + +**影響がない場合:** + +「ルール変更に伴うコード修正は不要です.」 + +## ステップ 8: 結果報告 + +すべての作業が完了したら,結果を報告する: + +「**テンプレート同期が完了しました.** + +- ブランチ: `{ブランチ名}` +- 取り込んだ変更: {変更の要約} +- コード修正: {あり(内容)/なし} + +`/commit push` でプッシュと PR 作成ができます.」 + +## 注意事項 + +- テンプレートリポジトリへの push は行わない +- コード修正はユーザーの確認なしに実行しない +- ファイルコピーによりプロジェクト固有の変更が上書きされる場合は,`git diff` で確認してユーザーに報告する +- `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..8c20381 --- /dev/null +++ b/.claude/template-sync-sha @@ -0,0 +1 @@ +21c46e72e74f77a7dee7488d803b08e33b3c95bd 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 58fb001..1a7a8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ # Claude Code .claude/plans/ + +# /implement が /commit に渡すコンテキストファイル +.claude/commit-context.md diff --git a/CLAUDE.md b/CLAUDE.md index f7357b7..6df8bff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,11 +32,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 で更新がある場合のみ確認) +- テスト・リファクタリングをスキップしない ### 手動確認が必要な作業(自分で完了させないこと) 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 5bb3b96..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 等の構築用ファイルの作成 @@ -61,13 +81,13 @@ - **基本方針**: 言語・フレームワークの公式ガイドラインや広く採用されている標準規約に則る(例: 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_06_コーディング規約](GUIDE_06_コーディング規約.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 72b3a3f..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" @@ -4,7 +4,7 @@ ## 基本方針 (Basic Policy) -- 「実装完了」とは,コーディング・テスト・リファクタリングの全フェーズが完了した状態を指す.具体的な完了基準は [GUIDE_08](GUIDE_08_実装完了フロー.md) を参照. +- 「実装完了」とは,コーディング・テスト・リファクタリングの全フェーズが完了した状態を指す. - 各フェーズは専門エージェントが担当し,フレッシュなコンテキストでレビューする. - フェーズのスキップは原則禁止する.リファクタリング不要の判断は Refactorer エージェント自身が行う. - 各フェーズ間で人間が確認・判断を行う. @@ -50,15 +50,12 @@ │ テストを安全網としてリファクタリング │ テスト再実行で挙動が変わっていないことを保証 │ - ├─ ドキュメント更新チェック - │ 変更内容に関連する docs/ の更新要否を確認 - │ 必要なら更新してからコミットへ進む + ├─ Phase 4 ──▶ ドキュメント更新 + │ docs/ と CLAUDE.md を必要に応じて更新 + │ 更新がある場合のみ人間の確認を挟む + │ 結果を .claude/commit-context.md に書き出す │ - ├─ 人間の確認ポイント 3 - │ 最終確認 - │ OK → コミット・push・PR 作成 - │ - └─ CLAUDE.md 進捗更新 + └─ 完了 → /commit でコミット ``` ### Phase 1: コーディング (Coding) @@ -78,7 +75,6 @@ - Tester エージェントが仕様(`docs/04_SPEC/`)を基準にテストを作成する. - テストは実装コードではなく**仕様**を基準に書く. - 実装が仕様と異なればテストが失敗し,バグを検出する. -- テスト方針は [GUIDE_07](GUIDE_07_テスト方針.md) を参照. ### Phase 2 完了後の分岐 @@ -94,11 +90,10 @@ - 挙動は変更しない. - リファクタリング後にテストを再実行し,全テストが通ることを確認する. - リファクタリング不要と判断した場合は,理由を明示して終了する. -- リファクタリングの判断基準は [GUIDE_08](GUIDE_08_実装完了フロー.md) のリファクタリング方針を参照. -### ドキュメント更新チェック (Documentation Update Check) +### Phase 4: ドキュメント更新 (Documentation) -Phase 3 完了後,コミット前に `docs/` 配下のドキュメント更新が必要かを確認する.エージェントが更新候補を提示し,人間が最終判断する(コミット前の具体的なチェックリストは [GUIDE_08](GUIDE_08_実装完了フロー.md) を参照). +Phase 3 完了後,実装内容に応じて `docs/` と `CLAUDE.md` を更新する. - **チェック観点**: - API・データ構造の変更 → `docs/04_SPEC/` の該当仕様を更新 @@ -106,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) @@ -129,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) に従う. ※ リファクタリングとテストは実装と一体の成果物として,まとめてコミットする.必要に応じて分割コミットも可.