From f470f4b86571e9f61974c3cee8f54fd5beaa3273 Mon Sep 17 00:00:00 2001 From: 0xJeff Date: Fri, 8 May 2026 11:26:00 +0800 Subject: [PATCH 01/14] fix(setup): support multi-agent environments (issue #48) - Add --target for explicit install directory override - Add --scope user|project|agent for per-agent skill pools - Validate directory writability during auto-detection (skip read-only dirs) - Prompt user to select when multiple writable ~/.openclaw*/ dirs are found - Parse all flags upfront; uninstall now uses --uninstall flag (positional still works) Co-Authored-By: Claude Sonnet 4.6 --- setup.sh | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/setup.sh b/setup.sh index 755aa4a..4d4c882 100755 --- a/setup.sh +++ b/setup.sh @@ -4,12 +4,52 @@ set -euo pipefail # GoPlus AgentGuard — One-click setup # Supports: Claude Code, OpenClaw, ClawHub # Detects the platform and installs to the correct location. +# +# Usage: +# ./setup.sh Auto-detect platform +# ./setup.sh --target Install to explicit directory +# ./setup.sh --scope user Install to ~/.openclaw/skills +# ./setup.sh --scope project Install to ~/.openclaw-/skills +# ./setup.sh --scope agent Install to ~/.openclaw-/skills +# ./setup.sh --uninstall Remove installed skill SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SKILL_SRC="$SCRIPT_DIR/skills/agentguard" AGENTGUARD_DIR="$HOME/.agentguard" MIN_NODE_VERSION=18 +# ---- Parse arguments ---- +TARGET_DIR="" +SCOPE_TYPE="" +SCOPE_NAME="" +UNINSTALL=false +POSITIONAL=() + +while [[ $# -gt 0 ]]; do + case "$1" in + --target) + TARGET_DIR="${2:-}" + [ -z "$TARGET_DIR" ] && { echo " ERROR: --target requires a path argument."; exit 1; } + shift 2 + ;; + --scope) + SCOPE_TYPE="${2:-}" + case "$SCOPE_TYPE" in + user) shift 2 ;; + project|agent) + SCOPE_NAME="${3:-}" + [ -z "$SCOPE_NAME" ] && { echo " ERROR: --scope $SCOPE_TYPE requires a name argument."; exit 1; } + shift 3 + ;; + *) echo " ERROR: --scope must be one of: user, project, agent"; exit 1 ;; + esac + ;; + --uninstall|uninstall) UNINSTALL=true; shift ;; + *) POSITIONAL+=("$1"); shift ;; + esac +done +set -- "${POSITIONAL[@]+"${POSITIONAL[@]}"}" + echo "" echo " GoPlus AgentGuard — AI Agent Security Guard" echo " =============================================" @@ -38,19 +78,78 @@ fi # ---- Detect platform ---- detect_platform() { - # Check OpenClaw first (workspace skills or managed skills) - if [ -d "$HOME/.openclaw" ]; then - # Prefer workspace skills if workspace exists - if [ -d "$HOME/.openclaw/workspace" ]; then - SKILLS_DIR="$HOME/.openclaw/workspace/skills/agentguard" + # --target overrides all detection + if [ -n "$TARGET_DIR" ]; then + SKILLS_DIR="$TARGET_DIR" + PLATFORM="custom" + return + fi + + # --scope selects a specific agent/project directory + if [ -n "$SCOPE_TYPE" ]; then + case "$SCOPE_TYPE" in + user) + SKILLS_DIR="$HOME/.openclaw/skills/agentguard" + PLATFORM="openclaw-user" + ;; + project) + SKILLS_DIR="$HOME/.openclaw-${SCOPE_NAME}/skills/agentguard" + PLATFORM="openclaw-project:$SCOPE_NAME" + ;; + agent) + SKILLS_DIR="$HOME/.openclaw-${SCOPE_NAME}/skills/agentguard" + PLATFORM="openclaw-agent:$SCOPE_NAME" + ;; + esac + return + fi + + # Auto-detect: collect all writable ~/.openclaw* directories + local candidates=() + for dir in "$HOME"/.openclaw*/; do + [ -d "$dir" ] || continue + [ -w "$dir" ] || continue + candidates+=("$dir") + done + + if [ "${#candidates[@]}" -eq 1 ]; then + local oc_dir="${candidates[0]%/}" + if [ -d "$oc_dir/workspace" ] && [ -w "$oc_dir/workspace" ]; then + SKILLS_DIR="$oc_dir/workspace/skills/agentguard" PLATFORM="openclaw-workspace" else - SKILLS_DIR="$HOME/.openclaw/skills/agentguard" + SKILLS_DIR="$oc_dir/skills/agentguard" PLATFORM="openclaw-managed" fi return fi + if [ "${#candidates[@]}" -gt 1 ]; then + echo " Multiple writable OpenClaw directories found:" + local i=1 + for dir in "${candidates[@]}"; do + echo " [$i] ${dir%/}" + i=$((i + 1)) + done + echo "" + printf " Select target [1-%d]: " "${#candidates[@]}" + read -r choice + if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#candidates[@]}" ]; then + local selected="${candidates[$((choice - 1))]%/}" + if [ -d "$selected/workspace" ] && [ -w "$selected/workspace" ]; then + SKILLS_DIR="$selected/workspace/skills/agentguard" + PLATFORM="openclaw-workspace" + else + SKILLS_DIR="$selected/skills/agentguard" + PLATFORM="openclaw-managed" + fi + return + else + echo " ERROR: Invalid selection. Use --target or --scope agent to specify explicitly." + exit 1 + fi + fi + # Check Claude Code if [ -d "$HOME/.claude" ]; then SKILLS_DIR="$HOME/.claude/skills/agentguard" @@ -69,7 +168,7 @@ echo " Install target: $SKILLS_DIR" echo "" # ---- Uninstall mode ---- -if [ "${1:-}" = "--uninstall" ] || [ "${1:-}" = "uninstall" ]; then +if [ "$UNINSTALL" = true ]; then echo " Uninstalling GoPlus AgentGuard..." rm -rf "$SKILLS_DIR" 2>/dev/null && echo " Removed skill from $SKILLS_DIR" || true # Also clean up other possible locations From ca3c120251c606038310ddaa07231e49e10caa23 Mon Sep 17 00:00:00 2001 From: 0xJeff Date: Fri, 8 May 2026 11:41:05 +0800 Subject: [PATCH 02/14] fix(setup): run npm install in correct directory (issue #49) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script was cd-ing into skills/agentguard/scripts/ before running npm install, but package.json lives in skills/agentguard/. npm silently walked up and found the parent package.json, installing node_modules there instead of in scripts/ — causing runtime failures when scripts tried to resolve their dependencies. Fixes: - Step 2: cd into $SKILL_SRC (skills/agentguard/) where package.json lives - Step 4: copy package.json from $SKILL_SRC into $SKILLS_DIR/scripts/ before running npm install there, so node_modules land next to the scripts - Remove stale copy of package.json/package-lock.json from scripts/ loop (those files don't exist in scripts/ and the copy was a no-op) Co-Authored-By: Claude Sonnet 4.6 --- setup.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/setup.sh b/setup.sh index 755aa4a..70dd531 100755 --- a/setup.sh +++ b/setup.sh @@ -97,8 +97,8 @@ fi # ---- Step 2: Install CLI dependencies ---- echo "[2/5] Installing CLI dependencies..." -if [ -d "$SKILL_SRC/scripts" ]; then - cd "$SKILL_SRC/scripts" +if [ -f "$SKILL_SRC/package.json" ]; then + cd "$SKILL_SRC" npm install 2>/dev/null echo " OK: CLI dependencies installed" fi @@ -116,7 +116,7 @@ echo "[4/5] Installing scripts and dependencies..." mkdir -p "$SKILLS_DIR/scripts" # Copy script files -for f in checkup-report.js guard-hook.js auto-scan.js trust-cli.ts action-cli.ts package.json package-lock.json; do +for f in checkup-report.js guard-hook.js auto-scan.js trust-cli.ts action-cli.ts; do [ -f "$SKILL_SRC/scripts/$f" ] && cp "$SKILL_SRC/scripts/$f" "$SKILLS_DIR/scripts/" 2>/dev/null || true done @@ -126,6 +126,10 @@ if [ -d "$SKILL_SRC/scripts/data" ]; then cp -r "$SKILL_SRC/scripts/data/"* "$SKILLS_DIR/scripts/data/" 2>/dev/null || true fi +# Copy package.json and node_modules from skills/agentguard/ (where npm install was run) +cp "$SKILL_SRC/package.json" "$SKILLS_DIR/scripts/package.json" 2>/dev/null || true +[ -f "$SKILL_SRC/package-lock.json" ] && cp "$SKILL_SRC/package-lock.json" "$SKILLS_DIR/scripts/package-lock.json" 2>/dev/null || true + # Install node_modules in the target (avoids symlink issues in containers) cd "$SKILLS_DIR/scripts" if [ -f "package.json" ]; then From 4c8eaa5cb93e851a9405700d0c4ac6dfadd1f200 Mon Sep 17 00:00:00 2001 From: 0xJeff Date: Fri, 8 May 2026 11:48:54 +0800 Subject: [PATCH 03/14] fix(setup): run npm install in correct directory (issue #49) package.json lives in skills/agentguard/, not scripts/. The old code cd'd into scripts/ before running npm install, so npm silently walked up to the parent and installed node_modules there instead of where scripts expect them. Fix: copy package.json to $SKILLS_DIR (the skill root) and run a single npm install there. Scripts are always invoked as: cd $SKILLS_DIR && node scripts/