mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-01 14:43:28 +08:00
* feat(install): add CodeBuddy(Tencent) adaptation with installation scripts * fix: add codebuddy to SUPPORTED_INSTALL_TARGETS * fix(codebuddy): resolve installer path issues, unused vars, and uninstall safety
232 lines
6.8 KiB
Bash
Executable File
232 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# ECC CodeBuddy Installer
|
|
# Installs Everything Claude Code workflows into a CodeBuddy project.
|
|
#
|
|
# Usage:
|
|
# ./install.sh # Install to current directory
|
|
# ./install.sh ~ # Install globally to ~/.codebuddy/
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
# When globs match nothing, expand to empty list instead of the literal pattern
|
|
shopt -s nullglob
|
|
|
|
# Resolve the directory where this script lives
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
# Locate the ECC repo root by walking up from SCRIPT_DIR to find the marker
|
|
# file (VERSION). This keeps the script working even when it has been copied
|
|
# into a target project's .codebuddy/ directory.
|
|
find_repo_root() {
|
|
local dir="$(dirname "$SCRIPT_DIR")"
|
|
# First try the parent of SCRIPT_DIR (original layout: .codebuddy/ lives in repo root)
|
|
if [ -f "$dir/VERSION" ] && [ -d "$dir/commands" ] && [ -d "$dir/agents" ]; then
|
|
echo "$dir"
|
|
return 0
|
|
fi
|
|
echo ""
|
|
return 1
|
|
}
|
|
|
|
REPO_ROOT="$(find_repo_root)"
|
|
if [ -z "$REPO_ROOT" ]; then
|
|
echo "Error: Cannot locate the ECC repository root."
|
|
echo "This script must be run from within the ECC repository's .codebuddy/ directory."
|
|
exit 1
|
|
fi
|
|
|
|
# CodeBuddy directory name
|
|
CODEBUDDY_DIR=".codebuddy"
|
|
|
|
ensure_manifest_entry() {
|
|
local manifest="$1"
|
|
local entry="$2"
|
|
|
|
touch "$manifest"
|
|
if ! grep -Fqx "$entry" "$manifest"; then
|
|
echo "$entry" >> "$manifest"
|
|
fi
|
|
}
|
|
|
|
manifest_has_entry() {
|
|
local manifest="$1"
|
|
local entry="$2"
|
|
|
|
[ -f "$manifest" ] && grep -Fqx "$entry" "$manifest"
|
|
}
|
|
|
|
copy_managed_file() {
|
|
local source_path="$1"
|
|
local target_path="$2"
|
|
local manifest="$3"
|
|
local manifest_entry="$4"
|
|
local make_executable="${5:-0}"
|
|
|
|
local already_managed=0
|
|
if manifest_has_entry "$manifest" "$manifest_entry"; then
|
|
already_managed=1
|
|
fi
|
|
|
|
if [ -f "$target_path" ]; then
|
|
if [ "$already_managed" -eq 1 ]; then
|
|
ensure_manifest_entry "$manifest" "$manifest_entry"
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
cp "$source_path" "$target_path"
|
|
if [ "$make_executable" -eq 1 ]; then
|
|
chmod +x "$target_path"
|
|
fi
|
|
ensure_manifest_entry "$manifest" "$manifest_entry"
|
|
return 0
|
|
}
|
|
|
|
# Install function
|
|
do_install() {
|
|
local target_dir="$PWD"
|
|
|
|
# Check if ~ was specified (or expanded to $HOME)
|
|
if [ "$#" -ge 1 ]; then
|
|
if [ "$1" = "~" ] || [ "$1" = "$HOME" ]; then
|
|
target_dir="$HOME"
|
|
fi
|
|
fi
|
|
|
|
# Check if we're already inside a .codebuddy directory
|
|
local current_dir_name="$(basename "$target_dir")"
|
|
local codebuddy_full_path
|
|
|
|
if [ "$current_dir_name" = ".codebuddy" ]; then
|
|
# Already inside the codebuddy directory, use it directly
|
|
codebuddy_full_path="$target_dir"
|
|
else
|
|
# Normal case: append CODEBUDDY_DIR to target_dir
|
|
codebuddy_full_path="$target_dir/$CODEBUDDY_DIR"
|
|
fi
|
|
|
|
echo "ECC CodeBuddy Installer"
|
|
echo "======================="
|
|
echo ""
|
|
echo "Source: $REPO_ROOT"
|
|
echo "Target: $codebuddy_full_path/"
|
|
echo ""
|
|
|
|
# Subdirectories to create
|
|
SUBDIRS="commands agents skills rules"
|
|
|
|
# Create all required codebuddy subdirectories
|
|
for dir in $SUBDIRS; do
|
|
mkdir -p "$codebuddy_full_path/$dir"
|
|
done
|
|
|
|
# Manifest file to track installed files
|
|
MANIFEST="$codebuddy_full_path/.ecc-manifest"
|
|
touch "$MANIFEST"
|
|
|
|
# Counters for summary
|
|
commands=0
|
|
agents=0
|
|
skills=0
|
|
rules=0
|
|
|
|
# Copy commands from repo root
|
|
if [ -d "$REPO_ROOT/commands" ]; then
|
|
for f in "$REPO_ROOT/commands"/*.md; do
|
|
[ -f "$f" ] || continue
|
|
local_name=$(basename "$f")
|
|
target_path="$codebuddy_full_path/commands/$local_name"
|
|
if copy_managed_file "$f" "$target_path" "$MANIFEST" "commands/$local_name"; then
|
|
commands=$((commands + 1))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Copy agents from repo root
|
|
if [ -d "$REPO_ROOT/agents" ]; then
|
|
for f in "$REPO_ROOT/agents"/*.md; do
|
|
[ -f "$f" ] || continue
|
|
local_name=$(basename "$f")
|
|
target_path="$codebuddy_full_path/agents/$local_name"
|
|
if copy_managed_file "$f" "$target_path" "$MANIFEST" "agents/$local_name"; then
|
|
agents=$((agents + 1))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Copy skills from repo root (if available)
|
|
if [ -d "$REPO_ROOT/skills" ]; then
|
|
for d in "$REPO_ROOT/skills"/*/; do
|
|
[ -d "$d" ] || continue
|
|
skill_name="$(basename "$d")"
|
|
target_skill_dir="$codebuddy_full_path/skills/$skill_name"
|
|
skill_copied=0
|
|
|
|
while IFS= read -r source_file; do
|
|
relative_path="${source_file#$d}"
|
|
target_path="$target_skill_dir/$relative_path"
|
|
|
|
mkdir -p "$(dirname "$target_path")"
|
|
if copy_managed_file "$source_file" "$target_path" "$MANIFEST" "skills/$skill_name/$relative_path"; then
|
|
skill_copied=1
|
|
fi
|
|
done < <(find "$d" -type f | sort)
|
|
|
|
if [ "$skill_copied" -eq 1 ]; then
|
|
skills=$((skills + 1))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Copy rules from repo root
|
|
if [ -d "$REPO_ROOT/rules" ]; then
|
|
while IFS= read -r rule_file; do
|
|
relative_path="${rule_file#$REPO_ROOT/rules/}"
|
|
target_path="$codebuddy_full_path/rules/$relative_path"
|
|
|
|
mkdir -p "$(dirname "$target_path")"
|
|
if copy_managed_file "$rule_file" "$target_path" "$MANIFEST" "rules/$relative_path"; then
|
|
rules=$((rules + 1))
|
|
fi
|
|
done < <(find "$REPO_ROOT/rules" -type f | sort)
|
|
fi
|
|
|
|
# Copy README files (skip install/uninstall scripts to avoid broken
|
|
# path references when the copied script runs from the target directory)
|
|
for readme_file in "$SCRIPT_DIR/README.md" "$SCRIPT_DIR/README.zh-CN.md"; do
|
|
if [ -f "$readme_file" ]; then
|
|
local_name=$(basename "$readme_file")
|
|
target_path="$codebuddy_full_path/$local_name"
|
|
copy_managed_file "$readme_file" "$target_path" "$MANIFEST" "$local_name" || true
|
|
fi
|
|
done
|
|
|
|
# Add manifest file itself to manifest
|
|
ensure_manifest_entry "$MANIFEST" ".ecc-manifest"
|
|
|
|
# Installation summary
|
|
echo "Installation complete!"
|
|
echo ""
|
|
echo "Components installed:"
|
|
echo " Commands: $commands"
|
|
echo " Agents: $agents"
|
|
echo " Skills: $skills"
|
|
echo " Rules: $rules"
|
|
echo ""
|
|
echo "Directory: $(basename "$codebuddy_full_path")"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Open your project in CodeBuddy"
|
|
echo " 2. Type / to see available commands"
|
|
echo " 3. Enjoy the ECC workflows!"
|
|
echo ""
|
|
echo "To uninstall later:"
|
|
echo " cd $codebuddy_full_path"
|
|
echo " ./uninstall.sh"
|
|
}
|
|
|
|
# Main logic
|
|
do_install "$@"
|