diff --git a/scripts/install.sh b/scripts/install.sh index c20ae26e..a127e265 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -24,6 +24,7 @@ # # Flags: # --tool Install only the specified tool +# --link Use symbolic links instead of copying (for development) # --interactive Show interactive selector (default when run in a terminal) # --no-interactive Skip interactive selector, install all detected tools # --help Show this help @@ -54,6 +55,16 @@ err() { printf "${C_RED}[ERR]${C_RESET} %s\n" "$*" >&2; } header() { printf "\n${C_BOLD}%s${C_RESET}\n" "$*"; } dim() { printf "${C_DIM}%s${C_RESET}\n" "$*"; } +install_file() { + local src="$1" + local dest="$2" + if [[ "$USE_LINK" == "true" ]]; then + ln -sf "$src" "$dest" + else + cp "$src" "$dest" + fi +} + # --------------------------------------------------------------------------- # Box drawing -- pure ASCII, fixed 52-char wide # box_top / box_mid / box_bot -- structural lines @@ -86,6 +97,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" INTEGRATIONS="$REPO_ROOT/integrations" ALL_TOOLS=(claude-code copilot antigravity gemini-cli opencode openclaw cursor aider windsurf qwen) +USE_LINK=false # --------------------------------------------------------------------------- # Usage @@ -280,7 +292,7 @@ install_claude_code() { while IFS= read -r -d '' f; do first_line="$(head -1 "$f")" [[ "$first_line" == "---" ]] || continue - cp "$f" "$dest/" + install_file "$f" "$dest/" (( count++ )) || true done < <(find "$REPO_ROOT/$dir" -name "*.md" -type f -print0) done @@ -298,7 +310,7 @@ install_copilot() { while IFS= read -r -d '' f; do first_line="$(head -1 "$f")" [[ "$first_line" == "---" ]] || continue - cp "$f" "$dest/" + install_file "$f" "$dest/" (( count++ )) || true done < <(find "$REPO_ROOT/$dir" -name "*.md" -type f -print0) done @@ -315,7 +327,7 @@ install_antigravity() { while IFS= read -r -d '' d; do local name; name="$(basename "$d")" mkdir -p "$dest/$name" - cp "$d/SKILL.md" "$dest/$name/SKILL.md" + install_file "$d/SKILL.md" "$dest/$name/SKILL.md" (( count++ )) || true done < <(find "$src" -mindepth 1 -maxdepth 1 -type d -print0) ok "Antigravity: $count skills -> $dest" @@ -331,12 +343,12 @@ install_gemini_cli() { [[ -f "$manifest" ]] || { err "integrations/gemini-cli/gemini-extension.json missing. Run ./scripts/convert.sh --tool gemini-cli first."; return 1; } [[ -d "$skills_dir" ]] || { err "integrations/gemini-cli/skills missing. Run ./scripts/convert.sh --tool gemini-cli first."; return 1; } mkdir -p "$dest/skills" - cp "$manifest" "$dest/gemini-extension.json" + install_file "$manifest" "$dest/gemini-extension.json" local d while IFS= read -r -d '' d; do local name; name="$(basename "$d")" mkdir -p "$dest/skills/$name" - cp "$d/SKILL.md" "$dest/skills/$name/SKILL.md" + install_file "$d/SKILL.md" "$dest/skills/$name/SKILL.md" (( count++ )) || true done < <(find "$skills_dir" -mindepth 1 -maxdepth 1 -type d -print0) ok "Gemini CLI: $count skills -> $dest" @@ -350,7 +362,7 @@ install_opencode() { mkdir -p "$dest" local f while IFS= read -r -d '' f; do - cp "$f" "$dest/"; (( count++ )) || true + install_file "$f" "$dest/"; (( count++ )) || true done < <(find "$src" -maxdepth 1 -name "*.md" -print0) ok "OpenCode: $count agents -> $dest" warn "OpenCode: project-scoped. Run from your project root to install there." @@ -366,9 +378,9 @@ install_openclaw() { while IFS= read -r -d '' d; do local name; name="$(basename "$d")" mkdir -p "$dest/$name" - cp "$d/SOUL.md" "$dest/$name/SOUL.md" - cp "$d/AGENTS.md" "$dest/$name/AGENTS.md" - cp "$d/IDENTITY.md" "$dest/$name/IDENTITY.md" + install_file "$d/SOUL.md" "$dest/$name/SOUL.md" + install_file "$d/AGENTS.md" "$dest/$name/AGENTS.md" + install_file "$d/IDENTITY.md" "$dest/$name/IDENTITY.md" # Register with OpenClaw so agents are usable by agentId immediately if command -v openclaw >/dev/null 2>&1; then openclaw agents add "$name" --workspace "$dest/$name" --non-interactive || true @@ -389,7 +401,7 @@ install_cursor() { mkdir -p "$dest" local f while IFS= read -r -d '' f; do - cp "$f" "$dest/"; (( count++ )) || true + install_file "$f" "$dest/"; (( count++ )) || true done < <(find "$src" -maxdepth 1 -name "*.mdc" -print0) ok "Cursor: $count rules -> $dest" warn "Cursor: project-scoped. Run from your project root to install there." @@ -403,7 +415,7 @@ install_aider() { warn "Aider: CONVENTIONS.md already exists at $dest (remove to reinstall)." return 0 fi - cp "$src" "$dest" + install_file "$src" "$dest" ok "Aider: installed -> $dest" warn "Aider: project-scoped. Run from your project root to install there." } @@ -416,7 +428,7 @@ install_windsurf() { warn "Windsurf: .windsurfrules already exists at $dest (remove to reinstall)." return 0 fi - cp "$src" "$dest" + install_file "$src" "$dest" ok "Windsurf: installed -> $dest" warn "Windsurf: project-scoped. Run from your project root to install there." } @@ -432,7 +444,7 @@ install_qwen() { local f while IFS= read -r -d '' f; do - cp "$f" "$dest/" + install_file "$f" "$dest/" (( count++ )) || true done < <(find "$src" -maxdepth 1 -name "*.md" -print0) @@ -462,10 +474,12 @@ install_tool() { main() { local tool="all" local interactive_mode="auto" + use_link=false while [[ $# -gt 0 ]]; do case "$1" in --tool) tool="${2:?'--tool requires a value'}"; shift 2; interactive_mode="no" ;; + --link) use_link=true; USE_LINK=true; shift ;; --interactive) interactive_mode="yes"; shift ;; --no-interactive) interactive_mode="no"; shift ;; --help|-h) usage ;; @@ -528,6 +542,9 @@ main() { header "The Agency -- Installing agents" printf " Repo: %s\n" "$REPO_ROOT" printf " Installing: %s\n" "${SELECTED_TOOLS[*]}" + if [[ "$USE_LINK" == "true" ]]; then + printf " Mode: ${C_CYAN}symbolic links${C_RESET} (use --link flag)\n" + fi printf "\n" local installed=0 t