Files
ClaudeForge/install.sh
T
Claude a45e6f5dbd feat(plugin): ship as Claude Code plugin with 150-line cap and sync command
Turns ClaudeForge into an installable Claude Code plugin and adds the
missing pieces for a clean lifecycle: hard line-cap enforcement, modular
chaining via @path imports, a sync/cleanup command, and Explore-agent
delegation for project discovery.

- .claude-plugin/plugin.json: plugin manifest registering both skills,
  both commands, and the guardian agent (installable via /plugin marketplace
  add alirezarezvani/ClaudeForge && /plugin install claudeforge)
- skill/validator.py: MAX_RECOMMENDED_LINES 300 -> 150 (warning at 120)
- skill/template_selector.py: target_lines capped at 150 across all
  team sizes (solo 75 / small 100 / medium 125 / large 150) so any
  single CLAUDE.md fits within the cap; bigger projects spread content
  across modular sub-files
- skill/analyzer.py: length thresholds, quality scoring, and recommendations
  rebased on the 150 cap (was 300/400)
- skill/generator.py: modular root now emits @path imports next to the
  human-readable links; every sub-CLAUDE.md gets a back-link header
  pointing to ../CLAUDE.md (markdown + @import) for bidirectional chaining
- command/sync-claude-md.md: new /sync-claude-md command that inventories
  every CLAUDE.md, prunes stale references, enforces the 150 cap by
  splitting into sub-files, and repairs the root <-> sub chain
- command/enhance-claude-md.md: discovery phase now delegates the deep
  codebase scan to the Explore subagent to keep context lean
- install.sh / install.ps1: each command in command/ installs as its own
  ~/.claude/commands/<name>.md (legacy bundle backed up on upgrade)
- skill/SKILL.md, CLAUDE.md, README.md, CHANGELOG.md: docs updated for
  the plugin install path, sync command, and new line cap

Verified via smoke test: validator constants, template targets, generator
output line counts across 5 presets (all <= 150), context files with
backlinks, @-import chain in modular root, idempotent merge_with_existing,
validator status transitions at the new cap, analyzer quality differential,
and plugin manifest JSON shape with all referenced paths existing on disk.
2026-05-19 02:03:59 +00:00

