-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathccvm.sh
More file actions
239 lines (195 loc) · 5.68 KB
/
ccvm.sh
File metadata and controls
239 lines (195 loc) · 5.68 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
#!/bin/bash
# CCVM - Claude Code Version Manager
# https://github.com/ra-kesh/ccvm
# Manage multiple native Claude Code installations
export CCVM_DIR="${CCVM_DIR:-$HOME/.ccvm}"
export CCVM_VERSIONS_DIR="$HOME/.local/share/claude/versions"
export CCVM_BIN_DIR="$HOME/.local/bin"
export CCVM_BIN="$CCVM_BIN_DIR/claude"
# Colors for output
_ccvm_red='\033[0;31m'
_ccvm_green='\033[0;32m'
_ccvm_yellow='\033[0;33m'
_ccvm_blue='\033[0;34m'
_ccvm_cyan='\033[0;36m'
_ccvm_reset='\033[0m'
# Main ccvm function
ccvm() {
local command=$1
shift
case "$command" in
install|i)
_ccvm_install "$@"
;;
use)
_ccvm_use "$@"
;;
list|ls)
_ccvm_list
;;
current)
_ccvm_current
;;
remove|rm|uninstall)
_ccvm_remove "$@"
;;
upgrade)
_ccvm_upgrade
;;
help|--help|-h|"")
_ccvm_help
;;
--version|-v)
echo "ccvm v1.0.0"
;;
*)
echo -e "${_ccvm_red}Unknown command: $command${_ccvm_reset}"
_ccvm_help
return 1
;;
esac
}
_ccvm_install() {
local version=""
local force=""
# Parse arguments
for arg in "$@"; do
case "$arg" in
--force|-f)
force="--force"
;;
*)
version="$arg"
;;
esac
done
version=${version:-latest}
# Check if version already exists
if [[ -f "$CCVM_VERSIONS_DIR/$version" ]]; then
echo -e "${_ccvm_yellow}Version $version already installed.${_ccvm_reset}"
echo "Use 'ccvm use $version' to switch to it."
return 0
fi
echo -e "${_ccvm_blue}Installing Claude Code $version...${_ccvm_reset}"
# Use the native installer
if curl -fsSL https://claude.ai/install.sh | bash -s -- "$version" $force; then
echo -e "${_ccvm_green}✓ Successfully installed Claude Code $version${_ccvm_reset}"
else
echo -e "${_ccvm_red}✗ Failed to install Claude Code $version${_ccvm_reset}"
return 1
fi
}
_ccvm_use() {
local version=$1
if [[ -z "$version" ]]; then
echo -e "${_ccvm_red}Usage: ccvm use <version>${_ccvm_reset}"
echo ""
_ccvm_list
return 1
fi
local version_path="$CCVM_VERSIONS_DIR/$version"
if [[ ! -f "$version_path" ]]; then
echo -e "${_ccvm_red}Version $version not installed.${_ccvm_reset}"
echo ""
_ccvm_list
echo ""
echo "Run: ccvm install $version"
return 1
fi
# Update the symlink
rm -f "$CCVM_BIN"
ln -sf "$version_path" "$CCVM_BIN"
echo -e "${_ccvm_green}Now using Claude Code $version${_ccvm_reset}"
"$CCVM_BIN" --version 2>/dev/null || echo -e "${_ccvm_yellow}Warning: Could not verify version${_ccvm_reset}"
}
_ccvm_list() {
echo -e "${_ccvm_blue}Installed versions:${_ccvm_reset}"
if [[ ! -d "$CCVM_VERSIONS_DIR" ]] || [[ -z "$(ls -A "$CCVM_VERSIONS_DIR" 2>/dev/null)" ]]; then
echo " (none installed)"
echo ""
echo "Run: ccvm install latest"
return
fi
# Get current version from symlink
local current_version=""
if [[ -L "$CCVM_BIN" ]]; then
current_version=$(basename "$(readlink "$CCVM_BIN")")
fi
# List all versions sorted
for file in $(ls -1 "$CCVM_VERSIONS_DIR" | sort -V); do
local version_path="$CCVM_VERSIONS_DIR/$file"
if [[ -f "$version_path" ]]; then
local version="$file"
local marker=""
if [[ "$version" == "$current_version" ]]; then
marker=" ${_ccvm_green}← current${_ccvm_reset}"
fi
# Get file size
local size=$(du -h "$version_path" | cut -f1)
echo -e " $version ${_ccvm_cyan}($size)${_ccvm_reset}$marker"
fi
done
}
_ccvm_current() {
if [[ -L "$CCVM_BIN" ]]; then
local current=$(basename "$(readlink "$CCVM_BIN")")
echo "$current"
else
echo "No version selected"
return 1
fi
}
_ccvm_remove() {
local version=$1
if [[ -z "$version" ]]; then
echo -e "${_ccvm_red}Usage: ccvm remove <version>${_ccvm_reset}"
return 1
fi
local version_path="$CCVM_VERSIONS_DIR/$version"
if [[ ! -f "$version_path" ]]; then
echo -e "${_ccvm_red}Version $version is not installed.${_ccvm_reset}"
return 1
fi
# Check if this is the current version
if [[ -L "$CCVM_BIN" ]]; then
local current=$(basename "$(readlink "$CCVM_BIN")")
if [[ "$current" == "$version" ]]; then
echo -e "${_ccvm_red}Cannot remove current version.${_ccvm_reset}"
echo "Switch to another version first: ccvm use <other-version>"
return 1
fi
fi
rm -f "$version_path"
echo -e "${_ccvm_green}✓ Removed Claude Code $version${_ccvm_reset}"
}
_ccvm_upgrade() {
echo -e "${_ccvm_blue}Upgrading CCVM...${_ccvm_reset}"
curl -fsSL https://raw.githubusercontent.com/ra-kesh/ccvm/main/install.sh | bash
}
_ccvm_help() {
cat << 'EOF'
CCVM - Claude Code Version Manager
Easily switch between multiple Claude Code versions.
Works with the native Claude Code installation.
Usage: ccvm <command> [args]
Commands:
install, i [version] [--force]
Install a Claude Code version (default: latest)
Examples: ccvm install latest
ccvm install 2.0.52
ccvm i 2.0.75 --force
use <version> Switch to a specific installed version
list, ls List all installed versions
current Show currently active version
remove, rm <ver> Remove an installed version
upgrade Upgrade CCVM to latest version
help Show this help message
--version, -v Show CCVM version
Examples:
ccvm install latest # Install latest Claude Code
ccvm list # Show all installed versions
ccvm use 2.0.64 # Switch to version 2.0.64
ccvm remove 2.0.50 # Remove a version
More info: https://github.com/ra-kesh/ccvm
EOF
}