rulecrafter
Version:
Adaptive automation system that learns from your Claude Code workflow and generates intelligent rules and commands
255 lines (216 loc) • 7.55 kB
Markdown
## rulecrafter-review
Review and approve pending rule suggestions.
**Usage:** `/rulecrafter-review [action] [rule_id]`
**Arguments:**
- `action` (optional): approve, reject, or approve-all
- `rule_id` (optional): specific rule ID to act on
**Description:**
Interactive interface to review, approve, or reject rule suggestions generated by RuleCrafter's pattern analysis.
**What this command does:**
1. Shows all pending rule suggestions
2. Provides details about evidence and confidence
3. Allows individual or batch approval/rejection
4. Updates CLAUDE.md with approved rules
```bash
#!/bin/bash
PROJECT_ROOT=$(pwd)
while [[ "$PROJECT_ROOT" != "/" && ! -d "$PROJECT_ROOT/.claude" ]]; do
PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
done
if [[ "$PROJECT_ROOT" == "/" ]]; then
echo "❌ RuleCrafter not found in this project"
exit 1
fi
RULECRAFTER_DIR="$PROJECT_ROOT/.claude/rulecrafter"
PENDING_FILE="$RULECRAFTER_DIR/storage/pending_rules.json"
if [[ ! -f "$PENDING_FILE" ]]; then
echo "📝 No pending rules to review"
echo " 💡 Use /rulecrafter-mine to generate new suggestions"
exit 0
fi
# Check if we have pending rules
PENDING_COUNT=$(python3 -c "
import json
try:
with open('$PENDING_FILE', 'r') as f:
data = json.load(f)
pending = [r for r in data if r.get('status') == 'pending']
print(len(pending))
except:
print(0)
" 2>/dev/null || echo "0")
if [[ $PENDING_COUNT -eq 0 ]]; then
echo "📝 No pending rules to review"
echo " ✅ All suggestions have been processed"
exit 0
fi
ACTION="$1"
RULE_ID="$2"
# Function to display pending rules
show_pending_rules() {
echo "📋 Pending Rule Suggestions ($PENDING_COUNT):"
echo "============================================="
python3 -c "
import json
try:
with open('$PENDING_FILE', 'r') as f:
data = json.load(f)
pending = [r for r in data if r.get('status') == 'pending']
for i, rule in enumerate(pending):
print(f'')
print(f'Rule #{i+1}:')
print(f'Category: {rule.get(\"category\", \"General\")}')
print(f'Type: {rule.get(\"type\", \"unknown\")}')
print(f'Rule: {rule.get(\"rule\", \"\")}')
print(f'Confidence: {rule.get(\"confidence\", 0):.1%}')
evidence = rule.get('evidence', {})
if evidence:
print('Evidence:')
for key, value in evidence.items():
if key == 'message':
print(f' {key}: {str(value)[:60]}...' if len(str(value)) > 60 else f' {key}: {value}')
else:
print(f' {key}: {value}')
print(f'Generated: {rule.get(\"generated_at\", \"unknown\")}')
print('-' * 50)
except Exception as e:
print(f'Error reading pending rules: {e}')
"
}
# Function to approve rule(s)
approve_rule() {
local rule_index="$1"
python3 -c "
import json
from datetime import datetime
try:
with open('$PENDING_FILE', 'r') as f:
data = json.load(f)
pending = [i for i, r in enumerate(data) if r.get('status') == 'pending']
if '$rule_index' == 'all':
# Approve all pending rules
for i in pending:
data[i]['status'] = 'approved'
data[i]['approved_at'] = datetime.now().isoformat()
approved_count = len(pending)
else:
# Approve specific rule
rule_idx = int('$rule_index') - 1
if 0 <= rule_idx < len(pending):
actual_idx = pending[rule_idx]
data[actual_idx]['status'] = 'approved'
data[actual_idx]['approved_at'] = datetime.now().isoformat()
approved_count = 1
else:
print('Invalid rule number')
exit(1)
# Save updated rules
with open('$PENDING_FILE', 'w') as f:
json.dump(data, f, indent=2)
print(f'✅ Approved {approved_count} rule(s)')
# Get approved rules for CLAUDE.md update
approved_rules = [r for r in data if r.get('status') == 'approved']
# Update CLAUDE.md
if approved_rules:
import sys
sys.path.append('$RULECRAFTER_DIR/generators')
from rule_generator import RuleGenerator
generator = RuleGenerator('$PROJECT_ROOT')
if generator.update_claude_md(approved_rules):
print('📝 Updated CLAUDE.md with approved rules')
else:
print('⚠️ Failed to update CLAUDE.md')
except Exception as e:
print(f'Error approving rules: {e}')
exit(1)
"
}
# Function to reject rule(s)
reject_rule() {
local rule_index="$1"
python3 -c "
import json
from datetime import datetime
try:
with open('$PENDING_FILE', 'r') as f:
data = json.load(f)
pending = [i for i, r in enumerate(data) if r.get('status') == 'pending']
if '$rule_index' == 'all':
# Reject all pending rules
for i in pending:
data[i]['status'] = 'rejected'
data[i]['rejected_at'] = datetime.now().isoformat()
rejected_count = len(pending)
else:
# Reject specific rule
rule_idx = int('$rule_index') - 1
if 0 <= rule_idx < len(pending):
actual_idx = pending[rule_idx]
data[actual_idx]['status'] = 'rejected'
data[actual_idx]['rejected_at'] = datetime.now().isoformat()
rejected_count = 1
else:
print('Invalid rule number')
exit(1)
# Save updated rules
with open('$PENDING_FILE', 'w') as f:
json.dump(data, f, indent=2)
print(f'❌ Rejected {rejected_count} rule(s)')
except Exception as e:
print(f'Error rejecting rules: {e}')
exit(1)
"
}
# Handle different actions
case "$ACTION" in
"approve")
if [[ -n "$RULE_ID" ]]; then
approve_rule "$RULE_ID"
else
echo "❌ Please specify a rule number to approve"
echo " Usage: /rulecrafter-review approve <rule_number>"
fi
;;
"reject")
if [[ -n "$RULE_ID" ]]; then
reject_rule "$RULE_ID"
else
echo "❌ Please specify a rule number to reject"
echo " Usage: /rulecrafter-review reject <rule_number>"
fi
;;
"approve-all")
echo "⚠️ This will approve ALL pending rules. Continue? (y/N)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
approve_rule "all"
else
echo "Cancelled"
fi
;;
"reject-all")
echo "⚠️ This will reject ALL pending rules. Continue? (y/N)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
reject_rule "all"
else
echo "Cancelled"
fi
;;
*)
# Show pending rules and usage
show_pending_rules
echo ""
echo "📋 Review Options:"
echo "=================="
echo " /rulecrafter-review approve <rule_number> - Approve specific rule"
echo " /rulecrafter-review reject <rule_number> - Reject specific rule"
echo " /rulecrafter-review approve-all - Approve all pending rules"
echo " /rulecrafter-review reject-all - Reject all pending rules"
echo ""
echo "💡 Approved rules will be added to CLAUDE.md"
echo "💡 Rejected rules will be ignored but kept for reference"
;;
esac
```
*This command is part of RuleCrafter's management interface*