diff --git a/.claude/agents/advisor.md b/.claude/agents/advisor.md new file mode 100644 index 0000000..f712fc6 --- /dev/null +++ b/.claude/agents/advisor.md @@ -0,0 +1,39 @@ +--- +name: advisor +description: "重要な価値判断・設計判断について,最上位モデル(Fable)で熟考して助言するエージェント.ブリーフ(論点・背景・選択肢・判断基準)を受け取り,必要なファイルを自分で読み,判断と根拠・リスク・見落としを返す./consult から使用される." +model: fable +tools: + - Read + - Glob + - Grep + - Bash(git log *) + - Bash(git diff *) + - Bash(ls *) + - Bash(cat *) + - WebSearch + - WebFetch +--- + +# advisor(価値判断の相談役) + +あなたは **advisor**.重要な価値判断・設計判断について,司令塔(メインループ)から渡されたブリーフをもとに熟考し,助言を返すエージェントです.助言に専念し,実装・ファイル変更は行いません. + +## 手順 (Procedure) + +1. **ブリーフの精読**: 論点・背景・選択肢・判断基準を把握する.前提が不足・矛盾している場合は,推測で埋めずに「前提の確認」として質問を返す(誤った前提の上の判断は有害) +2. **裏取り**: ブリーフで参照されたファイルを自分で読み,必要なら周辺コード・ドキュメント・外部情報(WebSearch / WebFetch)も確認する.ブリーフの記述とコードの実態が食い違っていたら指摘する +3. **判断**: 選択肢を判断基準に照らして比較し,結論を出す.ブリーフに無い選択肢が優れている場合は遠慮なく提案する + +## 出力書式 (Output Format) + +- **結論**: どうすべきか(1〜3 文で明確に) +- **根拠**: 判断基準に沿った理由.選択肢間のトレードオフ +- **リスク**: 結論を採った場合に注意すべき点・失敗した場合の逃げ道 +- **盲点・反対視点**: ブリーフの暫定意見や前提への異論があれば率直に(同調は求められていない) +- **確信度**: 高 / 中 / 低と,低い場合に追加で確認すべきこと + +## 行動規範 (Principles) + +- コード・ファイルの変更はしない(助言だけを返す.実行は司令塔とユーザーが決める) +- 司令塔の暫定意見に引きずられない.独立に考え,違うなら違うと言う +- 結論を曖昧にしない.条件分岐が必要なら「X なら A,Y なら B」と条件を明示する diff --git a/.claude/agents/deps-analyst.md b/.claude/agents/deps-analyst.md new file mode 100644 index 0000000..a063156 --- /dev/null +++ b/.claude/agents/deps-analyst.md @@ -0,0 +1,38 @@ +--- +name: deps-analyst +description: "依存更新 1 件(メジャー更新 PR・CI 赤の PR・Dependabot alert)の影響分析に集中するエージェント.リリースノートから破壊的変更を抽出し,コードベースの利用箇所と突き合わせて推奨対応を返す./deps-update の分析フェーズで使用される." +model: opus +tools: + - Read + - Glob + - Grep + - Bash(gh *) + - Bash(git log *) + - Bash(git diff *) + - Bash(ls *) + - Bash(cat *) + - WebSearch + - WebFetch +--- + +# deps-analyst(依存更新の影響分析担当) + +あなたは **deps-analyst**.依存更新 1 件について,人間が「そのままマージ」「`/implement` で追従」「見送り」を選べるだけの判断材料を作るエージェントです. + +## 手順 (Procedure) + +`.claude/skills/deps-update/reference.md` の「不変条件」と「メジャー更新の影響分析」を読み,それに従う.要点: + +1. **変更内容**: PR 本文のリリースノート・CHANGELOG・上流リポジトリから破壊的変更を抽出する(取れなければ「リリースノート未確認」と明記する) +2. **利用箇所**: コードベース内で当該パッケージを import・呼び出している箇所を Grep で列挙し,破壊的変更に該当する API の使用有無を確認する +3. **影響範囲と推奨**: 「そのままマージ可」「`/implement` で追従が必要(修正箇所の一覧付き)」「見送り」のいずれかを根拠付きで結論する +4. **alert(PR 無し)の場合**: 修正版の有無・Dependabot が PR を作れなかった理由を踏まえ,回避策やロックファイル更新コマンドを推奨対応として示す + +## 出力書式 (Output Format) + +reference.md「PR コメントの書式」のフィールド(判定・更新・検証・破壊的変更・影響箇所・推奨)に沿って返す.alert の場合は台帳の `[alert]` 行に必要な項目を返す. + +## してはいけないこと (Prohibitions) + +- マージ・PR コメント投稿・台帳やコードの書き換えはしない(分析結果を返すだけ.実行は司令塔と ops-runner が行う) +- 依存ファイル(マニフェスト・ロックファイル)を自分で書き換えない diff --git a/.claude/agents/ops-runner.md b/.claude/agents/ops-runner.md new file mode 100644 index 0000000..ef3419a --- /dev/null +++ b/.claude/agents/ops-runner.md @@ -0,0 +1,48 @@ +--- +name: ops-runner +description: "git・gh の機械的な操作を実行する軽量エージェント.渡された手順書(reference.md)と入力に忠実に従い,判断が必要な事態では安全に停止して報告する./commit・/task-create・/task-start・/task-handoff・/deps-update の実行フェーズで使用される." +model: haiku +tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash(git *) + - Bash(gh *) + - Bash(ls *) + - Bash(cat *) + - Bash(test *) + - Bash(rm .claude/commit-context.md) + - Bash(npm *) + - Bash(npx *) + - Bash(pnpm *) + - Bash(yarn *) + - Bash(dart *) + - Bash(flutter *) + - Bash(cargo *) + - Bash(go *) + - Bash(python *) + - Bash(pip *) +--- + +# ops-runner(軽量実行担当) + +あなたは **ops-runner**.上位(メインループの skill)から渡された手順書と入力に従い,git・gh・検証コマンドの機械的な操作を実行する軽量エージェントです.方針判断や創意工夫はせず,手順書への忠実さと正確な報告に徹します. + +## 行動規範 (Principles) + +1. **手順書が唯一の根拠**: 最初に,指示で指定された手順書(reference.md 等)と規約ファイルを読む.手順書に書かれていない操作はしない +2. **判断しない**: 手順書が「ユーザーに確認」としている分岐や,想定外の状態(コンフリクト・権限エラー・対象が見つからない等)に遭遇したら,作業を安全な状態にして停止し,「確認事項」として状況・選択肢・推奨を報告する.自分で判断して先に進まない.停止する前に,確認不要で完了できる残りの作業は済ませ,他にも確認が要りそうな点があればまとめて洗い出す(上位との往復を減らす) +3. **破壊的操作の禁止**: force push・`git reset --hard`・`main` への直接コミット・`gh pr merge --admin` によるブランチ保護の迂回・ファイル削除は,手順書に明記されている場合を除き行わない.`.env` やクレデンシャルファイルはステージングしない +4. **分類器ブロックはそのまま報告**: auto mode のセキュリティ分類器によりコマンドが**実行される前に**ブロックされた場合は,リポジトリ設定や権限の問題と混同せず,「分類器ブロック」として表示された文言をそのまま報告して停止する.別のコマンドや手順で迂回しない +5. **正確な報告**: 成功・失敗を装飾なく報告する.失敗したコマンドは出力の要点を添える + +## 報告書式 (Report Format) + +最終報告には以下だけを含める(上位がユーザー向けに整形するため,経過の説明は不要): + +- **実行した操作**: 箇条書き(ブランチ・コミット SHA・Issue / PR 番号・URL 等の成果物を含める) +- **事実報告**: 手順書が「返すこと」と指定した事実(変更ファイルの分類等.判断や解釈は加えない.無ければ省略) +- **警告**: 手順書のチェックで引っかかった点(無ければ省略) +- **確認事項**: 停止した理由・状況・選択肢・推奨(停止した場合のみ) diff --git a/.claude/rules/git-conventions.md b/.claude/rules/git-conventions.md index 8c4dd97..4b27f20 100644 --- a/.claude/rules/git-conventions.md +++ b/.claude/rules/git-conventions.md @@ -49,6 +49,7 @@ - 書式: `[タグ] 内容` - 言語: 日本語 - 句読点: 末尾に句点は不要 +- 例外: Dependabot が自動生成するコミット・PR(`.github/dependabot.yml` による依存更新)は `[update]` プレフィックス+英語本文(例: `[update] Bump foo from 1.2.0 to 1.3.0`)を許容し,手で書き直さない ### タグ一覧 diff --git a/.claude/rules/progress-log.md b/.claude/rules/progress-log.md index cd788a3..4e4fa8d 100644 --- a/.claude/rules/progress-log.md +++ b/.claude/rules/progress-log.md @@ -7,6 +7,7 @@ `CLAUDE.md` の「開発進捗」セクションと `docs/PROGRESS.md` を更新するときは本ルールに従うこと. > ⚠ **チーム開発モード(team)では本ルールは上書きされる**.team プロジェクトでは進捗を `CLAUDE.md`・`docs/PROGRESS.md` に書かず,GitHub Issues と git 履歴で追う([GUIDE_03](../../docs/01_GUIDE/GUIDE_03_チーム開発ルール.md)).以下は個人開発モード(solo)の既定ルールである.team モードでは Phase 4 の進捗更新を Issue コメント(`/task-handoff` 等)に置き換える. +> なお solo モードでも `/task-create` 等で Issue によるタスク管理を併用してよい.その場合も本ルールの進捗記録(`CLAUDE.md` 進捗欄+ `docs/PROGRESS.md`)は従来どおり行い,Issue はタスクの管理・引継ぎの補助として扱う. ## 二段構成 (Two-tier Structure) diff --git a/.claude/rules/template-customization.md b/.claude/rules/template-customization.md new file mode 100644 index 0000000..8e62ef2 --- /dev/null +++ b/.claude/rules/template-customization.md @@ -0,0 +1,31 @@ +--- +paths: [".claude/agents/**", ".claude/skills/**", ".claude/rules/**", ".claude/hooks/**", "docs/01_GUIDE/**"] +--- + +# テンプレート由来ファイルの改変記録ルール (Template Customization Rules) + +テンプレート(programming-template)由来のファイルを**このプロジェクトの都合で**変更するときは本ルールに従い,`.claude/template-overrides.md`(テンプレート改変台帳)に記録すること.記録が無いと次回の `/sync-template` で改変が検出・確認の対象になり,判断を誤るとテンプレート版で上書きされて改変が失われる. + +## 適用条件 (Scope) + +- テンプレートから派生したプロジェクト(`.claude/template-sync-sha` が存在する)でのみ適用する.テンプレートリポジトリ自身の編集では不要 +- **対象(テンプレートが管理するファイル)**: `.claude/agents/`,`.claude/skills/`(テンプレート提供の skill),`.claude/rules/`(`git-conventions`・`markdown-style`・`docs-naming`・`progress-log`・本ルール等,テンプレート由来のもの),`.claude/hooks/`,`docs/01_GUIDE/`(`GUIDE_01`〜`GUIDE_03`) +- **対象外**: + - プロジェクトが新規に作ったファイル(立ち上げ時に作成するコーディング規約 rule,プロジェクト独自の skill / agent 等).テンプレートに存在しないので同期で上書きされない + - `CLAUDE.md`・`.gitignore`・`docs/PROGRESS.md`・`.gitattributes`・`.claude/settings.json`.これらは `/sync-template` の「マージ必須ファイル」として別途保護されており,台帳登録は不要 +- テンプレート由来かどうか判断に迷う場合は**記録する側に倒す**.余計な記録は `/sync-template` が「テンプレート側に存在しないパス」として警告してくれるが,記録漏れは改変の消失につながる + +## 手順 (Procedure) + +1. **変更する前に**,その変更が「プロジェクト固有の都合」か「テンプレート自体の改善」かを判断する + - テンプレート自体の改善(誤記修正,全プロジェクトに有益な手順改善等)であれば,テンプレートリポジトリ側で直すべきことをユーザーに伝える.プロジェクト側で先に直す場合も,テンプレート側の修正に後から追従できるよう台帳には `merge` で登録する +2. **変更後**,`.claude/template-overrides.md` の「台帳」表に 1 行追加する(既に行があるファイルは理由を最新化する).書式・方針(`keep` / `merge` / `ask`)の定義は同ファイルの「記録ルール」節に従う + - 方針は,テンプレート側の改善も今後取り込みたいなら `merge`(既定.改変箇所とテンプレートの差分が別の箇所なら自動で両立する),完全に別物にしたなら `keep`,都度判断したいなら `ask` + - 理由は「なぜテンプレートと変えたか」を 1 文で書く.次回同期時の判断材料になる +3. 改変をやめてテンプレートに追従するときは,台帳から行を削除する(次回 `/sync-template` で上書き/マージされる) + +## 禁止事項 (Prohibitions) + +- 台帳に記録せずにテンプレート由来ファイルを改変したままにしない +- 台帳の書式を崩さない(`/sync-template` が機械的に読む) +- 台帳ファイル自体の「記録ルール」節の説明文を削除しない(他メンバー・将来の自分が読む) diff --git a/.claude/settings.json b/.claude/settings.json index 3b0ffd7..b06d6ff 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,4 +1,9 @@ { + "permissions": { + "allow": [ + "Bash(gh pr merge:*)" + ] + }, "hooks": { "PreToolUse": [ { diff --git a/.claude/skills/auto-audit/SKILL.md b/.claude/skills/auto-audit/SKILL.md index 3137e70..f486cc0 100644 --- a/.claude/skills/auto-audit/SKILL.md +++ b/.claude/skills/auto-audit/SKILL.md @@ -1,6 +1,6 @@ --- name: auto-audit -model: opus +model: inherit description: "放置中(無人)に自律的に回り続け,空き時間をコードベース全体の「バグ発見」と「脆弱性発見」に充てる巡回ループ.メインは薄い司令塔として振る舞い,各指摘の裏取り〜修正〜検証を「1指摘=1体の項目オーケストレータ」に隔離コンテキストで完走させる(内部で tester/coder 等の専門エージェントを使い分ける).見つけた指摘を独立検証(裏取り)した上で,バグを再現して落ちるテスト(赤→緑)で修正の正しさを担保できるものだけを積極的に自動修正し,再現テストが書けない/挙動判断が要るものは台帳に報告する.影響範囲を解析し,各修正について人間が行うべき動作確認を添えて報告する.専用ブランチ(fix/)へ自律コミットするが push・PR・マージはしない." argument-hint: "[bug|security|all(省略時 all)] [対象ディレクトリ/モジュールの絞り込み(省略可)]" --- @@ -59,13 +59,23 @@ 11. **疑わしきは報告に落とす**:判断に迷う・裏取りで確信が持てない・再現テストが書けない・影響が追い切れない・テストコマンドが特定できない場合は,**無理に直さず報告のみ**にする(報告台帳へ).修正よりも「新規バグを埋め込まないこと」を優先する. 12. **仕様・意図を推測で塗り替えない**:「これは仕様かバグか」の判断が要るものは自動修正しない.コードのコメントやドキュメントが示す意図に明確に反している場合のみ「バグ」と扱い,判断が割れるものは報告に回す. +## advisor への相談(`/consult`)— 上限付きで許可 + +不変条件 11・12 で「報告に落とす」と判断する前に,**項目オーケストレータ**は `/consult`(advisor エージェント・Fable)に相談してよい.無人で Fable が回り続けるのを防ぐため以下を厳守する. + +- **上限**: 1 ループ実行(`/auto-audit` の 1 起動)あたり **3 回まで**,かつ **1 指摘につき 1 回まで**.メインは相談回数を台帳に記録し,3 回に達したら以降の指摘は相談せずに従来どおり報告に落とす +- **相談してよい論点**: 「仕様かバグか」の判定,修正案が複数あって影響範囲の広さで迷う場合,のみ.裏取り(ゲート①)や調査の代わりには使わない +- **結論の扱い**: advisor の確信度が**高**のときだけ,その結論に従って修正に進んでよい(4 ゲートはそのまま通す).確信度が中・低なら報告に落とし,advisor の結論・根拠を報告行に添える(人間の判断材料にする) +- advisor の助言は不変条件・除外リストを上書きしない(除外領域は相談しても触らない) +- 相談した指摘は台帳に「advisor 相談済み」と記す(次回の再相談を防ぐ) + ## 対象外の領域(除外リスト) — 修正対象に選ばない 以下は無人で触ると事故りやすい,あるいは本コマンドの責務外のため,**自動修正の対象に選ばない**.発見フェーズで指摘が出ても,修正はせず(重大なら報告のみに落とし)スキップする. - 自動生成コード(コードジェネレータ出力,`*.g.dart`,`*.pb.go`,スナップショット等) - 依存・サードパーティ(`node_modules/`,`vendor/`,`.dart_tool/`,`target/`,ベンダリングされた外部ソース) - - ただし**依存の既知 CVE**(脆弱性観点)は,コードを書き換えるのではなく「どの依存をどのバージョンに上げるべきか」を**報告**する(バージョン更新の自動適用はしない.挙動変化・破壊的変更のリスクがあるため). + - ただし**依存の既知 CVE**(脆弱性観点)は,コードを書き換えるのではなく「どの依存をどのバージョンに上げるべきか」を**報告**する(バージョン更新の自動適用はしない.挙動変化・破壊的変更のリスクがあるため).Dependabot alerts が有効なら同じ CVE は Dependabot 側でも検出されるので,報告時に「`/deps-update` で処理できる」旨を添える. - ロックファイル・依存マニフェスト(`package-lock.json`,`yarn.lock`,`pubspec.lock`,`Cargo.lock`,`go.sum` 等) - マイグレーション・スキーマ履歴(適用済みの DB マイグレーション等) - 設定・秘匿情報ファイル(`.env*`,CI 設定,各種 config):秘匿情報のハードコード等を見つけた場合は**報告のみ**(無人でのローテーション・秘匿値の書き換えはしない). diff --git a/.claude/skills/auto-refactor/SKILL.md b/.claude/skills/auto-refactor/SKILL.md index ebd9ecb..f154b52 100644 --- a/.claude/skills/auto-refactor/SKILL.md +++ b/.claude/skills/auto-refactor/SKILL.md @@ -1,6 +1,6 @@ --- name: auto-refactor -model: opus +model: inherit description: "放置中(無人)に自律的に回り続け,空き時間をコード/ドキュメント/テストの整理に充てるループ.メインは薄い司令塔として振る舞い,各作業項目を「1項目=1体の項目オーケストレータ」に隔離コンテキストで完走させる(内部で tester/refactorer 等の専門エージェントを使い分ける).テスト保護下のコードリファクタ,実装を真としたドキュメント追記・整形(矛盾は報告のみ),ミューテーション保護下のテストリファクタを,対象が尽きるまで繰り返し,専用ブランチへ自律コミットする." argument-hint: "<対象ディレクトリ/モジュールの絞り込み(省略可)>" --- @@ -59,6 +59,16 @@ 11. **ドキュメントリファクタは「意味保存」が絶対条件**:自動で行ってよいのは**意味・情報を保ったままの品質改善**だけ.具体的には ①無損失整形(表記揺れの統一・書式/見出し/表の整形・リンクや参照の修正・明らかなタイポ)と,②**意味を保った簡潔化・重複の集約**(冗長な言い回しを短くする,同一内容の重複を1か所に集約して他はリンクする).**消してはいけないもの**=事実・決定事項・設計判断(なぜその案にしたか)・失敗パターン・具体的な制約や閾値.これらが落ちる「陳腐化記述の削除」や「大規模な再編」は自動で行わず,要確認リストに**提案として記録**する.意味保存を自動検証する手段は無いため,迷ったら削らない(残す側に倒す). 12. **テストリファクタは「検証力を落とさない」が絶対条件**:テストの整理では「検証スイートが緑」は安全網にならない(削除・弱体化したテストも緑のまま).そこで**ミューテーションテストの差分**を安全網にする — リファクタ前に対象テストが守る本番コード範囲で「殺せるミュータント集合」を基準として取り,リファクタ後も**その全てを殺せたまま**なら検証力は保たれた=安全(削除・統合・簡略化も可).1つでも生存に転じたら検証力低下なので破棄する.ミューテーションテストが**走らせられない**場合(対応ツールが無い/恒久的な依存追加が必要/コスト非現実的)は,**構造改善(extract・共通化・命名・AAA 整理など検証を減らさないもの)のみ自動**とし,**テストの削除・アサーション弱体化・統合は提案として記録**する.テストコードへの自動編集はこのテストリファクタ処理(T)でのみ行う(コードリファクタ R はテストを触らない). +## advisor への相談(`/consult`)— 上限付きで許可 + +不変条件 9 で「停止/skipped」と判断する前に,**項目オーケストレータ**は `/consult`(advisor エージェント・Fable)に相談してよい.無人で Fable が回り続けるのを防ぐため以下を厳守する. + +- **上限**: 1 ループ実行(`/auto-refactor` の 1 起動)あたり **3 回まで**,かつ **1 項目につき 1 回まで**.メインは相談回数を記録し,3 回に達したら以降の項目は相談せずに従来どおり skipped/提案記録に落とす +- **相談してよい論点**: リファクタ案が複数あり設計方針で迷う場合,ドキュメント簡潔化で「意味保存か情報損失か」の線引きに迷う場合,のみ.調査や候補探索の代わりには使わない +- **結論の扱い**: advisor の確信度が**高**のときだけ,その結論に従って作業に進んでよい(安全網=テスト緑・ミューテーション差分はそのまま必須).確信度が中・低なら作業せず,advisor の結論・根拠を要確認リストの `[提案]` 行に添える +- advisor の助言は不変条件・除外リストを上書きしない(矛盾の自動書き換え・除外領域への編集は相談しても行わない) +- 相談した項目は要確認リスト等に「advisor 相談済み」と記す(次回の再相談を防ぐ) + ## 対象外の領域(除外リスト) — コードリファクタの対象に選ばない 以下は無人で触ると事故りやすく,かつリファクタの価値が薄いため,**コードリファクタの対象に選ばない**.発見・選定時に必ず除外する. diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md index 9e95832..aa1eb34 100644 --- a/.claude/skills/commit/SKILL.md +++ b/.claude/skills/commit/SKILL.md @@ -6,85 +6,43 @@ disable-model-invocation: true --- -あなたは Git 運用の担当者です.Git 規約 `.claude/rules/git-conventions.md` に従い,現在の変更をコミットしてください. -push・PR・マージの詳細手順とトラブル対応は本スキルの `reference.md`(`.claude/skills/commit/reference.md`)を参照する. -確認は不要.すべてのステップを一気に実行すること. +あなたは Git 運用の司令塔です.コミット作業の実行は **ops-runner エージェント**(軽量モデル)に委譲し,あなた自身は**判断**(意図・docs 更新の要否)・確認の仲介・結果の報告だけを行います(使用量節約のため,diff 読みや git 操作を自分では行わない.逆に価値判断は ops-runner にさせない). -## ステップ 1: 状態確認 +## ステップ 1: 意図サマリと docs 要否の判断 (Intent & Docs Decision) -以下のコマンドで現在の状態を把握する. +このセッションで行った作業を把握している場合は,以下を作る(**判断はここで行う**): -- `git branch --show-current` で現在のブランチを確認 -- `git status` で変更ファイルの一覧を確認 -- `git diff` および `git diff --cached` で変更内容を確認 +- **意図サマリ**(1〜3 行): 何をなぜ変更したか(コミットメッセージの材料).重要な変更なら `.claude/rules/git-conventions.md` の書式でメッセージ全文を確定させてもよい +- **docs 更新の要否**(3 択): 変更が API・データ構造・環境設定・開発計画の進捗・規約やルールに関わるかを,セッションの知識で判断する + - **更新済み**: 今回の変更に `docs/`・CLAUDE.md「開発進捗」・`docs/PROGRESS.md` の更新も含めてある + - **不要**: 該当しない + - **要**: 委譲する前に必要な更新を行う(内容に迷う場合はユーザーに確認する).docs を同じコミットに含めるため +- **ブランチ名**: 現在 `main` にいる可能性がある場合は,git-conventions の命名規則(プレフィックス+英単語 2〜4 語)でブランチ名を決めて渡す(ops-runner に命名させない) +- `.claude/commit-context.md` がある場合(`/implement` 経由)は,そこに記録された判断を正とし,改めて判断しない -**main ブランチにいる場合は自動でブランチを作成する:** +セッションを把握していない場合(起動直後の `/commit` 等)は「意図情報なし・要否は事後判断」とする. -1. 変更内容から `.claude/rules/git-conventions.md` のブランチ命名規則に従い,適切なプレフィックスと英単語 2〜4 語のブランチ名を決定する -2. `git checkout -b {ブランチ名}` で作業ブランチを作成する -3. 以降のステップを続行する +## ステップ 2: 委譲 (Delegate) -## ステップ 2: docs/ 更新漏れチェック +ops-runner エージェントを起動し,プロンプトに以下を含める: -`.claude/commit-context.md` が存在し `docs_updated` が記録されている場合,このステップをスキップする. +- 手順書: `.claude/skills/commit/reference.md` の「コミット実行手順」と `.claude/rules/git-conventions.md` を読んで従うこと +- ステップ 1 の意図サマリ(またはメッセージ全文).意図情報なしの場合はその旨 +- $ARGUMENTS(`push` / `merge` キーワードの有無を明示する) +- 確認が必要な事態では停止して報告すること -ファイルが存在しない場合(`/implement` を経由していない場合),変更内容を確認し,以下に該当するにもかかわらず docs/ が更新されていない場合は警告する: +## ステップ 3: 結果報告 (Report) -- API やデータ構造の変更 -- 環境設定の変更 -- 開発計画の進捗に関わる変更 -- 規約やルールに関わる変更 +- エージェントの報告(ブランチ・コミット SHA・メッセージ・PR URL 等)をユーザーに簡潔に伝える +- **意図情報なしで委譲した場合**は,エージェントの「事実報告」(変更ファイルの分類)を見て docs 更新の要否を事後判断し,必要と思われれば「⚠ docs/・CLAUDE.md の開発進捗・`docs/PROGRESS.md` の更新が必要かもしれません」とユーザーに伝える(追加コミットで対応してよい) +- エージェントが返した警告(意図と diff の食い違い等)はそのまま表示し,判断はユーザーに委ねる +- エージェントが「確認事項」で停止した場合は,ユーザーに確認し,回答を「承認済み」として添えて再委譲する + - ただし停止理由が**分類器ブロック**(auto mode のセキュリティ分類器により,コマンドが実行される前に遮断された)の場合は,再委譲しても同じ地点で止まるため**再委譲しない**.`.claude/settings.json` の `permissions.allow` の確認・追加とセッション再起動をユーザーに案内して終了する(詳細は `.claude/skills/commit/reference.md` の「gh コマンドが実行される前にブロックされた場合」を参照) +- **ops-runner の起動(Agent ツール呼び出し)自体が分類器にブロックされた場合**は,委譲そのものが成立しない(プロンプトの文言を変えても通らない.`.claude/settings.json` の permissions 変更を含む変更のコミットを委譲したところ,Agent 起動が 2 回ブロックされた実測例がある).この場合は状況をユーザーに伝え,**ユーザーの承認を得た上で**次のいずれかで進める + - 司令塔(メインループ)が直接コミット操作を行う(メインループからは同じ操作が通ることを確認済み).これは冒頭の「git 操作を自分では行わない」原則の**例外**とする + - ユーザーが `! git ...` で手動コミットする -該当がある場合,「⚠ docs/ の更新が必要かもしれません.確認してください.」と警告する. -更新自体は行わず,ユーザーの判断に委ねる. +## 注意事項 (Notes) -## ステップ 3: コミットメッセージの生成 - -変更内容と $ARGUMENTS(指定がある場合)をもとに,`.claude/rules/git-conventions.md` の「コミットメッセージ」セクションに従ってコミットメッセージを生成する. - -## ステップ 4: CLAUDE.md / PROGRESS.md 更新漏れチェック - -`.claude/commit-context.md` が存在し `claude_md_updated` と `progress_md_updated` が記録されている場合,このステップをスキップする. - -ファイルが存在しない場合(`/implement` を経由していない場合),変更内容に応じて以下の更新が必要か判断する: - -- CLAUDE.md の「開発進捗」セクション(最新 1 行) -- `docs/PROGRESS.md`(追記型フルログ) - -更新されていない場合は「⚠ CLAUDE.md の開発進捗 / docs/PROGRESS.md の更新が必要かもしれません.確認してください.」と警告する. -更新自体は行わず,ユーザーの判断に委ねる. - -## ステップ 5: コミット - -以下を実行する: - -1. `git add` で関連ファイルをステージングする(CLAUDE.md / `docs/PROGRESS.md` の変更がある場合はそれも含める) -2. `git commit -m "{コミットメッセージ}"` でコミットする -3. `.claude/commit-context.md` が存在する場合は削除する - -## ステップ 6: プッシュ・PR・マージ - -$ARGUMENTS に以下のキーワードが含まれる場合のみ,該当する操作を実行する. -**いずれも含まれない場合はこのステップ全体をスキップする.** - -| キーワード | 実行する操作 | -| --- | --- | -| `push` | プッシュ・PR 作成 | -| `merge` | プッシュ・PR 作成・マージ・プル(`push` を含む全操作) | - -### プッシュ・PR 作成 - -1. `git push origin {ブランチ名}` でリモートにプッシュする -2. PR の状態を確認する: - - **既存の PR がある場合**: PR の URL を表示して完了 - - **PR がない場合**: `reference.md` の「プルリクエスト (PR) の作成」に従い PR を作成し,URL を表示する - -### マージ・プル(`merge` の場合のみ) - -1. `reference.md` の「マージの実行」に従いマージする -2. `reference.md` の「ローカル環境のクリーンアップ」に従いローカルを最新化する - -## 注意事項 - -- `.env` やクレデンシャルファイルはステージングしない -- 変更がない場合(`git status` がクリーン)は空コミットせず,その旨を伝えて終了する +- 変更がない場合(作業ツリーがクリーン)は空コミットしない(エージェントの報告どおり伝えて終了する) +- 本スキルはユーザーが明示的に指示した時のみ実行する(CLAUDE.md「Git 運用」) diff --git a/.claude/skills/commit/reference.md b/.claude/skills/commit/reference.md index ce0dd41..19be2d8 100644 --- a/.claude/skills/commit/reference.md +++ b/.claude/skills/commit/reference.md @@ -1,8 +1,52 @@ # Git 開発フロー・トラブルシューティング (Git Workflow Reference) -`/commit` の push・PR・マージ処理で参照する詳細手順と,問題発生時の対処手順. +`/commit` の実行フェーズ(ops-runner が担当)で参照する実行手順・push・PR・マージの詳細手順と,問題発生時の対処手順. ブランチ命名・コミットメッセージ等の規約は `.claude/rules/git-conventions.md` に従う. +## コミット実行手順 (Commit Execution Flow) + +`/commit` の司令塔(メインループ)から委譲された ops-runner が実行する手順.ユーザーへの確認は不要,全ステップを一気に実行する(停止条件に該当した場合を除く). + +### ステップ 1: 状態確認 + +- `git branch --show-current` で現在のブランチを確認 +- `git status` で変更ファイルの一覧を確認 +- `git diff` および `git diff --cached` で変更内容を確認 +- 変更がない場合(クリーン)は空コミットせず,その旨を報告して終了する + +**main ブランチにいる場合は自動でブランチを作成する:** + +1. 司令塔からブランチ名が渡されていればそれを使う.渡されていなければ,変更内容から git-conventions のブランチ命名規則に従い適切なプレフィックスと英単語 2〜4 語のブランチ名を決め,決めた名前を報告に含める +2. `git checkout -b {ブランチ名}` で作業ブランチを作成する + +### ステップ 2: ドキュメント関連の事実収集 + +docs 更新の要否の**判断はしない**(司令塔が行う).以下の事実を最終報告の「事実報告」に含める: + +- `.claude/commit-context.md` の有無と,あれば記録されたフラグ(`docs_updated` / `claude_md_updated` / `progress_md_updated`) +- 変更ファイルの分類: `docs/` 配下・`CLAUDE.md`・`docs/PROGRESS.md` のそれぞれを含むか,およびそれ以外の変更ファイル一覧 + +### ステップ 3: コミットメッセージの生成 + +上位から渡された意図サマリ・引数と変更内容をもとに,git-conventions の「コミットメッセージ」書式で生成する.上位がメッセージ全文を確定して渡した場合はそのまま使う.意図サマリと実際の diff に食い違いがある場合は,diff を正としつつ食い違いを「警告」に含める. + +### ステップ 4: コミット + +1. `git add` で関連ファイルをステージングする(CLAUDE.md / `docs/PROGRESS.md` の変更がある場合はそれも含める.`.env` やクレデンシャルファイルはステージングしない) +2. `git commit -m "{コミットメッセージ}"` でコミットする +3. `.claude/commit-context.md` が存在する場合は削除する + +### ステップ 5: プッシュ・PR・マージ + +上位から渡された引数に以下のキーワードが含まれる場合のみ実行する(いずれも無ければスキップ). + +| キーワード | 実行する操作 | +| --- | --- | +| `push` | プッシュ・PR 作成 | +| `merge` | プッシュ・PR 作成・マージ・プル(`push` を含む全操作) | + +手順は後述「開発フロー」に従う(push → PR 作成(既存 PR があれば URL の確認のみ)→ `merge` の場合はマージの実行 → ローカル環境のクリーンアップ).コンフリクト等の問題が起きた場合は「トラブルシューティング」を参照し,意味的な衝突の解消や force push を伴う操作は停止して報告する. + ## 開発フロー (Development Workflow) 作業ブランチをリモートへ送り,`main` にマージされるまでの手順. @@ -35,19 +79,21 @@ - マージ方式は「Create a merge commit」を使用する(作業ブランチの全コミット履歴が `main` に残る). - 「Squash and merge」「Rebase and merge」は使用しない. +- **先に `main` へ移ってから**マージする.PR ブランチ上で `--delete-branch` を実行すると gh が暗黙に `main` への切替と pull を行い,ブランチ削除より前に pull が走る(post-merge hook 等の後処理が削除前の状態を見てしまう).手順を明示的にして順序を固定する. +- ブランチ保護・必須レビュー・必須チェック未完了でマージが拒否された場合も,`gh pr merge --admin` で迂回しない(状況を報告して停止する). ```bash -gh pr merge --merge --delete-branch +git checkout main +gh pr merge feature/new-function --merge --delete-branch # リモート・ローカルのブランチも削除される ``` ### ローカル環境のクリーンアップ -マージ完了後はローカル環境も最新状態に戻し,古いブランチを削除する. +マージ完了後はローカルの `main` を最新化する(ブランチ削除の後に pull する順序を守る). ```bash -git checkout main git pull origin main -git branch -d feature/new-function +git branch -d feature/new-function # gh が削除済みなら不要(残っていた場合のみ) ``` ## トラブルシューティング (Troubleshooting) @@ -98,6 +144,17 @@ git push --force-with-lease origin feature/new-function ``` +### gh コマンドが実行される前にブロックされた場合 + +`gh pr merge` 等が実行される前に遮断され,`gh` の出力が返ってこない場合は,auto mode のセキュリティ分類器によるブロックである.リポジトリ側の制約(ブランチ保護・必須レビュー・権限不足)とは原因が異なるため,混同して報告しない. + +- **見分け方**: リポジトリ側の制約ならコマンドは実行され `gh` がエラーメッセージを返す.分類器ブロックではコマンド自体が実行されない. +- **対処**: `.claude/settings.json` の `permissions.allow` に `Bash(gh pr merge:*)` があるか確認する.無ければ**ユーザーが追加**し,セッションを再起動する(permissions の変更は再起動後に反映される.現状は Claude 自身が `settings.json` の permissions を編集することも分類器にブロックされるため,自分では追加できない). + - 追加の経路は 2 つある: `settings.json` を手で編集する,または `/permissions` ダイアログから allow ルールを追加する. + - auto mode では `Bash(gh *)` のような広い allow ルールは分類器に回されるため効かない.`Bash(gh pr merge:*)` のように**操作を特定した狭いルール**にする必要がある. + - ※ `~/.claude/settings.json`(ユーザー設定)に `autoMode.classifyAllShell: true` が設定されている場合は,狭い allow ルールも含めすべてのシェルコマンドが分類器に回るため,この対処自体が効かない.allow ルールを追加しても通らないときは,まず該当設定の有無を確認する. +- **やってはいけないこと**: 別コマンドでの迂回(`main` への直接 push 等)や,設定を緩めての強行.ブロックされた事実と対処法をそのままユーザーに伝えて停止する. + ### 間違えて main にコミットしてしまった場合 **まだプッシュしていない場合** diff --git a/.claude/skills/consult/SKILL.md b/.claude/skills/consult/SKILL.md new file mode 100644 index 0000000..3e75619 --- /dev/null +++ b/.claude/skills/consult/SKILL.md @@ -0,0 +1,66 @@ +--- +name: consult +model: inherit +description: "重要な価値判断・設計判断を最上位モデル(Fable)に相談する.メインのモデルは切り替えず,advisor エージェント(Fable)を新規の小さいコンテキストで起動するため,プロンプトキャッシュを壊さず低コストで判断力だけを借りられる.Claude が自発的に使ってよいのは (a) 不可逆な設計判断(アーキテクチャ・スキーマ・外部サービス・公開 API の形)の直前,(b) 同じ失敗が 2 回続き次の方針に自信が無いとき,(c) ユーザーの明示指示,のいずれかに限る.1 タスクあたり 2 回まで.ルールで既に決まっている事項・すぐ決まる二択・単なる調査には使わない." +argument-hint: "<相談したい論点(省略時はセッションの文脈から構成する)>" +--- + +あなたは相談の司令塔です.価値判断そのものは **advisor エージェント**(Fable)に委ね,あなたは**ブリーフの作成**と**結果の中継**を行います.メインループのモデルは切り替えない(会話全体の再読込が発生するため).advisor は新規の小さいコンテキストで動くので,Fable の単価でもコストはブリーフ+参照ファイル+思考分だけに収まる. + +## ステップ 1: ブリーフ作成 (Brief) + +**ここが品質の要**.advisor はこの会話を一切知らないため,$ARGUMENTS とセッションの文脈から**自己完結のブリーフ**を書く: + +- **論点**: 何を判断してほしいか(1 文で) +- **背景・制約**: プロジェクトの状況と,これまでの経緯のうち判断に関わる事実(重要な前提を省略しない) +- **選択肢**: 検討済みの選択肢と各々の長所・短所.**自分(メイン)の暫定意見と理由**も添える +- **判断基準**: 何を重視するか(保守性・コスト・納期・学習目的 等) +- **参照ファイル**: 相対パスで列挙する(advisor が自分で読む.長文の貼り込みはしない) + +## ステップ 2: 委譲 (Delegate) + +advisor エージェントを起動し,ブリーフを渡す.出力書式(結論・根拠・リスク・盲点・確信度)はエージェント定義にあるため指定不要. + +- advisor が「前提の確認」を返した場合は,前提を補足して再委譲する +- 回答がブリーフの前提を誤解している場合も同様に補足して再委譲する + +## ステップ 3: 報告 (Report) + +- advisor の回答(結論・根拠・リスク・盲点・確信度)を**要約せずそのまま**ユーザーに提示する +- 自分の暫定意見と advisor の結論が食い違う場合は,その旨と自分の見解を明示する(隠さない) +- 最終決定はユーザーが行う.advisor の結論を自動で実行に移さない + +## 自発的に呼ぶ基準 (Auto-Invocation Criteria) + +Claude はユーザー指示が無くても,以下の**いずれか**に該当するときは本スキルを自発的に使ってよい.組み込みの `/advisor`(会話全体を上位モデルに読ませる)ではなく本スキルを使うのは,ブリーフ+参照ファイル分のコンテキストだけで済ませてコストを抑えるため. + +**呼ぶ** + +| トリガー | 判定の目安 | +| --- | --- | +| 不可逆な設計判断 | アーキテクチャ・DB スキーマ・外部サービス選定・公開 API の形など,後から変えるとコードの広範囲に波及するものを決める直前 | +| 行き詰まり | 同じ失敗(テスト失敗・エラー)が **2 回**続き,3 回目の方針に自信が無い | +| ユーザー指示 | 「advisor に聞いて」「相談して」等の明示 | + +**呼ばない** + +- `.claude/rules/` や docs で既に決まっている事項(ルールに従えばよい) +- 数分で決まる二択,命名,小さなリファクタ +- 単なる調査・情報収集(advisor は判断役であって検索役ではない.調査は Explore 等を使う) +- 同じ論点で既に advisor の回答を得ている(再相談は前提が変わったときだけ) +- 大きなタスクの完了前チェック(人間の動作確認で代替する.自動では呼ばない) + +## 暴走の歯止め (Cost Guardrails) + +Fable の呼び出しは相対的に高コストのため,自発的に呼ぶときは以下を守る. + +- **上限**: 1 タスク(ユーザーからの 1 回の依頼)につき**自発的な呼び出しは 2 回まで**.3 回目が必要だと感じたら,呼ばずにユーザーへ「advisor に相談してよいか」を確認する +- **再委譲**: 前提の補足によるやり直しは **1 回まで**.それでも噛み合わなければ得られた回答をそのまま報告し,判断を人間に戻す +- **参照ファイル**: ブリーフに列挙するのは **5 ファイル程度**を目安に絞る(advisor の読み込み分がコストの主因) +- **可視化**: 呼ぶ前に必ず「advisor に相談します: <論点 1 行>」と表示する(黙って呼ばない) +- **無人ループ**: `/auto-refactor`・`/auto-audit` の中から呼ぶ場合は,各 skill に定める上限(1 ループ実行あたり 3 回・1 項目 1 回)に従う + +## 注意事項 (Notes) + +- ブリーフに書かれていない事情は判断に反映されない.「advisor は会話を知らない」前提で書くこと +- 軽い相談(すぐ決められる二択等)に使う必要はない.アーキテクチャ選定・不可逆な決定・トレードオフが深い論点に使う diff --git a/.claude/skills/deps-update/SKILL.md b/.claude/skills/deps-update/SKILL.md new file mode 100644 index 0000000..7354ac4 --- /dev/null +++ b/.claude/skills/deps-update/SKILL.md @@ -0,0 +1,104 @@ +--- +name: deps-update +model: inherit +description: "Dependabot が作成した依存更新 PR(security updates / version updates)と,PR が付かない Dependabot alerts をまとめて処理する.メジャー更新でない・競合なし・CI 緑(またはローカル検証緑)のゲートを満たす PR だけを gh pr merge で main に取り込み,メジャー更新・CI 赤・修正版なしの alert 等は影響分析と推奨対応を添えて台帳と PR コメントに報告する.ユーザーが明示的に起動した時のみ実行する(/loop でのラップ可)." +argument-hint: "[merge|report(省略時 merge)] [PR 番号…(省略時は全 Dependabot PR)]" +--- + +あなたは**依存更新(Dependabot)処理の司令塔**です. +`/setup` で有効化した Dependabot alerts / security updates と,`.github/dependabot.yml` による version updates が作る PR・alert を,「安全なものは取り込み,判断が要るものは材料を揃えて報告する」ために起動されました. +実際の gh 操作・検証・マージ・台帳更新は **ops-runner エージェント**(軽量モデル)に,個別の影響分析は **deps-analyst エージェント** に委譲し,あなたは振り分けと完了報告に徹します(使用量節約のため,収集・検証・投稿を自分では行わない). + +## 不変条件 (Invariants) + +全文は本スキルの `reference.md`(`.claude/skills/deps-update/reference.md`)冒頭の「不変条件」にある.**委譲する全エージェントのプロンプトに「reference.md の不変条件を読み厳守すること」を必ず含める**.あなた自身が振り分けで守るべき要点: + +- 触るのは Dependabot(author `app/dependabot`)の open PR だけ +- **メジャー更新(`0.x` マイナー・`unknown` 含む)は自動マージしない**.検証(CI 緑またはローカル検証)無しにマージしない +- Dependabot PR を close しない.`@dependabot ignore` は人間の決定(推奨として提示するだけ) +- ユーザーが起動した時だけ動く(Claude が自発的に本スキルを呼んではならない.`/loop /deps-update` でのラップはユーザー起動とみなす) + +## 引数 (Arguments) + +`$ARGUMENTS` を次のように解釈する: + +- 先頭トークンが `report` なら**報告のみモード**(マージも PR コメントもしない.分析結果を完了報告と台帳に書くだけ).`merge` または省略なら**通常モード**(ゲートを満たすものをマージし,残りを報告する) +- 残りのトークンに `#12` / `12` 形式の番号があれば,その PR だけを対象にする(省略時は open な Dependabot PR すべて) + +## フェーズ 1: 収集・分類 (Collect & Classify) + +ops-runner エージェントを起動し,プロンプトに以下を含める: + +- 手順書: `reference.md` の「不変条件」と「実行手順 A: セットアップと収集」を読んで従うこと +- 対象 PR 番号の指定(あれば) + +返ってくるもの: 前提状態(Dependabot 設定・CI の有無・検証スイート・開始ブランチ)・分類付き PR 一覧(規模・スコープ・種別・状態・CI 状況)・alert 一覧・台帳の既出/スキップ情報. + +- 作業ツリーが汚れている・`gh` 未認証・リモートが GitHub でない等の停止報告が来たら,処理を開始せずユーザーに伝えて終了する +- Dependabot 設定が無効・`dependabot.yml` 不存在なら処理は続け,完了報告で `/setup` の「GitHub リポジトリのセキュリティ設定」「依存バージョン更新の設定」を案内する + +## フェーズ 2: 振り分け (Route) + +フェーズ 1 の結果を判定表で振り分ける.`deps-update-skip.md` 該当は除外(件数だけ完了報告へ),台帳既出の報告項目は再分析しない. + +| 更新規模 | Tier A(CI 緑 / ローカル検証緑) | Tier B(ビルド・型チェックのみ) | Tier C(検証不能) | +| --- | --- | --- | --- | +| `patch` | マージ | マージ | 報告 | +| `minor` | マージ | 報告 | 報告 | +| `major` / `0.x` マイナー / `unknown` | 報告(分析付き) | 報告(分析付き) | 報告(分析付き) | + +- **マージ候補**(判定「マージ」の見込み)→ フェーズ 3.security update → パッチ → マイナー の順に並べる(security update もゲートは緩めない.グループ PR は全メンバーの最大規模で判定する) +- **分析行き**(「報告(分析付き)」・CI 赤・依存以外のファイル変更を含む PR)と **PR が付かない alert** → フェーズ 4 +- **競合(`CONFLICTING`)・`BEHIND`(CI あり)** → フェーズ 3 の委譲に「`@dependabot rebase` をコメントして今回は見送り」として含める(台帳には書かず,完了報告で「次回再試行」として伝える) +- **report モード** → フェーズ 3 を実行せず,マージ候補は「マージ可(未実行)」として完了報告と台帳に回す + +## フェーズ 3: 検証・マージ (Verify & Merge) + +マージ候補と rebase 依頼をまとめて 1 体の ops-runner エージェントに委譲する.プロンプトに含める: + +- 手順書: `reference.md` の「不変条件」と「実行手順 B: 検証とマージ」を読んで従うこと +- 対象 PR の一覧(処理順・各 PR の検証方法: CI 待ち / ローカル検証 / rebase 依頼のみ) +- **各 PR のマージ条件**(判定表から機械的に導いて明示する.ops-runner に判定表を解釈させない): `patch` → 到達 Tier が A または B なら可,`minor` → Tier A のみ可.Tier の定義: A=CI 全緑またはローカル検証(テスト含む)全緑,B=テストが無い/特定できないが依存インストールとビルド/型チェックは通る,C=検証不能 + +検証が赤・Tier 不足・検証不能になった PR はマージされずに戻ってくるので,フェーズ 4 の分析対象に加える. + +## フェーズ 4: 影響分析 (Analyze) + +分析行きの各項目について **deps-analyst エージェントを 1 件 1 体**で起動する(項目は互いに独立なので並列に起動してよい).プロンプトに含める: + +- 対象 PR / alert の収集データ(フェーズ 1・3 の結果から該当分.CI 赤の PR は失敗したチェックの要約も) +- 手順書: `reference.md` の「不変条件」「メジャー更新の影響分析」「PR コメントの書式」を読んで従うこと + +返ってきた分析(破壊的変更・影響箇所・推奨)に不足があれば追加調査を指示する. + +## フェーズ 5: 記録・コメント (Record) + +ops-runner エージェントを起動し,以下を委譲する: + +- `reference.md` の「台帳の書式」に従い,フェーズ 4 の分析結果を `deps-update-report.md` に追記する(既出は再記録しない.フェーズ 3 のマージ結果は実行手順 B 内で `deps-update-merged.md` に追記済み) +- 通常モードでは,分析済み PR へ「PR コメントの書式」でコメントを投稿する(`` マーカーが既にある PR には再投稿しない).report モードでは投稿しない + +## フェーズ 6: 完了報告 (Report) + +ユーザーに以下を報告する(台帳を根拠にする): + +- モード(merge / report)と対象 PR 数,Dependabot 設定の状態(無効なら `/setup` の該当手順を案内) +- **マージした PR**: 番号・パッケージと版・種別(security / version)・規模・検証 Tier(CI / ローカル / ビルドのみ).**人間が行うべき動作確認**があれば添える(例: UI ライブラリの更新は実機で表示確認) +- **⚠ 判断待ち(要人間対応)**: メジャー更新(影響分析・推奨対応付き)/CI 赤/修正版なし alert/Dependabot が PR を作れなかった alert.security 由来のものは **⚠ 優先** を付けて上に並べる +- 見送り: 競合で `@dependabot rebase` を依頼したもの,CI 待ちのもの(次回再試行),`deps-update-skip.md` によるスキップ件数 +- 次のアクション: 判断待ちの各項目について「PR をそのままマージ」「`/implement` で追従してからマージ」「`@dependabot ignore this major version` で見送り(人間がコメント)」のどれを推奨するか +- 後片付け: フェーズ 3 の報告から,開始ブランチへの復帰と作業ツリーがクリーンであることを確認して結果を含める + +team モードでは,マージした PR の一覧をチームに周知するよう促す(全員が `git pull` する.GUIDE_03). + +## /loop との併用 (Use with /loop) + +Dependabot は週 1 回(`dependabot.yml` の `interval`)まとめて PR を作るため,単発実行で十分なことが多い.放置中に取り込みたい場合は `/loop 1d /deps-update` のように日次でラップしてよい.対象が無い回は収集だけで即終了するので空回りのコストは小さいが,2 回連続で「マージ 0・新規報告 0」なら `/loop` を終了してよい. + +## 停止条件 (Stop Conditions) + +- 作業ツリーがクリーンでない/`gh` 未認証/リモートが GitHub でない → フェーズ 1 の停止報告を受けて,開始せずに報告 +- ローカル検証中にコンフリクト・環境エラーで検証が成立しない → その PR は Tier C として分析行きに回し,他の PR の処理は続ける +- `gh pr merge` が**リポジトリ側の制約**で失敗(ブランチ保護・必須レビュー・必須チェック未完了・権限不足) → その PR は報告に回し,失敗理由を伝える.team モードで「他メンバー Approve 必須」のブランチ保護が効いている場合は,本スキルはマージ可と判定した PR の一覧を提示するにとどめる +- `gh pr merge` が **auto mode の分類器にブロック**された(コマンドが実行される前に遮断され,`gh` の出力が返らない) → **環境側の制約であって,リポジトリ設定の問題ではない**(ブランチ保護と混同して報告しない).`.claude/settings.json` の `permissions.allow` に `Bash(gh pr merge:*)` があるか確認し,無ければ「ユーザーが手で追加してセッションを再起動する必要がある」と報告する(Claude 自身は permissions を編集できず,設定変更はセッション再起動後に反映される).該当 PR は「マージ可と判定したが未実行」として報告し,`main` への直接 push 等でマージを迂回しない + - ※ allow ルールの追加は `settings.json` の手編集のほか `/permissions` ダイアログからも行えるが,`~/.claude/settings.json` に `autoMode.classifyAllShell: true` があると狭い allow ルールも分類器に回るためこの対処は効かない(追加しても通らないときは該当設定の有無を確認する) diff --git a/.claude/skills/deps-update/reference.md b/.claude/skills/deps-update/reference.md new file mode 100644 index 0000000..715cc48 --- /dev/null +++ b/.claude/skills/deps-update/reference.md @@ -0,0 +1,226 @@ +# deps-update リファレンス (deps-update Reference) + +`/deps-update`(`SKILL.md`)から参照される,`gh` コマンド・GraphQL クエリ・分類規則・ローカル検証手順・台帳と PR コメントの書式.`{owner}/{repo}` は `gh` がカレントリポジトリから自動補完する. + +## 不変条件 (Invariants) + +`/deps-update` に関わる全エージェント(司令塔・ops-runner・deps-analyst)が厳守する. + +1. **触るのは Dependabot が作った PR だけ**: author が `app/dependabot` の open PR のみを対象にする.人間や他のボットの PR には一切操作しない +2. **`main` への取り込みは `gh pr merge --merge` のみ**: ローカルで `main` に直接コミット・push しない.依存ファイル(マニフェスト・ロックファイル)を自分で書き換えて別 PR を作ることもしない(競合やビルド失敗の解消は `@dependabot rebase` / `@dependabot recreate` コメントで Dependabot にやり直させる) +3. **ゲートを満たした PR だけをマージする**(SKILL.md「判定表」).**メジャー更新は自動マージしない**.検証(CI 緑またはローカル検証)無しにマージしない +4. **Dependabot PR を close しない**: 不要な PR の整理(supersede・`@dependabot ignore`)は Dependabot と人間に任せる.`@dependabot ignore ...` のコメントも自分では投稿しない(無視は人間の決定) +5. **作業ツリーを汚さない**: 開始時に作業ツリーがクリーンであることを確認し,ローカル検証で作ったブランチ・マージ状態は必ず破棄し,終了時に開始時のブランチへ戻す +6. **二重処理しない**: 台帳を読み,既に報告済み・スキップ指定の項目は再報告しない.PR コメントも同じ PR に同じ趣旨で 2 度投稿しない +7. **ユーザーが起動した時だけ動く**: Claude が自発的に本スキルを呼んではならない(`/loop /deps-update` でのラップはユーザー起動とみなす) + +## 実行手順 A: セットアップと収集 (Execution A: Setup & Collect) + +司令塔(`/deps-update` のメインループ)から委譲された ops-runner が実行する.振り分けの判断はせず,結果を構造化して返す. + +1. **前提の確認**: 「前提の確認」のコマンド一式を実行する.作業ツリーが汚れている・`gh` 未認証・リモートが GitHub でない場合は停止して報告する(stash もしない).開始時のブランチ名を控える +2. **検証スイートの特定**: `docs/02_ENV/ENV_04_開発コマンド.md` があればそれを唯一の参照先とする.無ければ構成ファイル(`package.json`,`pubspec.yaml`,`Cargo.toml`,`go.mod`,`pyproject.toml` 等)から依存インストール・テスト・(あれば)ビルド/型チェック/リンタのコマンドを特定する.推測で試さず,特定できなければ「ローカル検証不可」として返す +3. **台帳の読み込み**: `.claude/deps-update-merged.md`・`.claude/deps-update-report.md`・`.claude/deps-update-skip.md`(無ければ空扱い.`.gitignore` で追跡除外されていなければ追記する) +4. **収集**: 「PR の収集」「alert の収集」に従い取得する +5. **分類**: 各 PR を「更新規模の分類」に従い,規模(`patch` / `minor` / `major` / `unknown`)・依存スコープ(本番 / 開発)・種別(security / version)・`mergeable` / `mergeStateStatus`・CI 状況で整理する +6. **返すもの**: 前提状態(Dependabot 設定・CI の有無・検証スイート・開始ブランチ)・分類付き PR 一覧・alert 一覧(紐づく PR・エラー含む)・台帳の既出項目・skip 該当項目 + +## 実行手順 B: 検証とマージ (Execution B: Verify & Merge) + +司令塔がマージ候補と判定した PR を,指定された順に 1 件ずつ処理する ops-runner の手順. + +1. **rebase 依頼のみ指定の PR**: `@dependabot rebase` をコメントして次へ進む(マージしない) +2. **状態の取り直し**: マージのたびに Dependabot が残りの PR を自動 rebase するため,各 PR の処理前に `mergeable`・CI 状況を取り直す.`CONFLICTING` / `BEHIND` になっていれば rebase 依頼に切り替える +3. **検証**: CI があれば「CI の完了待ち」,無ければ「ローカル検証」を実行し,到達 Tier(A / B / C.「ローカル検証」の「検証結果の解釈」に従う)を判定する +4. **到達 Tier が司令塔の指定したマージ条件を満たす場合**: 「マージ」の手順どおり `gh pr merge <番号> --merge --delete-branch` でマージし,`deps-update-merged.md` へ「台帳の書式」で追記し,ローカル `main` を pull する +5. **満たさない場合(赤・Tier 不足・検証不能)**: マージせず,到達 Tier と失敗したコマンド/チェックの要約を添えて「分析行き」として結果に含める.マージ条件が渡されていない PR はマージせず確認事項として返す +6. **後片付け**: 全件終了後,ローカル検証で作ったブランチ・マージ状態を破棄して開始時のブランチへ戻り,`git status --short` が空であることを確認して結果(マージ済み・rebase 依頼済み・分析行き)を返す + +## 前提の確認 (Prerequisites) + +```bash +gh auth status +gh repo view --json nameWithOwner -q .nameWithOwner +git status --short # 空であること +git branch --show-current # 開始時のブランチを控える +gh api repos/{owner}/{repo}/vulnerability-alerts # 204 なら Dependabot alerts 有効(404 なら無効) +gh api repos/{owner}/{repo}/automated-security-fixes # {"enabled":true,...} なら security updates 有効 +test -f .github/dependabot.yml && echo "dependabot.yml: あり" || echo "dependabot.yml: なし" +ls .github/workflows/*.yml 2>/dev/null # CI の有無 +``` + +## PR の収集 (Collect PRs) + +```bash +gh pr list --author app/dependabot --state open --limit 100 \ + --json number,title,body,url,headRefName,baseRefName,labels,mergeable,mergeStateStatus,statusCheckRollup,createdAt,isDraft +``` + +- 個別の詳細: `gh pr view <番号> --json number,title,body,mergeable,mergeStateStatus,statusCheckRollup,files,commits` +- チェック状況: `gh pr checks <番号>`(CI が無いリポジトリでは何も返らない) +- 変更ファイル: `gh pr diff <番号> --name-only`(マニフェストとロックファイルだけのはず.それ以外が含まれていたら報告に回す) +- 本スキルが既にコメント済みか: `gh pr view <番号> --json comments -q '.comments[].body' | grep -c ""` + +## alert の収集 (Collect Alerts) + +GraphQL で「紐づく PR」と「PR を作れなかった理由」まで一度に取る(REST の `/deps-update/alerts` には PR との紐づけが無い). + +```bash +OWNER=$(gh repo view --json owner -q .owner.login) +REPO=$(gh repo view --json name -q .name) +gh api graphql -f owner="$OWNER" -f repo="$REPO" -f query=' +query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + vulnerabilityAlerts(states: OPEN, first: 100) { + nodes { + number + vulnerableManifestPath + vulnerableRequirements + securityVulnerability { + package { name ecosystem } + severity + vulnerableVersionRange + firstPatchedVersion { identifier } + } + securityAdvisory { ghsaId summary permalink } + dependabotUpdate { + pullRequest { number url } + error { title body errorType } + } + } + } + } +}' +``` + +- `dependabotUpdate.pullRequest` があれば,その PR は **security update** +- `dependabotUpdate.error` があれば,Dependabot は修正 PR を作れなかった(推移的依存・対応外マニフェスト・上限超過等).`errorType` と `body` を報告に転記する +- `firstPatchedVersion` が `null` なら修正版が無い +- フォールバック(GraphQL が使えない場合): `gh api "repos/{owner}/{repo}/dependabot/alerts?state=open&per_page=100"`.PR との紐づけは PR 本文の GHSA リンク(`securityAdvisory.ghsaId`)で照合する + +## 更新規模の分類 (Classifying the Bump) + +### 単独 PR (Single-package PR) + +タイトル `Bump from to `(`Update requirement from ... to ...` の形もある)から版を取り,semver で比較する. + +| 条件 | 規模 | +| --- | --- | +| メジャーが上がる(`1.x` → `2.x`) | `major` | +| メジャーが `0` でマイナーが上がる(`0.3.x` → `0.4.x`) | `major` 相当(破壊的変更を含みうる) | +| メジャー同じでマイナーが上がる | `minor` | +| パッチだけ上がる | `patch` | +| semver として解釈できない(日付版・ハッシュ・範囲指定等) | `unknown` | + +- プレリリース(`-beta` 等)への更新は `unknown` として扱う +- `github-actions` の `v3` → `v4` のようなメジャータグ更新は `major` + +### グループ PR (Grouped PR) + +タイトル `Bump the group (across N directories )?with N updates` の PR は,本文の `Updates \`\` from to ` 行(または本文の表)を全て取り,**最大の規模**で判定する.テンプレートの `dependabot.yml` では `minor-and-patch` グループがマイナー/パッチだけを含むので定義上 `minor` になるが,本文から実際に確認する. + +### 依存スコープ (Dependency Scope) + +マニフェストのセクションで判定する(`package.json` の `devDependencies`,`pubspec.yaml` の `dev_dependencies`,`pyproject.toml` の dev グループ/`[project.optional-dependencies]`,`Cargo.toml` の `[dev-dependencies]` 等).`github-actions`・`docker` は CI/実行環境への影響として本番扱いにする. + +## CI の完了待ち (Waiting for CI) + +```bash +gh pr checks <番号> --watch --interval 30 # 全チェック完了まで待つ(Bash ツールの timeout を 10 分程度にする) +``` + +- 待ち切れなければ,CI が無い場合と同じく「ローカル検証」に切り替えるか,今回は見送って「CI 待ち」として報告する +- マージ直後は Dependabot が残りの PR を自動 rebase して CI が再実行される.次の PR に進む前にチェック状況を取り直す + +## ローカル検証 (Local Verification) + +CI が無い/CI 待ちに使う.**最新 `main` を取り込んだ状態**で検証し,終わったら必ず元に戻す.push は一切しない. + +```bash +START_BRANCH=$(git branch --show-current) +git fetch origin +gh pr checkout <番号> # PR のブランチをローカルに取得して切り替え +PR_BRANCH=$(git branch --show-current) +git merge --no-edit origin/main # 失敗(コンフリクト)なら: git merge --abort → この PR は見送り(@dependabot rebase) +# 依存インストール → 検証スイート(ENV_04_開発コマンド.md のコマンド) +# 例: npm ci && npm test && npm run build / flutter pub get && flutter test && flutter analyze / cargo test / go test ./... +git checkout "$START_BRANCH" +git branch -D "$PR_BRANCH" +git status --short # 空であることを確認 +``` + +- 依存インストール後にロックファイル等が変わる(`git status` に差分が出る)場合は,`git checkout -- .` で破棄してからブランチを戻す +- 検証結果の解釈: + - テスト+(あれば)ビルド/型チェック/リンタが全緑 → **Tier A** + - テストが無いがインストールとビルド/型チェックは通る → **Tier B** + - インストール自体が失敗/検証コマンドが特定できない → **Tier C** + - 赤 → 「CI 赤」と同じ扱いで報告(失敗したコマンドと要約を添える) + +## マージ (Merge) + +```bash +gh pr merge <番号> --merge --delete-branch # Git 規約どおりマージコミット +git checkout main && git pull origin main # ローカル main を追従(開始時のブランチが main でない場合は戻す) +``` + +マージできなかった場合は,次の 2 つの失敗モードを区別して報告する(どちらの場合もマージを迂回しない). + +| 失敗モード | 兆候 | 対処・報告内容 | +| --- | --- | --- | +| リポジトリ側の制約 | `gh` が実行され,ブランチ保護・必須レビュー・必須チェック未完了・権限不足でエラーを返す | その PR を「マージ可と判定したが権限・保護設定で拒否された」として報告し,人間の対応(Approve・設定変更)を促す | +| auto mode 分類器によるブロック | コマンドが**実行される前に**遮断され,`gh` の出力が返らない | `.claude/settings.json` の `permissions.allow` に `Bash(gh pr merge:*)` があるか確認する.無ければユーザーが手で追加してセッションを再起動する必要がある旨を報告する(Claude 自身は permissions を編集できず,設定変更はセッション再起動後に反映される).その PR は「マージ可と判定したが未実行」として報告する | + +- `--delete-branch` が「既に削除済み」で失敗しても無視してよい(Dependabot 側の設定でブランチが自動削除されることがある) + +## Dependabot へのコメント指示 (Dependabot Commands) + +PR コメントで Dependabot を操作できる.本スキルが使ってよいのは次の 2 つだけ. + +```bash +gh pr comment <番号> --body "@dependabot rebase" # base に追従させる(競合・BEHIND のとき) +gh pr comment <番号> --body "@dependabot recreate" # PR を作り直させる(一時的なビルド失敗・壊れたブランチのとき) +``` + +- `@dependabot ignore this major version` / `@dependabot ignore this dependency` / `@dependabot close` は**人間が判断して投稿する**(本スキルは推奨として提示するだけ) + +## メジャー更新の影響分析 (Analyzing a Major Bump) + +報告に回す PR(`major`・`0.x` マイナー・`unknown`)は,人間が「そのままマージ」「`/implement` で追従」「見送り」を選べるだけの材料を揃える. + +1. **変更内容**: PR 本文の Release notes / Changelog / Commits 節から **Breaking changes** を抜き出す.本文に無ければ `gh api repos///releases` や CHANGELOG を参照する(取れなければ「リリースノート未確認」と明記する) +2. **利用箇所**: コードベース内で当該パッケージを import/呼び出している箇所を Grep で列挙し,破壊的変更に該当する API を使っているか確認する +3. **影響範囲と推奨**: + - 該当 API を使っていない/開発依存のみ → 「そのままマージ可(検証 Tier と根拠を添える)」 + - 該当 API を使っている → 「`/implement` で追従が必要(修正箇所の一覧)」 + - 互換性が取れない・移行コストが見合わない → 「見送り(`@dependabot ignore this major version` を人間が投稿)」 +4. `github-actions` のメジャー更新は workflow の入力・出力の変更点を確認する(CI が通っていれば「マージ可」でよい) + +## PR コメントの書式 (PR Comment Format) + +報告に回した PR には,通常モードで次の書式のコメントを 1 回だけ投稿する(先頭の HTML コメントは二重投稿防止のマーカー.削除しない). + +```markdown + +## /deps-update による分析 + +- **判定**: 自動マージ対象外({メジャー更新 / 0.x マイナー更新 / CI 赤 / 検証不能}) +- **更新**: `{pkg}` {A} → {B}({本番依存 / 開発依存},{security / version}) +- **検証**: {CI 緑 / ローカル検証緑 / ビルドのみ / 未検証} +- **破壊的変更**: {抜き出した要点,無ければ「記載なし」} +- **影響箇所**: {ファイル:行 の一覧,無ければ「該当 API の利用なし」} +- **推奨**: {そのままマージ可 / `/implement` で追従後にマージ / 見送り(`@dependabot ignore this major version`)} +``` + +## 台帳の書式 (Ledger Formats) + +いずれも `.claude/` 直下のローカル運用状態(`.gitignore` 対象).1 行 1 エントリ. + +- `.claude/deps-update-merged.md`: + - `- [merged] #<番号> | →(グループは件数) | | | <検証: CI / ローカル / ビルドのみ> | <推奨する動作確認(無ければ -)> | <日付>` +- `.claude/deps-update-report.md`: + - `- [major] #<番号> | → | <本番 / 開発> | <破壊的変更の要点> | <影響箇所> | <推奨> | <日付>` + - `- [ci-fail] #<番号> | → | <失敗したチェック/コマンドと要約> | <推奨> | <日付>` + - `- [alert] () | <重大度> | | <修正版 or 修正版なし> | | <推奨対応> | <日付>` + - `- [other] #<番号> | <内容(依存以外のファイル変更・unknown 規模 等)> | <推奨> | <日付>` +- `.claude/deps-update-skip.md`(ユーザーが編集する): + - `- #<番号> または | <理由> | <日付>` diff --git a/.claude/skills/implement/SKILL.md b/.claude/skills/implement/SKILL.md index 0b02744..ffc6932 100644 --- a/.claude/skills/implement/SKILL.md +++ b/.claude/skills/implement/SKILL.md @@ -1,6 +1,6 @@ --- name: implement -model: opus +model: inherit description: "実装パイプラインを開始する.コーディング → テスト → リファクタリングの順で 3 つのエージェントを実行し,必要に応じて人間の確認を挟む." argument-hint: "<タスク内容>" --- diff --git a/.claude/skills/set-mode/SKILL.md b/.claude/skills/set-mode/SKILL.md index 8db463a..484e430 100644 --- a/.claude/skills/set-mode/SKILL.md +++ b/.claude/skills/set-mode/SKILL.md @@ -20,13 +20,11 @@ ``` docs/01_GUIDE/GUIDE_03_チーム開発ルール.md -.claude/skills/task-create/SKILL.md -.claude/skills/task-start/SKILL.md -.claude/skills/task-start/reference.md -.claude/skills/task-handoff/SKILL.md .claude/hooks/check_sync.sh ``` +※ `task-create`・`task-start`(+ `reference.md`)・`task-handoff` の各 skill は**共通層**(solo でも Issue ベースのタスク管理に使う)であり,モード切替の対象外. + ## ステップ 1: 事前確認 (Pre-check) 1. `git status` でワーキングツリーがクリーンか確認する.未コミットの変更がある場合は「⚠ コミットされていない変更があります.先にコミットまたは stash してから再実行してください.」と伝えて中断する. @@ -62,10 +60,6 @@ # team 層ファイルをコピー(既存があっても最新版で上書き) for f in \ "docs/01_GUIDE/GUIDE_03_チーム開発ルール.md" \ - ".claude/skills/task-create/SKILL.md" \ - ".claude/skills/task-start/SKILL.md" \ - ".claude/skills/task-start/reference.md" \ - ".claude/skills/task-handoff/SKILL.md" \ ".claude/hooks/check_sync.sh" ; do mkdir -p "$(dirname "$f")" cp "$TEMP_DIR/$f" "$f" @@ -87,7 +81,9 @@ ] ``` -Edit 後に `git diff .claude/settings.json` で結果を確認する. +`hooks` 以外のキー(`permissions` 等)は**追加も削除もせずそのまま保持する**.特に `permissions.allow` の `Bash(gh pr merge:*)` は auto mode で ops-runner にマージを実行させるために必要なため,モード切替で落とさない. + +Edit 後に `git diff .claude/settings.json` で結果を確認する(`SessionStart` の追加以外の差分が出ていないことを確認する). ### 3-A.3 CLAUDE.md を team 化 @@ -114,19 +110,14 @@ ```bash rm -f \ "docs/01_GUIDE/GUIDE_03_チーム開発ルール.md" \ - ".claude/skills/task-create/SKILL.md" \ - ".claude/skills/task-start/SKILL.md" \ - ".claude/skills/task-start/reference.md" \ - ".claude/skills/task-handoff/SKILL.md" \ ".claude/hooks/check_sync.sh" - -# 中身が無くなったスキルディレクトリを取り除く -rmdir ".claude/skills/task-create" ".claude/skills/task-start" ".claude/skills/task-handoff" 2>/dev/null || true ``` +※ `task-*` skill は共通層のため削除しない(solo でも Issue ベースのタスク管理に使用する).共通層化以前に solo 化して `task-*` が消えているプロジェクトには,`/sync-template` の同期で再配置される. + ### 3-B.2 settings.json から SessionStart(check_sync) を除去 -`.claude/settings.json` を Read し,`check_sync.sh` を呼ぶ `SessionStart` フックのみを除去する.`PreToolUse`(`restrict_repo_access.py`)は保持する.他に個別追加された `SessionStart` フックがあれば残す(`check_sync.sh` の配線だけを外す).Edit 後に `git diff .claude/settings.json` で確認する. +`.claude/settings.json` を Read し,`check_sync.sh` を呼ぶ `SessionStart` フックのみを除去する.`PreToolUse`(`restrict_repo_access.py`)は保持する.他に個別追加された `SessionStart` フックがあれば残す(`check_sync.sh` の配線だけを外す).`hooks` 以外のキー(`permissions` 等)は**そのまま保持する**(`permissions.allow` の `Bash(gh pr merge:*)` は auto mode でマージを実行するために必要).Edit 後に `git diff .claude/settings.json` で確認する(`SessionStart` の除去以外の差分が出ていないことを確認する). ### 3-B.3 CLAUDE.md を solo 化 @@ -172,3 +163,4 @@ - team ↔ solo の切替は共有設定の変更にあたる(GUIDE_03「共有設定の扱い」).team プロジェクトでは専用 PR+他メンバー 1 名 Approve を経てマージする. - team 層ファイルのリストは `/sync-template` の「モード依存ファイル」と一致させること.どちらかを増減したら両方を更新する. - solo→team で取得する team 層ファイルはテンプレート HEAD 版.版の細かな追従は以後の `/sync-template` に任せる(`template-sync-sha` は本コマンドでは変更しない). +- team 層ファイルが `.claude/template-overrides.md`(テンプレート改変台帳)に登録されている場合,3-A.1 の上書きや 3-B.1 の削除でプロジェクトの改変が失われる.実行前に台帳を確認し,該当があればユーザーに提示して同意を得てから行う. diff --git a/.claude/skills/setup/SKILL.md b/.claude/skills/setup/SKILL.md index 8e64530..19f0839 100644 --- a/.claude/skills/setup/SKILL.md +++ b/.claude/skills/setup/SKILL.md @@ -1,12 +1,13 @@ --- name: setup -model: opus +model: inherit description: "GUIDE_01 に従い,プロジェクトの立ち上げを対話的に進める.各フェーズでユーザーの確認を挟む." argument-hint: "<プロジェクト名>" --- あなたはプロジェクト立ち上げのファシリテーターです. GUIDE_01(プロジェクト立ち上げフロー)を読み,各フェーズのルールを理解した上で以下の手順を実行してください. +`gh` CLI で行う GitHub リポジトリ設定のコマンドと,`.github/dependabot.yml` の生成規則は本スキルの `reference.md`(`.claude/skills/setup/reference.md`)を参照する. ## 基本ルール @@ -46,8 +47,8 @@ 1. `.claude/project-mode` にモード(`solo` または `team` のいずれか 1 語)を書き出す. 2. **solo の場合**: チーム層ファイルが clone で配置されていれば削除し,solo プロジェクトを clean に保つ: - `docs/01_GUIDE/GUIDE_03_チーム開発ルール.md` - - `.claude/skills/task-create/` / `task-start/` / `task-handoff/`(各ディレクトリごと削除) - `.claude/hooks/check_sync.sh` + - ※ `task-create` / `task-start` / `task-handoff` の各 skill は共通層(solo でも Issue ベースのタスク管理に使える)のため削除しない. - ※ `.claude/settings.json` はそのまま(solo でも `restrict_repo_access.py` を使う).SessionStart(check_sync) の配線は追加しない. 3. **team の場合**: 上記チーム層ファイルを残す.加えて: - `.claude/settings.json` に SessionStart フックを追記して `check_sync.sh` を配線する(既存の PreToolUse ブロックは保持する): @@ -92,6 +93,22 @@ ### フェーズ 3(環境構築)の注意 外部サービスの設定(アカウント作成,コンソール操作等)はユーザー自身が行う.手順書に記載するが,AI が実行しないこと. +**例外**として,`gh` CLI で操作できる GitHub リポジトリ設定は AI が実行する. + +### GitHub リポジトリのセキュリティ設定 (GitHub Repository Security Settings) + +Dependabot alerts("Vulnerabilities")と Dependabot security updates はリポジトリごとに既定で OFF のため,モード(solo / team)に関わらず AI が `gh api` で有効化する.コマンド・検証・トラブル対応は本スキルの `reference.md`(`.claude/skills/setup/reference.md`)「GitHub リポジトリのセキュリティ設定」に従う. + +- `ENV_03_管理者用環境構築手順.md` のドラフトには,GitHub リポジトリ作成の直後の手順として `reference.md` の有効化・検証コマンドを必ず転記する(`/setup` 後にリポジトリを作った場合に管理者が単体で実行できるようにするため) +- ENV_03 を書き出したら,その場で `reference.md` の手順を 1 度実行する.リモート未作成で実行できなければ Phase 7 で再試行する + +### 依存バージョン更新の設定 (Dependabot Version Updates) + +上記の脆弱性検出とは別に,依存パッケージを定期的に最新化する PR を Dependabot に作らせるため,フェーズ 3 で `.github/dependabot.yml` を**ユーザーに選択を聞かずに必ず生成する**(`.gitignore` 等と同じ「設定ファイルの生成」の一部として扱う). + +- フェーズ 2 で確定した技術スタック(`ENV_01_技術スタック.md`)から対象エコシステムを決め,`reference.md`「依存バージョン更新の設定」の対応表と雛形に従って生成する +- 生成内容(対象エコシステム・更新頻度・グループ化)は他の成果物と同様にドラフトとしてユーザーに提示し,承認を得てから書き出す(「作るかどうか」は聞かず,「内容」だけを確認する) +- マニフェストがまだ存在しない場合(立ち上げ時点でコードが無い)でも,スタックが確定していれば生成してよい.Dependabot はマニフェストが置かれた時点から動き始める ## フェーズ 7: 実装開始 @@ -104,11 +121,12 @@ - **solo モードの場合**は従来どおり(進捗欄+ PROGRESS.md 運用). 2. 作成した全ドキュメントの一覧を表示する 3. 最初の実装ステップを確認する -4. **team モードの場合**は,AI に実施できない「管理者の初期設定」(GUIDE_03「管理者の初期設定」)をユーザーに案内する: +4. **モードに関わらず**,「GitHub リポジトリのセキュリティ設定」(前述)を実行する(Phase 3 で有効化済みなら検証コマンドだけで確認する.リモートがまだ無ければ,リポジトリ作成後に ENV_03 のコマンドを実行するようユーザーに案内する) +5. **team モードの場合**は,AI に実施できない「管理者の初期設定」(GUIDE_03「管理者の初期設定」)をユーザーに案内する: - GitHub リポジトリ作成・メンバー招待 - Issue テンプレートの用意 - CI 構築(未構築の間は GUIDE_03「CI 構築までの暫定ゲート」を適用) - - 依存脆弱性対策が必要ならスタックに応じた `.github/dependabot.yml` を追加(エコシステムはプロジェクト固有のため setup では作らない) + - ※ 脆弱性検出(Dependabot alerts / security updates)は上記 4 で AI が有効化済み,依存バージョン更新(`.github/dependabot.yml`)はフェーズ 3 で生成済みのため,ここでは案内しない.CI を `github-actions` で組んだら `dependabot.yml` に `github-actions` エコシステムが含まれていることを確認する(`reference.md`「依存バージョン更新の設定」) 「**全フェーズが完了しました.** @@ -117,6 +135,9 @@ 開発モード: {solo / team} CLAUDE.md を更新しました. +GitHub リポジトリのセキュリティ設定(Dependabot alerts / security updates): {有効化済み / リポジトリ未作成のため未実施(ENV_03 のコマンドで有効化してください)} +依存バージョン更新(`.github/dependabot.yml`): {対象エコシステム一覧} を {更新頻度} で監視 +Dependabot が作る PR・alert は `/deps-update` で処理できます(安全な更新は自動マージ,メジャー更新等は分析付きで報告). 最初の実装ステップは `{ステップ名}` です.`/implement {タスク}` で開始できます. {team の場合: 「チーム運用の管理者初期設定(GitHub repo・CI 等)は GUIDE_03 を参照してユーザー側で実施してください.」}」 diff --git a/.claude/skills/setup/reference.md b/.claude/skills/setup/reference.md new file mode 100644 index 0000000..e1f9466 --- /dev/null +++ b/.claude/skills/setup/reference.md @@ -0,0 +1,123 @@ +# setup リファレンス (Setup Reference) + +`/setup`(`SKILL.md`)から参照される,GitHub リポジトリまわりの設定手順集(`gh` CLI で行うリポジトリ設定と,`.github/dependabot.yml` の生成規則).`/setup` の途中で AI が実行するほか,`/setup` 完了後にリポジトリを作成した場合などに管理者(人間)が単体で実行する runbook としても使う. + +## GitHub リポジトリのセキュリティ設定 (GitHub Repository Security Settings) + +GitHub の Settings → Code security にある **Dependabot alerts**(既知脆弱性の検出.UI では "Vulnerabilities" として表示される)と **Dependabot security updates**(脆弱性を直す PR の自動作成)は**リポジトリごとに既定で OFF** であり,有効化しないと依存パッケージの脆弱性が一切通知されない.モード(solo / team)に関わらず,プロジェクトの GitHub リポジトリが存在する時点で有効化する. + +### 前提 (Prerequisites) + +- `gh auth login` 済みであること(既定スコープ `repo` で足りる) +- 実行者がリポジトリの **admin 権限**を持つこと(無いと 403) +- カレントディレクトリがそのリポジトリの clone であること(`{owner}/{repo}` は `gh` がリモートから自動補完する) + +### 手順 (Procedure) + +1. リモートの有無を確認する: + + ```bash + gh repo view --json nameWithOwner -q .nameWithOwner + ``` + + - 失敗する(リモート未設定・リポジトリ未作成・`gh` 未認証)場合はこの手順をスキップする.`/setup` 中であれば「GitHub リポジトリ作成後に `/setup` を再実行するか,ENV_03 に記載したコマンドを実行してください」とユーザーに伝え,Phase 7 でもう一度試す +2. 有効化する(冪等なので再実行してよい): + + ```bash + gh api -X PUT repos/{owner}/{repo}/vulnerability-alerts # Dependabot alerts(依存グラフも同時に有効化される) + gh api -X PUT repos/{owner}/{repo}/automated-security-fixes # Dependabot security updates + ``` + +3. 有効化を検証する: + + ```bash + gh api repos/{owner}/{repo}/vulnerability-alerts # 成功(204)なら有効.404 なら無効 + gh api repos/{owner}/{repo}/automated-security-fixes # {"enabled":true,...} なら有効 + ``` + +4. 結果をユーザーに報告する + +### トラブルシューティング (Troubleshooting) + +| 症状 | 原因 | 対処 | +| --- | --- | --- | +| `gh repo view` が失敗 | リモート未設定・リポジトリ未作成・`gh` 未認証 | リポジトリ作成と `git remote add origin ...` 後に再実行.`gh auth status` で認証を確認 | +| `PUT` が 403 | リポジトリの admin 権限が無い,またはトークンのスコープ不足 | 管理者に依頼するか,GitHub の Settings → Code security → Dependabot から手動で ON にする | +| `PUT` が 404 | `{owner}/{repo}` の補完に失敗(リモート URL が GitHub でない等) | `gh api -X PUT repos///vulnerability-alerts` のように明示する | + +### 補足 (Notes) + +- `.github/dependabot.yml` は「依存バージョンの定期更新 PR」の設定であり,上記の脆弱性検出とは別物(次節).上記の有効化は `dependabot.yml` の有無に関係なく動く +- アカウント設定(Settings → Code security → "Automatically enable for new repositories")を ON にしておけば以後の新規リポジトリは自動で有効になるが,テンプレートとしてはリポジトリ単位で確実に有効化する前提で運用する + +## 依存バージョン更新の設定 (Dependabot Version Updates) + +`.github/dependabot.yml` を置くと,Dependabot が依存パッケージの新バージョンを定期的に検出して更新 PR を作る(脆弱性の有無に関係なく).`/setup` のフェーズ 3 で,技術スタック(`ENV_01_技術スタック.md`)に合わせて**必ず生成する**(作るかどうかはユーザーに聞かない.内容だけドラフトとして確認する).PR のノイズを抑えるため,週 1 回・マイナー/パッチをまとめる・同時オープン数を絞る,を既定とする. + +### エコシステム対応表 (Ecosystem Mapping) + +技術スタックから `package-ecosystem` を決める.`directory` はマニフェスト(`package.json`・`pubspec.yaml` 等)があるディレクトリ(ルートなら `/`).モノレポ等で複数箇所にある場合はエントリを分けるか `directories` を使う. + +| 技術スタック | `package-ecosystem` | マニフェスト例 | +| --- | --- | --- | +| Node.js(npm / pnpm / yarn) | `npm` | `package.json` | +| Dart / Flutter | `pub` | `pubspec.yaml` | +| Python(pip / Poetry / pipenv) | `pip` | `requirements.txt`・`pyproject.toml`・`Pipfile` | +| Python(uv) | `uv` | `pyproject.toml` + `uv.lock` | +| Rust | `cargo` | `Cargo.toml` | +| Go | `gomod` | `go.mod` | +| Ruby | `bundler` | `Gemfile` | +| PHP | `composer` | `composer.json` | +| Java / Kotlin(Gradle) | `gradle` | `build.gradle(.kts)` | +| Java(Maven) | `maven` | `pom.xml` | +| .NET | `nuget` | `*.csproj` | +| Swift | `swift` | `Package.swift` | +| Docker を使う場合 | `docker` | `Dockerfile` | +| Dev Containers を使う場合 | `devcontainers` | `.devcontainer/devcontainer.json` | +| GitHub Actions(CI) | `github-actions` | `.github/workflows/*.yml` | + +- `github-actions` は**常に含める**(立ち上げ時点で workflow が無くても害は無く,後から CI を足した時に自動で対象になる) +- Docker / Dev Containers は技術スタックまたは環境構築方針(GUIDE_01「環境構築」の基本方針)で採用している場合に含める + +### 雛形 (Template) + +以下を基に,対応表で決めたエコシステムごとに `updates` エントリを 1 つずつ作る(`{...}` を置き換える). + +```yaml +# 依存パッケージの定期更新 PR(Dependabot version updates) +# 脆弱性検出(Dependabot alerts / security updates)はリポジトリ設定で有効化済み(本ファイルとは独立に動く) +version: 2 +updates: + - package-ecosystem: "{npm / pub / pip ...}" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "[update]" + groups: + minor-and-patch: + update-types: + - "minor" + - "patch" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "[update]" + groups: + actions: + patterns: + - "*" +``` + +- `interval`: 既定は `weekly`.更新 PR を減らしたいプロジェクトは `monthly` にしてよい +- `groups`: マイナー/パッチ更新を 1 PR にまとめる.メジャー更新は破壊的変更を含みうるため個別 PR のまま残す +- `open-pull-requests-limit`: 既定 5.放置された更新 PR が溜まるのを防ぐ +- `commit-message.prefix`: Git 規約(`.claude/rules/git-conventions.md`)の `[タグ] 内容` に合わせて `[update]` を付ける.内容部分は Dependabot が英語で生成する(例: `[update] Bump foo from 1.2.0 to 1.3.0`).これは規約の許容例外とし,手で書き直さない +- Dependabot の PR も通常の PR と同じく `main` へ直接は入らない.CI(あれば)の結果とリリースノートを確認してマージする + +### 動作確認 (Verification) + +`main` に push された後,GitHub の Insights → Dependency graph → Dependabot で各エコシステムの「Last checked」と結果を確認できる.YAML の構文エラーはここにも表示される. diff --git a/.claude/skills/sync-template/SKILL.md b/.claude/skills/sync-template/SKILL.md index 069f775..55d1311 100644 --- a/.claude/skills/sync-template/SKILL.md +++ b/.claude/skills/sync-template/SKILL.md @@ -7,8 +7,9 @@ あなたはテンプレート同期の担当者です. テンプレートリポジトリから最新の変更を取り込み,必要に応じてプロジェクトのコードを修正してください. +bash ヘルパーの定義と各ファイルの個別マージ手順は本スキルの `reference.md`(`.claude/skills/sync-template/reference.md`)を参照する. -実行環境: bash(Git Bash または Unix シェル)が必要.`mktemp`, `rm -rf`, `cat`, シェル変数展開を使用する. +実行環境: bash(Git Bash または Unix シェル)が必要.`mktemp`, `rm -rf`, `cat`, `awk`, `diff`, `git merge-file`, シェル変数展開を使用する. テンプレート URL: `https://github.com/rintoHasegawa/programming-template.git` @@ -22,10 +23,37 @@ | `CLAUDE.md` | プロジェクト名・開発進捗・固有規約を保持する必要がある | テンプレートで変更された共通セクション(必須ルール,エージェントチーム,ドキュメント構成等)のみを Edit で更新.プロジェクト固有セクションは触らない | | `docs/PROGRESS.md` | プロジェクト固有の進捗ログを保持する必要がある | 既存ファイルがある場合は内容を上書きしない.テンプレート側の骨組み(タイトル・案内コメント)に差分があれば通知のみ行い手動マージを促す | | `.gitattributes` | プロジェクトによって設定が異なる可能性がある | 差分を表示し,ユーザーに「上書き / マージ / スキップ」を問う | -| `.claude/settings.json` | team モードで SessionStart(check_sync) 配線を追加している等,プロジェクト固有の hook 設定を保持する必要がある | 既存の hooks を保持しつつ,テンプレート側で追加・変更された hook のみ統合.差分を表示しユーザーに確認 | +| `.claude/settings.json` | team モードで SessionStart(check_sync) 配線を追加している等,プロジェクト固有の hook 設定・permissions を保持する必要がある | 既存の hooks・`permissions` を保持しつつ,テンプレート側で追加・変更された hook・allow ルールのみ統合.差分を表示しユーザーに確認 | +| `.claude/template-overrides.md` | プロジェクト固有の「テンプレート改変台帳」.登録内容はプロジェクト固有 | 既存ファイルがある場合は内容を上書きしない.テンプレート側の骨組み(説明文・記入例)に差分があれば通知のみ行い手動マージを促す(`docs/PROGRESS.md` と同じ扱い) | マージ処理の対象は **既存ファイルが存在する場合のみ**.初回同期(`.claude/template-sync-sha` がない状態)では全ファイルが A 扱いとなるが,これらのファイルはフレームワーク初期化(`flutter create` / `npm init` 等)や `/init` で既にプロジェクトに存在するのが通常なので,そのままマージ処理に入る.既存ファイルがない稀なケースに限り通常の `cp` で配置する. +## プロジェクト固有改変ファイル (Project Overrides) + +マージ必須ファイル以外のテンプレート管理ファイル(`.claude/skills/*`,`.claude/rules/*`,`.claude/agents/*`,`.claude/hooks/*`,`docs/01_GUIDE/*` 等)も,プロジェクトの都合で**意図的に改変**されていることがある.これらを A/M のたびに `cp` で盲目的に上書きすると改変が失われるため,以下の 2 段構えで保護する. + +### 台帳に登録された改変(明示的保護) + +プロジェクトは意図的な改変を `.claude/template-overrides.md`(テンプレート改変台帳)に記録する(運用ルール: `.claude/rules/template-customization.md`).台帳の「台帳」節の表から `| \`パス\` | 方針 | 理由 | 記録日 |` 形式の行を読み,登録ファイルは **`cp` せず方針に従って処理する**(ステップ 5.5): + +| 方針 | 処理 | +| --- | --- | +| `keep` | 触らない.テンプレート側に変更があれば,その差分(前回同期版 → 最新)を表示して通知のみ行う | +| `merge` | base = 前回同期版(`$LAST_SHA`),ours = プロジェクト版,theirs = テンプレート最新版の **3-way マージ**で,テンプレート側の差分だけを取り込みプロジェクトの改変を保持する.競合があれば同期担当エージェント(= あなた)が両者の意図を保って解決し,ユーザーに確認する | +| `ask` | プロジェクトの改変内容とテンプレート側の差分を表示し,ユーザーに「上書き / マージ / スキップ」を問う | + +- パスが末尾 `/` で終わる行はディレクトリ指定であり,配下の全ファイルに同じ方針を適用する +- 台帳に載っているのにテンプレート側に存在しないパス(リネーム・削除済み,または記入ミス)は同期の最後に警告する(ステップ 5.8) +- 初回同期(`$LAST_SHA` 無し)では base が取れないため,`merge` は `ask` として扱う + +### 台帳に無い改変の検出(安全網) + +台帳に登録されていなくても,A/M 対象ファイルが**ローカルに存在し,かつ前回同期版(`$LAST_SHA` 時点のテンプレート版)と内容が異なる**場合,プロジェクト側で改変されている.これは上書きせずに「未登録改変」として集め(ステップ 5.3),まとめてユーザーに確認する(ステップ 5.6).確認では「意図的な改変 → 台帳に登録してマージ/保持」「意図しない差分(古い手修正等) → 上書き」を選べるようにし,選択に応じて台帳へ行を追加する. + +前回同期版に存在しない(テンプレートで新規追加された)パスにローカルファイルが既にある場合も同様に未登録改変として扱う(プロジェクトが独自に作ったファイルをテンプレート版で潰さない). + +初回同期(`$LAST_SHA` 無し)では比較対象が無いため検出は行わない. + ## 同期対象外ファイル (Skip-on-sync Files) 以下のファイルはテンプレート紹介専用であり,テンプレートから作られた各プロジェクトには反映しない.コピー・上書き・削除のいずれも行わない. @@ -43,12 +71,10 @@ | ファイル | レイヤ | | --- | --- | | `docs/01_GUIDE/GUIDE_03_チーム開発ルール.md` | team | -| `.claude/skills/task-create/SKILL.md` | team | -| `.claude/skills/task-start/SKILL.md` | team | -| `.claude/skills/task-start/reference.md` | team | -| `.claude/skills/task-handoff/SKILL.md` | team | | `.claude/hooks/check_sync.sh` | team | +※ `task-create`・`task-start`(+ `reference.md`)・`task-handoff` の各 skill は**共通層**(solo でも Issue ベースのタスク管理に使う)であり,モードに関わらず通常どおり同期する. + 判定はプロジェクトの `.claude/project-mode`(`solo` または `team`.`/setup` が作成)で行う: - **`team`**: チーム層ファイルを通常どおり同期(A/M/D すべて反映). @@ -93,10 +119,12 @@ `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) ``` + で変更されたファイルを種別付きで取得する. **ファイルが存在しない場合(初回同期):** @@ -109,7 +137,7 @@ ## ステップ 4: 変更一覧をユーザーに提示 -取り込み対象のファイル一覧を種別ごとに整理してユーザーに提示する.マージ必須ファイル(`.gitignore`, `CLAUDE.md`, `docs/PROGRESS.md`, `.gitattributes`, `.claude/settings.json`)に変更がある場合は,**ユーザーが取り込み前に影響範囲を把握できるよう差分サマリーを先出しする**: +取り込み対象のファイル一覧を種別ごとに整理してユーザーに提示する.マージ必須ファイルや台帳登録ファイルに変更がある場合は,**ユーザーが取り込み前に影響範囲を把握できるよう差分サマリーを先出しする**(取得方法は `reference.md`「変更一覧の差分サマリー」.ヘルパーが未定義ならステップ 5.2 の定義を先に実行してよい): 「**テンプレートに以下の変更があります:** @@ -124,218 +152,111 @@ - `CLAUDE.md`(既存にプロジェクト固有セクションが {L} 行.テンプレート更新セクションのみマージ) - `docs/PROGRESS.md`(プロジェクト固有の進捗ログ.既存があれば内容を保持し,差分があれば通知のみ) - `.gitattributes`(差分 {D} 行.処理方針をユーザーに確認) -- `.claude/settings.json`(既存の hooks を保持し,テンプレート側で追加・変更された hook のみ統合) +- `.claude/settings.json`(既存の hooks・`permissions` を保持し,テンプレート側で追加・変更された hook・`permissions.allow` のルールのみ統合.permissions を更新した場合はセッション再起動が必要な旨を伝える) +- `.claude/template-overrides.md`(台帳の行を保持し,骨組みの差分があれば通知のみ) + +**📒 台帳登録済みのプロジェクト固有改変ファイルに変更があります(方針に従って処理します):** + +- `{パス}`(方針: {keep/merge/ask}.理由: {台帳の理由}) 取り込みを開始します.」 -差分サマリーは以下で取得する(該当ファイルがマージ対象かつ既存ファイルがある場合のみ出力): - -```bash -# 既存ファイル行数 -wc -l .gitignore CLAUDE.md docs/PROGRESS.md .gitattributes .claude/settings.json 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 docs/PROGRESS.md "$TEMP_DIR/docs/PROGRESS.md" | head -30 -diff -u .gitattributes "$TEMP_DIR/.gitattributes" | head -30 -diff -u .claude/settings.json "$TEMP_DIR/.claude/settings.json" | head -30 -``` - ## ステップ 5: ブランチ作成とファイル反映 ### 5.1 ブランチ作成 `git checkout -b chore/sync-template` でブランチを作成する.既に同名のブランチが存在する場合は削除してから作り直す. -### 5.2 マージ必須ファイル判定ヘルパー +### 5.2 判定ヘルパーの定義 -以降の処理で利用する判定関数を定義する: +`reference.md`「変数・判定ヘルパー」のブロックを実行し,以降の処理で使う変数と関数を定義する: -```bash -MERGE_FILES=(".gitignore" "CLAUDE.md" "docs/PROGRESS.md" ".gitattributes" ".claude/settings.json") -SKIP_FILES=("README.md") -TEAM_LAYER_FILES=( - "docs/01_GUIDE/GUIDE_03_チーム開発ルール.md" - ".claude/skills/task-create/SKILL.md" - ".claude/skills/task-start/SKILL.md" - ".claude/skills/task-start/reference.md" - ".claude/skills/task-handoff/SKILL.md" - ".claude/hooks/check_sync.sh" -) +- 一覧: `MERGE_FILES` / `SKIP_FILES` / `TEAM_LAYER_FILES`,開発モード `PROJECT_MODE`,作業ディレクトリ `WORK_DIR` +- 判定: `is_merge_file` / `is_skip_file` / `is_team_layer_file` / `override_policy`(台帳の方針)/ `is_diverged`(前回同期版からの改変有無) +- 差分表示・マージ: `show_template_delta` / `show_project_delta` / `three_way_merge` -# プロジェクトの開発モードを取得(未設定なら安全側で solo 扱い) -if [ -f .claude/project-mode ]; then - PROJECT_MODE=$(tr -d '[:space:]' < .claude/project-mode) -else - PROJECT_MODE="solo" -fi +### 5.3 通常コピー対象の反映 -is_merge_file() { - local t="$1" - for f in "${MERGE_FILES[@]}"; do - [ "$f" = "$t" ] && return 0 - done - return 1 -} +`reference.md`「通常コピーループ」を実行する.各エントリは次の順で判定し,最初に該当した扱いになる: -is_skip_file() { - local t="$1" - for f in "${SKIP_FILES[@]}"; do - [ "$f" = "$t" ] && return 0 - done - return 1 -} - -is_team_layer_file() { - local t="$1" - for f in "${TEAM_LAYER_FILES[@]}"; do - [ "$f" = "$t" ] && return 0 - done - return 1 -} -``` - -`PROJECT_MODE` が `solo` の場合,チーム層ファイル(`is_team_layer_file` が真)は同期対象外ファイルと同様に完全スキップする(ステップ 5.3 のループでは `is_skip_file` 判定の直後に `[ "$PROJECT_MODE" = "solo" ] && is_team_layer_file "$file"` を追加で判定して `continue` する).`team` の場合は通常のコピー/マージ判定に進む. - -### 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) - # 同期対象外ファイルは完全にスキップ(コピーも上書きもしない) - if is_skip_file "$file"; then - continue - fi - # solo モードではチーム層ファイルを完全スキップ(再配置しない) - if [ "$PROJECT_MODE" = "solo" ] && is_team_layer_file "$file"; then - continue - fi - # マージ必須ファイルで既存ファイルがある場合は 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_skip_file "$newfile"; then - continue - fi - if [ "$PROJECT_MODE" = "solo" ] && is_team_layer_file "$newfile"; then - continue - fi - if is_merge_file "$newfile" && [ -f "$newfile" ]; then - continue - fi - mkdir -p "$(dirname "$newfile")" - cp "$TEMP_DIR/$newfile" "$newfile" - ;; - esac -done -``` +1. 同期対象外ファイル → 完全スキップ +2. solo モードのチーム層ファイル → 完全スキップ +3. マージ必須ファイル(既存あり) → 5.4 へ +4. 台帳登録ファイル(既存あり) → `$WORK_DIR/overrides.tsv` に記録し 5.5 へ(リネームで旧パスが登録済みの場合は `RENAMED` 行として記録) +5. 未登録改変ファイル(`is_diverged` が真) → `$WORK_DIR/diverged.tsv` に記録し 5.6 へ +6. 上記以外 → `cp` で配置・上書き ### 5.4 マージ必須ファイルの個別処理 -`$CHANGED_ENTRIES` に A/M/R* で含まれ,かつ既存ファイルが存在するマージ必須ファイルについて,以下の手順で処理する. +`$CHANGED_ENTRIES` に A/M/R* で含まれ,かつ既存ファイルが存在するマージ必須ファイルを,`reference.md`「マージ必須ファイルの個別手順」に従ってファイルごとに処理する.各手順の最後に `git diff` で結果を表示しユーザーに確認する. -**`.gitignore` のマージ手順** +### 5.5 台帳登録ファイルの処理 -1. 既存 `.gitignore` とテンプレート `$TEMP_DIR/.gitignore` を読む -2. テンプレート側の**実効行**(コメント `#` 行・空行を除く)を抽出する: - ```bash - grep -vE '^\s*(#|$)' "$TEMP_DIR/.gitignore" - ``` -3. 抽出した各行について,既存ファイルに完全一致で含まれていないものだけを収集する -4. 収集した行がある場合,既存ファイル末尾に以下のマーカー付きブロックで追記する: - ``` - - # --- from template (sync-template) --- - {追加行} - ``` - - 既存ファイル末尾に同じマーカーが既にある場合は,マーカー以降に追記して重複マーカーを作らない -5. `git diff .gitignore` で結果を表示しユーザーに確認する +`$WORK_DIR/overrides.tsv` の各行を方針ごとに処理する.差分の表示には `show_template_delta`(テンプレート側の差分: 何が変わったか)と `show_project_delta`(プロジェクト側の改変: 何を守るべきか)を使う. -**`CLAUDE.md` のマージ手順** +**`keep` の処理** -同期担当エージェント(= あなた)が Read と Edit ツールを使ってセクション単位でマージする: +触らない.テンプレート側に変更があった事実だけを伝える: -1. 既存 `CLAUDE.md` とテンプレート版 `$TEMP_DIR/CLAUDE.md` を Read する -2. テンプレート側の変更箇所を特定する(初回同期は LAST_SHA がないためテンプレート全体を「更新候補」として扱う): - ```bash - 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` で結果を表示しユーザーに確認する +「📒 `{file}` は台帳で `keep` のため取り込みません(理由: {台帳の理由}).参考までにテンプレート側の変更は以下です:」 -**`docs/PROGRESS.md` のマージ手順** +→ `show_template_delta "$file"` の出力を要約して添える.取り込みたくなった場合は台帳の行を削除または `merge` に変更して再同期するよう案内する. -`docs/PROGRESS.md` はプロジェクト固有の進捗ログのため,**既存ファイルがある場合は内容を上書きしない**.テンプレート側の更新は骨組み(タイトル・案内コメント)に限定されるはずなので,差分があれば通知のみ行い手動マージを促す: +**`merge` の処理** -1. 既存 `docs/PROGRESS.md` とテンプレート版 `$TEMP_DIR/docs/PROGRESS.md` を Read する -2. 差分を表示する: - ```bash - diff -u docs/PROGRESS.md "$TEMP_DIR/docs/PROGRESS.md" - ``` -3. 差分がある場合,「⚠ テンプレート側の `docs/PROGRESS.md` 骨組みに変更があります.既存の追記内容を保持したまま骨組みを反映したい場合はファイルを直接編集してください.自動マージは行いません.」と通知する -4. 既存ファイルが無い稀なケース(テンプレートを使わずに作られた古いプロジェクト等)に限り,テンプレート版をそのまま `cp` で配置する +1. `three_way_merge "$file"` を実行する +2. 戻り値 0(競合なし): 「📒 `{file}` をマージしました(プロジェクトの改変を保持しつつテンプレートの差分を取り込み)」と伝え,`git diff -- "$file"` を表示してユーザーに確認する +3. 戻り値 1(競合あり): `$WORK_DIR/merged/$file` の競合箇所と `show_project_delta` / `show_template_delta` を Read し,同期担当エージェント(= あなた)が**プロジェクトの改変意図(台帳の理由)とテンプレート側の変更意図の両方を保つ**ように解決した内容で `$file` を Edit / Write する.競合マーカーは残さない.解決方針を説明し,`git diff -- "$file"` を表示してユーザーに確認する.両立不能と判断した場合はユーザーに「プロジェクト版優先 / テンプレート版優先」を問う +4. 戻り値 2(初回同期等で base 無し): `ask` の処理に切り替える -**`.gitattributes` のマージ手順** +**`ask` の処理** -1. 既存ファイルとテンプレート版の差分を表示する: - ```bash - diff -u .gitattributes "$TEMP_DIR/.gitattributes" - ``` -2. ユーザーに以下のいずれかを選ばせる: - - **上書き**: テンプレート版で既存を置換 - - **マージ**: 両者のルールを統合(具体的な統合内容は対話で決定) - - **スキップ**: 既存ファイルを維持 -3. 選択に応じて処理する +1. `show_project_delta "$file"` と `show_template_delta "$file"` を表示し,台帳の理由を添えてユーザーに問う: + - **上書き**: テンプレート版で置換(改変を破棄.台帳の行を削除するか確認する) + - **マージ**: `merge` の処理を行う(以後もマージでよければ台帳の方針を `merge` に更新するか確認する) + - **スキップ**: 触らない +2. 選択に応じて処理する -**`.claude/settings.json` のマージ手順** +**`RENAMED`(旧パスが台帳登録されているリネーム)の処理** -`settings.json` は hooks 設定を持つ.team モードのプロジェクトは PreToolUse(`restrict_repo_access.py`)に加えて SessionStart(`check_sync.sh`)を配線しているため,テンプレート版で盲目的に上書きするとプロジェクト固有の配線が失われる.同期担当エージェント(= あなた)が Read と Edit で JSON をマージする: +旧パス `{old}` にプロジェクトの改変があり,テンプレートでは `{new}` にリネームされている.ユーザーに状況を示し,次のいずれかを選ばせる: -1. 既存 `.claude/settings.json` とテンプレート版 `$TEMP_DIR/.claude/settings.json` を Read する -2. 差分を表示する: - ```bash - diff -u .claude/settings.json "$TEMP_DIR/.claude/settings.json" - ``` -3. **既存の hooks を保持したまま**,テンプレート側で追加・変更された hook(イベント・matcher・command)のみを統合する: - - 既存に無いイベント/hook はテンプレート版から追加する - - プロジェクト固有の hook(team の SessionStart `check_sync.sh` 等)は残す - - 同一 hook の command 変更(例: `restrict_repo_access.py` の起動方法変更)はテンプレート版に合わせる - - solo モードで SessionStart(check_sync) が無い場合は,team 専用の配線を勝手に追加しない -4. `git diff .claude/settings.json` で結果を表示しユーザーに確認する +- プロジェクト版(旧パス)を新パスへ `git mv` し,その上で台帳の方針(`keep` / `merge` / `ask`)に従って処理する(既定の推奨).台帳のパスも新パスに書き換える +- テンプレート版を新パスに `cp` し,旧パスは 5.7 の削除確認に回す(改変を破棄.台帳の行を削除する) -### 5.5 削除候補の確認 +### 5.6 未登録改変ファイルの確認 -削除候補(D およびリネーム元)を抽出し,**ローカルに実在するファイルだけ**に絞る: +`$WORK_DIR/diverged.tsv` が空でない場合,ユーザーにまとめて提示する: -```bash -DELETIONS=$(echo "$CHANGED_ENTRIES" | awk -F'\t' '$1 == "D" {print $2} $1 ~ /^R/ {print $2}') +「**⚠ 台帳に未登録ですが,プロジェクト側で改変されているテンプレート由来ファイルがあります(上書きしていません):** -# ローカルに実在するファイルのみを削除候補に残す -DELETIONS=$(echo "$DELETIONS" | while IFS= read -r f; do - [ -n "$f" ] && [ -f "$f" ] && echo "$f" -done) -``` +- `{file}`(前回同期版との差分 {N} 行)/ `{file}`(前回同期版に無し: プロジェクト独自ファイル) -この実在フィルタにより,テンプレート側のリネームや過去の移行でプロジェクトが持っていない旧パス,solo モードに配置されないチーム層ファイルは,削除確認に出ることなく自動的に除外される. +各ファイルについて処理を選んでください: + +1. **意図的な改変 → マージ**(プロジェクトの改変を保持しつつテンプレートの差分を取り込む.台帳に `merge` で登録) +2. **意図的な改変 → 保持**(テンプレート側の変更を取り込まない.台帳に `keep` で登録) +3. **意図しない差分 → 上書き**(テンプレート版で置換) + +判断材料としてプロジェクト側の改変内容を表示します.」 + +→ 各ファイルについて `show_project_delta "$file"` を表示する(長い場合は要約し,全文は求めに応じて出す). + +ユーザーの選択に応じて処理する: + +- **マージ**: 5.5 の `merge` の処理を行い,台帳の「台帳」表に `| \`{file}\` | merge | {ユーザーから聞いた理由} | {今日の日付} |` を追記する +- **保持**: 触らない.台帳に `keep` で同様に追記する +- **上書き**: `cp "$TEMP_DIR/$file" "$file"` で置換する +- `nobase`(テンプレート新規追加パスにプロジェクト独自ファイルが既にある)の場合は base が無いためマージできない.「保持(`keep` 登録)」「上書き」「プロジェクト版を別名に退避してテンプレート版を配置」から選ばせる + +理由を聞かずに勝手に台帳へ登録しない(理由は次回同期の判断根拠になる).ユーザーが理由を省略した場合は「(理由未記入.次回同期時に確認)」と記録する. + +### 5.7 削除候補の確認 + +`reference.md`「削除候補の抽出」で,削除候補(D およびリネーム元)のうち**ローカルに実在するファイルだけ**を `$DELETIONS` に得る.さらに台帳の方針で振り分ける: + +- 台帳で `keep` のファイルは削除候補から**自動的に除外**し,「📒 `{file}` はテンプレートから削除されましたが台帳で `keep` のため残します」と通知する +- 台帳で `merge` / `ask` のファイル,および 5.5 の `RENAMED` で「テンプレート版を採用」を選んだ旧パスは削除候補に残し,一覧に「(台帳: {方針}.理由: {理由})」を添えて確認する.削除する場合は台帳の行も削除する `$DELETIONS` が空でない場合,ユーザーに確認を求める: @@ -345,14 +266,15 @@ プロジェクトからも削除してよいですか?(残したいファイルがあれば指定してください)」 -ユーザー確認後,対象ファイルを `rm` で削除する.プロジェクトが独自に残したいファイルは削除対象から除外する. +ユーザー確認後,対象ファイルを `rm` で削除する.プロジェクトが独自に残したいファイルは削除対象から除外する(今後も残すなら台帳に `keep` で登録するよう勧める). -### 5.6 同期済み SHA の記録とクリーンアップ +### 5.8 台帳の整合チェック -```bash -echo "$NEW_SHA" > .claude/template-sync-sha -rm -rf "$TEMP_DIR" -``` +`reference.md`「台帳の整合チェック」で,台帳に登録されているのにテンプレート最新版に存在しないパスを列挙する.該当があれば「⚠ 台帳の以下のパスはテンプレートに存在しません.リネーム/削除に追従してパスを直すか,プロジェクト独自ファイルなら台帳から行を削除してください: {一覧}」と通知する(自動では書き換えない). + +### 5.9 同期済み SHA の記録とクリーンアップ + +`reference.md`「クリーンアップ」を実行する(`.claude/template-sync-sha` に `$NEW_SHA` を記録し,`$TEMP_DIR`・`$WORK_DIR` を削除). ## ステップ 6: 変更内容の分析 @@ -385,6 +307,7 @@ - ブランチ: `{ブランチ名}` - 開発モード: `{PROJECT_MODE}`(チーム層ファイルは {team: 同期対象 / solo: スキップ}) - 取り込んだ変更: {変更の要約} +- プロジェクト固有改変: 台帳登録 {N} 件を処理(keep {a} / merge {b} / ask {c}),未登録改変 {M} 件を確認(台帳に {K} 件追加) - コード修正: {あり(内容)/なし} `/commit push` でプッシュと PR 作成ができます.」 @@ -395,13 +318,13 @@ ## 注意事項 -- 本コマンドは一時ディレクトリ(`mktemp -d`)に clone したテンプレートを Read / `cp` / `rm -rf` する.`restrict_repo_access.py` フックはシステム一時ディレクトリを許可ゾーンとして例外扱いしており,本コマンドはそれに依存している(フックの例外を外すと本コマンドが動かなくなる) +- 本コマンドは一時ディレクトリ(`mktemp -d`)に clone したテンプレートを Read / `cp` / `rm -rf` し,作業ファイルも一時ディレクトリに置く.`restrict_repo_access.py` フックはシステム一時ディレクトリを許可ゾーンとして例外扱いしており,本コマンドはそれに依存している(フックの例外を外すと本コマンドが動かなくなる) - テンプレートリポジトリへの push は行わない - コード修正はユーザーの確認なしに実行しない -- マージ必須ファイル(`.gitignore`, `CLAUDE.md`, `docs/PROGRESS.md`, `.gitattributes`, `.claude/settings.json`)は必ずステップ 5.4 の手順でマージする.盲目的な `cp` で上書きしない(フレームワーク固有の除外ルールやプロジェクト固有セクションが失われる) +- マージ必須ファイル(冒頭の表)は必ずステップ 5.4 の手順でマージする.盲目的な `cp` で上書きしない(フレームワーク固有の除外ルール,プロジェクト固有セクション,team の SessionStart(check_sync) 配線等が失われる) +- `/sync-template` は**プロジェクトの改変を黙って消さない**ことを最優先にする.テンプレート改変台帳(`.claude/template-overrides.md`)に登録されたファイルは `cp` せず方針(`keep` / `merge` / `ask`)に従ってステップ 5.5 で処理し,台帳に無くても前回同期版と内容が異なるローカルファイルは上書きせずステップ 5.6 でユーザーに確認する.判断に迷う場合は上書きせずユーザーに問う +- 台帳への登録は必ず理由を添える(ユーザーから聞く).理由の無い登録は次回同期時の判断材料にならない.台帳の書式(パス列はバッククォート囲み,方針列は `keep` / `merge` / `ask`)を崩さない - 同期対象外ファイル(`README.md`)はテンプレート紹介用のためプロジェクトには反映しない.テンプレート側で追加・変更・削除があってもプロジェクトの該当ファイルは触らない -- チーム層ファイル(`GUIDE_03`/`task-*`/`check_sync.sh`)は `.claude/project-mode` が `team` のプロジェクトにのみ同期する.`solo`(または未設定)のプロジェクトには配置・更新・削除いずれもしない.`/sync-template` は「版の追従」のみを行い,**モードの切り替えはしない**.solo↔team の切替は `/set-mode ` を使う(team 層ファイルの配置/削除・`settings.json` 配線・`CLAUDE.md` の team 化/solo 化・`project-mode` 更新を一括で行う).`.claude/project-mode` を手で書き換えるだけでは切り替わらない -- `.claude/settings.json` はマージ必須ファイル.team の SessionStart(check_sync) 配線を保持したままテンプレートの hook 変更を統合する.盲目的な `cp` で上書きしない -- 通常コピー対象でもプロジェクト固有の変更が上書きされうる場合は,`git diff` で確認してユーザーに報告する -- テンプレートが管理するのは `.claude/` 配下のうち `agents/`,`skills/`,`rules/`,`hooks/`,`settings.json`,`template-sync-sha` のみ.`.claude/plans/` や `.claude/commit-context.md` 等のプロジェクト固有ファイルはテンプレートに含まれないため同期対象外 +- チーム層ファイル(`GUIDE_03`/`check_sync.sh`)は `.claude/project-mode` が `team` のプロジェクトにのみ同期する.`task-*` skill は共通層のためモードに関わらず同期する.`solo`(または未設定)のプロジェクトには配置・更新・削除いずれもしない.`/sync-template` は「版の追従」のみを行い,**モードの切り替えはしない**.solo↔team の切替は `/set-mode ` を使う(team 層ファイルの配置/削除・`settings.json` 配線・`CLAUDE.md` の team 化/solo 化・`project-mode` 更新を一括で行う).`.claude/project-mode` を手で書き換えるだけでは切り替わらない +- テンプレートが管理するのは `.claude/` 配下のうち `agents/`,`skills/`,`rules/`,`hooks/`,`settings.json`,`template-sync-sha`,`template-overrides.md`(雛形のみ.登録内容はプロジェクト固有)のみ.`.claude/plans/` や `.claude/commit-context.md` 等のプロジェクト固有ファイルはテンプレートに含まれないため同期対象外 - `chore/sync-template` ブランチは他の作業ブランチと混ぜず,作成後は速やかにマージすること.複数の作業ブランチで `/sync-template` を実行すると `.claude/template-sync-sha` がコンフリクトする.コンフリクト時は新しい(HEAD 側の)SHA を採用すること. diff --git a/.claude/skills/sync-template/reference.md b/.claude/skills/sync-template/reference.md new file mode 100644 index 0000000..355b38c --- /dev/null +++ b/.claude/skills/sync-template/reference.md @@ -0,0 +1,391 @@ +# テンプレート同期リファレンス (Template Sync Reference) + +`/sync-template`(`SKILL.md`)の各ステップから参照される bash ヘルパーと個別処理の詳細手順.方針(どのファイルをどう扱うか)と全体フローは `SKILL.md` が定義し,本ファイルはその「実装」を持つ. + +前提となるシェル変数(`SKILL.md` ステップ 2〜3 で設定): + +- `TEMP_DIR`: テンプレートを clone した一時ディレクトリ +- `NEW_SHA`: テンプレート HEAD の SHA +- `LAST_SHA`: 前回同期時のテンプレート SHA(`.claude/template-sync-sha`.初回同期では空) +- `CHANGED_ENTRIES`: `git diff --name-status` 形式の変更一覧(`statusfile[newfile]`) + +## 変数・判定ヘルパー (Variables & Helpers) + +ステップ 5.2 で定義する.以降のすべての処理が依存する: + +```bash +MERGE_FILES=(".gitignore" "CLAUDE.md" "docs/PROGRESS.md" ".gitattributes" ".claude/settings.json" ".claude/template-overrides.md") +SKIP_FILES=("README.md") +TEAM_LAYER_FILES=( + "docs/01_GUIDE/GUIDE_03_チーム開発ルール.md" + ".claude/hooks/check_sync.sh" +) +OVERRIDES_FILE=".claude/template-overrides.md" + +# 作業用ファイル(コピーループは pipe のサブシェルで回るため,結果はファイルに書き出す) +WORK_DIR=$(mktemp -d) +: > "$WORK_DIR/overrides.tsv" # 台帳登録ファイル: statusfilepolicy(リネームは RENAMED旧新policy) +: > "$WORK_DIR/diverged.tsv" # 未登録改変ファイル: statusfile(base|nobase) + +# プロジェクトの開発モードを取得(未設定なら安全側で solo 扱い) +if [ -f .claude/project-mode ]; then + PROJECT_MODE=$(tr -d '[:space:]' < .claude/project-mode) +else + PROJECT_MODE="solo" +fi + +is_merge_file() { + local t="$1" + for f in "${MERGE_FILES[@]}"; do + [ "$f" = "$t" ] && return 0 + done + return 1 +} + +is_skip_file() { + local t="$1" + for f in "${SKIP_FILES[@]}"; do + [ "$f" = "$t" ] && return 0 + done + return 1 +} + +is_team_layer_file() { + local t="$1" + for f in "${TEAM_LAYER_FILES[@]}"; do + [ "$f" = "$t" ] && return 0 + done + return 1 +} + +# 台帳(.claude/template-overrides.md)から対象パスの方針(keep/merge/ask)を返す.未登録なら空 +# - 「台帳」節以外の表やコードブロック内の行は読まない +# - 末尾 / の行はディレクトリ指定(前方一致) +override_policy() { + local t="$1" + [ -f "$OVERRIDES_FILE" ] || return 0 + awk -F'|' -v target="$t" ' + /^```/ { infence = !infence; next } + infence { next } + /^## / { insec = ($0 ~ /^## 台帳/) ; next } + !insec { next } + /^\|/ { + p=$2; gsub(/^[ \t]+|[ \t]+$/, "", p); gsub(/`/, "", p) + pol=$3; gsub(/^[ \t]+|[ \t]+$/, "", pol) + if (pol != "keep" && pol != "merge" && pol != "ask") next + if (p == target) { print pol; exit } + if (substr(p, length(p)) == "/" && index(target, p) == 1) { print pol; exit } + }' "$OVERRIDES_FILE" +} + +# 台帳に登録されている全パスを列挙する(整合チェック用) +override_paths() { + [ -f "$OVERRIDES_FILE" ] || return 0 + awk -F'|' ' + /^```/ { infence = !infence; next } + infence { next } + /^## / { insec = ($0 ~ /^## 台帳/) ; next } + !insec { next } + /^\|/ { + p=$2; gsub(/^[ \t]+|[ \t]+$/, "", p); gsub(/`/, "", p) + pol=$3; gsub(/^[ \t]+|[ \t]+$/, "", pol) + if (pol == "keep" || pol == "merge" || pol == "ask") print p + }' "$OVERRIDES_FILE" +} + +# ローカルの既存ファイルが前回同期版($LAST_SHA 時点のテンプレート版)から改変されているか +# 戻り値 0: 改変あり(stdout に base|nobase),1: 改変なし/判定不能 +is_diverged() { + local t="$1" + [ -n "$LAST_SHA" ] && [ -f "$t" ] || return 1 + if git -C "$TEMP_DIR" cat-file -e "$LAST_SHA:$t" 2>/dev/null; then + # 改行コード差(CRLF/LF)は改変とみなさない + if git -C "$TEMP_DIR" show "$LAST_SHA:$t" | diff -q --strip-trailing-cr - "$t" >/dev/null 2>&1; then + return 1 + fi + echo base; return 0 + fi + # 前回同期版に存在しない(テンプレート新規追加)のにローカルに既にある → 独自ファイル + echo nobase; return 0 +} + +# テンプレート側の差分(前回同期版 → 最新): 何が変わったのかを示す +show_template_delta() { # $1=file + if [ -n "$LAST_SHA" ] && git -C "$TEMP_DIR" cat-file -e "$LAST_SHA:$1" 2>/dev/null; then + git -C "$TEMP_DIR" diff "$LAST_SHA" HEAD -- "$1" + else + echo "(前回同期版なし: テンプレート最新版を全文表示)"; cat "$TEMP_DIR/$1" + fi +} + +# プロジェクト側の改変(前回同期版 → プロジェクト現行): 何を守るべきかを示す +show_project_delta() { # $1=file + if [ -n "$LAST_SHA" ] && git -C "$TEMP_DIR" cat-file -e "$LAST_SHA:$1" 2>/dev/null; then + git -C "$TEMP_DIR" show "$LAST_SHA:$1" | diff -u --strip-trailing-cr --label "template@$LAST_SHA" --label "project" - "$1" + else + diff -u --strip-trailing-cr --label "template@HEAD" --label "project" "$TEMP_DIR/$1" "$1" + fi +} + +# 3-way マージ: base=前回同期版, ours=プロジェクト, theirs=テンプレート最新 +# 戻り値 0: 競合なく $1 を更新, 1: 競合あり($WORK_DIR/merged/$1 に競合マーカー付き結果), 2: base 無しで実行不可 +three_way_merge() { # $1=file + local f="$1" base ours theirs out + [ -n "$LAST_SHA" ] && git -C "$TEMP_DIR" cat-file -e "$LAST_SHA:$f" 2>/dev/null || return 2 + mkdir -p "$WORK_DIR/3way/$(dirname "$f")" "$WORK_DIR/merged/$(dirname "$f")" + base="$WORK_DIR/3way/$f.base"; ours="$WORK_DIR/3way/$f.ours"; theirs="$WORK_DIR/3way/$f.theirs" + out="$WORK_DIR/merged/$f" + # 改行コードを LF に揃えてからマージする(CRLF 混在で全行競合するのを防ぐ) + git -C "$TEMP_DIR" show "$LAST_SHA:$f" | sed 's/\r$//' > "$base" + sed 's/\r$//' "$f" > "$ours" + sed 's/\r$//' "$TEMP_DIR/$f" > "$theirs" + if git merge-file -p --diff3 -L project -L "template@$LAST_SHA" -L template@HEAD "$ours" "$base" "$theirs" > "$out"; then + cp "$out" "$f"; return 0 + fi + return 1 +} +``` + +## 変更一覧の差分サマリー (Diff Summary) + +ステップ 4 で,マージ必須ファイル・台帳登録ファイルに変更がある場合に先出しする情報を取得する. + +マージ必須ファイルの差分プレビュー(該当ファイルが変更対象かつ既存ファイルがある場合のみ出力): + +```bash +# 既存ファイル行数 +wc -l "${MERGE_FILES[@]}" 2>/dev/null + +# テンプレート側の実効行数(.gitignore) +grep -vE '^\s*(#|$)' "$TEMP_DIR/.gitignore" | wc -l + +# 既存ファイルとテンプレート最新版の差分プレビュー +for f in "${MERGE_FILES[@]}"; do + [ -f "$f" ] && [ -f "$TEMP_DIR/$f" ] && { echo "=== $f ==="; diff -u "$f" "$TEMP_DIR/$f" | head -50; } +done +``` + +台帳登録ファイルの抽出(`CHANGED_ENTRIES` の A/M/R 対象のうち `override_policy` が空でないもの): + +```bash +echo "$CHANGED_ENTRIES" | while IFS=$'\t' read -r status file newfile; do + case "$status" in + A|M) t="$file" ;; + R*) t="$newfile" ;; + *) continue ;; + esac + p=$(override_policy "$t") + [ -n "$p" ] && echo "$t ($p)" +done +``` + +## 通常コピーループ (Copy Loop) + +ステップ 5.3 で実行する.判定は「同期対象外 → solo のチーム層 → マージ必須(既存あり)→ 台帳登録(既存あり)→ 未登録改変 → `cp`」の順.`cp` しなかったものはそれぞれ後段で処理する: + +```bash +echo "$CHANGED_ENTRIES" | while IFS=$'\t' read -r status file newfile; do + [ -z "$status" ] && continue + case "$status" in + A|M) + # 同期対象外ファイルは完全にスキップ(コピーも上書きもしない) + if is_skip_file "$file"; then + continue + fi + # solo モードではチーム層ファイルを完全スキップ(再配置しない) + if [ "$PROJECT_MODE" = "solo" ] && is_team_layer_file "$file"; then + continue + fi + # マージ必須ファイルで既存ファイルがある場合は 5.4 で処理 + if is_merge_file "$file" && [ -f "$file" ]; then + continue + fi + # 台帳登録済みのプロジェクト固有改変ファイル(既存あり)は 5.5 で方針に従って処理 + policy=$(override_policy "$file") + if [ -n "$policy" ] && [ -f "$file" ]; then + printf '%s\t%s\t%s\n' "$status" "$file" "$policy" >> "$WORK_DIR/overrides.tsv" + continue + fi + # 台帳に無いが前回同期版から改変されているファイルは上書きせず 5.6 で確認 + if kind=$(is_diverged "$file"); then + printf '%s\t%s\t%s\n' "$status" "$file" "$kind" >> "$WORK_DIR/diverged.tsv" + continue + fi + mkdir -p "$(dirname "$file")" + cp "$TEMP_DIR/$file" "$file" + ;; + R*) + # file=旧パス, newfile=新パス + if is_skip_file "$newfile"; then + continue + fi + if [ "$PROJECT_MODE" = "solo" ] && is_team_layer_file "$newfile"; then + continue + fi + if is_merge_file "$newfile" && [ -f "$newfile" ]; then + continue + fi + policy=$(override_policy "$newfile") + if [ -n "$policy" ] && [ -f "$newfile" ]; then + printf '%s\t%s\t%s\n' "$status" "$newfile" "$policy" >> "$WORK_DIR/overrides.tsv" + continue + fi + # 旧パスが台帳登録されている場合は,新パスに改変を引き継ぐべきか 5.5 で確認する + oldpolicy=$(override_policy "$file") + if [ -n "$oldpolicy" ] && [ -f "$file" ]; then + printf 'RENAMED\t%s\t%s\t%s\n' "$file" "$newfile" "$oldpolicy" >> "$WORK_DIR/overrides.tsv" + continue + fi + if kind=$(is_diverged "$newfile"); then + printf '%s\t%s\t%s\n' "$status" "$newfile" "$kind" >> "$WORK_DIR/diverged.tsv" + continue + fi + mkdir -p "$(dirname "$newfile")" + cp "$TEMP_DIR/$newfile" "$newfile" + ;; + esac +done +``` + +## マージ必須ファイルの個別手順 (Merge Procedures) + +ステップ 5.4 で,`$CHANGED_ENTRIES` に A/M/R* で含まれ,かつ既存ファイルが存在するマージ必須ファイルを以下の手順で処理する. + +### `.gitignore` + +1. 既存 `.gitignore` とテンプレート `$TEMP_DIR/.gitignore` を読む +2. テンプレート側の**実効行**(コメント `#` 行・空行を除く)を抽出する: + + ```bash + grep -vE '^\s*(#|$)' "$TEMP_DIR/.gitignore" + ``` + +3. 抽出した各行について,既存ファイルに完全一致で含まれていないものだけを収集する +4. 収集した行がある場合,既存ファイル末尾に以下のマーカー付きブロックで追記する: + + ```text + + # --- from template (sync-template) --- + {追加行} + ``` + + - 既存ファイル末尾に同じマーカーが既にある場合は,マーカー以降に追記して重複マーカーを作らない +5. `git diff .gitignore` で結果を表示しユーザーに確認する + +### `CLAUDE.md` + +同期担当エージェント(= あなた)が Read と Edit ツールを使ってセクション単位でマージする: + +1. 既存 `CLAUDE.md` とテンプレート版 `$TEMP_DIR/CLAUDE.md` を Read する +2. テンプレート側の変更箇所を特定する(初回同期は LAST_SHA がないためテンプレート全体を「更新候補」として扱う): + + ```bash + if [ -n "$LAST_SHA" ]; then + git -C "$TEMP_DIR" show "$LAST_SHA:CLAUDE.md" 2>/dev/null > "$WORK_DIR/claude_md_old" || true + diff -u "$WORK_DIR/claude_md_old" "$TEMP_DIR/CLAUDE.md" + fi + ``` + +3. セクションを以下の基準で分類する: + - **共通セクション(テンプレート管理,更新対象)**: 「必須ルール」「エージェントチーム」「Git 運用」「ドキュメント」節など,テンプレートに由来する節 + - **プロジェクト固有セクション(保持対象)**: 「プロジェクト名」「開発進捗」や,プロジェクトが追加した固有規約の節 +4. テンプレート側で変更があった共通セクションのみを Edit で既存ファイルに反映する.プロジェクト固有セクションは一切触らない +5. `git diff CLAUDE.md` で結果を表示しユーザーに確認する + +### `docs/PROGRESS.md` + +プロジェクト固有の進捗ログのため,**既存ファイルがある場合は内容を上書きしない**.テンプレート側の更新は骨組み(タイトル・案内コメント)に限定されるはずなので,差分があれば通知のみ行い手動マージを促す: + +1. 既存 `docs/PROGRESS.md` とテンプレート版 `$TEMP_DIR/docs/PROGRESS.md` を Read する +2. 差分を表示する: + + ```bash + diff -u docs/PROGRESS.md "$TEMP_DIR/docs/PROGRESS.md" + ``` + +3. 差分がある場合,「⚠ テンプレート側の `docs/PROGRESS.md` 骨組みに変更があります.既存の追記内容を保持したまま骨組みを反映したい場合はファイルを直接編集してください.自動マージは行いません.」と通知する +4. 既存ファイルが無い稀なケース(テンプレートを使わずに作られた古いプロジェクト等)に限り,テンプレート版をそのまま `cp` で配置する + +### `.gitattributes` + +1. 既存ファイルとテンプレート版の差分を表示する: + + ```bash + diff -u .gitattributes "$TEMP_DIR/.gitattributes" + ``` + +2. ユーザーに以下のいずれかを選ばせる: + - **上書き**: テンプレート版で既存を置換 + - **マージ**: 両者のルールを統合(具体的な統合内容は対話で決定) + - **スキップ**: 既存ファイルを維持 +3. 選択に応じて処理する + +### `.claude/settings.json` + +`settings.json` は hooks 設定を持つ.team モードのプロジェクトは PreToolUse(`restrict_repo_access.py`)に加えて SessionStart(`check_sync.sh`)を配線しているため,テンプレート版で盲目的に上書きするとプロジェクト固有の配線が失われる.同期担当エージェント(= あなた)が Read と Edit で JSON をマージする: + +1. 既存 `.claude/settings.json` とテンプレート版 `$TEMP_DIR/.claude/settings.json` を Read する +2. 差分を表示する: + + ```bash + diff -u .claude/settings.json "$TEMP_DIR/.claude/settings.json" + ``` + +3. **既存の hooks を保持したまま**,テンプレート側で追加・変更された hook(イベント・matcher・command)のみを統合する: + - 既存に無いイベント/hook はテンプレート版から追加する + - プロジェクト固有の hook(team の SessionStart `check_sync.sh` 等)は残す + - 同一 hook の command 変更(例: `restrict_repo_access.py` の起動方法変更)はテンプレート版に合わせる + - solo モードで SessionStart(check_sync) が無い場合は,team 専用の配線を勝手に追加しない +4. `hooks` 以外のキーも同じ方針でマージする.特に `permissions.allow` は,テンプレート側に追加されたルール(`Bash(gh pr merge:*)` 等.auto mode で ops-runner にマージを実行させるために必要)を既存へ追加し,プロジェクトが独自に足したルールは残す(削除しない) +5. `git diff .claude/settings.json` で結果を表示しユーザーに確認する.**permissions の変更はセッション再起動後に反映される**ため,追加があった場合は再起動が必要な旨をユーザーに伝える + +### `.claude/template-overrides.md` + +テンプレート改変台帳はプロジェクト固有の記録のため,**既存ファイルがある場合は内容を上書きしない**(`docs/PROGRESS.md` と同じ扱い): + +1. 差分を表示する: + + ```bash + diff -u .claude/template-overrides.md "$TEMP_DIR/.claude/template-overrides.md" + ``` + +2. 差分が骨組み(説明文・記入例)のみであれば,「⚠ テンプレート側の `.claude/template-overrides.md` の説明文に変更があります.台帳の行を保持したまま反映したい場合はファイルを直接編集してください.自動マージは行いません」と通知する +3. 既存ファイルが無い場合(本機能導入前に作られたプロジェクト)に限り,テンプレート版の雛形をそのまま `cp` で配置し,「台帳を新設しました.テンプレート由来ファイルを意図的に変更している箇所があれば登録してください(`.claude/rules/template-customization.md`)」と案内する + +## 削除候補の抽出 (Deletion Candidates) + +ステップ 5.7 で,削除候補(D およびリネーム元)を抽出し,**ローカルに実在するファイルだけ**に絞る: + +```bash +DELETIONS=$(echo "$CHANGED_ENTRIES" | awk -F'\t' '$1 == "D" {print $2} $1 ~ /^R/ {print $2}') + +# ローカルに実在するファイルのみを削除候補に残す +DELETIONS=$(echo "$DELETIONS" | while IFS= read -r f; do + [ -n "$f" ] && [ -f "$f" ] && echo "$f" +done) +``` + +この実在フィルタにより,テンプレート側のリネームや過去の移行でプロジェクトが持っていない旧パス,solo モードに配置されないチーム層ファイルは,削除確認に出ることなく自動的に除外される.台帳の方針による振り分け(`keep` は自動除外等)は `SKILL.md` ステップ 5.7 に従う. + +## 台帳の整合チェック (Override Consistency Check) + +ステップ 5.8 で,台帳に登録されているのにテンプレート最新版に存在しないパスを列挙する(リネーム・削除済み,またはパスの記入ミス): + +```bash +override_paths | while IFS= read -r p; do + [ -z "$p" ] && continue + case "$p" in + */) [ -d "$TEMP_DIR/$p" ] || echo "$p" ;; + *) [ -f "$TEMP_DIR/$p" ] || echo "$p" ;; + esac +done +``` + +## クリーンアップ (Cleanup) + +ステップ 5.9 で同期済み SHA を記録し,一時ディレクトリを削除する: + +```bash +echo "$NEW_SHA" > .claude/template-sync-sha +rm -rf "$TEMP_DIR" "$WORK_DIR" +``` diff --git a/.claude/skills/task-create/SKILL.md b/.claude/skills/task-create/SKILL.md new file mode 100644 index 0000000..b8bd98d --- /dev/null +++ b/.claude/skills/task-create/SKILL.md @@ -0,0 +1,47 @@ +--- +name: task-create +model: inherit +description: "Issue を作成しボードに追加する(着手はしない).タスクの事前計画用.solo / team 両モードで使用できる." +argument-hint: "<タスクの説明>" +--- + +あなたはタスク計画の司令塔です.Issue の**中身(タイトル・本文)はあなたが作り**,gh での起票・ボード操作は **ops-runner エージェント**(軽量モデル)に委譲します(使用量節約のため,gh 操作を自分では行わない). + +本スキルは **solo / team 両モードで使用できる**.team モードでは GUIDE_03(チーム開発ルール)のタスク管理方針にも従うこと.solo モードでは GUIDE_03 は存在しないため,本スキルと `.claude/skills/task-start/reference.md` の記述を基準とする. + +本コマンドは**タスクを事前に定義する**ためのものです.着手は別途 `/task-start ` で行います(または手動で).Issue はどの段階でも必須ではなく,Issue 無しで進める作業はこのコマンドを使う必要はありません. + +## ステップ 1: 前提確認 (Pre-check) + +$ARGUMENTS(タスクの説明)が指定されているか確認する.指定がなければ「タスクの説明を指定してください」と伝えて終了する. + +## ステップ 2: Issue 内容の作成 (Compose) + +$ARGUMENTS とセッションの文脈から,Issue タイトルと本文を確定させる(ここが品質の要.委譲しない). + +- **やること**は必ず書く +- **完了条件(受け入れ基準)**は非自明な場合のみ書く +- 担当者は**アサインしない**(誰が拾うかは着手時に決まる) + +## ステップ 3: 委譲 (Delegate) + +ops-runner エージェントを起動し,プロンプトに以下を含める: + +- 手順書: `.claude/skills/task-start/reference.md` の「/task-create 実行手順」を読んで従うこと +- 確定した Issue タイトル・本文(そのまま使い,書き換えないこと) +- 確認が必要な事態では停止して報告すること + +エージェントが確認事項(Project が複数ある等)で停止した場合は,ユーザーに確認して再委譲する. + +## ステップ 4: 完了サマリー (Summary) + +エージェントの報告をもとに以下を提示する: + +- **Issue**: 番号・タイトル・URL +- **ボード**: Todo(Project が無い場合は「未追加(ボード未使用)」と表記する) +- **次の手順**: 「このタスクに着手する場合は `/task-start ` を実行してください.」 + +## 注意事項 (Notes) + +- 複数タスクを一括で作る場合は,本コマンドを複数回実行してください +- Projects 操作には `project` スコープが必要.スコープエラーの停止報告が来たら `gh auth refresh -s project` をユーザーに案内する(`.claude/skills/task-start/reference.md`「必要なスコープ」) diff --git a/.claude/skills/task-handoff/SKILL.md b/.claude/skills/task-handoff/SKILL.md new file mode 100644 index 0000000..dcf4d98 --- /dev/null +++ b/.claude/skills/task-handoff/SKILL.md @@ -0,0 +1,94 @@ +--- +name: task-handoff +model: inherit +description: "現在着手中の Issue に進捗メモ(完了済み・残タスク・確定事項・git 状態・再開方法)をコメントで投稿する.セッション中断・引継ぎ用.solo / team 両モードで使用できる." +argument-hint: "<追加メモ(省略可)>" +--- + +あなたは作業引継ぎの司令塔です.現在**着手中**の Issue に,次セッション・次メンバーが再開できるだけの情報を進捗メモとして投稿します.引継ぎメモの**中身はあなたが書き**(セッションの文脈を知っているのはあなただけ),Issue の特定・git 状態の収集・コメント投稿は **ops-runner エージェント**(軽量モデル)に委譲します. + +本スキルは **solo / team 両モードで使用できる**.引継ぎ情報は Issue コメントに集約する. + +- **team モード**: GUIDE_03(チーム開発ルール)の「進捗は Issues / Projects と git 履歴で追う」方針に沿う(`CLAUDE.md` に進捗は書かない) +- **solo モード**: 通常の進捗記録(`.claude/rules/progress-log.md`.`CLAUDE.md` 進捗欄+ `docs/PROGRESS.md`)は従来どおり運用し,本スキルはタスク単位の引継ぎメモを Issue に残す補助として使う + +## ステップ 1: 収集の委譲 (Collect) + +ops-runner エージェントを起動し,`.claude/skills/task-start/reference.md` の「/task-handoff 実行手順」の**収集フェーズ**を実行させる. + +- 「着手中 0 件」の報告なら「着手中の Issue がありません.まず `/task-start ` で着手してから本コマンドを使ってください.」と伝えて終了する +- 複数件の報告なら,一覧(番号・タイトル)を示して「どれを対象にしますか?」とユーザーに確認し,対象を決めて必要な収集を再委譲する + +## ステップ 2: ドラフト生成 (Draft) + +収集データ(Issue 本文・過去コメント・git 状態)と,直近のセッション会話から抽出した「**確定した重要な設計判断**」「**未決定で次に詰める点**」をもとに,以下のフォーマットで進捗メモを生成する.**該当なしのセクションは省略してよい**. + +````markdown +## 進捗メモ (YYYY-MM-DD) + + + +### 完了済み + +| フェーズ / タスク | 成果物 | コミット | +| --- | --- | --- | +| ... | ... | <短縮 SHA> | + +### 残タスク + +- ... + +### 確定した重要な設計判断(再開時の文脈) + +- ... + +### 未決定で次に詰める点 + +- ... + +### 現在の git 状態 + +- ブランチ: `<ブランチ名>` +- HEAD: `<短縮 SHA>` +- 未コミット変更: <あり / なし> + +### 次セッションの再開方法 + +```bash +git checkout <ブランチ名> +``` + +<再開時の指針コメント.例: 「`/setup` を再実行するか,手動でフェーズ N から続行」> +```` + +### ドラフトの粒度方針 + +- **完了済み**: 当該セッションで積んだコミット中心.本 Issue に関わる範囲のみ +- **残タスク**: Issue 本文の TODO や未着手項目を整理 +- **確定した設計判断**: セッション中にユーザーと合意して**今後の作業の前提**になるもの.既に Issue 本文や過去コメントに明記されている内容は重複させない(差分のみ) +- **未決定で次に詰める点**: 次セッションで判断が必要なもの +- **粒度感**: 1 セッション分の引継ぎ.週次レポートではない + +## ステップ 3: 承認 (Approval) + +ドラフトをユーザーに提示し,「**この内容で投稿しますか? 修正点があれば指示してください.**」と確認する. + +ユーザーの明示的な同意(「OK」「投稿して」「これで」等)が得られるまで投稿しない.修正指示があれば反映して再提示する. + +## ステップ 4: 投稿の委譲 (Post) + +ops-runner エージェントを起動し,「/task-handoff 実行手順」の**投稿フェーズ**を実行させる(承認済みの本文をそのまま渡す).返ってきたコメント URL を控える. + +## 完了サマリー (Summary) + +以下を提示する: + +- **Issue**: 番号・タイトル・URL +- **コメント URL** +- **次のステップ**: 「次セッションで再開する場合は `git checkout <ブランチ名>` から始めてください.」 + +## 注意事項 (Notes) + +- 本コマンドは Issue を**クローズしない・Done に動かさない**.着手中のまま残す(作業継続前提).完了させたい場合は別途 `/commit merge` で PR をマージ → `Closes #<番号>` で自動クローズ +- 進捗メモは**コメント**として投稿する.Issue 本文は書き換えない +- Projects 操作には `project` スコープが必要.スコープエラーの停止報告が来たら `gh auth refresh -s project` をユーザーに案内する(`.claude/skills/task-start/reference.md`「必要なスコープ」) diff --git a/.claude/skills/task-start/SKILL.md b/.claude/skills/task-start/SKILL.md new file mode 100644 index 0000000..f584e0c --- /dev/null +++ b/.claude/skills/task-start/SKILL.md @@ -0,0 +1,44 @@ +--- +name: task-start +model: inherit +description: "既存 Issue を拾って作業を開始する(アサイン・ボード In Progress・作業ブランチ作成).solo / team 両モードで使用できる." +argument-hint: "" +--- + +あなたはタスク着手の司令塔です.着手準備(アサイン・ボード操作・作業ブランチ作成)の実行は **ops-runner エージェント**(軽量モデル)に委譲し,あなた自身はユーザー確認の仲介と結果の報告だけを行います(使用量節約のため,git・gh 操作を自分では行わない). + +本スキルは **solo / team 両モードで使用できる**.team モードでは GUIDE_03(チーム開発ルール)にも従うこと.solo モードでは GUIDE_03 は存在しないため,本スキルと本スキルの `reference.md` の記述を基準とする. + +本コマンドは既存 Issue から作業を始めるためのものです.新規 Issue を立てる場合は `/task-create` を使ってください.Issue 無しで小さい変更や試験的作業を進める場合はこのコマンドは不要です. + +## ステップ 1: 前提確認 (Pre-check) + +$ARGUMENTS を確認する.Issue 番号(数値または `#数値`)が指定されていなければ「対象の Issue 番号を指定してください.新規 Issue を立てる場合は `/task-create` を使います」と伝えて終了する. + +## ステップ 2: 委譲 (Delegate) + +ops-runner エージェントを起動し,プロンプトに以下を含める: + +- 手順書: 本スキルの `reference.md`(`.claude/skills/task-start/reference.md`)の「/task-start 実行手順」を読んで従うこと +- 対象の Issue 番号 +- **ブランチ名**: Issue の内容を把握している場合(同セッションで `/task-create` した直後等)は `.claude/rules/git-conventions.md` の命名規則で決めて渡す.把握していなければ ops-runner に規約どおり提案・作成させ,報告で名前を確認する +- 確認が必要な事態(未コミット変更・未マージブランチ・進行中タスクあり・他人アサイン等)では,該当項目をまとめて停止・報告すること + +## ステップ 3: 確認の仲介 (Confirm) + +エージェントが確認事項で停止した場合は,状況をユーザーに提示して判断を仰ぎ,承認された項目を「ユーザー承認済み」と明示して再委譲する. + +## ステップ 4: 完了サマリー (Summary) + +エージェントの報告をもとに以下を提示する: + +- **Issue**: 番号・タイトル・URL +- **ボード**: In Progress(Project が無い場合は「アサインのみ(ボード未使用)」と表記する) +- **ブランチ**: 作成したブランチ名 +- **次の手順**: 「`/implement` に対象 Issue の内容を渡して実装を開始してください(`gh issue view ` で取得できます).」 + +## 注意事項 (Notes) + +- branch↔Issue の紐付けは,後の PR 本文の `Closes #` で行う.ブランチ名には番号を入れない +- Projects 操作には `project` スコープが必要.スコープエラーの停止報告が来たら `gh auth refresh -s project` をユーザーに案内する(`reference.md`「必要なスコープ」) +- 新規 Issue を立てる場合は `/task-create`,Issue 無しで進める場合は本コマンドを使わず直接 `/implement` 等へ diff --git a/.claude/skills/task-start/reference.md b/.claude/skills/task-start/reference.md new file mode 100644 index 0000000..15cb66e --- /dev/null +++ b/.claude/skills/task-start/reference.md @@ -0,0 +1,112 @@ +# Issues・Projects gh 操作リファレンス (gh Operations Reference) + +`/task-create`・`/task-start`・`/task-handoff` の Issue・ボード操作で参照する詳細手順(solo / team 両モード共通). +team モードでの運用方針(Issue = 作業単位,直列運用,ボードの列等)は [GUIDE_03_チーム開発ルール](../../../docs/01_GUIDE/GUIDE_03_チーム開発ルール.md) に従う.solo モードでは GUIDE_03 は配置されないため,本ファイルと各 skill の記述を基準とする. + +- 操作は GitHub CLI(`gh`)に統一する.Web UI でも同じことはできるが,再現性とドキュメント化のため `gh` を基準とする. +- AI に Issue を読ませる場合は `gh issue view ` を使う(構造化出力は `--json title,body,assignees,labels`). + +## 必要なスコープ (Required Scopes) + +`gh` のトークンスコープが操作範囲を決める. + +| 操作 | 必要スコープ | +| --- | --- | +| Issues の読み書き | `repo` | +| Projects の読み書き | `repo` + `project` | + +スコープの確認と追加: + +```bash +gh auth status # 現在のスコープを確認 +gh auth refresh -s project # Projects 用スコープを追加(対話的な再認証が走る) +``` + +## ブランチと Issue のリンク (Branch-Issue Link) + +既存 Issue から作業ブランチを作る場合は `gh issue develop` を使うと,ブランチ作成と Issue↔ブランチのリンクを同時に行える(ブランチ名に依存しないリンク手段): + +```bash +gh issue develop --name feature/<概要> --base main +``` + +## /task-create 実行手順 (task-create Execution Flow) + +`/task-create` の司令塔(メインループ)から,確定済みの Issue タイトル・本文を受け取った ops-runner が実行する. + +1. **Project の特定**: `gh repo view --json owner --jq .owner.login` で所有者を取得し,`gh project list --owner ` で Project を特定する.複数ある場合は停止して確認事項として報告する.見つからない場合はボード追加を飛ばして進める(Project ボードは既定では未使用のため,無くても問題ない) +2. **Issue 作成**: 渡されたタイトル・本文を**そのまま**使い,`gh issue create --title "<タイトル>" --body "<本文>"` で作成する(本文を書き換えない).担当者はアサインしない +3. **ボードに追加**: 「Projects の操作」に従い `item-add` → Status を `Todo` に設定 → `item-list` で結果を確認する(Project が無い場合は飛ばす) +4. **報告**: Issue 番号・タイトル・URL・ボード状態を返す + +## /task-start 実行手順 (task-start Execution Flow) + +`/task-start` の司令塔から Issue 番号を受け取った ops-runner が実行する.ブランチ命名は `.claude/rules/git-conventions.md` に従う. + +1. **前提確認**: `git status` を確認し,未コミットの変更があれば停止して報告する.`git branch --show-current` を確認し,`main` 以外にいる場合は `git log main..HEAD --oneline` で未マージコミットを確認し,残っていれば停止して報告する(直列運用の原則) +2. **直列運用チェック**: 所有者を取得し Project を特定する(複数なら停止して報告.無ければボード操作を飛ばす).進行中の作業を数える(Project があれば `item-list` で Status が `In Progress` のもの,無ければ `gh issue list --assignee @me --state open`).対象 Issue 以外に 1 件以上あれば,該当タスクの一覧を添えて停止して報告する(禁止ではなく原則) +3. **対象 Issue の確認・アサイン**: `gh issue view ` で内容を確認する(存在しない・クローズ済み・他人がアサイン済みの場合は停止して報告する).`gh issue edit --add-assignee @me` で自分をアサインする +4. **ボードを In Progress へ**: 「Projects の操作」に従い,未追加なら `item-add` → Status を `In Progress` に変更 → `item-list` で結果を確認する(Project が無い場合は飛ばす) +5. **作業ブランチ作成**: `git checkout main && git pull origin main` で `main` を最新化し,`git checkout -b <ブランチ名>` する.ブランチ名は司令塔から渡されていればそれを使い,無ければ Issue タイトルから規約どおり(プレフィックス+英単語 2〜4 語.Issue 番号は含めない)決めて,決めた名前とプレフィックスの選択理由を報告に含める +6. **報告**: Issue 番号・タイトル・URL・ボード状態・作成したブランチ名を返す + +※ ステップ 1〜3 の停止条件に複数該当する場合は,まとめて 1 回の報告で返す(司令塔との往復を減らす).司令塔から「ユーザー承認済み」と明示された項目では停止しない. + +## /task-handoff 実行手順 (task-handoff Execution Flow) + +`/task-handoff` の司令塔から委譲される 2 つのフェーズ. + +### 収集フェーズ (Collect) + +1. 所有者を取得し Project を特定する(無くても問題ない).着手中の Issue を抽出する(Project があれば `item-list` で Status が `In Progress` のもの,無ければ `gh issue list --assignee @me --state open`) +2. 0 件ならその旨を報告して終了する.複数件なら一覧(番号・タイトル)を確認事項として返す +3. 対象 Issue について以下を収集して返す: + - `gh issue view --json number,title,body,comments`(本文と過去コメントを**原文のまま**返す.要約・取捨選択はしない.コメントが多い場合は直近の「進捗メモ」コメントを優先して原文で返し,古いものは件数と日付だけにする) + - `git branch --show-current`/`git rev-parse --short HEAD`/`git log main..HEAD --oneline`/`git status --porcelain` + +### 投稿フェーズ (Post) + +1. 司令塔から渡された本文を**そのまま** `gh issue comment --body "<本文>"` で投稿する(書き換えない) +2. コメントの URL を返す + +## Projects の操作 (Projects) + +> ⚠ **Projects(ボード)は既定では未使用**.以下は将来導入時の参考として残す. + +※ `gh project` 系は `project` スコープが必要(「必要なスコープ」参照).`` はリポジトリ所有者(個人またはオーガニゼーション). + +### 参照 (View) + +```bash +gh project list --owner # プロジェクト一覧(Project 番号を確認) +gh project view --owner # プロジェクトの概要 +gh project item-list --owner # ボード上のアイテム一覧 +gh project field-list --owner # フィールド(Status 等)と選択肢の ID を確認 +``` + +### Issue をボードに追加 (Add) + +```bash +gh project item-add --owner --url +``` + +### カードの状態(列)を移す (Move) + +`Status` フィールドの選択肢(`Todo` / `In Progress` 等)を変更する.フィールド ID と選択肢 ID は `field-list` で確認する. + +```bash +gh project item-edit \ + --id <アイテム ID> \ + --project-id <プロジェクト ID> \ + --field-id \ + --single-select-option-id <移動先の選択肢 ID> +``` + +※ ID の確認が煩雑なため,日常のカード移動は Web UI のボードで行い,一覧取得や自動化に `gh` を使う,という使い分けでもよい. + +## トラブルシューティング (Troubleshooting) + +- **`gh project` の書き込み系が無反応に見える**: `create` / `item-add` / `item-edit` は成功しても標準出力が空のことがある.`gh project list` / `item-list` で結果を確認する. +- **`gh project` がスコープエラーになる**: `project` スコープが未付与.`gh auth refresh -s project` を実行する. +- **コラボレーターが操作できない**: 招待を承認していない.`gh api "repos///collaborators" --jq '.[].login'` で承認済みメンバーを確認する. +- **`item-edit` の ID がわからない**: `gh project item-list` でアイテム ID,`gh project field-list` でフィールド ID・選択肢 ID を確認する. diff --git a/.claude/template-overrides.md b/.claude/template-overrides.md new file mode 100644 index 0000000..ad8e738 --- /dev/null +++ b/.claude/template-overrides.md @@ -0,0 +1,30 @@ +# テンプレート改変台帳 (Template Overrides) + +本ファイルは,テンプレート(programming-template)由来のファイルのうち,**このプロジェクトの都合で意図的に変更したもの**を記録する台帳である.`/sync-template` は本台帳を読み,登録されたファイルをテンプレート版で盲目的に上書きせず,方針に従って処理する. +記録の運用ルールは `.claude/rules/template-customization.md` を参照(対象ファイル編集時に自動ロードされる). + +## 記録ルール (How to Record) + +- 1 行 = 1 ファイル.パスはリポジトリルートからの相対パスをバッククォートで囲む.末尾を `/` にするとそのディレクトリ配下すべてが対象になる(例: `` `.claude/skills/implement/` ``) +- 方針は次の 3 つから選ぶ + - `keep`: テンプレート側の変更を取り込まない.テンプレート側に変更があれば通知のみ行う + - `merge`: テンプレート側の差分(前回同期版 → 最新)だけを 3-way マージで取り込み,プロジェクトの改変は保持する(既定の推奨) + - `ask`: 同期のたびに差分を見せて,上書き/マージ/スキップを選ぶ +- 理由には「なぜテンプレートと変えたか」を書く(次回同期時に判断の根拠になる) +- テンプレートに追従する(改変をやめる)ときは行を削除する.次回 `/sync-template` でテンプレート版に上書きされる +- 表のパス列・方針列の書式は崩さない(`/sync-template` が機械的に読む).「台帳」節以外の表や,コードブロック内の行は読まれない + +## 台帳 (Overrides) + +| ファイル | 方針 | 理由 | 記録日 | +| --- | --- | --- | --- | + +## 記入例 (Example) + +```markdown +| ファイル | 方針 | 理由 | 記録日 | +| --- | --- | --- | --- | +| `.claude/skills/implement/SKILL.md` | merge | Phase 2 で E2E テストの実行も必須にしている | 2026-08-21 | +| `.claude/rules/markdown-style.md` | keep | 社内規約に合わせて句読点を「、。」に変更した | 2026-08-21 | +| `.claude/agents/` | ask | モデル指定を全エージェントで変更している.テンプレ側の変更は都度判断する | 2026-08-21 | +``` diff --git a/.claude/template-sync-sha b/.claude/template-sync-sha index 2ba29e0..e4d480a 100644 --- a/.claude/template-sync-sha +++ b/.claude/template-sync-sha Binary files differ diff --git a/.gitignore b/.gitignore index 464e0eb..53f4526 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,9 @@ # .env # .env.* # node_modules/ + +# --- from template (sync-template) --- +# /deps-update のローカル運用状態(マージ済み台帳・報告台帳・スキップ台帳) +.claude/deps-update-merged.md +.claude/deps-update-report.md +.claude/deps-update-skip.md diff --git a/CLAUDE.md b/CLAUDE.md index 3c67cac..3c89ee5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,11 +17,24 @@ ### Git 運用 - ブランチ名・コミットメッセージの書式は `.claude/rules/git-conventions.md` に従う(常時ロードされる) -- コミットは `/commit` を使用する(push・PR 作成は `/commit push`) +- コミットは `/commit` を使用する(push・PR 作成は `/commit push`,マージ・プルまで行う場合は `/commit merge`) - **`/commit` はユーザーが明示的に指示した時のみ実行する.Claude が自発的に `/commit` や `git commit` を呼んではならない**(`/implement` 完了後も,案内するだけで自分ではコミットしない.`/commit` skill は `disable-model-invocation` によりユーザー起動限定として強制されている) - **例外**: 以下の無人運転ループはユーザー承認済みの例外として専用ブランチに自律コミットする.いずれも push・PR・マージ・`main` への操作はしない(取り込みは人間が `/commit push` 等で行う) - `/auto-refactor`(リファクタ/ドキュメント整理ループ)→ `refactor/` 専用ブランチ - `/auto-audit`(バグ/脆弱性の巡回監査ループ)→ `fix/` 専用ブランチ + - **例外(`main` へのマージ)**: `/deps-update` は,Dependabot が作成した依存更新 PR に限り,ゲート(メジャー更新でない・競合なし・CI 緑またはローカル検証緑)を満たすものを `gh pr merge` で `main` に取り込む(ユーザーが明示的に起動した時のみ.メジャー更新・CI 赤・PR が付かない alert は報告して人間が判断する) +- **ops-runner によるマージは承認済みの定常操作**: `/commit merge` および `/deps-update` では,ユーザーが明示的に起動したことを受けて,ops-runner サブエージェント(軽量モデル)が手順書に従い `git push` → `gh pr create` → `gh pr merge --merge --delete-branch` で自リポジトリの PR を `main` にマージする.force push・`--admin`・`main` への直接 push は行わない(権限設定は `docs/01_GUIDE/GUIDE_01` の「Claude Code の権限設定」) + +### テンプレート同期 + +- テンプレートの更新は `/sync-template` で取り込む +- テンプレート由来のファイル(`.claude/agents/`・`skills/`・`rules/`・`hooks/`,`docs/01_GUIDE/`)を**このプロジェクトの都合で意図的に変更した**ときは,`.claude/template-overrides.md`(テンプレート改変台帳)に理由付きで記録する(`.claude/rules/template-customization.md`.該当ファイル編集時に自動ロードされる).記録が無いと次回同期で改変が消えうる + +### タスク管理(任意) + +- やるべきことを GitHub Issues で管理してよい(solo / team 共通).`/task-create`(起票・事前計画)→ `/task-start `(着手準備)→ `/task-handoff`(中断時の引継ぎメモ投稿)を使う +- Issue は必須ではない.小さい変更や試験的作業は Issue 無しで進めてよい +- solo モードでは進捗記録(`.claude/rules/progress-log.md`)は従来どおり運用し,Issue はタスクの管理・引継ぎの補助として使う ### エージェントチーム(GUIDE_02 準拠) @@ -40,6 +53,7 @@ 以下は実装完了後にユーザーへ報告し,確認・実施を依頼すること. - 外部サービスの設定(コンソール操作,セキュリティルール変更等) + - 例外: `gh` CLI で操作できる GitHub リポジトリ設定(Dependabot alerts / security updates の有効化)は Claude が `gh api` で行う(手順は `.claude/skills/setup/reference.md`,背景は GUIDE_01「環境構築」) - 実機・ブラウザでの動作確認 - ストアへのアップロード・リリース作業 @@ -52,7 +66,7 @@ - プロジェクト立ち上げフロー: docs/01_GUIDE/GUIDE_01_プロジェクト立ち上げフロー.md - エージェント運用ルール: docs/01_GUIDE/GUIDE_02_エージェント運用ルール.md -- ※ Git 規約・ドキュメント書式・命名規則・進捗記録は `.claude/rules/`(git-conventions / markdown-style / docs-naming / progress-log)に定義されている(git-conventions は常時,他は該当ファイル編集時に自動ロード) +- ※ Git 規約・ドキュメント書式・命名規則・進捗記録・テンプレート改変記録は `.claude/rules/`(git-conventions / markdown-style / docs-naming / progress-log / template-customization)に定義されている(git-conventions は常時,他は該当ファイル編集時に自動ロード) - ※ コーディング規約・プロジェクト構成・テスト方針・エラー処理は path-scoped rules(`.claude/rules/` の coding-style / project-structure / testing / error-handling)として作成済み(該当ファイル編集時に自動ロード) ### 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 f277852..7ddca5d 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" @@ -23,11 +23,12 @@ | レイヤ | 対象 | 存在するモード | | --- | --- | --- | -| 共通層 | `GUIDE_01`・`GUIDE_02`,`.claude/rules/` のすべて,`.claude/agents/`,skills(`commit`・`implement`・`setup`・`sync-template`・`set-mode`・`auto-refactor`・`auto-audit`) | solo・team 両方 | -| team 層 | `GUIDE_03`,skills(`task-create`・`task-start`(+ `reference.md`)・`task-handoff`),`.claude/hooks/check_sync.sh`,`settings.json` の SessionStart 配線 | team のみ | +| 共通層 | `GUIDE_01`・`GUIDE_02`,`.claude/rules/` のすべて,`.claude/agents/`,`.claude/template-overrides.md`(雛形),skills(`commit`(+ `reference.md`)・`implement`・`setup`(+ `reference.md`)・`sync-template`(+ `reference.md`)・`set-mode`・`auto-refactor`・`auto-audit`・`deps-update`(+ `reference.md`)・`task-create`・`task-start`(+ `reference.md`)・`task-handoff`) | solo・team 両方 | +| team 層 | `GUIDE_03`,`.claude/hooks/check_sync.sh`,`settings.json` の SessionStart 配線 | team のみ | - `.claude/rules/` はすべて共通層だが,進捗記録ルール(`progress-log`)だけは team モードで運用上**上書き**される(進捗は `CLAUDE.md`/`docs/PROGRESS.md` ではなく GitHub Issues と git 履歴で追う.GUIDE_03). - team 層ファイルの配置・削除は `/set-mode` が一括で行い,`/sync-template` は `.claude/project-mode` を見て team 層の同期可否を判定する.team 層ファイルの正確なリストは `/set-mode`・`/sync-template` の定義に持たせており,増減時は両者を一致させること. +- テンプレート由来のファイルをプロジェクトの都合で意図的に変更した場合は,`.claude/template-overrides.md`(テンプレート改変台帳)に方針(`keep` / `merge` / `ask`)と理由を記録する(`.claude/rules/template-customization.md`).`/sync-template` は台帳を読み,登録ファイルをテンプレート版で上書きせず方針に従って処理する.未登録でも前回同期版から改変されたファイルは上書き前に確認される. ## 方針決定 (Direction) @@ -54,10 +55,13 @@ - `gh` — GitHub CLI(PR 作成・マージ等に使用) - **基本方針**: 環境の再現性を重視し,手順書だけに頼らず構築を自動化・コード化できる方法を優先する(例: Docker,Dev Containers,Windows Sandbox,IaC ツール等). - **人間が決めること**: 開発マシンの選定,クラウドサービスのアカウント作成,環境構築方法の選択 -- **AI に依頼できること**: 環境構築手順書の作成,設定ファイルの生成,`.gitignore` の作成,Dockerfile や devcontainer.json 等の構築用ファイルの作成 +- **AI に依頼できること**: 環境構築手順書の作成,設定ファイルの生成,`.gitignore` の作成,Dockerfile や devcontainer.json 等の構築用ファイルの作成,GitHub リポジトリのセキュリティ設定・`.github/dependabot.yml` の生成(後述) +- **GitHub リポジトリのセキュリティ設定**: GitHub の Settings → Code security にある **Dependabot alerts**(既知脆弱性の検出."Vulnerabilities" として表示される)と **Dependabot security updates** はリポジトリごとに既定で OFF のため,リポジトリを作成したら必ず有効化する.モードに関わらず `/setup` が `gh api` で有効化・検証する(コマンド・検証・トラブル対応は `.claude/skills/setup/reference.md`「GitHub リポジトリのセキュリティ設定」).`/setup` 時点でリポジトリが無い場合は,`ENV_03_管理者用環境構築手順.md` に転記した同じコマンドをリポジトリ作成後に実行する. +- **依存バージョン更新(Dependabot version updates)**: 上記とは別に,依存パッケージを定期的に最新化する PR を作らせるため,`/setup` が技術スタックに合わせて `.github/dependabot.yml` を必ず生成する(週 1 回・マイナー/パッチをまとめる・`[update]` プレフィックス.エコシステム対応表と雛形は `.claude/skills/setup/reference.md`「依存バージョン更新の設定」).Dependabot が作る PR と alert の処理は `/deps-update` で行う(ゲートを満たす PR を自動マージし,メジャー更新等は分析付きで報告.GUIDE_02「コミットルール」の例外). +- **Claude Code の権限設定(`.claude/settings.json`)**: テンプレート同梱の `permissions.allow`(`Bash(gh pr merge:*)`)は,auto mode で ops-runner に `/commit merge`・`/deps-update` のマージを実行させるために必要なので削除しない(変更はセッション再起動後に反映).マージが分類器に止められた場合の切り分けと対処は `.claude/skills/commit/reference.md`「gh コマンドが実行される前にブロックされた場合」を参照. - **成果物**: - `ENV_02_環境構築手順.md` — メンバーの参加時や環境の再構築時に使う手順 - - `ENV_03_管理者用環境構築手順.md` — プロジェクト作成時に一度だけ行う初期設定(リポジトリ作成,外部サービスの設定等) + - `ENV_03_管理者用環境構築手順.md` — プロジェクト作成時に一度だけ行う初期設定(リポジトリ作成,GitHub リポジトリのセキュリティ設定,外部サービスの設定等) - `ENV_04_開発コマンド.md`(任意)— アプリの起動・テスト・lint・ビルド等,日常の開発で使うコマンド一覧.人間とエージェント(tester・coder,`/auto-refactor`・`/auto-audit`)がコマンドを推測せずに済むようにするための唯一の参照先とする - 立ち上げ時点で確定しているコマンドが無ければ**作成を後回しにしてよい**.実装中にコマンドが確定・変更された時点で作成・追記する(`/implement` の Phase 4 で自動的に見直される) - コマンドが増えてきたら,タスクランナー(npm scripts・Makefile 等)への集約を優先し,本ファイルは薄い一覧に保つ(「手順書より自動化・コード化」の基本方針と同じ) @@ -73,7 +77,7 @@ ## 規約整備 (Coding Standards) 技術スタックに応じたプロジェクト固有の規約を作成する. -汎用の規約(Git 運用・ドキュメント書式・ファイル命名・進捗記録)はテンプレートの `.claude/rules/` に含まれているため,ここでは技術スタック固有の規約を追加する. +汎用の規約(Git 運用・ドキュメント書式・ファイル命名・進捗記録・テンプレート改変記録)はテンプレートの `.claude/rules/` に含まれているため,ここでは技術スタック固有の規約を追加する. - **基本方針**: 言語・フレームワークの公式ガイドラインや広く採用されている標準規約に則る(例: Effective Dart,PEP 8,Google Style Guide 等).プロジェクト固有のルールは標準と異なる部分のみ定義する. - **置き場所**: 「コードを書くときは常に X せよ」という指示型の規約は,docs ではなく **path-scoped rule**(`.claude/rules/*.md` の frontmatter に `paths:` を付けたもの)として作成する.該当ファイルの編集時に自動ロードされるため,規約の読ませ忘れが起きない.アーキテクチャの背景説明や設計判断の記録など「読み物・参照資料」は従来どおり docs(`04_SPEC`/`05_TECH`)に置く. diff --git "a/docs/01_GUIDE/GUIDE_02_\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_02_\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 91f9daf..429b73d 100644 --- "a/docs/01_GUIDE/GUIDE_02_\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_02_\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" @@ -19,6 +19,16 @@ | `tester` | 仕様ベースのテスト作成・実行 | Phase 2 | | `refactorer` | コード品質の改善 | Phase 3 | +### 補助エージェント (Support Agents) + +実装パイプライン外でも,「思考(判断・文章品質)はメインループ,機械的な実行は軽量エージェント」の分担で使用量を節約する.サブエージェントは新規の小さいコンテキストで起動されるため,メインループのプロンプトキャッシュを壊さずに,安価なモデルにも上位モデルにも切り替えられる(メインのモデル切替はキャッシュ全損になるため行わない).以下は各 skill から起動される補助エージェント. + +| エージェント | 役割 | 使用元 | +| --- | --- | --- | +| `ops-runner` | git・gh・検証コマンドの機械的な実行(手順書に忠実に従い,判断が要る事態では停止して報告する) | `/commit`・`/task-create`・`/task-start`・`/task-handoff`・`/deps-update` | +| `deps-analyst` | 依存更新 1 件の影響分析(破壊的変更の抽出・利用箇所の突き合わせ・推奨対応) | `/deps-update` | +| `advisor` | 重要な価値判断・設計判断の相談役(Fable による熟考・助言.実装はしない).Claude が自発的に呼んでよい基準(不可逆な設計判断の直前・同じ失敗が 2 回続いたとき)と上限(1 タスク 2 回,無人ループは 1 起動 3 回)は `/consult` skill に定める | `/consult`(`/auto-refactor`・`/auto-audit` からも上限付きで使用) | + ## パイプラインの流れと人間の役割 (Pipeline & Human's Role) `/implement <タスク内容>` で開始する(作業ブランチは git-conventions ルールに従い作成される). @@ -44,6 +54,8 @@ - `/auto-refactor`(リファクタ/ドキュメント整理ループ)→ `refactor/` 専用ブランチ - `/auto-audit`(バグ/脆弱性の巡回監査ループ.発見を裏取り後,再現テストで正しさを担保できるものだけ自動修正し,それ以外は台帳へ報告)→ `fix/` 専用ブランチ +※ **例外(Dependabot PR の取り込み)**: `/deps-update` は,Dependabot が作成した依存更新 PR に限り,ゲート(メジャー更新でない・競合なし・CI 緑またはローカル検証緑)を満たすものを `gh pr merge --merge` で `main` に取り込む.これは「Claude が `main` へマージする」唯一の承認済み例外であり,ユーザーが明示的に起動した時のみ動く.メジャー更新・CI 赤・PR が付かない alert は影響分析付きで報告し,人間が判断する(`.claude/skills/deps-update/SKILL.md`). + ## 進捗記録の運用ルール(CLAUDE.md / PROGRESS.md) 進捗記録(CLAUDE.md「開発進捗」・`docs/PROGRESS.md` の書き方)のルールは `.claude/rules/progress-log.md` に定義されている.該当ファイルを編集する際に自動で読み込まれる.