-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·144 lines (122 loc) · 4.73 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·144 lines (122 loc) · 4.73 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
#!/usr/bin/env bash
#
# Claude Code configuration installer.
# Links this repo's CLAUDE.md, commands/, agents/, skills/, and codex.json into
# ~/.claude/ so Claude Code picks them up. Idempotent and safe to re-run.
#
# Usage:
# ./install.sh # Install symlinks
# ./install.sh --check # Check status without changes
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CHECK_ONLY=false
[[ "${1:-}" == "--check" ]] && CHECK_ONLY=true
print_info() { echo "[INFO] $1"; }
print_warn() { echo "[WARN] $1"; }
print_ok() { echo "[OK] $1"; }
# Create symlink idempotently
# Args: $1=target (source file in repo), $2=link path (destination)
ensure_symlink() {
local target="$1"
local link="$2"
local link_name
link_name="$(basename "$link")"
if [[ ! -e "$target" ]]; then
print_warn "$link_name: target does not exist: $target"
return 1
fi
if [[ -L "$link" ]]; then
local current
current="$(readlink "$link")"
local resolved_target
local resolved_link
resolved_target="$(python3 -c "import os; print(os.path.realpath('${target}'))" 2>/dev/null || true)"
resolved_link="$(python3 -c "import os; print(os.path.realpath('${link}'))" 2>/dev/null || true)"
if [[ "$current" == "$target" || ( -n "$resolved_target" && -n "$resolved_link" && "$resolved_target" == "$resolved_link" ) ]]; then
print_ok "$link_name: symlink correct"
return 0
else
if [[ "$CHECK_ONLY" == true ]]; then
print_warn "$link_name: symlink points to wrong target: $current"
return 1
fi
print_info "$link_name: updating symlink..."
rm "$link"
ln -s "$target" "$link"
print_ok "$link_name: symlink updated"
fi
elif [[ -e "$link" ]]; then
if [[ "$CHECK_ONLY" == true ]]; then
print_warn "$link_name: regular file exists (not a symlink)"
return 1
fi
local backup="${link}.backup.$(date +%Y%m%d%H%M%S)"
print_warn "$link_name: backing up regular file to $backup"
mv "$link" "$backup"
ln -s "$target" "$link"
print_ok "$link_name: symlink created (old file backed up)"
else
if [[ "$CHECK_ONLY" == true ]]; then
print_warn "$link_name: does not exist"
return 1
fi
ln -s "$target" "$link"
print_ok "$link_name: symlink created"
fi
}
remove_legacy_settings_base() {
local legacy_path="$HOME/.claude/settings.base.json"
local legacy_name
legacy_name="$(basename "$legacy_path")"
if [[ ! -e "$legacy_path" && ! -L "$legacy_path" ]]; then
return 0
fi
if [[ "$CHECK_ONLY" == true ]]; then
print_warn "$legacy_name: deprecated file exists and should be removed"
return 1
fi
if [[ -L "$legacy_path" ]]; then
rm "$legacy_path"
print_ok "$legacy_name: removed deprecated symlink"
return 0
fi
local backup="${legacy_path}.backup.$(date +%Y%m%d%H%M%S)"
print_warn "$legacy_name: backing up deprecated file to $backup"
mv "$legacy_path" "$backup"
print_ok "$legacy_name: removed deprecated file (backup created)"
}
main() {
echo "Claude Code install.sh"
echo "Repository: $SCRIPT_DIR"
echo ""
# Ensure ~/.claude exists
mkdir -p "$HOME/.claude"
# CLAUDE.md - user-level instructions (open-source, editable)
ensure_symlink "$SCRIPT_DIR/CLAUDE.md" "$HOME/.claude/CLAUDE.md"
# commands/, agents/, skills/ - assets discoverable by Claude Code
ensure_symlink "$SCRIPT_DIR/commands" "$HOME/.claude/commands"
ensure_symlink "$SCRIPT_DIR/agents" "$HOME/.claude/agents"
ensure_symlink "$SCRIPT_DIR/.claude/skills" "$HOME/.claude/skills"
# codex.json - Codex CLI config consumed by the codex-reviewer plugin.
# Prefer a parent dotfiles tree (../codex/codex.json) when present; otherwise
# fall back to the in-repo sample so standalone installs still work.
local codex_source="$SCRIPT_DIR/codex.json"
if [[ -e "$SCRIPT_DIR/../codex/codex.json" ]]; then
codex_source="$SCRIPT_DIR/../codex/codex.json"
fi
ensure_symlink "$codex_source" "$HOME/.claude/codex.json"
# Legacy compatibility cleanup: baseline now loads directly from repository path.
remove_legacy_settings_base || true
# Regenerate runtime settings if merge helper exists.
if command -v claude-settings-merge >/dev/null 2>&1; then
claude-settings-merge --fix || print_warn "Failed to regenerate ~/.claude/settings.json"
fi
echo ""
if [[ "$CHECK_ONLY" == true ]]; then
echo "Check complete. Run without --check to apply changes."
else
echo "Done."
fi
}
main "$@"