-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
79 lines (69 loc) · 2.83 KB
/
Copy pathinstall.sh
File metadata and controls
79 lines (69 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env bash
# Install codebase-visualize for Claude Code or Codex at user or project scope.
set -euo pipefail
TOOL=""
SCOPE=""
FORCE=false
HOME_ROOT="${HOME:-}"
PROJECT_ROOT="$(pwd)"
while [ "$#" -gt 0 ]; do
case "$1" in
--tool) TOOL="${2:-}"; shift 2 ;;
--scope) SCOPE="${2:-}"; shift 2 ;;
--home) HOME_ROOT="${2:-}"; shift 2 ;;
--project-root) PROJECT_ROOT="${2:-}"; shift 2 ;;
--force) FORCE=true; shift ;;
*) echo "Error: unsupported argument: $1" >&2; exit 1 ;;
esac
done
case "$TOOL" in claude) TOOL_DIR=".claude" ;; codex) TOOL_DIR=".agents" ;; *)
echo "Error: --tool must be claude or codex" >&2; exit 1 ;;
esac
case "$SCOPE" in user) BASE_DIR="$HOME_ROOT" ;; project) BASE_DIR="$PROJECT_ROOT" ;; *)
echo "Error: --scope must be user or project" >&2; exit 1 ;;
esac
[ -n "$BASE_DIR" ] || { echo "Error: install base directory is empty" >&2; exit 1; }
command -v node >/dev/null 2>&1 || { echo "Error: Node.js 18+ is required but node was not found on PATH." >&2; exit 1; }
NODE_MAJOR="$(node -p "process.versions.node.split('.')[0]")"
[ "$NODE_MAJOR" -ge 18 ] || { echo "Error: Node.js 18+ is required; found major version $NODE_MAJOR." >&2; exit 1; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SOURCE_DIR="$(cd "$SCRIPT_DIR/../skills/codebase-visualize" && pwd)"
DEST_DIR="$BASE_DIR/$TOOL_DIR/skills/codebase-visualize"
DEST_PARENT="$(dirname "$DEST_DIR")"
STAGING_DIR="$DEST_DIR.install-$$"
BACKUP_DIR="$DEST_DIR.backup-$$"
REQUIRED=("SKILL.md" "assets/renderer.css" "lib/commands.mjs" "scripts/visualize.mjs")
for path in "${REQUIRED[@]}"; do
[ -f "$SOURCE_DIR/$path" ] || { echo "Error: canonical skill package is missing required file: $path" >&2; exit 1; }
done
if [ -e "$DEST_DIR" ] && [ "$FORCE" = false ]; then
echo "Error: destination already exists: $DEST_DIR" >&2
echo "Re-run with --force for a clean exact-sync replacement." >&2
exit 1
fi
echo "Source : $SOURCE_DIR"
echo "Dest : $DEST_DIR"
echo "Mode : $TOOL / $SCOPE"
mkdir -p "$DEST_PARENT"
rm -rf "$STAGING_DIR" "$BACKUP_DIR"
cleanup() {
rm -rf "$STAGING_DIR"
if [ -e "$BACKUP_DIR" ] && [ ! -e "$DEST_DIR" ]; then mv "$BACKUP_DIR" "$DEST_DIR"; fi
}
trap cleanup EXIT
cp -R "$SOURCE_DIR" "$STAGING_DIR"
for path in "${REQUIRED[@]}"; do
[ -f "$STAGING_DIR/$path" ] || { echo "Error: staged installation is missing required file: $path" >&2; exit 1; }
done
if [ -e "$DEST_DIR" ]; then mv "$DEST_DIR" "$BACKUP_DIR"; fi
mv "$STAGING_DIR" "$DEST_DIR"
rm -rf "$BACKUP_DIR"
trap - EXIT
echo ""
echo "Installation complete. No repository was visualized."
echo "Installed: $DEST_DIR"
echo 'Invoke explicitly, then run: node "<skill-dir>/scripts/visualize.mjs" --target "<repo>"'
if [ "$SCOPE" = project ]; then
echo ""
echo "Optional .gitignore pattern: $TOOL_DIR/skills/codebase-visualize/"
fi