diff --git a/bin/ralphloop b/bin/ralphloop index 341b5b8..792f333 100755 --- a/bin/ralphloop +++ b/bin/ralphloop @@ -1,282 +1,223 @@ #!/usr/bin/env python3 """ -RalphLoop - Ralph Orchestrator Wrapper for Claude Code +RalphLoop - "Tackle Until Solved" Autonomous Agent Loop -This wrapper integrates Ralph Orchestrator with Claude Code skills, -providing autonomous "Tackle Until Solved" capabilities. - -Environment Variables: - RALPH_AGENT Agent to use (claude|gemini|kiro|q|auto) - RALPH_MAX_ITERATIONS Maximum iterations (default: 100) - RALPH_MAX_RUNTIME Maximum runtime in seconds (default: 14400) - RALPH_VERBOSE Enable verbose output (default: false) +Integration of Ralph Orchestrator with Claude Code CLI. +This script runs an autonomous agent loop that continues until the task is complete. Usage: - ralphloop "Design a microservices architecture" - ralphloop --agent claude --max-iterations 50 "Implement auth" + ./ralphloop "Your task description here" + ./ralphloop -i task.md + ./ralphloop --agent claude --max-iterations 50 + +Environment Variables: + ANTHROPIC_API_KEY Required for Claude agent + RALPH_AGENT Override agent selection (claude, gemini, etc.) + RALPH_MAX_ITERATIONS Override max iterations (default: 100) """ import os import sys -import json -import argparse import subprocess +import argparse +import json from pathlib import Path -from datetime import datetime, timedelta +from datetime import datetime # Configuration -DEFAULT_AGENT = os.getenv("RALPH_AGENT", "claude") -DEFAULT_MAX_ITERATIONS = int(os.getenv("RALPH_MAX_ITERATIONS", 100)) -DEFAULT_MAX_RUNTIME = int(os.getenv("RALPH_MAX_RUNTIME", 14400)) -VERBOSE = os.getenv("RALPH_VERBOSE", "false").lower() == "true" +DEFAULT_AGENT = "claude" +DEFAULT_MAX_ITERATIONS = 100 +DEFAULT_MAX_RUNTIME = 14400 # 4 hours -# Ralph directory -RALPH_DIR = Path(".ralph") -STATE_FILE = RALPH_DIR / "state.json" -PROMPT_FILE = RALPH_DIR / "PROMPT.md" -CONFIG_FILE = RALPH_DIR / "ralph.yml" -ITERATIONS_DIR = RALPH_DIR / "iterations" +# Path to Ralph in venv +SCRIPT_DIR = Path(__file__).parent.parent +VENV_BIN = SCRIPT_DIR / ".venv" / "bin" +RALPH_CMD = str(VENV_BIN / "ralph") - -def setup_ralph_directory(): - """Create .ralph directory structure.""" - RALPH_DIR.mkdir(exist_ok=True) - ITERATIONS_DIR.mkdir(exist_ok=True) - - -def load_state(): - """Load current Ralph state.""" - if STATE_FILE.exists(): - with open(STATE_FILE, "r") as f: - return json.load(f) - return { - "iteration": 0, - "status": "not_started", - "started_at": None, - "completed_at": None, - "last_error": None - } - - -def save_state(state): - """Save Ralph state.""" - with open(STATE_FILE, "w") as f: - json.dump(state, f, indent=2) - - -def create_prompt(task, agent, max_iterations, max_runtime): - """Create PROMPT.md with task and success criteria.""" - prompt = f"""# RalphLoop Task - -## Task -{task} - -## Success Criteria -- Task fully analyzed and understood -- All requirements addressed -- Implementation/design complete -- Quality standards met -- No critical issues remaining - -## Configuration -- Agent: {agent} -- Max Iterations: {max_iterations} -- Max Runtime: {max_runtime} seconds ({timedelta(seconds=max_runtime)}) -- Started: {datetime.now().isoformat()} - -## Instructions -Run autonomous iterations until all success criteria are met. -Update state.json after each iteration. -Save final result to iterations/final.md when complete. -""" - with open(PROMPT_FILE, "w") as f: - f.write(prompt) - - -def create_config(agent, max_iterations, max_runtime): - """Create ralph.yml configuration.""" - config = f"""# RalphLoop Configuration -agent: {agent} -max_iterations: {max_iterations} -max_runtime: {max_runtime} -verbose: {VERBOSE} - -# Output -iterations_dir: iterations -state_file: state.json -final_output: iterations/final.md - -# Claude Code Integration -skill_path: ~/.claude/skills/ralph -brainstorming_skill: ~/.claude/skills/brainstorming -""" - with open(CONFIG_FILE, "w") as f: - f.write(config) - - -def run_ralph_iteration(task, iteration, agent): - """Run a single Ralph iteration.""" - iteration_file = ITERATIONS_DIR / f"{iteration:03d}.md" - - # Check if ralph-orchestrator is installed +def check_dependencies(): + """Check if Ralph Orchestrator is available.""" try: result = subprocess.run( - ["ralph", "--agent", agent, "--prompt", task], + [RALPH_CMD, "run", "-h"], capture_output=True, text=True, - timeout=300 + timeout=5 + ) + if result.returncode == 0 or "usage:" in result.stdout: + return True + except (FileNotFoundError, subprocess.TimeoutExpired): + pass + + # Fallback: check if pip package is installed + try: + import ralph_orchestrator + return True + except ImportError: + return False + +def create_ralph_project(task_description=None, task_file=None): + """Create a Ralph project in the current directory.""" + ralph_dir = Path(".ralph") + ralph_dir.mkdir(exist_ok=True) + + # Create prompt file + prompt_file = Path("PROMPT.md") + + if task_file: + # Read from file + content = Path(task_file).read_text() + prompt_file.write_text(content) + elif task_description: + # Use inline task + prompt_file.write_text(f"# Task: {task_description}\n\n\n\n## Success Criteria\n\nThe task is complete when:\n- All requirements are implemented\n- Tests pass\n- Code is documented\n\n marker to this file -->") + else: + print("Error: Either provide task description or task file") + sys.exit(1) + + # Create config file + config_file = Path("ralph.yml") + config = { + "agent": os.getenv("RALPH_AGENT", DEFAULT_AGENT), + "prompt_file": "PROMPT.md", + "max_iterations": int(os.getenv("RALPH_MAX_ITERATIONS", DEFAULT_MAX_ITERATIONS)), + "max_runtime": int(os.getenv("RALPH_MAX_RUNTIME", DEFAULT_MAX_RUNTIME)), + "verbose": True, + "adapters": { + "claude": { + "enabled": True, + "timeout": 300 + } + } + } + + import yaml + with open(config_file, "w") as f: + yaml.dump(config, f, default_flow_style=False) + + print(f"āœ… Ralph project initialized") + print(f" Prompt: {prompt_file}") + print(f" Config: {config_file}") + +def run_ralph_loop(task=None, task_file=None, agent=None, max_iterations=None, max_runtime=None): + """Run the Ralph autonomous loop.""" + print("šŸ”„ RalphLoop: 'Tackle Until Solved' Autonomous Agent Loop") + print("=" * 60) + + # Initialize project + create_ralph_project(task, task_file) + + # Build command + cmd = [RALPH_CMD, "run"] + + if agent: + cmd.extend(["-a", agent]) + + if max_iterations: + cmd.extend(["-i", str(max_iterations)]) + + if max_runtime: + cmd.extend(["-t", str(max_runtime)]) + + cmd.append("-v") # Verbose output + + print(f"Command: {' '.join(cmd)}") + print("=" * 60) + + # Run Ralph + try: + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1 ) - output = result.stdout or result.stderr + # Stream output + for line in process.stdout: + print(line, end='', flush=True) - with open(iteration_file, "w") as f: - f.write(f"""# Iteration {iteration} - -## Agent: {agent} -## Time: {datetime.now().isoformat()} - -## Output -{output} - -## Status -{'COMPLETE' if result.returncode == 0 else 'IN_PROGRESS'} -""") - return result.returncode == 0 - - except FileNotFoundError: - # Ralph not installed, use placeholder - with open(iteration_file, "w") as f: - f.write(f"""# Iteration {iteration} - -## Agent: {agent} -## Time: {datetime.now().isoformat()} - -## Note -Ralph Orchestrator not installed. Install with: - pip install ralph-orchestrator - -## Task Analysis -{task} - -## Next Steps -1. Install Ralph Orchestrator -2. Re-run ralphloop command -""") - return False - except subprocess.TimeoutExpired: - with open(iteration_file, "w") as f: - f.write(f"""# Iteration {iteration} - -## Agent: {agent} -## Time: {datetime.now().isoformat()} - -## Status: TIMEOUT - -Iteration exceeded 300 second timeout. -""") - return False - - -def run_ralph(task, agent, max_iterations, max_runtime): - """Run Ralph autonomous loop.""" - setup_ralph_directory() - - state = load_state() - if state["status"] == "completed": - print(f"Task already completed at {state['completed_at']}") - print(f"See {ITERATIONS_DIR / 'final.md'} for results") - return - - # Initialize - state["status"] = "running" - state["started_at"] = datetime.now().isoformat() - save_state(state) - - create_prompt(task, agent, max_iterations, max_runtime) - create_config(agent, max_iterations, max_runtime) - - start_time = datetime.now() - completed = False - - for iteration in range(1, max_iterations + 1): - # Check runtime - elapsed = (datetime.now() - start_time).total_seconds() - if elapsed > max_runtime: - print(f"Max runtime ({max_runtime}s) exceeded") - break - - if VERBOSE: - print(f"[Ralph] Iteration {iteration}/{max_iterations}") - - state["iteration"] = iteration - save_state(state) - - # Run iteration - if run_ralph_iteration(task, iteration, agent): - completed = True - break - - # Finalize - state["status"] = "completed" if completed else "max_iterations_reached" - state["completed_at"] = datetime.now().isoformat() - save_state(state) - - # Create final output - final_file = ITERATIONS_DIR / "final.md" - with open(final_file, "w") as f: - f.write(f"""# RalphLoop Final Result - -## Task -{task} - -## Agent: {agent} -## Iterations: {state['iteration']} -## Status: {state['status']} -## Started: {state['started_at']} -## Completed: {state['completed_at']} - -## Result -{'Task completed successfully!' if completed else 'Max iterations reached. Manual review needed.'} - -## Output Files -- iterations/001.md through iterations/{iteration:03d}.md -- state.json - Progress tracking -- ralph.yml - Configuration - -## Next Steps -{'Implement the solution from the final iteration.' if completed else 'Review iterations and continue manually or increase max_iterations.'} -""") - - print(f"\n[Ralph] {state['status'].upper()}") - print(f"[Ralph] Iterations: {state['iteration']}/{max_iterations}") - print(f"[Ralph] Output: {final_file}") + process.wait() + return process.returncode + except KeyboardInterrupt: + print("\n\nāš ļø Interrupted by user") + return 130 + except Exception as e: + print(f"āŒ Error: {e}") + return 1 def main(): parser = argparse.ArgumentParser( - description="RalphLoop - Ralph Orchestrator Wrapper", + description="RalphLoop - Autonomous agent loop for Claude Code CLI", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__ ) - parser.add_argument("task", help="Task description") - parser.add_argument("--agent", default=DEFAULT_AGENT, help="Agent to use") - parser.add_argument("--max-iterations", type=int, default=DEFAULT_MAX_ITERATIONS) - parser.add_argument("--max-runtime", type=int, default=DEFAULT_MAX_RUNTIME) - parser.add_argument("--verbose", action="store_true") + + parser.add_argument( + "task", + nargs="?", + help="Task description (inline)" + ) + + parser.add_argument( + "-i", "--input", + dest="task_file", + help="Read task from file" + ) + + parser.add_argument( + "-a", "--agent", + choices=["claude", "kiro", "q", "gemini", "acp", "auto"], + default=os.getenv("RALPH_AGENT", DEFAULT_AGENT), + help="AI agent to use" + ) + + parser.add_argument( + "--max-iterations", + type=int, + default=int(os.getenv("RALPH_MAX_ITERATIONS", DEFAULT_MAX_ITERATIONS)), + help="Maximum iterations" + ) + + parser.add_argument( + "--max-runtime", + type=int, + default=int(os.getenv("RALPH_MAX_RUNTIME", DEFAULT_MAX_RUNTIME)), + help="Maximum runtime in seconds" + ) + + parser.add_argument( + "--init-only", + action="store_true", + help="Only initialize project, don't run" + ) args = parser.parse_args() - if args.verbose: - global VERBOSE - VERBOSE = True + # Check dependencies + if not check_dependencies(): + print("āš ļø Ralph Orchestrator not found at:", RALPH_CMD) + print("\nTo install:") + print(f" .venv/bin/pip install ralph-orchestrator") + print("\nFor now, creating project files only...") + args.init_only = True - run_ralph( + # Initialize only mode + if args.init_only: + create_ralph_project(args.task, args.task_file) + print("\nšŸ’” To run the loop later:") + print(f" {RALPH_CMD} run") + return 0 + + # Run the loop + return run_ralph_loop( task=args.task, + task_file=args.task_file, agent=args.agent, max_iterations=args.max_iterations, max_runtime=args.max_runtime ) - if __name__ == "__main__": - main() + sys.exit(main() or 0) diff --git a/commands/brainstorm.md b/commands/brainstorm.md index 485d5c0..0fb3a89 100644 --- a/commands/brainstorm.md +++ b/commands/brainstorm.md @@ -1,44 +1,6 @@ -# /brainstorm +--- +description: "You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores requirements and design before implementation." +disable-model-invocation: true +--- -Multi-AI brainstorming session with Ralph integration. - -## Usage - -``` -/brainstorm "Design a feature for user authentication" -``` - -## Description - -Launches a collaborative brainstorming session using multiple AI perspectives: -- Claude (primary) -- Qwen (consultation) -- Ralph Orchestrator (autonomous iteration) - -## Modes - -**Direct Mode** (simple tasks): -- Quick ideation -- Feature exploration -- Design discussions - -**Ralph Mode** (complex tasks): -- Architecture design -- System planning -- Multi-phase projects - -## Environment Variables - -```bash -QWEN_CONSULT_MODE=always|delegate|off -RALPH_AUTO=true|false -QWEN_MAX_ITERATIONS=3 -``` - -## Examples - -``` -/brainstorm "How should we structure the API?" -/brainstorm "Design a notification system" -/brainstorm "Plan the database schema" -``` +Invoke the superpowers:brainstorming skill and follow it exactly as presented to you diff --git a/commands/execute-plan.md b/commands/execute-plan.md index 44aa40e..c48f140 100644 --- a/commands/execute-plan.md +++ b/commands/execute-plan.md @@ -1,52 +1,6 @@ -# /execute-plan +--- +description: Execute plan in batches with review checkpoints +disable-model-invocation: true +--- -Execute a previously created implementation plan. - -## Usage - -``` -/execute-plan -/execute-plan my-plan.md -/execute-plan --review -``` - -## Description - -Executes implementation plans created with `/write-plan`: -- Reads plan from `.claude/plans/` -- Executes each step in order -- Creates checkpoints for rollback -- Validates each step completion - -## Options - -``` ---review # Review plan before executing ---from=N # Start from step N ---to=N # Execute through step N ---dry-run # Show what would be done ---continue # Continue after error -``` - -## Execution Process - -1. **Load Plan** - Read and parse plan file -2. **Review** (optional) - Show steps and confirm -3. **Execute** - Run each step sequentially -4. **Validate** - Verify each step completed -5. **Checkpoint** - Save progress after each step -6. **Report** - Summary of changes - -## Examples - -``` -/execute-plan # Execute latest plan -/execute-plan auth-plan.md # Execute specific plan -/execute-plan --review # Review before executing -/execute-plan --from=5 # Start from step 5 -``` - -## Checkpoints - -Each step creates a checkpoint in `.claude/plans/.checkpoint/` -Use `--continue` to resume from last checkpoint after failure. +Invoke the superpowers:executing-plans skill and follow it exactly as presented to you diff --git a/commands/write-plan.md b/commands/write-plan.md index 6aaedb1..12962fd 100644 --- a/commands/write-plan.md +++ b/commands/write-plan.md @@ -1,40 +1,6 @@ -# /write-plan +--- +description: Create detailed implementation plan with bite-sized tasks +disable-model-invocation: true +--- -Create implementation plans from requirements or specifications. - -## Usage - -``` -/write-plan "Add user authentication with OAuth" -``` - -## Description - -Creates detailed, step-by-step implementation plans including: -- Technical approach -- File changes needed -- Testing strategy -- Dependencies -- Risks and mitigations - -## Plan Structure - -1. **Summary** - High-level overview -2. **Technical Approach** - Architecture decisions -3. **Implementation Steps** - Ordered task list -4. **Files to Create/Modify** - Specific files -5. **Testing Strategy** - Validation approach -6. **Dependencies** - Required packages/changes -7. **Risks & Mitigations** - Potential issues - -## Examples - -``` -/write-plan "Implement Stripe subscriptions" -/write-plan "Add real-time notifications with WebSockets" -/write-plan "Migrate from REST to GraphQL" -``` - -## Output - -Saves plan to `.claude/plans/` directory for later execution with `/execute-plan`. +Invoke the superpowers:writing-plans skill and follow it exactly as presented to you diff --git a/hooks/QWEN-HOOK-README.md b/hooks/QWEN-HOOK-README.md new file mode 100644 index 0000000..adab90d --- /dev/null +++ b/hooks/QWEN-HOOK-README.md @@ -0,0 +1,88 @@ +# Qwen Consultation Hook for Claude Code + +Allows Claude Code to consult with the local Qwen installation (`/usr/local/bin/qwen`) for assistance with tasks. + +## Files Created + +- `/home/uroma/.claude/hooks/qwen-consult.sh` - Main hook script +- `/home/uroma/.claude/hooks/hooks.json` - Updated with Qwen hook +- `/home/uroma/.claude/hooks.json` - Updated with Qwen hook + +## Configuration + +The hook behavior is controlled via environment variables: + +| Variable | Default | Description | +|----------|---------|-------------| +| `QWEN_CONSULT_MODE` | `off` | When to consult Qwen: `off`, `delegate`, or `always` | +| `QWEN_MODEL` | (default) | Optional: specify Qwen model to use | +| `QWEN_MAX_ITERATIONS` | `30` | Max iterations for Qwen execution | + +## Usage Modes + +### 1. Off Mode (Default) +```bash +export QWEN_CONSULT_MODE=off +``` +Qwen is never consulted. Hook is disabled. + +### 2. Delegate Mode +```bash +export QWEN_CONSULT_MODE=delegate +``` +Qwen is consulted when you use keywords like: +- "consult qwen" +- "ask qwen" +- "delegate to qwen" +- "get a second opinion" +- "alternative approach" + +### 3. Always Mode +```bash +export QWEN_CONSULT_MODE=always +``` +Qwen is consulted for every request. + +## Examples + +### Enable delegate mode in current session +```bash +export QWEN_CONSULT_MODE=delegate +``` + +### Use with a specific model +```bash +export QWEN_CONSULT_MODE=delegate +export QWEN_MODEL=qwen2.5-coder-32b-instruct +``` + +### Make permanent (add to ~/.bashrc) +```bash +echo 'export QWEN_CONSULT_MODE=delegate' >> ~/.bashrc +``` + +## Monitoring Qwen + +When Qwen is triggered, it runs in the background. You can monitor it: + +```bash +# View Qwen output in real-time +tail -f ~/.claude/qwen-output.log + +# Check if Qwen is running +ps aux | grep qwen + +# Stop Qwen manually +kill $(cat ~/.claude/qwen.lock) +``` + +## Hook Event + +This hook triggers on `UserPromptSubmit` - every time you submit a prompt to Claude Code. + +## State Files + +- `~/.claude/qwen-consult.md` - Current consultation state +- `~/.claude/qwen-output.log` - Qwen execution output +- `~/.claude/qwen.lock` - PID file for running Qwen process +- `~/.claude/qwen-consult.log` - Consultation trigger log diff --git a/hooks/consult-qwen.sh b/hooks/consult-qwen.sh index 4704663..cc7920a 100755 --- a/hooks/consult-qwen.sh +++ b/hooks/consult-qwen.sh @@ -1,14 +1,21 @@ #!/bin/bash -# Qwen Consultation Wrapper Hook -# Trigger: user-prompt -# Wrapper for Qwen consultation functionality +# Simple Qwen Consultation Script +# Usage: consult-qwen.sh "your question here" -# This hook integrates with the brainstorming skill -# to provide multi-AI consultation capabilities +set -euo pipefail -QWEN_MAX_ITERATIONS="${QWEN_MAX_ITERATIONS:-3}" +QUESTION="${1:-}" -# Delegate to the brainstorming skill when appropriate -# The actual consultation logic is in the skill +if [[ -z "$QUESTION" ]]; then + echo "Usage: $0 \"your question\"" + exit 1 +fi -exit 0 +echo "=== Consulting Qwen ===" +echo "Question: $QUESTION" +echo "" +echo "Qwen's Response:" +echo "---" + +# Run Qwen with the question +echo "$QUESTION" | timeout 30 qwen -p - 2>&1 diff --git a/hooks/demo-qwen-consult.sh b/hooks/demo-qwen-consult.sh index 6decfe3..a678af7 100755 --- a/hooks/demo-qwen-consult.sh +++ b/hooks/demo-qwen-consult.sh @@ -1,11 +1,72 @@ #!/bin/bash -# Demo Qwen Integration Hook -# Trigger: user-prompt -# Demonstrates Qwen AI consultation capabilities +# Demo script showing how to use Qwen consultation hook -# This is a demo hook showing how to integrate -# Qwen AI for consultation and multi-AI brainstorming +set -euo pipefail -# The actual implementation is in the multi-ai-brainstorm skill +echo "=====================================" +echo " Qwen Consultation Hook Demo" +echo "=====================================" +echo "" -exit 0 +# Step 1: Show current mode +echo "1. Current QWEN_CONSULT_MODE: ${QWEN_CONSULT_MODE:-off (default)}" +echo "" + +# Step 2: Enable delegate mode +echo "2. Enabling delegate mode..." +export QWEN_CONSULT_MODE=delegate +echo " QWEN_CONSULT_MODE is now: $QWEN_CONSULT_MODE" +echo "" + +# Step 3: Trigger consultation with delegate keyword +echo "3. Triggering Qwen consultation..." +echo " Prompt: 'please consult qwen for advice on bash scripting best practices'" +echo "" + +# Clear previous log +> ~/.claude/qwen-output.log + +# Trigger the hook +echo '{"prompt": "please consult qwen for advice on bash scripting best practices"}' | \ + /home/uroma/.claude/hooks/qwen-consult.sh 2>&1 + +# Wait a moment for Qwen to start +sleep 2 + +# Step 4: Show Qwen is running +echo "4. Checking if Qwen is running..." +if [[ -f ~/.claude/qwen.lock ]]; then + PID=$(cat ~/.claude/qwen.lock) + if kill -0 "$PID" 2>/dev/null; then + echo " āœ“ Qwen is running (PID: $PID)" + else + echo " āœ— Qwen process not found" + fi +else + echo " āœ— Qwen lock file not found" +fi +echo "" + +# Step 5: Wait for output and show it +echo "5. Waiting for Qwen's response (10 seconds)..." +sleep 10 + +echo "" +echo "=====================================" +echo " Qwen's Response:" +echo "=====================================" +tail -n +4 ~/.claude/qwen-output.log + +echo "" +echo "=====================================" +echo " Monitoring Commands:" +echo "=====================================" +echo "View output in real-time:" +echo " tail -f ~/.claude/qwen-output.log" +echo "" +echo "Check if Qwen is running:" +echo " ps aux | grep qwen" +echo "" +echo "Stop Qwen:" +echo " kill \$(cat ~/.claude/qwen.lock)" +echo "" diff --git a/hooks/qwen-consult.sh b/hooks/qwen-consult.sh index d047dda..20faf8c 100755 --- a/hooks/qwen-consult.sh +++ b/hooks/qwen-consult.sh @@ -1,22 +1,163 @@ #!/bin/bash -# Qwen AI Consultation Hook -# Trigger: user-prompt -# Consults Qwen AI for additional perspectives +# Qwen Consult Hook - Integration with Qwen Code CLI +# Allows Claude Code to consult with local Qwen installation for tasks +# +# Modes (via QWEN_CONSULT_MODE environment variable): +# "always" - Consult Qwen for every request +# "delegate" - Only when explicitly asked to delegate/consult +# "off" - Disable Qwen consultation (default) +# +# Usage: +# Set QWEN_CONSULT_MODE environment variable to control behavior +# The hook runs Qwen in non-blocking mode and logs output -QWEN_MODE="${QWEN_CONSULT_MODE:-delegate}" -QWEN_MODEL="${QWEN_MODEL:-qwen-coder-plus}" +set -euo pipefail -# Only run in delegate or always mode -if [ "$QWEN_MODE" != "delegate" ] && [ "$QWEN_MODE" != "always" ]; then +# Configuration +CLAUDE_DIR="$HOME/.claude" +QWEN_STATE_FILE="$CLAUDE_DIR/qwen-consult.md" +QWEN_OUTPUT_LOG="$CLAUDE_DIR/qwen-output.log" +QWEN_LOCK_FILE="$CLAUDE_DIR/qwen.lock" + +# Read hook input from stdin +HOOK_INPUT=$(cat) +USER_PROMPT=$(echo "$HOOK_INPUT" | jq -r '.prompt // empty' 2>/dev/null || echo "") + +# Fallback: if no JSON input, use first argument +if [[ -z "$USER_PROMPT" && $# -gt 0 ]]; then + USER_PROMPT="$1" +fi + +# Get Qwen mode (default: off - requires explicit opt-in) +QWEN_CONSULT_MODE="${QWEN_CONSULT_MODE:-off}" +QWEN_MODEL="${QWEN_MODEL:-}" +QWEN_MAX_ITERATIONS="${QWEN_MAX_ITERATIONS:-30}" + +# Exit if consultation is disabled +if [[ "$QWEN_CONSULT_MODE" == "off" ]]; then exit 0 fi -# Check if qwen CLI is available -if ! command -v qwen &> /dev/null; then - exit 0 +# Check if Qwen is already running +if [[ -f "$QWEN_LOCK_FILE" ]]; then + LOCK_PID=$(cat "$QWEN_LOCK_FILE" 2>/dev/null || echo "") + if [[ -n "$LOCK_PID" ]] && kill -0 "$LOCK_PID" 2>/dev/null; then + exit 0 + else + rm -f "$QWEN_LOCK_FILE" + fi fi -# Run consultation (would be called by the skill, not here directly) -# This is a placeholder for the hook mechanism +# Keywords that trigger Qwen consultation (in delegate mode) +DELEGATE_KEYWORDS="consult|qwen|delegate|second opinion|alternative|get.*advice|ask.*qwen" +# Determine if we should consult Qwen +should_consult=false + +case "$QWEN_CONSULT_MODE" in + "always") + should_consult=true + ;; + "delegate") + if echo "$USER_PROMPT" | grep -iqE "$DELEGATE_KEYWORDS"; then + should_consult=true + fi + ;; +esac + +if [[ "$should_consult" == true ]]; then + # Create state directory + mkdir -p "$CLAUDE_DIR" + + # Build Qwen command arguments + QWEN_ARGS=() + if [[ -n "$QWEN_MODEL" ]]; then + QWEN_ARGS+=(-m "$QWEN_MODEL") + fi + + # Prepare prompt for Qwen with context + QWEN_PROMPT="You are Qwen, consulted by Claude Code for assistance. The user asks: $USER_PROMPT + +Please provide your analysis, suggestions, or solution. Be concise and actionable." + + # Create state file + cat > "$QWEN_STATE_FILE" << EOF +# Qwen Consult State +# Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC") + +**User Request:** +$USER_PROMPT + +**Mode:** $QWEN_CONSULT_MODE +**Model:** ${QWEN_MODEL:-default} +**Timestamp:** $(date -Iseconds) + +## Context + +This state file was generated by the Qwen consultation hook. Qwen Code CLI +is being consulted to provide additional insights on this request. + +## Configuration + +- Hook: UserPromptSubmit +- Trigger mode: $QWEN_CONSULT_MODE +- Log file: $QWEN_OUTPUT_LOG + +## Usage + +Qwen is running autonomously in the background. Monitor progress: + +\`\`\`bash +# View Qwen output in real-time +tail -f ~/.claude/qwen-output.log + +# Check if Qwen is still running +ps aux | grep qwen + +# Stop Qwen manually +kill \$(cat ~/.claude/qwen.lock) +\`\`\` +EOF + + # Check if Qwen is available + if command -v qwen &> /dev/null; then + # Create log file + touch "$QWEN_OUTPUT_LOG" + + # Start Qwen in background + { + echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Qwen consultation started" + echo "Mode: $QWEN_CONSULT_MODE" + echo "Model: ${QWEN_MODEL:-default}" + echo "---" + } >> "$QWEN_OUTPUT_LOG" + + # Run Qwen in background + if [[ ${#QWEN_ARGS[@]} -gt 0 ]]; then + nohup qwen "${QWEN_ARGS[@]}" -p "$QWEN_PROMPT" >> "$QWEN_OUTPUT_LOG" 2>&1 & + else + nohup qwen -p "$QWEN_PROMPT" >> "$QWEN_OUTPUT_LOG" 2>&1 & + fi + + QWEN_PID=$! + echo "$QWEN_PID" > "$QWEN_LOCK_FILE" + + # Log the consultation + { + echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Qwen consultation triggered" + echo " Mode: $QWEN_CONSULT_MODE" + echo " Model: ${QWEN_MODEL:-default}" + echo " PID: $QWEN_PID" + echo " Log: $QWEN_OUTPUT_LOG" + } >> "$CLAUDE_DIR/qwen-consult.log" 2>/dev/null || true + + # Notify user + echo "šŸ¤– Qwen consultation started (PID: $QWEN_PID)" >&2 + echo " Monitor: tail -f ~/.claude/qwen-output.log" >&2 + else + echo "āš ļø Qwen CLI not found at /usr/local/bin/qwen" >&2 + fi +fi + +# Exit immediately (non-blocking) exit 0 diff --git a/hooks/ralph-auto-trigger.sh b/hooks/ralph-auto-trigger.sh index 848affe..3d63182 100755 --- a/hooks/ralph-auto-trigger.sh +++ b/hooks/ralph-auto-trigger.sh @@ -1,17 +1,193 @@ #!/bin/bash -# Ralph Auto-Trigger Hook -# Trigger: user-prompt -# Automatically triggers Ralph for complex tasks +# Ralph Auto-Trigger Hook - Enhanced with Background Task Spawning +# Automatically starts Ralph CLI in background when needed +# +# Modes (via RALPH_AUTO_MODE environment variable): +# "always" - Start Ralph for every request +# "agents" - Only for agent requests (default) +# "off" - Disable auto-trigger +# +# Background Execution: +# - Ralph runs as background process (non-blocking) +# - Claude Code continues immediately +# - Ralph output logged to: ~/.claude/ralph-output.log +# - Ralph PID tracked in: ~/.claude/ralph.pid -# Analyze task complexity and auto-trigger Ralph -# when RALPH_AUTO=true or task appears complex +set -euo pipefail -RALPH_AUTO="${RALPH_AUTO:-false}" +# Configuration +CLAUDE_DIR="$HOME/.claude" +RALPH_STATE_FILE="$CLAUDE_DIR/ralph-loop.local.md" +RALPH_PID_FILE="$CLAUDE_DIR/ralph.pid" +RALPH_LOG_FILE="$CLAUDE_DIR/ralph-output.log" +RALPH_LOCK_FILE="$CLAUDE_DIR/ralph.lock" -if [ "$RALPH_AUTO" = "true" ]; then - # Auto-delegate to Ralph for complex tasks - # The actual delegation logic is in the ralph skill - : +# Read hook input from stdin +HOOK_INPUT=$(cat) +USER_PROMPT=$(echo "$HOOK_INPUT" | jq -r '.prompt // empty' 2>/dev/null || echo "") + +# Fallback: if no JSON input, use first argument +if [[ -z "$USER_PROMPT" && $# -gt 0 ]]; then + USER_PROMPT="$1" fi +# Get Ralph mode (default: agents) +RALPH_AUTO_MODE="${RALPH_AUTO_MODE:-agents}" +RALPH_MAX_ITERATIONS="${RALPH_MAX_ITERATIONS:-50}" + +# Exit if auto-trigger is disabled +if [[ "$RALPH_AUTO_MODE" == "off" ]]; then + exit 0 +fi + +# Check if Ralph is already running (via lock file) +if [[ -f "$RALPH_LOCK_FILE" ]]; then + # Check if process is still alive + LOCK_PID=$(cat "$RALPH_LOCK_FILE" 2>/dev/null || echo "") + if [[ -n "$LOCKPD" ]] && kill -0 "$LOCK_PID" 2>/dev/null; then + # Ralph is already running, don't start another instance + exit 0 + else + # Lock file exists but process is dead, clean up + rm -f "$RALPH_LOCK_FILE" "$RALPH_PID_FILE" + fi +fi + +# Agent detection list (lowercase for matching) +AGENTS=( + "ai-engineer" "backend-architect" "devops-automator" "frontend-developer" + "mobile-app-builder" "rapid-prototyper" "test-writer-fixer" + "tiktok-strategist" "growth-hacker" "content-creator" "instagram-curator" + "reddit-builder" "twitter-engager" "app-store-optimizer" + "brand-guardian" "ui-designer" "ux-researcher" "visual-storyteller" + "whimsy-injector" "ui-ux-pro-max" + "feedback-synthesizer" "sprint-prioritizer" "trend-researcher" + "experiment-tracker" "project-shipper" "studio-producer" "studio-coach" + "analytics-reporter" "finance-tracker" "infrastructure-maintainer" + "legal-compliance-checker" "support-responder" + "api-tester" "performance-benchmarker" "test-results-analyzer" + "tool-evaluator" "workflow-optimizer" + "joker" "agent-updater" + "explore" "plan" "general-purpose" +) + +# Detect agent request (case-insensitive) +agent_detected=false +detected_agent="" + +for agent in "${AGENTS[@]}"; do + if echo "$USER_PROMPT" | grep -iq "$agent"; then + agent_detected=true + detected_agent="$agent" + break + fi +done + +# Determine if we should start Ralph +should_trigger=false + +case "$RALPH_AUTO_MODE" in + "always") + # Trigger on all prompts + should_trigger=true + ;; + "agents") + # Only trigger on agent requests OR development keywords + if [[ "$agent_detected" == true ]]; then + should_trigger=true + elif echo "$USER_PROMPT" | grep -qiE "build|create|implement|develop|fix|add|refactor|optimize|write|generate|delegate|autonomous"; then + should_trigger=true + detected_agent="general-development" + fi + ;; +esac + +if [[ "$should_trigger" == true ]]; then + # Create Ralph state file + mkdir -p "$CLAUDE_DIR" + + cat > "$RALPH_STATE_FILE" << EOF +# Ralph Loop State - Auto-Triggered +# Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC") + +**User Request:** +$USER_PROMPT + +**Detected Agent:** $detected_agent +**Mode:** $RALPH_AUTO_MODE +**Max Iterations:** $RALPH_MAX_ITERATIONS +**Timestamp:** $(date -Iseconds) + +## Context + +This state file was automatically generated by the Ralph auto-trigger hook. +Ralph CLI will read this file and autonomously execute the request. + +## Auto-Trigger Details + +- Triggered by: Claude Code UserPromptSubmit hook +- Trigger mode: $RALPH_AUTO_MODE +- Background execution: Yes (non-blocking) +- Log file: $RALPH_LOG_FILE + +## Usage + +Ralph is running autonomously in the background. Monitor progress: + +\`\`\`bash +# View Ralph output in real-time +tail -f ~/.claude/ralph-output.log + +# Check if Ralph is still running +ps aux | grep ralph + +# Stop Ralph manually +kill \$(cat ~/.claude/ralph.pid) +rm ~/.claude/ralph.lock +\`\`\` +EOF + + # Spawn Ralph in background (NON-BLOCKING) + if command -v ralph &> /dev/null; then + # Create log file + touch "$RALPH_LOG_FILE" + + # Start Ralph in background with nohup (survives terminal close) + echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Starting Ralph in background..." >> "$RALPH_LOG_FILE" + echo "Mode: $RALPH_AUTO_MODE" >> "$RALPH_LOG_FILE" + echo "Agent: $detected_agent" >> "$RALPH_LOG_FILE" + echo "Max iterations: $RALPH_MAX_ITERATIONS" >> "$RALPH_LOG_FILE" + echo "---" >> "$RALPH_LOG_FILE" + + # Start Ralph in background + nohup ralph build "$RALPH_MAX_ITERATIONS" >> "$RALPH_LOG_FILE" 2>&1 & + RALPH_PID=$! + + # Save PID for tracking + echo "$RALPH_PID" > "$RALPH_PID_FILE" + echo "$RALPH_PID" > "$RALPH_LOCK_FILE" + + # Log the trigger + { + echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Ralph auto-triggered" + echo " Mode: $RALPH_AUTO_MODE" + echo " Agent: $detected_agent" + echo " PID: $RALPH_PID" + echo " Log: $RALPH_LOG_FILE" + } >> "$CLAUDE_DIR/ralph-trigger.log" 2>/dev/null || true + + # Notify user via stderr (visible in Claude Code) + echo "šŸ”„ Ralph CLI auto-started in background" >&2 + echo " PID: $RALPH_PID" >&2 + echo " Agent: $detected_agent" >&2 + echo " Monitor: tail -f ~/.claude/ralph-output.log" >&2 + echo " Stop: kill \$(cat ~/.claude/ralph.pid)" >&2 + else + # Ralph not installed, just create state file + echo "āš ļø Ralph CLI not installed. State file created for manual use." >&2 + echo " Install: npm install -g @iannuttall/ralph" >&2 + fi +fi + +# Exit immediately (NON-BLOCKING - Claude Code continues) exit 0 diff --git a/hooks/session-start-superpowers.sh b/hooks/session-start-superpowers.sh index 0daef5e..f47cd4e 100755 --- a/hooks/session-start-superpowers.sh +++ b/hooks/session-start-superpowers.sh @@ -1,14 +1,15 @@ -#!/bin/bash -# Session Start Hook - Auto-inject superpowers context -# This hook runs on every session start/resume -# Trigger: session-start +#!/usr/bin/env bash +set -euo pipefail -# Check if AUTO_SUPERPOWERS is enabled -if [ "${AUTO_SUPERPOWERS:-false}" = "true" ]; then - # Inject superpowers context into the session - if [ -f "$HOME/.claude/skills/using-superpowers/skill.md" ]; then - cat "$HOME/.claude/skills/using-superpowers/skill.md" - fi -fi +# Read skill files and inject into session context +auto_superpowers_content=$(cat "${HOME}/.claude/skills/auto-superpowers/SKILL.md" 2>/dev/null || echo "Skill not found") +using_superpowers_content=$(cat "${HOME}/.claude/skills/using-superpowers/SKILL.md" 2>/dev/null || echo "Skill not found") -exit 0 +# Output JSON with skills injected +cat < -``` - -## Configuration - -Plugin settings go in `~/.claude/settings.json` under `plugins` section. +# Claude Code Plugin System + +A Conduit-inspired plugin and hooks system for Claude Code, enabling extensible functionality through GitHub-based plugins, event-driven hooks, and secure sandboxed execution. + +## Table of Contents + +- [Features](#features) +- [Installation](#installation) +- [Quick Start](#quick-start) +- [Plugin Development](#plugin-development) +- [Hooks System](#hooks-system) +- [CLI Reference](#cli-reference) +- [Security](#security) +- [Examples](#examples) + +## Features + +### šŸŽÆ Core Capabilities + +- **GitHub-based Discovery**: Automatically discover plugins from GitHub repositories +- **Zero-Configuration Install**: One-command installation from any GitHub repo +- **Event-Driven Hooks**: Hook into any Claude Code event (pre/post execution) +- **Security Sandboxing**: Isolated execution with permission validation +- **Command Extensions**: Add custom commands to Claude Code +- **Tool Extensions**: Extend Claude Code's built-in tools +- **Version Management**: Track, update, and manage plugin versions +- **Integrity Checking**: SHA-256 verification for plugin security + +### šŸ” Security Features + +- Permission-based access control +- File system sandboxing +- Command execution validation +- Network access control +- Code injection prevention +- Binary integrity verification + +## Installation + +The plugin system is included with Claude Code. No additional installation required. + +## Quick Start + +### Discover Plugins + +```bash +# List all available plugins +claude-plugin discover + +# Search for specific plugins +claude-plugin discover git +claude-plugin discover docker +``` + +### Install Plugins + +```bash +# Install from a marketplace +claude-plugin install claude-plugins-official hookify + +# Install directly from GitHub +claude-plugin install-github username/my-plugin +``` + +### Manage Plugins + +```bash +# View plugin information +claude-plugin info hookify + +# Enable/disable plugins +claude-plugin enable hookify +claude-plugin disable hookify + +# Update plugins +claude-plugin update hookify + +# Uninstall plugins +claude-plugin uninstall hookify +``` + +## Plugin Development + +### Plugin Structure + +``` +my-plugin/ +ā”œā”€ā”€ .claude-plugin/ +│ └── plugin.json # Plugin metadata +ā”œā”€ā”€ commands/ # Command handlers +│ └── my-command.ts +ā”œā”€ā”€ hooks/ # Hook handlers +│ └── my-hook.ts +ā”œā”€ā”€ skills/ # Skill definitions +│ └── my-skill.md +ā”œā”€ā”€ install.sh # Installation script (optional) +└── uninstall.sh # Uninstallation script (optional) +``` + +### Plugin Metadata + +Create a `.claude-plugin/plugin.json` file: + +```json +{ + "name": "my-plugin", + "version": "1.0.0", + "description": "My awesome plugin for Claude Code", + "author": "Your Name", + "license": "MIT", + "repository": "https://github.com/username/my-plugin", + "claude": { + "minVersion": "1.0.0", + "permissions": [ + "read:files", + "write:files", + "execute:commands" + ], + "commands": [ + { + "name": "my:command", + "description": "Does something awesome", + "handler": "commands/my-command.ts", + "permissions": ["read:files"] + } + ], + "hooks": [ + { + "event": "PostFileEdit", + "handler": "hooks/my-hook.ts", + "priority": 10 + } + ] + } +} +``` + +### Creating Commands + +```typescript +// commands/my-command.ts +export interface MyCommandOptions { + input: string + option?: string +} + +export async function handle( + args: MyCommandOptions, + context: any +): Promise { + const { input, option } = args + + // Your logic here + return `āœ“ Command executed with: ${input}` +} + +export default { handle } +``` + +### Creating Hooks + +```typescript +// hooks/my-hook.ts +export interface HookContext { + event: string + timestamp: string + data: Record +} + +export async function handle( + context: HookContext +): Promise { + console.log(`Hook triggered: ${context.event}`) + console.log(`Data:`, context.data) + + // Your logic here +} + +export default { handle } +``` + +### Publishing Your Plugin + +1. Create a GitHub repository with your plugin +2. Add the `.claude-plugin/plugin.json` metadata file +3. Push to GitHub +4. Users can install with: + ```bash + claude-plugin install-github username/your-plugin + ``` + +## Hooks System + +### Available Hook Events + +| Event | Description | When It Fires | +|-------|-------------|---------------| +| `UserPromptSubmit` | User submits a prompt | Before sending to Claude | +| `PreToolUse` | Before tool execution | Tool about to be used | +| `PostToolUse` | After tool execution | Tool completed | +| `PreFileEdit` | Before file edit | File about to be modified | +| `PostFileEdit` | After file edit | File was modified | +| `PreCommand` | Before CLI command | Command about to run | +| `PostCommand` | After CLI command | Command completed | +| `SessionStart` | Session starts | New session begins | +| `SessionEnd` | Session ends | Session closing | +| `PluginLoad` | Plugin loads | Plugin loaded into memory | +| `PluginUnload` | Plugin unloads | Plugin being unloaded | +| `Error` | Error occurs | Any error happens | + +### Hook Priority + +Hooks execute in priority order (higher = earlier). Default priority is 0. + +```json +{ + "event": "PostFileEdit", + "handler": "hooks/auto-save.ts", + "priority": 100 +} +``` + +### Registering Hooks via Config + +You can register hooks in your `.claude/hooks.json`: + +```json +{ + "hooks": { + "PostFileEdit": [ + { + "hooks": [ + { + "type": "command", + "command": "/path/to/hook-script.sh", + "timeout": 5 + } + ] + } + ] + } +} +``` + +## CLI Reference + +### `claude-plugin discover [query]` +List available plugins, optionally filtering by search query. + +```bash +claude-plugin discover +claude-plugin discover git +``` + +### `claude-plugin install [plugin-name]` +Install a plugin from a marketplace. + +```bash +claude-plugin install claude-plugins-official hookify +claude-plugin install claude-plugins-official # List all plugins +``` + +### `claude-plugin install-github ` +Install a plugin directly from GitHub. + +```bash +claude-plugin install-github username/my-plugin +``` + +### `claude-plugin uninstall [marketplace]` +Uninstall a plugin. + +```bash +claude-plugin uninstall hookify +``` + +### `claude-plugin enable/disable [marketplace]` +Enable or disable a plugin without uninstalling. + +```bash +claude-plugin enable hookify +claude-plugin disable hookify +``` + +### `claude-plugin update [marketplace]` +Update a plugin to the latest version. + +```bash +claude-plugin update hookify +``` + +### `claude-plugin info ` +Show detailed information about a plugin. + +```bash +claude-plugin info hookify +``` + +### `claude-plugin hooks [event]` +List registered hooks. + +```bash +claude-plugin hooks # All hooks +claude-plugin hooks PostFileEdit # Specific event +``` + +### `claude-plugin add-marketplace ` +Add a new plugin marketplace. + +```bash +claude-plugin add-marketplace my-marketplace https://github.com/user/repo +``` + +### `claude-plugin validate ` +Validate a plugin structure and integrity. + +```bash +claude-plugin validate /path/to/plugin +``` + +## Security + +### Permissions + +Plugins request permissions in their `plugin.json`: + +| Permission | Description | +|------------|-------------| +| `read:files` | Read files from the file system | +| `write:files` | Write files to the file system | +| `execute:commands` | Execute shell commands | +| `network:request` | Make network requests | +| `read:config` | Read Claude Code configuration | +| `write:config` | Write Claude Code configuration | +| `hook:events` | Register event hooks | +| `read:secrets` | Access sensitive data (API keys, etc.) | + +### Sandboxing + +Plugins execute in a sandboxed environment with: + +- **File System**: Access restricted to allowed paths +- **Commands**: Dangerous patterns blocked (rm -rf /, etc.) +- **Network**: Domain whitelist/blacklist enforcement +- **Code**: Injection prevention and sanitization + +### Integrity Verification + +All plugins are verified with SHA-256 hashes: + +```bash +# View plugin integrity +claude-plugin info my-plugin + +# Verify manually +claude-plugin validate /path/to/plugin +``` + +## Examples + +### Example 1: Git Workflow Plugin + +Commands: +- `git:smart-commit` - Auto-stage and commit +- `git:pr-create` - Create pull requests +- `git:branch-cleanup` - Clean up merged branches + +```bash +claude-plugin install-github yourusername/git-workflow +git:smart-commit --type feat --scope api +git:pr-create --title "Add new feature" --base main +``` + +### Example 2: Docker Helper Plugin + +Commands: +- `docker:deploy` - Deploy with zero-downtime +- `docker:logs` - View and filter logs +- `docker:cleanup` - Clean up resources +- `docker:env` - Manage environment variables + +```bash +claude-plugin install-github yourusername/docker-helper +docker:deploy --env production --no-downtime +docker:logs --service app --tail 100 --follow +docker:cleanup --containers --images --volumes +``` + +### Example 3: Knowledge Base Plugin + +Commands: +- `knowledge:add` - Add knowledge entries +- `knowledge:search` - Search knowledge base +- `knowledge:list` - List all entries +- `knowledge:export` - Export to JSON/Markdown/CSV + +```bash +claude-plugin install-github yourusername/knowledge-base +knowledge:add --content "How to deploy to production" --tags deploy,ops +knowledge:search --query "deploy" --category ops +knowledge:export --format markdown +``` + +## Architecture + +### Core Components + +``` +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” +│ Claude Code Core │ +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ + ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” + │ │ │ +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā” +│ Plugin │ │ Hook │ │ Security │ +│ Manager │ │ System │ │ Manager │ +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ │ │ + ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ + ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” + │ Plugins │ + │ (Sandboxed) │ + ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ +``` + +### Data Flow + +1. **Installation**: Plugin downloaded from GitHub → Validation → Registration +2. **Loading**: Plugin metadata read → Security context created → Hooks registered +3. **Execution**: Command/tool called → Permission check → Sandboxed execution +4. **Hooks**: Event fires → Hooks executed by priority → Results collected + +## Contributing + +We welcome contributions! Please see our contributing guidelines for more information. + +## License + +MIT License - see LICENSE file for details + +## Support + +- GitHub Issues: https://github.com/anthropics/claude-code/issues +- Documentation: https://docs.anthropic.com + +## Acknowledgments + +Inspired by [Conduit](https://github.com/conduit-ui/conduit) - the developer liberation platform. diff --git a/plugins/glm-plan-bug/plugin.json b/plugins/glm-plan-bug/plugin.json deleted file mode 100644 index 758ee48..0000000 --- a/plugins/glm-plan-bug/plugin.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "glm-plan-bug:case-feedback", - "version": "1.0.0", - "description": "Bug case feedback system for GLM Coding Plan", - "type": "feedback", - "author": "GLM Team", - "capabilities": ["case-feedback"], - "triggers": ["/glm-plan-bug:case-feedback"], - "config": { - "endpoint": "https://glm-plan-bug.example.com/api/feedback" - } -} diff --git a/plugins/glm-plan-usage/plugin.json b/plugins/glm-plan-usage/plugin.json deleted file mode 100644 index adb3dbd..0000000 --- a/plugins/glm-plan-usage/plugin.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "glm-plan-usage:usage-query", - "version": "1.0.0", - "description": "Usage query system for GLM Coding Plan", - "type": "usage", - "author": "GLM Team", - "capabilities": ["usage-query"], - "triggers": ["/glm-plan-usage:usage-query"], - "config": { - "endpoint": "https://glm-plan-usage.example.com/api/query" - } -} diff --git a/plugins/marketplaces/README.md b/plugins/marketplaces/README.md deleted file mode 100644 index aed6910..0000000 --- a/plugins/marketplaces/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Plugin Marketplace - -References to external plugin marketplaces for Claude Code. - -## Available Marketplaces - -### Superpowers Marketplace -- **URL**: https://github.com/obra/superpowers-marketplace -- **Description**: Community-driven skills and plugins marketplace -- **Install**: Add to `config.json` marketplaces section - -## Installation - -To add a marketplace, edit `~/.claude/config.json`: - -```json -{ - "marketplaces": { - "obra/superpowers-marketplace": "/path/to/marketplace" - } -} -``` - -## Featured Plugins - -Browse the marketplace to discover: -- Custom skills -- Agent templates -- Tool integrations -- Theme packages diff --git a/plugins/rust-analyzer-lsp/plugin.json b/plugins/rust-analyzer-lsp/plugin.json deleted file mode 100644 index 4d7d732..0000000 --- a/plugins/rust-analyzer-lsp/plugin.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "rust-analyzer-lsp", - "version": "1.0.0", - "description": "Rust language support via LSP", - "type": "lsp", - "language": "rust", - "capabilities": ["definition", "references", "hover", "completion"], - "install": "rust-analyzer" -} diff --git a/scripts/sync-agents.sh b/scripts/sync-agents.sh index 0e272db..019d552 100755 --- a/scripts/sync-agents.sh +++ b/scripts/sync-agents.sh @@ -1,270 +1,246 @@ #!/bin/bash -################################################################################ -# sync-agents.sh - Agent Synchronization Script -################################################################################ -# Synchronizes agents from GitHub/Gitea repositories to local Claude Code -# installation. -# -# Usage: -# ./sync-agents.sh [options] -# -# Options: -# --source URL Source repository URL -# --branch NAME Branch to sync from (default: main) -# --force Force overwrite existing agents -# --dry-run Show what would be done without doing it -# --verbose Enable verbose output -# -# Configuration: -# Sources can be configured in ~/.claude/agents/sync-sources.json -################################################################################ +# Claude Code Agents Sync Script +# Syncs local agents with GitHub repository and backs up to Gitea -set -e +set -euo pipefail -# Colors +# Configuration +AGENTS_DIR="${HOME}/.claude/agents" +BACKUP_DIR="${AGENTS_DIR}.backup.$(date +%Y%m%d-%H%M%S)" +GITHUB_REPO="https://github.com/contains-studio/agents" +TEMP_DIR="/tmp/claude-agents-sync-$RANDOM" +UPSTREAM_DIR="$TEMP_DIR/upstream" +LOG_FILE="${AGENTS_DIR}/update.log" + +# Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' -CYAN='\033[0;36m' -BOLD='\033[1m' -NC='\033[0m' +NC='\033[0m' # No Color -# Directories -CLAUDE_DIR="${HOME}/.claude" -AGENTS_DIR="${CLAUDE_DIR}/agents" -CONFIG_FILE="${AGENTS_DIR}/sync-sources.json" - -# Flags -FORCE=false -DRY_RUN=false -VERBOSE=false - -# Default sources -DEFAULT_SOURCES=( - "https://github.com/anthropics/anthropic-agents" - "https://github.com/contains-cafe/studio-agents" -) - -################################################################################ -# Helper Functions -################################################################################ - -log_info() { - echo -e "${BLUE}[INFO]${NC} $1" +# Logging function +log() { + local level=$1 + shift + local message="$@" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE" } -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" +# Print colored message +print_msg() { + local color=$1 + shift + echo -e "${color}$*${NC}" } -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -log_step() { - echo -e "${CYAN}${BOLD}==>${NC} ${BOLD}$1${NC}" -} - -################################################################################ -# Agent Synchronization -################################################################################ - -sync_from_source() { - local source_url="$1" - local branch="${2:-main}" - local temp_dir - - log_step "Syncing from $source_url" - - # Create temp directory for clone - temp_dir=$(mktemp -d) - - if [ "$DRY_RUN" = true ]; then - log_info "[DRY RUN] Would clone $source_url (branch: $branch)" - rm -rf "$temp_dir" - return 0 - fi - - # Clone repository - if ! git clone --depth 1 --branch "$branch" "$source_url" "$temp_dir" 2>/dev/null; then - log_warn "Failed to clone $source_url" - rm -rf "$temp_dir" - return 1 - fi - - # Copy agents - local agent_count=0 - local copied_count=0 - local skipped_count=0 - - # Find agent definitions (look for common patterns) - while IFS= read -r -d '' agent_file; do - ((agent_count++)) - - local agent_name - agent_name=$(basename "$(dirname "$agent_file")") - local dest_dir="${AGENTS_DIR}/${agent_name}" - - # Check if already exists - if [ -d "$dest_dir" ] && [ "$FORCE" = false ]; then - ((skipped_count++)) - [ "$VERBOSE" = true ] && log_info "Skipped: $agent_name (exists)" - continue - fi - - # Create destination and copy - mkdir -p "$dest_dir" - cp -r "$(dirname "$agent_file")"/* "$dest_dir/" 2>/dev/null || true - ((copied_count++)) - - [ "$VERBOSE" = true ] && log_info "Copied: $agent_name" - - done < <(find "$temp_dir" -type f \( -name "agent.md" -o -name "skill.md" -o -name "AGENT.md" -o -name "SKILL.md" \) -print0 2>/dev/null) - - # Cleanup - rm -rf "$temp_dir" - - log_success "Synced from $source_url: $copied_count copied, $skipped_count skipped (found $agent_count total)" -} - -sync_from_config() { - local config_file="$1" - - if [ ! -f "$config_file" ]; then - log_warn "Config file not found: $config_file" - return 1 - fi - - # Parse JSON config (requires jq) - if command -v jq &> /dev/null; then - local sources - sources=$(jq -r '.sources[].url' "$config_file" 2>/dev/null) - - if [ -z "$sources" ]; then - log_warn "No sources found in config" - return 1 - fi - - while IFS= read -r source; do - local branch - branch=$(jq -r ".sources[] | select(.url==\"$source\") | .branch // \"main\"" "$config_file") - sync_from_source "$source" "$branch" - done <<< "$sources" +# Create backup +create_backup() { + print_msg "$BLUE" "šŸ“¦ Creating backup..." + if cp -r "$AGENTS_DIR" "$BACKUP_DIR"; then + print_msg "$GREEN" "āœ“ Backup created: $BACKUP_DIR" + log "INFO" "Backup created at $BACKUP_DIR" else - log_warn "jq not found. Cannot parse config file." - log_info "Install jq: sudo apt-get install jq" - return 1 + print_msg "$RED" "āœ— Failed to create backup" + log "ERROR" "Backup creation failed" + exit 1 fi } -sync_default_sources() { - log_step "Syncing from default sources" +# Download upstream agents +download_upstream() { + print_msg "$BLUE" "šŸ“„ Downloading agents from $GITHUB_REPO..." + mkdir -p "$TEMP_DIR" - for source in "${DEFAULT_SOURCES[@]}"; do - sync_from_source "$source" "main" - done -} - -################################################################################ -# Main -################################################################################ - -print_usage() { - cat << EOF -Usage: $0 [options] - -Options: - --source URL Source repository URL - --branch NAME Branch to sync from (default: main) - --force Force overwrite existing agents - --dry-run Show what would be done without doing it - --verbose Enable verbose output - -h, --help Show this help message - -Examples: - $0 # Sync from default sources - $0 --source https://github.com/user/repo - $0 --force --verbose # Force overwrite, verbose output - $0 --dry-run # Preview changes - -Configuration: - Sources can be configured in ~/.claude/agents/sync-sources.json - - Format: - { - "sources": [ - { - "url": "https://github.com/user/repo", - "branch": "main" - } - ] - } -EOF -} - -main() { - local custom_source="" - local custom_branch="main" - - # Parse arguments - while [[ $# -gt 0 ]]; do - case $1 in - --source) - custom_source="$2" - shift 2 - ;; - --branch) - custom_branch="$2" - shift 2 - ;; - --force) - FORCE=true - shift - ;; - --dry-run) - DRY_RUN=true - shift - ;; - --verbose) - VERBOSE=true - shift - ;; - -h|--help) - print_usage - exit 0 - ;; - *) - log_error "Unknown option: $1" - print_usage - exit 1 - ;; - esac - done - - # Ensure agents directory exists - mkdir -p "$AGENTS_DIR" - - # Sync - if [ -n "$custom_source" ]; then - sync_from_source "$custom_source" "$custom_branch" - elif [ -f "$CONFIG_FILE" ]; then - sync_from_config "$CONFIG_FILE" + if command -v git &> /dev/null; then + # Use git if available (faster) + git clone --depth 1 "$GITHUB_REPO" "$UPSTREAM_DIR" 2>/dev/null || { + print_msg "$RED" "āœ— Failed to clone repository" + log "ERROR" "Git clone failed" + exit 1 + } else - sync_default_sources + # Fallback to wget/curl + print_msg "$YELLOW" "⚠ Git not found, downloading archive..." + local archive="$TEMP_DIR/agents.tar.gz" + if command -v wget &> /dev/null; then + wget -q "$GITHUB_REPO/archive/main.tar.gz" -O "$archive" + elif command -v curl &> /dev/null; then + curl -sL "$GITHUB_REPO/archive/main.tar.gz" -o "$archive" + else + print_msg "$RED" "āœ— Need git, wget, or curl" + exit 1 + fi + mkdir -p "$UPSTREAM_DIR" + tar -xzf "$archive" -C "$UPSTREAM_DIR" --strip-components=1 + fi + + print_msg "$GREEN" "āœ“ Downloaded upstream agents" + log "INFO" "Downloaded agents from $GITHUB_REPO" +} + +# Compare and sync agents +sync_agents() { + print_msg "$BLUE" "šŸ”„ Syncing agents..." + + local new_agents=() + local updated_agents=() + local custom_agents=() + + # Find all agent files in upstream + while IFS= read -r upstream_file; do + local rel_path="${upstream_file#$UPSTREAM_DIR/}" + local local_file="$AGENTS_DIR/$rel_path" + + if [[ ! -f "$local_file" ]]; then + # New agent + new_agents+=("$rel_path") + mkdir -p "$(dirname "$local_file")" + cp "$upstream_file" "$local_file" + log "INFO" "Added new agent: $rel_path" + elif ! diff -q "$upstream_file" "$local_file" &>/dev/null; then + # Updated agent - check if customized + if grep -q "CUSTOMIZED" "$local_file" 2>/dev/null || \ + [[ -f "${local_file}.local" ]]; then + custom_agents+=("$rel_path") + log "WARN" "Skipped customized agent: $rel_path" + else + updated_agents+=("$rel_path") + cp "$upstream_file" "$local_file" + log "INFO" "Updated agent: $rel_path" + fi + fi + done < <(find "$UPSTREAM_DIR" -name "*.md" -type f) + + # Report results + echo "" + print_msg "$GREEN" "✨ New agents (${#new_agents[@]}):" + for agent in "${new_agents[@]}"; do + echo " + $agent" + done | head -20 + + echo "" + print_msg "$YELLOW" "šŸ“ Updated agents (${#updated_agents[@]}):" + for agent in "${updated_agents[@]}"; do + echo " ~ $agent" + done | head -20 + + if [[ ${#custom_agents[@]} -gt 0 ]]; then + echo "" + print_msg "$YELLOW" "āš ļø Preserved custom agents (${#custom_agents[@]}):" + for agent in "${custom_agents[@]}"; do + echo " • $agent" + done | head -20 fi # Summary - local total_agents - total_agents=$(find "$AGENTS_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l) - - log_success "Agent sync complete!" - log_info "Total agents in $AGENTS_DIR: $total_agents" + local total_changes=$((${#new_agents[@]} + ${#updated_agents[@]})) + log "INFO" "Sync complete: ${#new_agents[@]} new, ${#updated_agents[@]} updated, ${#custom_agents[@]} preserved" } -# Run main +# Commit to git +commit_to_git() { + print_msg "$BLUE" "šŸ’¾ Committing to git..." + + cd "$AGENTS_DIR" + + # Check if there are changes + if git diff --quiet && git diff --cached --quiet; then + print_msg "$YELLOW" "āš ļø No changes to commit" + return + fi + + # Add all agents + git add . -- '*.md' + + # Commit with descriptive message + local commit_msg="Update agents from upstream + +$(date '+%Y-%m-%d %H:%M:%S') + +Changes: +- $(git diff --cached --name-only | wc -l) files updated +- From: $GITHUB_REPO" + + git commit -m "$commit_msg" 2>/dev/null || { + print_msg "$YELLOW" "āš ļø Nothing to commit or git not configured" + log "WARN" "Git commit skipped" + return + } + + print_msg "$GREEN" "āœ“ Committed to local git" + log "INFO" "Committed changes to git" +} + +# Push to Gitea +push_to_gitea() { + if [[ -z "${GITEA_REPO_URL:-}" ]]; then + print_msg "$YELLOW" "āš ļø GITEA_REPO_URL not set, skipping push" + print_msg "$YELLOW" " Set it with: export GITEA_REPO_URL='your-gitea-repo-url'" + log "WARN" "GITEA_REPO_URL not set, push skipped" + return + fi + + print_msg "$BLUE" "šŸ“¤ Pushing to Gitea..." + + cd "$AGENTS_DIR" + + # Ensure remote exists + if ! git remote get-url origin &>/dev/null; then + git remote add origin "$GITEA_REPO_URL" + fi + + if git push -u origin main 2>/dev/null || git push -u origin master 2>/dev/null; then + print_msg "$GREEN" "āœ“ Pushed to Gitea" + log "INFO" "Pushed to Gitea: $GITEA_REPO_URL" + else + print_msg "$YELLOW" "āš ļø Push failed (check credentials/URL)" + log "ERROR" "Push to Gitea failed" + fi +} + +# Cleanup +cleanup() { + rm -rf "$TEMP_DIR" +} + +# Rollback function +rollback() { + print_msg "$RED" "šŸ”„ Rolling back to backup..." + if [[ -d "$BACKUP_DIR" ]]; then + rm -rf "$AGENTS_DIR" + mv "$BACKUP_DIR" "$AGENTS_DIR" + print_msg "$GREEN" "āœ“ Rolled back successfully" + log "INFO" "Rolled back to $BACKUP_DIR" + else + print_msg "$RED" "āœ— No backup found!" + log "ERROR" "Rollback failed - no backup" + fi +} + +# Main execution +main() { + print_msg "$BLUE" "šŸš€ Claude Code Agents Sync" + print_msg "$BLUE" "════════════════════════════" + echo "" + + trap cleanup EXIT + trap rollback ERR + + create_backup + download_upstream + sync_agents + commit_to_git + push_to_gitea + + echo "" + print_msg "$GREEN" "āœ… Sync complete!" + print_msg "$BLUE" "šŸ’¾ Backup: $BACKUP_DIR" + print_msg "$BLUE" "šŸ“‹ Log: $LOG_FILE" + echo "" + print_msg "$YELLOW" "To rollback: rm -rf $AGENTS_DIR && mv $BACKUP_DIR $AGENTS_DIR" +} + +# Run main function main "$@" diff --git a/templates/README.md b/templates/README.md deleted file mode 100644 index 3bdc2ef..0000000 --- a/templates/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Configuration Templates - -This directory contains template configuration files for Claude Code. - -## Files - -| File | Purpose | Location After Install | -|------|---------|----------------------| -| `settings.json` | Main Claude Code settings | `~/.claude/settings.json` | -| `settings.local.json` | Local permissions and settings | `~/.claude/settings.local.json` | -| `hooks.json` | Hook configuration | `~/.claude/hooks.json` | -| `config.json` | Marketplace and plugins config | `~/.claude/config.json` | - -## Installation - -The `supercharge.sh` script will install these templates if they don't already exist. - -Existing configurations are preserved - templates are only installed if the target file doesn't exist. - -## Settings Overview - -### settings.json -- **cursorFormatting**: How to format code cursors -- **skills**: Auto-load skills and priorities -- **hooks**: Hook configuration - -### settings.local.json -- **permissions**: Allowed prompt patterns -- **local**: Local environment settings - -### hooks.json -- **session-start**: Hooks that run when session starts -- **user-prompt**: Hooks that run on each user prompt -- **environment**: Environment variables for hooks - -### config.json -- **marketplaces**: Plugin marketplace sources -- **plugins**: Plugin sources -- **agents**: Agent sync sources - -## Customization - -After installation, edit the files in `~/.claude/` to customize your setup. - -Templates will not be overwritten on subsequent runs - your changes are preserved. diff --git a/templates/config.json b/templates/config.json index 1aeda47..69963f5 100644 --- a/templates/config.json +++ b/templates/config.json @@ -1,25 +1 @@ -{ - "marketplaces": { - "obra/superpowers-marketplace": "https://github.com/obra/superpowers-marketplace" - }, - "plugins": { - "sources": [ - "https://github.com/anthropics/claude-code-plugins" - ] - }, - "agents": { - "syncOnStartup": true, - "sources": [ - { - "url": "https://github.com/anthropics/anthropic-agents", - "branch": "main", - "enabled": true - }, - { - "url": "https://github.com/contains-cafe/studio-agents", - "branch": "main", - "enabled": true - } - ] - } -} +{"marketplaces": {"obra/superpowers-marketplace": "/home/uroma/.claude/plugins/marketplaces/superpowers-marketplace"}} diff --git a/templates/hooks.json b/templates/hooks.json index a7df298..36b6693 100644 --- a/templates/hooks.json +++ b/templates/hooks.json @@ -1,40 +1,21 @@ { + "description": "User hooks for Ralph auto-trigger and Qwen consultation", "hooks": { - "session-start": [ + "UserPromptSubmit": [ { - "file": "session-start-superpowers.sh", - "enabled": true, - "description": "Auto-inject superpowers context on session start" + "hooks": [ + { + "type": "command", + "command": "/home/uroma/.claude/hooks/ralph-auto-trigger.sh", + "timeout": 5 + }, + { + "type": "command", + "command": "/home/uroma/.claude/hooks/qwen-consult.sh", + "timeout": 3 + } + ] } - ], - "session-end": [], - "user-prompt": [ - { - "file": "qwen-consult.sh", - "enabled": true, - "description": "Qwen AI consultation on complex tasks" - }, - { - "file": "ralph-auto-trigger.sh", - "enabled": false, - "description": "Auto-trigger Ralph for autonomous iteration" - }, - { - "file": "consult-qwen.sh", - "enabled": true, - "description": "Qwen consultation wrapper" - } - ], - "tool-use": [], - "response": [] - }, - "environment": { - "RALPH_AGENT": "claude", - "RALPH_MAX_ITERATIONS": "100", - "RALPH_MAX_RUNTIME": "14400", - "QWEN_CONSULT_MODE": "delegate", - "QWEN_MODEL": "qwen-coder-plus", - "QWEN_MAX_ITERATIONS": "3", - "AUTO_SUPERPOWERS": "true" + ] } } diff --git a/templates/settings.json b/templates/settings.json index 35cbc44..891ca24 100644 --- a/templates/settings.json +++ b/templates/settings.json @@ -1,28 +1,15 @@ { - "cursorFormatting": "compact", - "inlineChatPreview": "compact", - "ensureConsistency": true, - "experimentalFeatures": { - "contextMenu": true, - "debugTools": true + "env": { + "ANTHROPIC_AUTH_TOKEN": "020f54a283144bfea9f182f2f2e37d9c.PsqKSA7AFIfKuaEl", + "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic", + "API_TIMEOUT_MS": "3000000", + "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", + "ANTHROPIC_MODEL": "glm-4.7" }, - "permissions": {}, - "skills": { - "autoLoad": [ - "always-use-superpowers", - "auto-superpowers" - ], - "priority": { - "always-use-superpowers": 9999 - } - }, - "hooks": { - "session-start": [ - "session-start-superpowers.sh" - ], - "user-prompt": [ - "qwen-consult.sh", - "ralph-auto-trigger.sh" - ] + "enabledPlugins": { + "glm-plan-bug@zai-coding-plugins": true, + "glm-plan-usage@zai-coding-plugins": true, + "superpowers@superpowers-marketplace": true, + "rust-analyzer-lsp@claude-plugins-official": true } } diff --git a/templates/settings.local.json b/templates/settings.local.json index dfa02a7..c785441 100644 --- a/templates/settings.local.json +++ b/templates/settings.local.json @@ -1,10 +1,22 @@ { "permissions": { - "allowedPrompts": [] - }, - "local": { - "autoSuperpowers": true, - "ralphAuto": false, - "qwenConsultMode": "delegate" + "allow": [ + "Bash(npm install:*)", + "Bash(npm run content:*)", + "Bash(npm run build:*)", + "Bash(grep:*)", + "Bash(find:*)", + "Bash(for:*)", + "Bash(do sed:*)", + "Bash(done)", + "Bash(python3:*)", + "Bash(while read f)", + "Bash(do echo \"$f%-* $f\")", + "Bash(ls:*)", + "Bash(node:*)", + "Bash(pm2 delete:*)", + "Bash(pm2 start npm:*)", + "Bash(pm2 save:*)" + ] } }