-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·118 lines (103 loc) · 3.46 KB
/
install.sh
File metadata and controls
executable file
·118 lines (103 loc) · 3.46 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env bash
# trio-dev installer — creates symlinks from plugin to .claude/commands and .claude/skills
# so Claude Code / Antigravity can discover the slash commands and skills.
#
# Safety model:
# * Never overwrites a regular file or a symlink that points outside the plugin
# directory. If a conflict is found, we stop and print the conflict — the user
# must remove it manually. This protects hand-rolled commands/skills with the
# same name.
# * Existing symlinks that already point inside THIS plugin are refreshed in-place.
# * Every created link is recorded in .claude/plugins/trio-dev/install-manifest.json
# so uninstall removes exactly what was created — not a hard-coded name list.
#
# Usage: run from your project root AFTER cloning the plugin to .claude/plugins/trio-dev
# bash .claude/plugins/trio-dev/install.sh
set -euo pipefail
# Absolute path of this script's directory -> plugin root.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLUGIN_DIR="$SCRIPT_DIR"
MANIFEST="$PLUGIN_DIR/install-manifest.json"
# Install root — the project (or home) directory that contains .claude/.
# Plugin lives at <root>/.claude/plugins/trio-dev, so root is three levels up.
INSTALL_ROOT="$(cd "$PLUGIN_DIR/../../.." && pwd)"
cd "$INSTALL_ROOT"
mkdir -p .claude/commands .claude/skills
# Returns 0 if $1 is a symlink whose target resolves inside $PLUGIN_DIR.
link_points_into_plugin() {
local link="$1"
[ -L "$link" ] || return 1
local resolved
resolved="$(readlink -f "$link" 2>/dev/null || true)"
[ -n "$resolved" ] || return 1
case "$resolved" in
"$PLUGIN_DIR"*) return 0 ;;
*) return 1 ;;
esac
}
CONFLICTS=()
CREATED=()
safe_link() {
local target="$1"
local linkpath="$2"
if [ -e "$linkpath" ] || [ -L "$linkpath" ]; then
if link_points_into_plugin "$linkpath"; then
# Safe to refresh — it's our own link.
rm -f "$linkpath"
else
CONFLICTS+=("$linkpath")
return 0
fi
fi
ln -s "$target" "$linkpath"
CREATED+=("$linkpath")
echo " $linkpath"
}
echo "Linking commands..."
for f in "$PLUGIN_DIR"/commands/*.md; do
[ -e "$f" ] || continue
name=$(basename "$f")
safe_link "$f" ".claude/commands/$name"
done
echo "Linking skills..."
for d in "$PLUGIN_DIR"/skills/*/; do
[ -d "$d" ] || continue
name=$(basename "$d")
# Strip trailing slash.
src="${d%/}"
safe_link "$src" ".claude/skills/$name"
done
if [ "${#CONFLICTS[@]}" -gt 0 ]; then
echo ""
echo "WARNING: the following paths were left untouched because they are not"
echo "trio-dev symlinks (regular file, or symlink pointing outside the plugin):"
for c in "${CONFLICTS[@]}"; do
echo " $c"
done
echo ""
echo "Resolve these manually (back up and remove) then re-run install.sh."
fi
# Write manifest — a JSON array of absolute link paths we created.
{
echo "{"
echo " \"plugin\": \"trio-dev\","
echo " \"plugin_dir\": \"$PLUGIN_DIR\","
echo " \"install_root\": \"$INSTALL_ROOT\","
echo " \"created\": ["
if [ "${#CREATED[@]}" -gt 0 ]; then
for i in "${!CREATED[@]}"; do
sep=","
[ "$i" -eq $(( ${#CREATED[@]} - 1 )) ] && sep=""
echo " \"$INSTALL_ROOT/${CREATED[$i]}\"$sep"
done
fi
echo " ]"
echo "}"
} > "$MANIFEST"
echo ""
if [ "${#CREATED[@]}" -gt 0 ]; then
echo "OK — trio-dev installed (${#CREATED[@]} links). Manifest: $MANIFEST"
else
echo "OK — trio-dev installer ran, but no new links were created."
fi
echo "Restart Claude Code and try: /trio-build"