settings について
settingsは、CCGSプロジェクトの共有設定project.yamlと開発者ごとのproject.local.yamlを確認・変更するスキルです。設定値と出所を解決・検証し、書き込み前にキーや承認要件を確認します。
主な機能
- 01全設定または単一キーを表示
- 02共有またはローカルのYAML値を設定
- 03有効値と設定元を解決
- 04列挙値を検証し既知キーを確認
- 05自動化モードに応じて書き込みを承認
活用シーン
- 01プロジェクトの有効設定を確認
- 02開発者用のローカル上書きを変更
- 03共有設定の更新と書き込み確認
- 04無効または未読の設定キーを発見
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ donchitos/ claude-code-game-studios --skill settingsインストール後、Claude Code で/settingsを入力して読み込まれたか確認します。
詳細
/settings — プロジェクト設定の表示または変更
project.yaml(チーム全体の設定。コミット対象)と project.local.yaml
(開発者ごとの上書き設定。gitignore 対象)を管理します。このスキルを使うと、
現在の設定を確認したり、YAML を手動で編集せずに変更したりできます。
自動化モード:modes.automation を解決します(project.local.yaml →
project.yaml → デフォルトの collaborative)。Phase 4 と Phase 5 の承認ゲートは、
.claude/docs/automation-modes.md のパターンに従います。注:
project.yaml への書き込みは schema_changes に関する判断です(デフォルトでは
automation_always_ask カテゴリー)。そのため、ユーザーが schema_changes を
常に確認を求めるリストから削除していない限り、autonomous モードでも
/settings は設定の書き込みを確認します。
Phase 0: 引数の解析
ユーザーが呼び出した形式を次の 4 つから判別します。
| 形式 | モード |
|---|---|
/settings(引数なし) | View-all(Phase 2) |
/settings <key>(単一引数。= なし) | View-one(Phase 3) |
/settings <key>=<value>(単一引数。= あり) | Set-yaml(Phase 4) |
/settings --local <key>=<value>(--local プレフィックスあり) | Set-local(Phase 5) |
Set-yaml と Set-local では、<key> は YAML のドット区切りパスです(例:
modes.review_mode、testing.strict.logic)。<value> は新しい値です。
空のオペランドの検証: key=value オペランドを
= で分割した後、<key> または <value> のどちらかが空の場合は形式が不正です。
書き込みを試みず、Phase 6(使用方法)に進みます。このルールは Set-yaml と
Set-local の両方に適用されます。--local の場合は、まず --local トークンを
取り除いてから、残ったオペランドを同じ方法で確認します(そのため、
/settings --local =foo と /settings --local key= はどちらも Phase 6 に進みます)。
上記 4 つの形式のいずれにも一致しない場合は、Phase 6(使用方法)に進みます。
Phase 1: ヘルパーの読み込み
4 つのサブコマンドすべてで yaml-helper.sh が必要です。各ヘルパー呼び出しを、
単独の通常コマンドとして実行します。
bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" <helper call>
<helper call> は、たとえば resolve_setting modes.review_mode や
validate_yaml_enum project.yaml のように、各フェーズで指定されている関数です。
ヘルパーは自らプロジェクトのルートに移動するため、セッションをサブフォルダーから
開始した場合でも、project.yaml と project.local.yaml の引数は正しく解決されます。
また、関数の終了ステータスを保持します。呼び出しは表示どおりに実行してください。
ファイルを source したり、cd ... && で囲んだり、; echo $? を追加したりしないでください。
このスキルで事前承認されているのは通常の形式だけです。複合コマンドを使うと、
毎回ユーザーに確認を求めます。
.claude/hooks/yaml-helper.sh が見つからない場合、このプロジェクトは CCGS
プロジェクトではありません。エラーを報告して終了します。
フェーズ 1b:予約済み設定の検出
完全に文書化され、設定可能でありながら、どのスキルや
フックからも読み取られない設定があります。設定しても何も変わりません。このスキルでは、そのことを必ず伝えてください。
通常の成功を返すと、その設定が説明する動作が適用されたとユーザーが
受け取っても無理はありません。アクセシビリティレベルは、それを動機づける
事例です。(キー名は意図的にここでは示しません。以下の注記を参照してください。)
バナーがあるのは
.claude/docs/effects-map.md だけです。プロジェクトを設定する人が
開くことのないファイルです。何も機能しない設定が、機能する設定と
まったく同じように見えてはなりません。.claude/rules/skill-authoring.md の義務 3 に従ってください。
義務 5 に従い、集合を導き出してください。ハードコードしてはいけません。
grep -B14 '^> ### RESERVED' .claude/docs/effects-map.md | grep -E '^## '
「RESERVED」という単語だけでなく、バナーの見出し(> ### RESERVED)に一致させてください。
platform.cert_tier のセクションでは、以前はバナーが付いていたものの、後に有効な設定になったことを記録するため、説明文中でバナーに言及しています。より緩い一致条件では、機能する設定が使用不能だと再び報告されます。これはフレームワークの機能を実際より少なく見せる方向であり、未使用設定のゲートが両方向を検証する理由でもあります。
見出しでキーが 2 つ「 and 」で連結されている場合があります。両方を取得できるよう、この区切り文字で分割してください。そうしないと、2 つ目のキーが気づかれないまま集合から漏れてしまいます。これを RESERVED_SET の結果とします。
これらのキー名を出さないよう、意図的に表現しています。未使用設定のゲートは、許可リストにある設定に読み取り元がないことを検証し、キーを記述しているスキルファイルをすべて数えます。分割方法を説明するためにここでキー名を挙げると、何も読み取らない 2 つの設定の読み取り元として
/settingsが登録され、ゲートは失敗します。これは正しい動作です。使用してはならない理由を説明するために未使用のパスを明記しても、同じ問題が起きます。例外を追加するのではなく、表現を言い換えてください。厳格さこそが重要なので、例をわかりやすくするためにキー名を再びそのまま書いてはいけません。
予約済みのキーへの書き込みを拒否してはいけません。ユーザーが意図する値を保存することは正当です。欠陥なのは、それを何も知らせずに保存することです。
フェーズ 2:全件表示モード
(引数がない場合)
-
project.yamlが存在することを確認します。存在しない場合は、次のように報告します。"
project.yamlが見つかりません。/startを実行して作成してください。" その後、終了します。 -
project.local.yamlが存在するか確認します。 -
validate_yaml_enum project.yamlを実行し、エラーがあれば取得します。project.local.yamlが存在する場合は、validate_yaml_enum project.local.yamlも実行します。 ユーザーが区別できるよう、各エラーにソースファイル名を付けます。 -
リーフを列挙します。
Readツールを使って、両方の YAML ファイルをテキストとして読み取ります。 各ファイルの構造をたどり、すべてのリーフキーをドット区切りのパスの 重複のないリストに集めます。リーフとは、値が空でない(スカラーまたはインライン配列である)key: value行のことです。ネストされたマップを導入する親ブロックは 含みません。ファイルごとに挿入順を保ち、project.local.yamlにあるリーフのうちproject.yamlにまだないものを追加します。こうして得られたリストが表示対象のリーフです。次に、リストにまだ含まれていない項目があれば、rigor ファミリーを追加します。対象は
modes.rigor、modes.workflow、docs.density、qa.level、modes.story_granularity、modes.review_mode、team.sizeの 7 項目です。 通常、これらはどちらのファイルのリーフでもありません。modes.rigorには 終端のデフォルト値があり、残り 6 項目は rigor の展開によって設定されます (modes.review_modeとteam.sizeはローカルで設定されていれば ファイルのリーフとして現れる場合もありますが、派生値を表示するために それでも追加する必要があります)。ファイルのリーフだけを列挙すると、 ユーザーがたった今選んだ設定が、まさにそのための表示画面で隠れてしまいます。 -
各リーフについて、3 回読み取り、1 回確認します。
resolve_setting <path>→<value>、TAB、<source>。チェーン全体(project.local.yaml→project.yaml→ レガシーファイル →rigorの展開 → デフォルト)をたどるため、派生値を報告したり、値の由来を示したりできる読み取りはこれだけです。get_yaml_key project.yaml <path>→ YAML のみの値(ローカルの上書き対象を示す場合にのみ必要)is_locally_overridable <path>→ 0(上書き可能)または 1(ロック済み)
<source>からソース注釈を決定します。<source>注釈 project.local.yaml、YAML のみの値が空でない(LOCAL OVERRIDE — yaml has: <yamlvalue>)project.local.yaml、YAML のみの値が空(project.local.yaml)project.yaml(project.yaml)レガシーファイルのパス(例: production/review-mode.txt)(<path>, legacy)rigor:<level>(derived from rigor: <level>)default(default)unsetリーフをスキップする(未設定のキーは出力しない) is_locally_overridableの戻り値が 1 の場合は、注釈に, lockedを追加します。リーフが
RESERVED_SET(フェーズ 1b)に含まれる場合は, reservedを追加し、この行をブロックの下にある凡例とともに出力します。reserved = stored, but nothing reads it. Setting it changes no behaviour today.4 つのフェーズすべてで、予約済みのマークを付ける必要があります。view-one、view-all、および両方の書き込みパスです。 view-one と書き込みパスにはマークを付けても、このスキルで最もよく使われる形式である view-all にマークを付けないと、予約済みのキーを設定したユーザーには、実際に最も多くの人が実行するビューで、そのキーが通常の
(project.yaml)注釈付きの有効な設定と並んで表示されます。4 つすべてを保護してください。view-one と view-all は、2 つの書き込みパスとまったく同じ意味で対になるものです。 -
出力は、最上位セクション(
framework、modes、engineなど)ごとにまとめ、リーフが最初に現れた順に並べます。グループ分けはリーフのファイルではなく、ドット区切りのパスで決まります。たとえば、project.local.yamlでのみ定義されていても、modes.automationはmodes:の下にまとめます。各セクション内ではリーフを 2 スペース字下げし、サブブロック(例:testing.strict.*)はさらに字下げします。 出力例:
project.yaml: present
project.local.yaml: present
Schema validation: ok
Effective config:
framework:
version: 1.2.0 (project.yaml, locked)
modes:
review_mode: lean (project.yaml)
automation: autonomous (LOCAL OVERRIDE — yaml has: collaborative)
rigor: full (project.yaml, locked)
workflow: full (derived from rigor: full, locked)
story_granularity: fine (derived from rigor: full, locked)
docs:
density: terse (project.yaml, locked)
qa:
level: full (derived from rigor: full, locked)
engine:
name: Godot (project.yaml, locked)
version: 4.7 (project.yaml, locked)
testing:
strict:
logic: false (LOCAL OVERRIDE — yaml has: true)
integration: true (project.yaml)
locked = cannot be overridden in project.local.yaml (project-wide setting).
It does NOT mean fixed: a derived value can still be set explicitly with
/settings <key>=<value>, and an explicit value wins over rigor.
出力した行に locked が含まれる場合は、設定ブロックの後にこの 2 行の凡例を出力します。そうしないと、ユーザーは locked を「変更不可」と読み違え、rigor から派生した設定値は変更できないと結論づけてしまいます。これは、同じ設定値についてフェーズ 3 の view-one が伝える内容(「明示的な値は rigor より優先される」)とは正反対です。同じ設定値の変更可能性について、2 つのビューが矛盾した印象を与えてはなりません。
上記の docs.density の行は、優先順位のルールを明示したものです。project.yaml の明示的な値は、rigor から導出されるはずの値よりも優先されるため、「包括的でありながら簡潔」な設定が可能です。
スキーマエラーがある場合は、有効な設定ブロックの前に次の形式で出力します。
Schema validation: ERRORS
[project.yaml] modes.review_mode: 'chaotic' is not a valid value (expected: full|lean|solo)
[project.local.yaml] engine.name: 'Pygame' is not a valid value (expected: Godot|Unity|Unreal)
フェーズ 3:単一表示モード
(引数が1つで、= が含まれない場合)
<key> が RESERVED_SET に含まれる場合は、値のブロックより前に表示します — 下ではなく上に表示してください。値の下に注意書きを置くと、現在有効な設定についての脚注のように見えてしまいます。
<key>は RESERVED です — 何も読み取りません。 以下の値は保存されていますが、現時点では動作に影響しません。
引数を <key> とします。次の4つを読み取ります。
resolve_setting <key>→<value>、タブ、<source>(有効な値+由来)get_yaml_key project.yaml <key>→ YAML のみの値get_yaml_key project.local.yaml <key>→ ローカルのみの値(ファイルがない場合はスキップ)is_locally_overridable <key>→ 0(上書き可能)または1(ロック済み)
<source>(フェーズ 2 のステップ 5 と同じ表)からソースを判定し、
ローカルで上書き済みかどうかを判定します。
- ローカルのみの値が空でない場合は
yes - それ以外は
no
次を表示します。
<key>
Effective value: <effective-value or "(not set)" if <source> is unset>
Source: <project.yaml | project.local.yaml | project.local.yaml (overrides project.yaml) | derived from rigor: <level> | default>
Locally overridden: <yes | no>
Whitelist: <"can be locally overridden" if is_locally_overridable returned 0, else "locked — project-wide">
両方のファイルでキーが設定されている場合(ローカル上書きのケース)は、Source の下にさらに2行追加します。
project.yaml value: <yamlvalue>
project.local.yaml value: <localvalue>
<source> が rigor:<level> の場合、値を設定する方法をユーザーに知らせるため、Source の下に1行追加します。
Set explicitly with: /settings <key>=<value> (an explicit value wins over rigor)
有効な値が空の場合(どこにもキーが設定されていない場合)は、次のみを表示します。
<key>
Effective value: (not set)
Locally overridden: no
Whitelist: <"can be locally overridden" | "locked — project-wide">
フェーズ 4:YAML 設定モード
(<key>=<value> の場合。--local は指定しません)
- スキーマ検証:
validate_enum_value <key> <value>を呼び出します。戻り値が 1 の場合、stderr の行(Invalid value '<value>' for '<key>'. Allowed: ...)をそのままユーザーに表示し、書き込みを行わずにスキルを終了します。戻り値が 0 の場合、値は有効か、キーに列挙制約がありません。次に進みます。
1b. 既知のキーか確認:フェーズ 1 と同様にプロジェクトルートから、bash .claude/scripts/config-set.sh <key> <value> --dry-run を実行し、その known 行を確認します。yes と表示された場合は次に進みます。no と表示された場合、CCGS はそのキーを読み取らないため、書き込んでも何も変わりません。多くの場合、これは入力ミスです。まだ書き込まず、その旨を伝えて、AskUserQuestion で次の選択肢を提示します。
Use <nearest> instead(行の末尾が nearest: <key> の場合のみ)
Write <key> anyway
Cancel
明示的な選択があった場合のみ続行します。Use <nearest> instead が選ばれた場合は、そのキーを使ってこのフェーズを最初からやり直します。回答が省略された場合、または空の場合はキャンセルします。
-
予約キーの警告:
<key>がRESERVED_SET(フェーズ 1b)に含まれる場合、承認プロンプトの前に次を表示します。"注意:
<key>は RESERVED です。これを読み取るスキルやフックはないため、設定しても動作は変わりません。どちらの場合も値は保存されます。"その後、通常どおり承認の確認に進みます。フェーズ 5 でも同じ警告を表示します。一方の書き込み経路でのみ警告すると、同じ結果に至る経路が警告なしで残ります。それを防ぐことが、この確認の目的です。
-
上書きの警告:
get_yaml_key project.local.yaml <key>を読み取ります。空でない値が返された場合、承認プロンプトの前に次を表示します。"注意:この設定は現在
project.local.yamlでローカル上書きされています(値:<localvalue>)。project.yamlに書き込んでも、実際に適用される値は変わりません。" -
承認確認:
AskUserQuestionを使います。- プロンプト:
Set `<key>=<value>` in `project.yaml`? - 選択肢:
[A] Yes, write/[B] No, cancel
- プロンプト:
-
Editツールを使って書き込みます。編集方法は、project.yamlにすでに存在する内容によって異なります。ケース A — キーが存在する場合:
project.yamlを読み取ります。<lastsegment>: <oldvalue>の行と、その直上にある親ブロックを示す行(例:modes.review_modeの場合はmodes:)を特定します。<lastsegment>: <oldvalue>が別の場所にも存在する場合に備え、親ブロック行とリーフ行の両方を含むold_stringを使ってEditを構成し、一意に一致するようにします。modes.review_mode=fullの例:old_string: modes: review_mode: lean new_string: modes: review_mode: fullケース B — 親ブロックは存在するが、リーフが存在しない場合:親ブロックの最後の行を見つけます。最後に存在するリーフを
old_stringのアンカーとして使い、適切なインデントで新しいリーフ行を追加するようEditを使用します。ケース C — 親ブロックが存在しない場合:ファイルの末尾に新しいトップレベルブロックを追加します(決定的に、常にファイル末尾に追加し、ブロックの間には挿入しません)。
Editでファイル内の最後の空でない行をold_stringとして使い、その後に新しいブロックを追加します。ケース D — ファイル構造が通常と異なる場合(同名のコメントアウトされたキー、曖昧なネスト、不正な YAML):停止し、
AskUserQuestionで次のように尋ねます。"
project.yamlで<key>を挿入する適切な場所が見つかりませんでした。どうすればよいか教えてください。" -
確認します:
Set `<key>=<value>` in `project.yaml`.<key>がmodes.rigorの場合、書き込みによって他の 6 つの設定項目も変更されます。それぞれの設定をresolve_settingで再度読み取り、現在の値を表示します。展開表の内容をそのまま読み上げてはいけません。明示的な値が設定されていて、そちらが優先される可能性があるためです。Set modes.rigor=full in project.yaml. It now supplies: modes.workflow: full (derived from rigor: full) docs.density: terse (project.yaml — explicit, unchanged) qa.level: full (derived from rigor: full) modes.story_granularity: fine (derived from rigor: full) modes.review_mode: full (derived from rigor: full) team.size: studio (derived from rigor: full)
フェーズ 5:ローカル設定モード
(--local <key>=<value> の場合)
-
ホワイトリストの確認:
is_locally_overridable <key>を呼び出します。- 1(ロック済み)が返された場合は、次の1行を出力します。
<key> はローカルで上書きできません — プロジェクト全体の設定です。チーム全体の設定を変更するには、`/settings <key>=<value>`(`--local` なし)を使用してください。 - 書き込みを行わずに終了します。
- 1(ロック済み)が返された場合は、次の1行を出力します。
-
スキーマ検証:
validate_enum_value <key> <value>を呼び出します。 1 が返された場合は、stderr のメッセージをそのまま表示し、書き込みを行わずに終了します。
2a. 既知のキーの確認:フェーズ 4 の手順 1b と同様に、<key> の前に --local を付けます。known 行が no の場合は、書き込む前に確認し、その行に nearest: キーが記載されていればそれを提示します。
2b. 予約済みの警告:<key> が RESERVED_SET(フェーズ 1b)に含まれる場合は、承認を求める前に次を出力します。
"注意:
<key>は RESERVED です — これを読み取るスキルやフックがないため、設定しても動作は変わりません。値はどちらの場合も保存されます。"
フェーズ 4 の手順 2 と同じですが、意図的に同じにしています。どちらの書き込み経路も、ユーザーの意図を記録する同じファイルに到達します。一方だけで警告すると、--local が警告なしの経路になってしまいます。
-
ベースファイルの確認:
project.yamlが存在しない場合:"
project.local.yamlを作成できません —project.yamlがありません。まず/startを実行して作成してください。" 終了します。(仕様により、ローカル上書きにはベースファイルが必要です。) -
承認の確認:
AskUserQuestionを使用します。- プロンプト:
`<key>=<value>` を `project.local.yaml` に設定しますか(個人用の上書き設定。gitignore 対象)? - 選択肢:
[A] はい、書き込む/[B] いいえ、キャンセル
- プロンプト:
-
書き込み:
project.local.yamlが存在しない場合は、新しい設定を親ブロックで囲んでWriteを使って作成します。--local modes.automation=autonomousの最小限の例:# project.local.yaml — 開発者ごとの上書き設定(gitignore 対象) modes: automation: autonomous- 存在する場合は、フェーズ 4 の手順 4 と同じ Case A/B/C の方法で
Editを使用します。
-
確認:
`<key>=<value>` を `project.local.yaml` に設定しました(上書き設定)。
フェーズ 6:使用方法
引数が4つの有効な形式のいずれにも一致しない場合(またはオペランドが空の場合)は、次を出力します。
Usage:
/settings — view all effective config
/settings <key> — view a single setting
/settings <key>=<value> — change a setting (project.yaml)
/settings --local <key>=<value> — change a setting locally
(project.local.yaml, gitignored)
Examples:
/settings modes.review_mode
/settings modes.review_mode=full
/settings --local modes.automation=autonomous
注記
- すべての YAML 書き込みには、既存のキー/ブロックには
Edit、新しいファイルにはWriteを使用します。このスキルはyqや外部 YAML ライブラリに依存しません。 - ホワイトリストは
yaml-helper.shのis_locally_overridable関数で適用されます。拡張する場合は、_yaml_helper_locally_overridable定数を編集してください。ここにリストを複製しないでください。 - 派生値はどこにも保存されません。
modes.workflow、docs.density、qa.level、modes.story_granularity、modes.review_mode、team.sizeには終端のデフォルト値がありません。ファイルで設定されていない場合、値はyaml-helper.shのmodes.rigor展開(_yaml_helper_rigor_expansion)から取得されます。これらはresolve_settingを使って報告してください。get_yaml_keyで読み取ると空になり、実際にはすべてのスキルが実値に基づいて動作しているにもかかわらず「(未設定)」と表示されてしまいます。 - スキーマ検証に使う列挙型定数は
yaml-helper.sh(_yaml_helper_enums)にあります。validate_enum_valueは書き込み前の単一キー検証に使用するバリデーターです。validate_yaml_enumはファイル全体を検証します(session-start.shで使用)。 project.local.yamlは gitignore 対象です。これらの上書き設定がチームメイトに反映されることはありません。- ゲームの種類や状況に応じてどの値を選ぶか、また変更を提案するタイミングについては、
.claude/docs/settings-guidance.md(推奨プリセットと変更のきっかけ)を参照してください。各設定の効果はeffects-map.mdに、このドキュメントには選ぶべき値が記載されています。