Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .claude/commands/codeReview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 29 additions & 5 deletions .claude/commands/cpp.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
Commit, push, pull request
Commit, review, push, pull request

## Usage
```
/cpp [in branch <branch-name>]
```

## 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 <branch-name>` - 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
Expand All @@ -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
```
45 changes: 44 additions & 1 deletion .claude/hooks/skill-activation-prompt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Empty file.
122 changes: 122 additions & 0 deletions .claude/hooks/utils/add-keywords-to-skill.sh
Original file line number Diff line number Diff line change
@@ -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 <skill-name> <keyword1> [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
72 changes: 72 additions & 0 deletions .claude/hooks/utils/extract-keywords.sh
Original file line number Diff line number Diff line change
@@ -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}'
31 changes: 30 additions & 1 deletion .claude/skills/skills-manager/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <keywords>`
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)
Expand All @@ -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

Expand Down
19 changes: 19 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <skill-name> <keyword1> [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
Expand Down
Loading