-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremote-install.sh
More file actions
executable file
·248 lines (208 loc) · 11.1 KB
/
remote-install.sh
File metadata and controls
executable file
·248 lines (208 loc) · 11.1 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/usr/bin/env bash
# remote-install.sh — Bootstrap a project to use claude-code-kit WITHOUT cloning the repo.
#
# Usage (macOS / Linux / WSL / Git Bash):
# curl -fsSL https://raw.githubusercontent.com/vivek43nit/claude-code-kit/main/remote-install.sh | bash -s -- /path/to/project
# curl -fsSL https://raw.githubusercontent.com/vivek43nit/claude-code-kit/main/remote-install.sh | bash -s -- .
#
# wget -qO- https://raw.githubusercontent.com/vivek43nit/claude-code-kit/main/remote-install.sh | bash -s -- /path/to/project
#
# What it does (identical to install.sh, but sources files from GitHub):
# 1. Downloads .claude/hooks/ scripts and .claude/prompts/
# 2. Downloads guidelines/ markdown files
# 3. Merges .claude/settings.json hooks (creates if absent; merges with jq if present)
# 4. Merges CLAUDE.md guideline imports (creates if absent; appends if present)
# 5. Seeds guidelines/active.md and updates .gitignore
# 6. Runs language detection immediately (populates guidelines/active.md)
# 7. Prints CI template instructions
#
# Safe on existing projects — never overwrites or deletes user files.
set -euo pipefail
# ── Config ────────────────────────────────────────────────────────────────────
REPO="vivek43nit/claude-code-kit"
BRANCH="main"
BASE_URL="https://raw.githubusercontent.com/${REPO}/${BRANCH}"
TARGET="${1:-.}"
TARGET="$(mkdir -p "$TARGET" && cd "$TARGET" && pwd)"
# ── Detect download tool ──────────────────────────────────────────────────────
if command -v curl &>/dev/null; then
download() { curl -fsSL "$1" -o "$2"; }
elif command -v wget &>/dev/null; then
download() { wget -qO "$2" "$1"; }
else
echo "Error: neither curl nor wget found. Install one and retry." >&2
exit 1
fi
echo "Installing claude-code-kit into: $TARGET"
echo ""
# ── Helper ────────────────────────────────────────────────────────────────────
fetch_file() {
local remote_path="$1" # e.g. ".claude/hooks/detect-languages.sh"
local local_path="$TARGET/$remote_path"
mkdir -p "$(dirname "$local_path")"
if [ -f "$local_path" ]; then
echo " [SKIP] $remote_path already exists (not overwriting)"
else
download "${BASE_URL}/${remote_path}" "$local_path"
echo " [OK] Downloaded $remote_path"
fi
}
# ── 1. Hooks ──────────────────────────────────────────────────────────────────
fetch_file ".claude/hooks/detect-languages.sh"
chmod +x "$TARGET/.claude/hooks/detect-languages.sh"
fetch_file ".claude/hooks/security-scan.sh"
chmod +x "$TARGET/.claude/hooks/security-scan.sh"
# ── 1b. Prompts ───────────────────────────────────────────────────────────────
local_prompt="$TARGET/.claude/prompts/audit.md"
mkdir -p "$TARGET/.claude/prompts"
if [ -f "$local_prompt" ]; then
echo " [SKIP] .claude/prompts/audit.md already exists (not overwriting)"
elif download "${BASE_URL}/.claude/prompts/audit.md" "$local_prompt" 2>/dev/null; then
echo " [OK] Downloaded .claude/prompts/audit.md"
else
rm -f "$local_prompt"
echo " [WARN] Could not download .claude/prompts/audit.md — skipping (install the kit manually to get it)"
fi
# ── 2. Guidelines ─────────────────────────────────────────────────────────────
GUIDELINE_FILES=(
"guidelines/base.md"
"guidelines/observability.md"
"guidelines/testing.md"
"guidelines/branching.md"
"guidelines/dependencies.md"
"guidelines/adr.md"
"guidelines/api-design.md"
"guidelines/database.md"
"guidelines/feature-flags.md"
"guidelines/incidents.md"
"guidelines/accessibility.md"
"guidelines/python.md"
"guidelines/typescript.md"
"guidelines/javascript.md"
"guidelines/go.md"
"guidelines/java.md"
"guidelines/kotlin.md"
"guidelines/rust.md"
)
SKIPPED_GUIDELINES=()
for f in "${GUIDELINE_FILES[@]}"; do
[ -f "$TARGET/$f" ] && SKIPPED_GUIDELINES+=("$f")
fetch_file "$f"
done
# Seed active.md (generated at runtime — never downloaded)
ACTIVE="$TARGET/guidelines/active.md"
if [ ! -f "$ACTIVE" ]; then
printf "# Active Language Guidelines\n<!-- Auto-generated — run a Claude Code session to populate -->\n" > "$ACTIVE"
echo " [OK] Created guidelines/active.md (empty — populated on first session)"
fi
# ── 3. settings.json ──────────────────────────────────────────────────────────
SETTINGS_DST="$TARGET/.claude/settings.json"
if [ ! -f "$SETTINGS_DST" ]; then
fetch_file ".claude/settings.json"
elif command -v jq &>/dev/null; then
if jq -e '[.hooks.SessionStart[]?.hooks[]?] | map(select(.command == "bash .claude/hooks/detect-languages.sh")) | length > 0' "$SETTINGS_DST" &>/dev/null; then
echo " [SKIP] .claude/settings.json already contains claude-code-kit hooks"
else
tmp="$(mktemp)"
jq '
.hooks.SessionStart = ((.hooks.SessionStart // []) + [{"hooks": [{"type": "command", "command": "bash .claude/hooks/detect-languages.sh"}]}]) |
.hooks.PreToolUse = ((.hooks.PreToolUse // []) + [{"matcher": "Write|Edit", "hooks": [{"type": "command", "command": "bash .claude/hooks/security-scan.sh"}]}])
' "$SETTINGS_DST" > "$tmp"
if [ -s "$tmp" ]; then
mv "$tmp" "$SETTINGS_DST"
echo " [OK] Merged claude-code-kit hooks into existing .claude/settings.json"
else
rm -f "$tmp"
echo " [WARN] jq merge produced empty output — .claude/settings.json unchanged"
echo " Add hooks manually from: ${BASE_URL}/.claude/settings.json"
fi
fi
else
echo " [WARN] .claude/settings.json already exists and jq is not installed."
echo " Install jq (brew install jq / apt install jq) and re-run to auto-merge, or add manually:"
echo ' "SessionStart": [{"hooks": [{"type": "command", "command": "bash .claude/hooks/detect-languages.sh"}]}]'
echo ' "PreToolUse" (matcher Write|Edit): [{"hooks": [{"type": "command", "command": "bash .claude/hooks/security-scan.sh"}]}]'
fi
# ── 4. CLAUDE.md ──────────────────────────────────────────────────────────────
CLAUDE_MD_DST="$TARGET/CLAUDE.md"
if [ ! -f "$CLAUDE_MD_DST" ]; then
fetch_file "CLAUDE.md"
elif grep -q "@guidelines/active.md" "$CLAUDE_MD_DST"; then
echo " [SKIP] CLAUDE.md already references @guidelines/active.md"
else
cat >> "$CLAUDE_MD_DST" <<'KITEOF'
---
<!-- Added by claude-code-kit — https://github.com/vivek43nit/claude-code-kit -->
## Active Language Guidelines
@guidelines/active.md
## Universal Guidelines
@guidelines/base.md
KITEOF
echo " [OK] Merged claude-code-kit guideline imports into existing CLAUDE.md"
fi
# ── 5. .gitignore ─────────────────────────────────────────────────────────────
GITIGNORE="$TARGET/.gitignore"
if [ -f "$GITIGNORE" ]; then
if ! grep -q "guidelines/active.md" "$GITIGNORE"; then
printf "\n# Auto-generated by claude-code-kit\nguidelines/active.md\n" >> "$GITIGNORE"
echo " [OK] Added guidelines/active.md to .gitignore"
else
echo " [SKIP] guidelines/active.md already in .gitignore"
fi
else
echo "guidelines/active.md" > "$GITIGNORE"
echo " [OK] Created .gitignore with guidelines/active.md"
fi
# ── 6. Language detection ─────────────────────────────────────────────────────
echo ""
echo "Running language detection..."
if (cd "$TARGET" && bash .claude/hooks/detect-languages.sh 2>/dev/null); then
echo " [OK] guidelines/active.md populated"
else
echo " [WARN] Language detection failed — will run automatically on first Claude Code session"
fi
# ── 7. CI instructions ────────────────────────────────────────────────────────
CI_BASE="https://raw.githubusercontent.com/${REPO}/${BRANCH}/ci"
echo ""
echo "────────────────────────────────────────────────────────"
echo "CI Templates (optional — run to add quality gates):"
echo ""
echo " GitHub Actions:"
echo " mkdir -p $TARGET/.github/workflows"
echo " curl -fsSL ${CI_BASE}/github/quality-gates.yml \\"
echo " -o $TARGET/.github/workflows/quality-gates.yml"
echo ""
echo " GitLab CI:"
echo " curl -fsSL ${CI_BASE}/gitlab/quality-gates.yml \\"
echo " -o $TARGET/.gitlab-ci.yml"
echo ""
echo "────────────────────────────────────────────────────────"
echo ""
echo "Done! Next steps:"
echo " 1. Copy the CI template above (optional)"
echo " 2. Open Claude Code in $TARGET"
echo " 3. Run /reload-plugins"
echo " 4. Start a session — languages will auto-detect and populate guidelines/active.md"
if [ ${#SKIPPED_GUIDELINES[@]} -gt 0 ]; then
echo ""
echo "────────────────────────────────────────────────────────"
echo "⚠ ${#SKIPPED_GUIDELINES[@]} guideline file(s) already existed and were not overwritten:"
for f in "${SKIPPED_GUIDELINES[@]}"; do
echo " · $f"
done
echo ""
echo " These may be outdated if this project used an older version of claude-code-kit."
echo " To review and update them, open Claude Code in $TARGET and run:"
echo ""
FILE_LIST=""
for f in "${SKIPPED_GUIDELINES[@]}"; do
FILE_LIST="${FILE_LIST:+$FILE_LIST }$f"
done
echo " claude \"Fetch the latest versions of: $FILE_LIST"
echo " from https://raw.githubusercontent.com/vivek43nit/claude-code-kit/main/"
echo " and compare each to my local copy. Update any that are outdated."
echo " Do not modify files that are not in that list.\""
echo ""
echo " Claude fetches directly from GitHub — no local clone needed."
echo "────────────────────────────────────────────────────────"
fi