Просмотр исходного кода

fix(output-styles): Match frontmatter name to filename in all 13 styles

The outputStyle setting resolves case-sensitively against a style's
frontmatter name, and an unresolvable value fails silently - the session
runs the default style with no error anywhere. Every style declared a
capitalised name against a lowercase filename, so the obvious setting
value ("vesper") was a no-op.

Add a validate.sh gate that hard-fails on name/filename drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0xDarkMatter 1 месяц назад
Родитель
Сommit
2ebd693990

+ 1 - 1
output-styles/atlas.md

@@ -1,5 +1,5 @@
 ---
-name: Atlas
+name: atlas
 description: Strategic advisor. Sees the big picture, thinks in systems.
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/coach.md

@@ -1,5 +1,5 @@
 ---
-name: Coach
+name: coach
 description: Keeps momentum up, celebrates every win, pushes you to level up.
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/executive.md

@@ -1,5 +1,5 @@
 ---
-name: Executive
+name: executive
 description: High-level summaries for non-technical stakeholders - decisions, impact, timelines
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/harbour.md

@@ -1,5 +1,5 @@
 ---
-name: Harbour
+name: harbour
 description: Warm, steady, makes complexity feel manageable - the calm in the storm
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/mentor.md

@@ -1,5 +1,5 @@
 ---
-name: Mentor
+name: mentor
 description: Patient, educational style - explains the why, builds understanding, encourages learning
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/meridian.md

@@ -1,5 +1,5 @@
 ---
-name: Meridian
+name: meridian
 description: Chief of staff. Calm, anticipatory, keeps everything running.
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/noir.md

@@ -1,5 +1,5 @@
 ---
-name: Noir
+name: noir
 description: Hard-boiled detective narrating your codebase. Chandler meets SRE.
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/pair.md

@@ -1,5 +1,5 @@
 ---
-name: Pair
+name: pair
 description: Collaborative pair programmer - thinks out loud, explores together, shares the driver's seat
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/roast.md

@@ -1,5 +1,5 @@
 ---
-name: Roast
+name: roast
 description: Your brutally honest friend who wants you to be better.
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/sage.md

@@ -1,5 +1,5 @@
 ---
-name: Sage
+name: sage
 description: Thoughtful, measured, technically precise - the engineer who writes excellent post-mortems
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/scout.md

@@ -1,5 +1,5 @@
 ---
-name: Scout
+name: scout
 description: Curious, lateral, challenges the question before solving the problem
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/spartan.md

@@ -1,5 +1,5 @@
 ---
-name: Spartan
+name: spartan
 description: Minimal, bullet-point responses - maximum signal, zero filler
 keep-coding-instructions: true
 ---

+ 1 - 1
output-styles/vesper.md

@@ -1,5 +1,5 @@
 ---
-name: Vesper
+name: vesper
 description: Sophisticated engineering companion with British wit, intellectual depth, and pattern recognition
 keep-coding-instructions: true
 ---

+ 44 - 0
tests/validate.sh

@@ -460,6 +460,49 @@ validate_rules() {
     done < <(find "$rules_dir" -name "*.md" -type f -print0)
 }
 
+# Validate output styles
+#
+# The `outputStyle` setting is resolved CASE-SENSITIVELY against a style's
+# frontmatter `name:` (falling back to the filename when `name:` is absent), and
+# an unresolvable value fails SILENTLY — the session just runs the default
+# style. A capitalised `name: Vesper` in `vesper.md` therefore makes the obvious
+# setting value ("vesper") a no-op with no error anywhere. Verified on 2.1.221;
+# see the corrected root-cause analysis on anthropics/claude-code#47482.
+validate_output_styles() {
+    echo ""
+    echo "=== Validating Output Styles ==="
+
+    local styles_dir="$PROJECT_DIR/output-styles"
+    if [[ ! -d "$styles_dir" ]]; then
+        echo "  (no output-styles/ directory - skipping)"
+        return
+    fi
+
+    while IFS= read -r -d '' file; do
+        local stem
+        stem=$(basename "$file" .md)
+
+        if [[ ! "$stem" =~ ^[a-z][a-z0-9]*(-[a-z0-9]+)*$ ]]; then
+            log_warn "$file - Filename not kebab-case: $stem"
+        fi
+
+        if ! check_yaml_frontmatter "$file"; then
+            continue
+        fi
+
+        # `name:` is optional; when present it MUST equal the filename stem, or
+        # the documented settings value silently selects nothing.
+        local declared
+        declared=$(get_yaml_field "$file" "name")
+        if grep -q "^name:" "$file" && [[ "$declared" != "$stem" ]]; then
+            log_fail "$file - Frontmatter name '$declared' != filename '$stem' (outputStyle would silently fail)"
+            continue
+        fi
+
+        log_pass "$file - Valid output style"
+    done < <(find "$styles_dir" -maxdepth 1 -name "*.md" -type f -print0)
+}
+
 # Validate settings files (permissions and hooks)
 validate_settings() {
     echo ""
@@ -607,6 +650,7 @@ main() {
     validate_skills
     validate_description_budget
     validate_rules
+    validate_output_styles
     validate_settings
     validate_plugin