diff --git a/.claude/commands/codeReview.md b/.claude/commands/codeReview.md index 7bbdf256dd..9e936783df 100644 --- a/.claude/commands/codeReview.md +++ b/.claude/commands/codeReview.md @@ -23,10 +23,13 @@ git diff develop...HEAD ### Step 2: Apply Review Standards **Apply the shared review guidelines from:** -`.github/workflows/code-review-guidelines.md` +`.claude/CODE_REVIEW_GUIDE.md` Follow all core rules, review sections, common mistakes, and analysis checklist defined in that file. +**Also consult:** +- `.claude/skills/code-review-developer/SKILL.md` - Quick reference for critical rules and workflow + **Context adaptation for local reviews:** - This is a local review (not a GitHub PR) - Reference file:line locations from the git diff diff --git a/.claude/commands/cpp.md b/.claude/commands/cpp.md index 57b9d954ea..c06a96cdbc 100644 --- a/.claude/commands/cpp.md +++ b/.claude/commands/cpp.md @@ -1,4 +1,4 @@ -Commit, push, pull request +Commit, review, push, pull request ## Usage ``` @@ -6,11 +6,35 @@ Commit, push, pull request ``` ## Description -Commits the current changes, pushes to remote, and creates a pull request. +Commits the current changes, performs a code review, applies fixes if needed, then pushes to remote and creates a pull request. ## Optional Arguments - `in branch ` - Specifies the target branch to use for the commit, push, and PR +## Workflow + +### 1. Commit Changes +- Stage and commit all changes with a descriptive message +- Follow CLAUDE.md commit message guidelines + +### 2. Code Review +- Run automated code review using `/codeReview` workflow +- Apply CODE_REVIEW_GUIDE.md standards +- Check for bugs, best practices violations, performance issues, security concerns + +### 3. Review Findings +- Present review results to developer +- If issues found, **STOP and discuss** with developer: + - Should we fix the issues now? + - Are the findings valid or false positives? + - Should we proceed anyway? +- **Developer decides next steps** - never auto-amend commits + +### 4. Push and PR (when approved) +- Only proceed when developer approves +- Push to remote with tracking +- Create pull request with summary + ## Branch Handling When a branch name is provided: 1. **Branch doesn't exist locally or remotely**: Creates a new branch with the specified name @@ -19,12 +43,12 @@ When a branch name is provided: ## Examples ```bash -# Commit, push, and PR on current branch +# Commit, review, push, and PR on current branch /cpp -# Commit, push, and PR on specific branch (creates if doesn't exist) +# Commit, review, push, and PR on specific branch (creates if doesn't exist) /cpp in branch ios-5364-add-claude-to-gh-actions -# Commit, push, and PR on existing branch +# Commit, review, push, and PR on existing branch /cpp in branch develop ``` diff --git a/.claude/hooks/skill-activation-prompt.sh b/.claude/hooks/skill-activation-prompt.sh index d9fbfb57c8..91b173f9cc 100755 --- a/.claude/hooks/skill-activation-prompt.sh +++ b/.claude/hooks/skill-activation-prompt.sh @@ -76,9 +76,52 @@ for skill in $(jq -r '.skills | keys[]' "$SKILL_RULES"); do fi done -# If no skills matched, exit silently +# If no skills matched, check if prompt is substantial if [ ${#MATCHED_SKILLS[@]} -eq 0 ]; then echo " No skills matched" >> "$LOG_FILE" + + # Calculate prompt size metrics + CHAR_COUNT=${#USER_PROMPT} + LINE_COUNT=$(echo "$USER_PROMPT" | wc -l | tr -d ' ') + + # Threshold: 100+ characters OR 3+ lines + if [ $CHAR_COUNT -ge 100 ] || [ $LINE_COUNT -ge 3 ]; then + echo " Substantial prompt (${CHAR_COUNT} chars, ${LINE_COUNT} lines) - prompting user" >> "$LOG_FILE" + + # Log to missed activations file + MISSED_LOG="$LOG_DIR/skill-activations-missed.log" + echo "[$(date '+%Y-%m-%d %H:%M:%S')] Missed activation" >> "$MISSED_LOG" + echo " Prompt: ${USER_PROMPT:0:200}..." >> "$MISSED_LOG" + echo " Size: ${CHAR_COUNT} chars, ${LINE_COUNT} lines" >> "$MISSED_LOG" + echo "" >> "$MISSED_LOG" + + # Build skill list for user + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "💡 NO SKILLS ACTIVATED" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Your prompt seems substantial (${CHAR_COUNT} chars, ${LINE_COUNT} lines) but no skills matched." + echo "" + echo "📚 Available skills:" + echo "" + + # List all skills + for skill in $(jq -r '.skills | keys[]' "$SKILL_RULES"); do + description=$(jq -r ".skills[\"$skill\"].description" "$SKILL_RULES") + echo " • $skill" + echo " $description" + echo "" + done + + echo "❓ Should any of these skills be activated for this task?" + echo " If yes, tell me which one and I'll extract keywords from your prompt" + echo " to improve future auto-activation." + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + fi + exit 0 fi diff --git a/.claude/hooks/skill-rules.json.tmp b/.claude/hooks/skill-rules.json.tmp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.claude/hooks/utils/add-keywords-to-skill.sh b/.claude/hooks/utils/add-keywords-to-skill.sh new file mode 100755 index 0000000000..39460329b0 --- /dev/null +++ b/.claude/hooks/utils/add-keywords-to-skill.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +# Auto-Learning Utility +# Adds keywords to a skill's configuration for improved auto-activation + +set -euo pipefail + +# Usage check +if [ $# -lt 2 ]; then + echo "Usage: $0 [keyword2] [keyword3] ..." + echo "" + echo "Example:" + echo " $0 localization-developer \"membership\" \"tiers\" \"settings\"" + exit 1 +fi + +SKILL_NAME=$1 +shift +NEW_KEYWORDS=("$@") + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SKILL_RULES="$SCRIPT_DIR/../skill-rules.json" +LOG_DIR="$SCRIPT_DIR/../../logs" +LOG_FILE="$LOG_DIR/skill-learning.log" + +# Ensure log directory exists +mkdir -p "$LOG_DIR" + +# Validate skill exists +if ! jq -e ".skills[\"$SKILL_NAME\"]" "$SKILL_RULES" > /dev/null 2>&1; then + echo "❌ Error: Skill '$SKILL_NAME' not found in skill-rules.json" + echo "" + echo "Available skills:" + jq -r '.skills | keys[]' "$SKILL_RULES" | sed 's/^/ - /' + exit 1 +fi + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📚 AUTO-LEARNING: Adding keywords to $SKILL_NAME" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Get existing keywords +EXISTING_KEYWORDS=$(jq -r ".skills[\"$SKILL_NAME\"].promptTriggers.keywords[]" "$SKILL_RULES" 2>/dev/null || echo "") + +# Check which keywords are new +TRULY_NEW_KEYWORDS=() +for keyword in "${NEW_KEYWORDS[@]}"; do + keyword_lower=$(echo "$keyword" | tr '[:upper:]' '[:lower:]') + + IS_DUPLICATE=false + while IFS= read -r existing; do + existing_lower=$(echo "$existing" | tr '[:upper:]' '[:lower:]') + if [ "$keyword_lower" = "$existing_lower" ]; then + IS_DUPLICATE=true + echo "⏭️ Skipping '$keyword' (already exists)" + break + fi + done <<< "$EXISTING_KEYWORDS" + + if [ "$IS_DUPLICATE" = false ]; then + TRULY_NEW_KEYWORDS+=("$keyword") + echo "✅ Adding '$keyword'" + fi +done + +# Exit if no new keywords +if [ ${#TRULY_NEW_KEYWORDS[@]} -eq 0 ]; then + echo "" + echo "ℹ️ No new keywords to add - all provided keywords already exist" + exit 0 +fi + +echo "" +echo "Updating skill-rules.json..." + +# Create backup +cp "$SKILL_RULES" "$SKILL_RULES.backup" + +# Build jq update command +JQ_FILTER=".skills[\"$SKILL_NAME\"].promptTriggers.keywords += [" +for i in "${!TRULY_NEW_KEYWORDS[@]}"; do + if [ $i -gt 0 ]; then + JQ_FILTER+=", " + fi + JQ_FILTER+="\"${TRULY_NEW_KEYWORDS[$i]}\"" +done +JQ_FILTER+="] | .skills[\"$SKILL_NAME\"].promptTriggers.keywords |= unique" + +# Update skill-rules.json +jq "$JQ_FILTER" "$SKILL_RULES" > "$SKILL_RULES.tmp" + +# Validate JSON +if jq empty "$SKILL_RULES.tmp" 2>/dev/null; then + mv "$SKILL_RULES.tmp" "$SKILL_RULES" + echo "✅ Updated skill-rules.json" + + # Remove backup + rm "$SKILL_RULES.backup" + + # Log the update + echo "[$(date '+%Y-%m-%d %H:%M:%S')] Added keywords to $SKILL_NAME" >> "$LOG_FILE" + for keyword in "${TRULY_NEW_KEYWORDS[@]}"; do + echo " + $keyword" >> "$LOG_FILE" + done + echo "" >> "$LOG_FILE" + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "✨ Success! Added ${#TRULY_NEW_KEYWORDS[@]} new keyword(s)" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "💡 The system will now auto-activate '$SKILL_NAME' for prompts" + echo " containing these keywords." + echo "" +else + echo "❌ Error: Generated invalid JSON, restoring backup" + mv "$SKILL_RULES.backup" "$SKILL_RULES" + rm -f "$SKILL_RULES.tmp" + exit 1 +fi diff --git a/.claude/hooks/utils/extract-keywords.sh b/.claude/hooks/utils/extract-keywords.sh new file mode 100755 index 0000000000..bca2a48031 --- /dev/null +++ b/.claude/hooks/utils/extract-keywords.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Keyword Extraction Utility +# Extracts relevant technical keywords from a user prompt for skill auto-learning + +set -euo pipefail + +# Read prompt from argument or stdin +if [ $# -eq 0 ]; then + PROMPT=$(cat) +else + PROMPT="$1" +fi + +# Convert to lowercase +PROMPT_LOWER=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]') + +# Common stopwords to exclude +STOPWORDS="the a an and or but in on at to for of with by from as is was are were be been being have has had do does did will would should could may might must can this that these those i you he she it we they my your his her its our their me him them what which who when where why how all each every both few more most other some such no nor not only own same so than too very just now need want like get make go see" + +# Extract words (alphanumeric + hyphens + dots) +WORDS=$(echo "$PROMPT_LOWER" | grep -oE '[a-z0-9][a-z0-9._-]*' | sort -u) + +# Filter and score words +SCORED_WORDS="" + +for word in $WORDS; do + # Skip short words + if [ ${#word} -lt 3 ]; then + continue + fi + + # Skip if stopword + if echo " $STOPWORDS " | grep -q " $word "; then + continue + fi + + # Calculate score + score=1 + + # Boost technical terms + if echo "$word" | grep -qE '^(view|model|controller|coordinator|service|repository|manager|handler)'; then + score=$((score + 3)) + fi + + # Boost Swift/iOS terms + if echo "$word" | grep -qE '^(swift|swiftui|combine|async|await|observable|published)'; then + score=$((score + 3)) + fi + + # Boost file extensions + if echo "$word" | grep -qE '\.(swift|xcstrings|yml|md)$'; then + score=$((score + 2)) + fi + + # Boost compound technical words + if echo "$word" | grep -qE '[_.]'; then + score=$((score + 2)) + fi + + # Boost longer words + if [ ${#word} -gt 8 ]; then + score=$((score + 1)) + fi + + # Store as "score word" + SCORED_WORDS="$SCORED_WORDS +$score $word" +done + +# Sort by score (descending) and take top 5 +echo "$SCORED_WORDS" | grep -v '^$' | sort -rn | head -5 | awk '{print $2}' diff --git a/.claude/skills/skills-manager/SKILL.md b/.claude/skills/skills-manager/SKILL.md index ae1ed3b7d2..044334f67b 100644 --- a/.claude/skills/skills-manager/SKILL.md +++ b/.claude/skills/skills-manager/SKILL.md @@ -97,6 +97,34 @@ echo '{"prompt":"add feature flag"}' | .claude/hooks/skill-activation-prompt.sh Should output skill suggestion if match found. +### Auto-Learning Feature + +**What it does**: When a substantial prompt (100+ chars OR 3+ lines) doesn't activate any skills, the system prompts you with available skills and auto-updates keywords based on your feedback. + +**Workflow**: +1. You submit a substantial prompt +2. No skills activate +3. System shows: "Should any of these skills be activated?" +4. You respond: "Yes, localization-developer should activate" +5. Claude extracts keywords from your prompt +6. Claude runs: `.claude/hooks/utils/add-keywords-to-skill.sh localization-developer ` +7. skill-rules.json updated +8. Future similar prompts auto-activate + +**Manual keyword extraction**: +```bash +# Test keyword extraction +echo "Update space settings localization for membership tiers" | .claude/hooks/utils/extract-keywords.sh +# Output: membership, settings, localization, tiers, update + +# Add keywords manually +.claude/hooks/utils/add-keywords-to-skill.sh localization-developer "membership" "tiers" +``` + +**Logs**: +- Missed activations: `.claude/logs/skill-activations-missed.log` +- Learning updates: `.claude/logs/skill-learning.log` + ## 🔧 The System Components ### Hooks (Automation) @@ -112,12 +140,13 @@ Should output skill suggestion if match found. **Location**: `.claude/skills/*/SKILL.md` -**The 5 skills**: +**The 6 skills**: 1. `ios-dev-guidelines` - Swift/iOS patterns 2. `localization-developer` - Localization 3. `code-generation-developer` - Feature flags, make generate 4. `design-system-developer` - Icons, typography, colors 5. `skills-manager` - This skill (meta!) +6. `code-review-developer` - Code review standards ### Configuration diff --git a/CLAUDE.md b/CLAUDE.md index 3248826525..80aef347f1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,6 +56,25 @@ The skills system provides context-aware guidance that auto-activates based on y **How it works**: When you start a task, the system analyzes your prompt and file context, then automatically suggests relevant skills. No manual loading needed. +**Auto-learning**: When the system fails to activate a skill for a substantial prompt (100+ chars or 3+ lines): +1. You'll be prompted with available skills +2. If you identify which skill should have activated, tell Claude +3. Claude extracts relevant keywords from your prompt +4. Keywords are automatically added to skill-rules.json +5. Future similar prompts will auto-activate the skill + +**Manual keyword management**: +```bash +# Extract keywords from a prompt +.claude/hooks/utils/extract-keywords.sh "your prompt text" + +# Add keywords to a skill +.claude/hooks/utils/add-keywords-to-skill.sh [keyword2] ... + +# Example +.claude/hooks/utils/add-keywords-to-skill.sh localization-developer "membership" "tiers" +``` + **Learn more**: See `.claude/skills/README.md` for system overview and `.claude/hooks/README.md` for automation details. #### Specialized Documentation