360 lines
12 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ClaudeForge Installer
# Automated installation script for macOS and Linux
# Version: 2.0.0
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Print colored output
print_info() {
echo -e "${BLUE}${NC} $1"
}
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
# Banner
echo ""
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}${GREEN}ClaudeForge Installer${BLUE}${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}║ Automated CLAUDE.md Management Tool ║${NC}"
echo -e "${BLUE}║ Version 2.0.0 ║${NC}"
echo -e "${BLUE}║ ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
echo ""
# Check if running from correct directory or need to download
REMOTE_INSTALL=false
ORIGINAL_DIR=$(pwd)
if [ ! -d "skill" ] || [ ! -d "command" ] || [ ! -d "agent" ]; then
print_info "Installing from GitHub..."
REMOTE_INSTALL=true
# Create temporary directory
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
print_info "Downloading ClaudeForge v2.0.0..."
# Download using curl or wget
if command -v curl &> /dev/null; then
curl -fsSL https://github.com/alirezarezvani/ClaudeForge/archive/refs/heads/main.tar.gz -o claudeforge.tar.gz
elif command -v wget &> /dev/null; then
wget -q https://github.com/alirezarezvani/ClaudeForge/archive/refs/heads/main.tar.gz -O claudeforge.tar.gz
else
print_error "Neither curl nor wget found. Please install one of them."
exit 1
fi
print_info "Extracting files..."
tar -xzf claudeforge.tar.gz
cd ClaudeForge-main
print_success "Downloaded ClaudeForge successfully"
fi
# Check for Claude Code installation
print_info "Checking for Claude Code installation..."
if [ ! -d "$HOME/.claude" ]; then
print_warning "Claude Code user directory (~/.claude) not found."
print_info "Creating ~/.claude directory structure..."
mkdir -p "$HOME/.claude"/{skills,commands,agents}
print_success "Directory structure created"
fi
# Check Claude Code version
check_claude_code_version() {
local version=""
if command -v claude &> /dev/null; then
version=$(claude --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
fi
if [ -z "$version" ]; then
print_warning "Could not detect Claude Code version"
print_info "ClaudeForge v2.0 requires Claude Code 2.1.0 or later"
print_info "Continuing with installation (compatibility not guaranteed)"
return 0
fi
local major=$(echo "$version" | cut -d. -f1)
local minor=$(echo "$version" | cut -d. -f2)
if [ "$major" -lt 2 ]; then
print_error "Claude Code version $version is not supported"
print_error "Please upgrade to Claude Code 2.1.0 or later"
return 1
elif [ "$major" -eq 2 ] && [ "$minor" -lt 1 ]; then
print_warning "Claude Code version $version may have limited features"
print_info "Recommended: Claude Code 2.1.4 or later for full hook support"
fi
print_success "Claude Code version $version detected"
return 0
}
print_info "Checking Claude Code version..."
check_claude_code_version || exit 1
# Ask for installation scope
echo ""
print_info "Where would you like to install ClaudeForge?"
echo ""
echo -e " ${GREEN}1)${NC} User-level (~/.claude/) - Available in all Claude Code projects"
echo -e " ${GREEN}2)${NC} Project-level (./.claude/) - Available only in current project"
echo ""
while true; do
read -p "$(echo -e ${BLUE}Enter choice [1/2]:${NC} )" choice < /dev/tty
case $choice in
1)
SKILLS_DIR="$HOME/.claude/skills"
COMMANDS_DIR="$HOME/.claude/commands"
AGENTS_DIR="$HOME/.claude/agents"
SCOPE="user-level"
print_success "Installing at user-level (all projects)"
break
;;
2)
if [ "$REMOTE_INSTALL" = true ]; then
SKILLS_DIR="$ORIGINAL_DIR/.claude/skills"
COMMANDS_DIR="$ORIGINAL_DIR/.claude/commands"
AGENTS_DIR="$ORIGINAL_DIR/.claude/agents"
else
SKILLS_DIR="./.claude/skills"
COMMANDS_DIR="./.claude/commands"
AGENTS_DIR="./.claude/agents"
fi
SCOPE="project-level"
print_success "Installing at project-level (current project only)"
break
;;
*)
print_error "Invalid choice. Please enter 1 or 2."
;;
esac
done
echo ""
print_info "Installation will create:"
echo " • Skill: $SKILLS_DIR/claudeforge-skill/"
echo " • Skill: $SKILLS_DIR/karpathy-guidelines/"
echo " • Command: $COMMANDS_DIR/enhance-claude-md.md"
echo " • Command: $COMMANDS_DIR/sync-claude-md.md"
echo " • Agent: $AGENTS_DIR/claude-md-guardian.md"
echo ""
# Confirm installation
read -p "$(echo -e "${BLUE}Proceed with installation? [Y/n]:${NC}")" confirm < /dev/tty
confirm=${confirm:-Y}
if [[ ! $confirm =~ ^[Yy]$ ]]; then
print_warning "Installation cancelled."
exit 0
fi
echo ""
print_info "Starting installation..."
echo ""
# Create directories if they don't exist
mkdir -p "$SKILLS_DIR" "$COMMANDS_DIR" "$AGENTS_DIR"
# Install skill
print_info "Installing ClaudeForge skill..."
if [ -d "$SKILLS_DIR/claudeforge-skill" ]; then
print_warning "Existing skill found. Creating backup..."
mv "$SKILLS_DIR/claudeforge-skill" "$SKILLS_DIR/claudeforge-skill.backup.$(date +%Y%m%d_%H%M%S)"
print_success "Backup created"
fi
cp -r skill "$SKILLS_DIR/claudeforge-skill"
print_success "Skill installed → $SKILLS_DIR/claudeforge-skill/"
# Install karpathy-guidelines as a separate top-level skill so it is
# discoverable as its own skill (and applies to every project, not only
# during /enhance-claude-md runs).
print_info "Installing karpathy-guidelines skill..."
if [ -d "$SKILLS_DIR/karpathy-guidelines" ]; then
print_warning "Existing karpathy-guidelines skill found. Creating backup..."
mv "$SKILLS_DIR/karpathy-guidelines" "$SKILLS_DIR/karpathy-guidelines.backup.$(date +%Y%m%d_%H%M%S)"
print_success "Backup created"
fi
cp -r skill/karpathy-guidelines "$SKILLS_DIR/karpathy-guidelines"
# Remove the nested duplicate so the karpathy skill exists once.
rm -rf "$SKILLS_DIR/claudeforge-skill/karpathy-guidelines"
print_success "Karpathy guidelines installed → $SKILLS_DIR/karpathy-guidelines/"
# Install slash commands. Each .md file in command/ is installed as its own
# top-level command file so it registers as /<name> rather than as a nested
# /<dir>:<name>. README.md and other non-command files are skipped.
print_info "Installing slash commands..."
# Migrate legacy bundle directory if present.
if [ -d "$COMMANDS_DIR/enhance-claude-md" ]; then
print_warning "Legacy command bundle found. Creating backup..."
mv "$COMMANDS_DIR/enhance-claude-md" "$COMMANDS_DIR/enhance-claude-md.backup.$(date +%Y%m%d_%H%M%S)"
print_success "Backup created"
fi
for cmd_file in command/*.md; do
cmd_basename=$(basename "$cmd_file")
# Skip the directory's own README.
if [ "$cmd_basename" = "README.md" ]; then
continue
fi
cmd_target="$COMMANDS_DIR/$cmd_basename"
if [ -f "$cmd_target" ]; then
print_warning "Existing $cmd_basename found. Creating backup..."
mv "$cmd_target" "$cmd_target.backup.$(date +%Y%m%d_%H%M%S)"
fi
cp "$cmd_file" "$cmd_target"
print_success "Command installed → $cmd_target"
done
# Install guardian agent
print_info "Installing claude-md-guardian agent..."
if [ -f "$AGENTS_DIR/claude-md-guardian.md" ]; then
print_warning "Existing agent found. Creating backup..."
mv "$AGENTS_DIR/claude-md-guardian.md" "$AGENTS_DIR/claude-md-guardian.md.backup.$(date +%Y%m%d_%H%M%S)"
print_success "Backup created"
fi
cp agent/claude-md-guardian.md "$AGENTS_DIR/"
print_success "Agent installed → $AGENTS_DIR/claude-md-guardian.md"
# Optional: Install quality hooks
echo ""
read -p "$(echo -e "${BLUE}Would you like to install quality hooks (pre-commit validation)? [y/N]:${NC}")" install_hooks < /dev/tty
install_hooks=${install_hooks:-N}
if [[ $install_hooks =~ ^[Yy]$ ]]; then
if [ "$SCOPE" == "project-level" ]; then
print_info "Installing quality hooks..."
if [ "$REMOTE_INSTALL" = true ]; then
HOOKS_DIR="$ORIGINAL_DIR/.claude/hooks"
else
HOOKS_DIR=".claude/hooks"
fi
mkdir -p "$HOOKS_DIR"
cp hooks/pre-commit.sh "$HOOKS_DIR/"
chmod +x "$HOOKS_DIR/pre-commit.sh"
print_success "Quality hooks installed → $HOOKS_DIR/"
else
print_warning "Quality hooks can only be installed at project-level"
print_info "Run installer with option 2 in your project directory"
fi
fi
# Validate v2.1.4 compatibility
validate_v214_compatibility() {
print_info "Validating v2.1.4 compatibility..."
local skill_file="$SKILLS_DIR/claudeforge-skill/SKILL.md"
local agent_file="$AGENTS_DIR/claude-md-guardian.md"
# Verify new syntax is present
if ! grep -q "permissions:" "$skill_file"; then
print_error "Skill missing v2.1.4 permissions syntax"
return 1
fi
if ! grep -q "permissions:" "$agent_file"; then
print_error "Agent missing v2.1.4 permissions syntax"
return 1
fi
# Check for hooks
if grep -q "hooks:" "$agent_file"; then
print_success "Guardian agent hooks configured"
else
print_warning "Guardian agent has no hooks (optional)"
fi
print_success "v2.1.4 compatibility validated"
return 0
}
echo ""
validate_v214_compatibility || {
print_error "Installation validation failed"
exit 1
}
# Installation complete
echo ""
echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ ║${NC}"
echo -e "${GREEN}║ Installation completed successfully!${NC}"
echo -e "${GREEN}║ ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
echo ""
# Next steps
print_info "Next steps:"
echo ""
echo -e " ${GREEN}1.${NC} Restart Claude Code (important!)"
echo -e " ${GREEN}2.${NC} Navigate to your project directory"
echo -e " ${GREEN}3.${NC} Run the command:"
echo ""
echo -e " ${BLUE}/enhance-claude-md${NC}"
echo ""
echo -e " ${GREEN}4.${NC} Follow the interactive prompts"
echo ""
# Additional information
print_info "Documentation:"
echo ""
echo " • Quick Start: docs/QUICK_START.md"
echo " • Installation: docs/INSTALLATION.md"
echo " • Architecture: docs/ARCHITECTURE.md"
echo " • Troubleshooting: docs/TROUBLESHOOTING.md"
echo ""
echo -e " • GitHub: ${BLUE}https://github.com/alirezarezvani/ClaudeForge${NC}"
echo ""
# Uninstall instructions
print_info "To uninstall, run:"
echo ""
if [ "$SCOPE" == "user-level" ]; then
echo " rm -rf ~/.claude/skills/claudeforge-skill"
echo " rm -rf ~/.claude/skills/karpathy-guidelines"
echo " rm -f ~/.claude/commands/enhance-claude-md.md"
echo " rm -f ~/.claude/commands/sync-claude-md.md"
echo " rm -f ~/.claude/agents/claude-md-guardian.md"
else
echo " rm -rf ./.claude/skills/claudeforge-skill"
echo " rm -rf ./.claude/skills/karpathy-guidelines"
echo " rm -f ./.claude/commands/enhance-claude-md.md"
echo " rm -f ./.claude/commands/sync-claude-md.md"
echo " rm -f ./.claude/agents/claude-md-guardian.md"
fi
echo ""
print_success "Thank you for installing ClaudeForge!"
echo ""
# Cleanup temporary directory if remote install
if [ "$REMOTE_INSTALL" = true ]; then
cd "$HOME"
rm -rf "$TEMP_DIR"
fi