openclacky 0.9.12 → 0.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/clacky/brand_config.rb +24 -5
- data/lib/clacky/cli.rb +20 -8
- data/lib/clacky/server/channel/adapters/feishu/ws_client.rb +43 -33
- data/lib/clacky/server/channel/adapters/wecom/ws_client.rb +41 -34
- data/lib/clacky/server/http_server.rb +74 -46
- data/lib/clacky/ui2/ui_controller.rb +3 -0
- data/lib/clacky/utils/parser_manager.rb +4 -1
- data/lib/clacky/version.rb +1 -1
- data/scripts/install.sh +493 -184
- data/scripts/install_simple.sh +582 -0
- metadata +36 -13
- data/scripts/install_original.sh +0 -891
data/scripts/install_original.sh
DELETED
|
@@ -1,891 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# OpenClacky Installation Script
|
|
3
|
-
# This script automatically detects your system and installs OpenClacky
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
# Brand configuration (populated by --brand-name / --command flags)
|
|
8
|
-
BRAND_NAME=""
|
|
9
|
-
BRAND_COMMAND=""
|
|
10
|
-
|
|
11
|
-
# Colors for output
|
|
12
|
-
RED='\033[0;31m'
|
|
13
|
-
GREEN='\033[0;32m'
|
|
14
|
-
YELLOW='\033[1;33m'
|
|
15
|
-
BLUE='\033[0;34m'
|
|
16
|
-
NC='\033[0m' # No Color
|
|
17
|
-
|
|
18
|
-
# Print colored messages
|
|
19
|
-
print_info() {
|
|
20
|
-
echo -e "${BLUE}ℹ${NC} $1"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
print_success() {
|
|
24
|
-
echo -e "${GREEN}✓${NC} $1"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
print_warning() {
|
|
28
|
-
echo -e "${YELLOW}⚠${NC} $1"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
print_error() {
|
|
32
|
-
echo -e "${RED}✗${NC} $1"
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
print_step() {
|
|
36
|
-
echo -e "\n${BLUE}==>${NC} $1"
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
# Detect OS
|
|
40
|
-
detect_os() {
|
|
41
|
-
case "$(uname -s)" in
|
|
42
|
-
Linux*) OS=Linux;;
|
|
43
|
-
Darwin*) OS=macOS;;
|
|
44
|
-
CYGWIN*) OS=Windows;;
|
|
45
|
-
MINGW*) OS=Windows;;
|
|
46
|
-
*) OS=Unknown;;
|
|
47
|
-
esac
|
|
48
|
-
print_info "Detected OS: $OS"
|
|
49
|
-
|
|
50
|
-
# Detect Linux distribution
|
|
51
|
-
if [ "$OS" = "Linux" ]; then
|
|
52
|
-
if [ -f /etc/os-release ]; then
|
|
53
|
-
. /etc/os-release
|
|
54
|
-
DISTRO=$ID
|
|
55
|
-
print_info "Detected Linux distribution: $DISTRO"
|
|
56
|
-
else
|
|
57
|
-
DISTRO=unknown
|
|
58
|
-
fi
|
|
59
|
-
fi
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# Check if command exists
|
|
63
|
-
command_exists() {
|
|
64
|
-
command -v "$1" >/dev/null 2>&1
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# Detect current shell type based on $SHELL environment variable
|
|
68
|
-
# Sets CURRENT_SHELL (e.g. "zsh", "bash", "fish") and SHELL_RC (rc file path)
|
|
69
|
-
detect_shell() {
|
|
70
|
-
local shell_name
|
|
71
|
-
shell_name=$(basename "$SHELL")
|
|
72
|
-
|
|
73
|
-
case "$shell_name" in
|
|
74
|
-
zsh)
|
|
75
|
-
CURRENT_SHELL="zsh"
|
|
76
|
-
SHELL_RC="$HOME/.zshrc"
|
|
77
|
-
;;
|
|
78
|
-
bash)
|
|
79
|
-
CURRENT_SHELL="bash"
|
|
80
|
-
# macOS uses ~/.bash_profile; Linux uses ~/.bashrc
|
|
81
|
-
if [ "$OS" = "macOS" ]; then
|
|
82
|
-
SHELL_RC="$HOME/.bash_profile"
|
|
83
|
-
else
|
|
84
|
-
SHELL_RC="$HOME/.bashrc"
|
|
85
|
-
fi
|
|
86
|
-
;;
|
|
87
|
-
fish)
|
|
88
|
-
CURRENT_SHELL="fish"
|
|
89
|
-
SHELL_RC="$HOME/.config/fish/config.fish"
|
|
90
|
-
;;
|
|
91
|
-
*)
|
|
92
|
-
# Fallback: treat as bash
|
|
93
|
-
CURRENT_SHELL="bash"
|
|
94
|
-
SHELL_RC="$HOME/.bashrc"
|
|
95
|
-
;;
|
|
96
|
-
esac
|
|
97
|
-
|
|
98
|
-
print_info "Detected shell: $CURRENT_SHELL (rc file: $SHELL_RC)"
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# Network-aware installer source selection
|
|
102
|
-
SLOW_THRESHOLD_MS=5000
|
|
103
|
-
NETWORK_REGION="global" # "china" | "global" | "unknown"
|
|
104
|
-
USE_CN_MIRRORS=false
|
|
105
|
-
|
|
106
|
-
# --- Upstream (global) defaults ---
|
|
107
|
-
GITHUB_RAW_BASE_URL="https://raw.githubusercontent.com"
|
|
108
|
-
HOMEBREW_INSTALL_SCRIPT_URL="${GITHUB_RAW_BASE_URL}/Homebrew/install/HEAD/install.sh"
|
|
109
|
-
OPENCLACKY_INSTALL_SCRIPT_URL="${GITHUB_RAW_BASE_URL}/clacky-ai/openclacky/main/scripts/install.sh"
|
|
110
|
-
DEFAULT_RUBYGEMS_URL="https://rubygems.org"
|
|
111
|
-
DEFAULT_NPM_REGISTRY="https://registry.npmjs.org"
|
|
112
|
-
DEFAULT_MISE_INSTALL_URL="https://mise.run"
|
|
113
|
-
|
|
114
|
-
CN_CDN_BASE_URL="https://oss.1024code.com" # reverse proxy for raw.githubusercontent.com
|
|
115
|
-
|
|
116
|
-
# --- CN source URLs ---
|
|
117
|
-
CN_HOMEBREW_INSTALL_SCRIPT_URL="${CN_CDN_BASE_URL}/Homebrew/install/HEAD/install.sh"
|
|
118
|
-
CN_MISE_INSTALL_URL="${CN_CDN_BASE_URL}/mise.sh"
|
|
119
|
-
CN_RUBY_PRECOMPILED_URL="${CN_CDN_BASE_URL}/ruby/ruby-{version}.{platform}.tar.gz"
|
|
120
|
-
CN_RUBYGEMS_URL="https://mirrors.aliyun.com/rubygems/"
|
|
121
|
-
CN_NPM_REGISTRY="https://registry.npmmirror.com"
|
|
122
|
-
CN_NODE_MIRROR_URL="https://cdn.npmmirror.com/binaries/node/"
|
|
123
|
-
|
|
124
|
-
# --- Homebrew CN mirrors (Aliyun) ---
|
|
125
|
-
CN_HOMEBREW_BREW_GIT_REMOTE="https://mirrors.aliyun.com/homebrew/brew.git"
|
|
126
|
-
CN_HOMEBREW_CORE_GIT_REMOTE="https://mirrors.aliyun.com/homebrew/homebrew-core.git"
|
|
127
|
-
CN_HOMEBREW_BOTTLE_DOMAIN="https://mirrors.aliyun.com/homebrew/homebrew-bottles"
|
|
128
|
-
CN_HOMEBREW_API_DOMAIN="https://mirrors.aliyun.com/homebrew-bottles/api"
|
|
129
|
-
|
|
130
|
-
# --- Active values (overridden by detect_network_region) ---
|
|
131
|
-
MISE_INSTALL_URL="$DEFAULT_MISE_INSTALL_URL"
|
|
132
|
-
RUBYGEMS_INSTALL_URL="$DEFAULT_RUBYGEMS_URL"
|
|
133
|
-
NPM_REGISTRY_URL="$DEFAULT_NPM_REGISTRY"
|
|
134
|
-
NODE_MIRROR_URL="" # empty = mise default (nodejs.org)
|
|
135
|
-
RUBY_VERSION_SPEC="ruby@3"
|
|
136
|
-
|
|
137
|
-
# Probe a single URL; echoes the round-trip time in milliseconds, or "timeout".
|
|
138
|
-
_probe_url() {
|
|
139
|
-
local url="$1"
|
|
140
|
-
local timeout_sec=5
|
|
141
|
-
local curl_output http_code total_time elapsed_ms
|
|
142
|
-
|
|
143
|
-
curl_output=$(curl -s -o /dev/null -w "%{http_code} %{time_total}" \
|
|
144
|
-
--connect-timeout "$timeout_sec" \
|
|
145
|
-
--max-time "$timeout_sec" \
|
|
146
|
-
"$url" 2>/dev/null) || true
|
|
147
|
-
http_code="${curl_output%% *}"
|
|
148
|
-
total_time="${curl_output#* }"
|
|
149
|
-
|
|
150
|
-
if [ -z "$http_code" ] || [ "$http_code" = "000" ] || [ "$http_code" = "$curl_output" ]; then
|
|
151
|
-
echo "timeout"
|
|
152
|
-
else
|
|
153
|
-
elapsed_ms=$(awk -v seconds="$total_time" 'BEGIN { printf "%d", seconds * 1000 }')
|
|
154
|
-
echo "$elapsed_ms"
|
|
155
|
-
fi
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
_is_timed_result() {
|
|
159
|
-
local result="$1"
|
|
160
|
-
|
|
161
|
-
[ -n "$result" ] && [ "$result" != "timeout" ] && [ "$result" -ge 0 ] 2>/dev/null
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
_is_slow_or_unreachable() {
|
|
165
|
-
local result="$1"
|
|
166
|
-
|
|
167
|
-
if [ "$result" = "timeout" ]; then
|
|
168
|
-
return 0
|
|
169
|
-
fi
|
|
170
|
-
|
|
171
|
-
[ "$result" -ge "$SLOW_THRESHOLD_MS" ] 2>/dev/null
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
_format_probe_time() {
|
|
175
|
-
local result="$1"
|
|
176
|
-
|
|
177
|
-
if [ "$result" = "timeout" ]; then
|
|
178
|
-
echo "timeout"
|
|
179
|
-
else
|
|
180
|
-
awk -v ms="$result" 'BEGIN { printf "%.1fs", ms / 1000 }'
|
|
181
|
-
fi
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
_print_probe_result() {
|
|
185
|
-
local label="$1"
|
|
186
|
-
local result="$2"
|
|
187
|
-
|
|
188
|
-
if [ "$result" = "timeout" ]; then
|
|
189
|
-
print_warning "UNREACHABLE (${result}) ${label}"
|
|
190
|
-
elif _is_slow_or_unreachable "$result"; then
|
|
191
|
-
print_warning "SLOW ($(_format_probe_time "$result")) ${label}"
|
|
192
|
-
else
|
|
193
|
-
print_success "OK ($(_format_probe_time "$result")) ${label}"
|
|
194
|
-
fi
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
# Probe a URL up to MAX_RETRIES times; returns the first successful ms or "timeout".
|
|
198
|
-
_probe_url_with_retry() {
|
|
199
|
-
local url="$1"
|
|
200
|
-
local max_retries="${2:-2}"
|
|
201
|
-
local attempt result
|
|
202
|
-
|
|
203
|
-
for attempt in $(seq 1 "$max_retries"); do
|
|
204
|
-
result=$(_probe_url "$url")
|
|
205
|
-
if [ "$result" != "timeout" ] && ! _is_slow_or_unreachable "$result"; then
|
|
206
|
-
echo "$result"
|
|
207
|
-
return 0
|
|
208
|
-
fi
|
|
209
|
-
# keep last result for reporting
|
|
210
|
-
done
|
|
211
|
-
echo "$result"
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
detect_network_region() {
|
|
215
|
-
print_step "Network pre-flight check..."
|
|
216
|
-
echo ""
|
|
217
|
-
|
|
218
|
-
# -----------------------------------------------------------------------
|
|
219
|
-
# Step 1: Region detection — google.com vs baidu.com
|
|
220
|
-
# google reachable → global
|
|
221
|
-
# google unreachable + baidu reachable → china
|
|
222
|
-
# both unreachable → unknown (best-effort, fall through)
|
|
223
|
-
# -----------------------------------------------------------------------
|
|
224
|
-
print_info "Step 1: Detecting network region..."
|
|
225
|
-
local google_result baidu_result
|
|
226
|
-
google_result=$(_probe_url "https://www.google.com")
|
|
227
|
-
baidu_result=$(_probe_url "https://www.baidu.com")
|
|
228
|
-
|
|
229
|
-
_print_probe_result "google.com" "$google_result"
|
|
230
|
-
_print_probe_result "baidu.com" "$baidu_result"
|
|
231
|
-
|
|
232
|
-
local google_ok=false baidu_ok=false
|
|
233
|
-
! _is_slow_or_unreachable "$google_result" && google_ok=true
|
|
234
|
-
! _is_slow_or_unreachable "$baidu_result" && baidu_ok=true
|
|
235
|
-
|
|
236
|
-
if [ "$google_ok" = true ]; then
|
|
237
|
-
NETWORK_REGION="global"
|
|
238
|
-
print_success "Region: global (Google reachable)"
|
|
239
|
-
elif [ "$baidu_ok" = true ]; then
|
|
240
|
-
NETWORK_REGION="china"
|
|
241
|
-
print_success "Region: china (Baidu reachable, Google not)"
|
|
242
|
-
else
|
|
243
|
-
NETWORK_REGION="unknown"
|
|
244
|
-
print_warning "Region: unknown (both Google and Baidu unreachable)"
|
|
245
|
-
fi
|
|
246
|
-
echo ""
|
|
247
|
-
|
|
248
|
-
# -----------------------------------------------------------------------
|
|
249
|
-
# Step 2: Probe region-specific sources (retry 2× to avoid false alarms)
|
|
250
|
-
# -----------------------------------------------------------------------
|
|
251
|
-
print_info "Step 2: Probing installation sources (up to 2 retries each)..."
|
|
252
|
-
|
|
253
|
-
if [ "$NETWORK_REGION" = "china" ]; then
|
|
254
|
-
# CN sources: CDN (oss.1024code.com) + Aliyun + npmmirror
|
|
255
|
-
local cdn_result mirror_result
|
|
256
|
-
cdn_result=$(_probe_url_with_retry "$CN_MISE_INSTALL_URL")
|
|
257
|
-
mirror_result=$(_probe_url_with_retry "$CN_RUBYGEMS_URL")
|
|
258
|
-
|
|
259
|
-
_print_probe_result "Chinese CDN (mise/Ruby)" "$cdn_result"
|
|
260
|
-
_print_probe_result "CN mirror (gem/brew)" "$mirror_result"
|
|
261
|
-
|
|
262
|
-
local cdn_ok=false mirror_ok=false
|
|
263
|
-
! _is_slow_or_unreachable "$cdn_result" && cdn_ok=true
|
|
264
|
-
! _is_slow_or_unreachable "$mirror_result" && mirror_ok=true
|
|
265
|
-
|
|
266
|
-
# Step 3: warn on source failures, but do not abort
|
|
267
|
-
if [ "$cdn_ok" = false ]; then
|
|
268
|
-
print_warning "Chinese CDN is slow/unreachable. mise and Ruby precompiled binaries may fail."
|
|
269
|
-
fi
|
|
270
|
-
if [ "$mirror_ok" = false ]; then
|
|
271
|
-
print_warning "Aliyun mirror is slow/unreachable. gem/brew installs may be slow."
|
|
272
|
-
fi
|
|
273
|
-
if [ "$cdn_ok" = false ] && [ "$mirror_ok" = false ]; then
|
|
274
|
-
print_warning "All CN mirrors unreachable — falling back to global sources. Expect slow downloads."
|
|
275
|
-
fi
|
|
276
|
-
|
|
277
|
-
# Step 4: apply CN sources
|
|
278
|
-
if [ "$cdn_ok" = true ] || [ "$mirror_ok" = true ]; then
|
|
279
|
-
USE_CN_MIRRORS=true
|
|
280
|
-
MISE_INSTALL_URL="$CN_MISE_INSTALL_URL"
|
|
281
|
-
RUBYGEMS_INSTALL_URL="$CN_RUBYGEMS_URL"
|
|
282
|
-
NPM_REGISTRY_URL="$CN_NPM_REGISTRY"
|
|
283
|
-
NODE_MIRROR_URL="$CN_NODE_MIRROR_URL"
|
|
284
|
-
RUBY_VERSION_SPEC="ruby@3.4.8"
|
|
285
|
-
print_info "CN mirrors applied: CDN (mise/Ruby) + Aliyun (gem/brew) + npmmirror (npm/Node)"
|
|
286
|
-
else
|
|
287
|
-
USE_CN_MIRRORS=false
|
|
288
|
-
print_info "Falling back to global sources despite CN region detection."
|
|
289
|
-
fi
|
|
290
|
-
|
|
291
|
-
else
|
|
292
|
-
# Global sources: GitHub / RubyGems / npmjs / mise.run
|
|
293
|
-
local github_result rubygems_result npm_result mise_result
|
|
294
|
-
github_result=$(_probe_url_with_retry "$GITHUB_RAW_BASE_URL")
|
|
295
|
-
rubygems_result=$(_probe_url_with_retry "$DEFAULT_RUBYGEMS_URL")
|
|
296
|
-
npm_result=$(_probe_url_with_retry "$DEFAULT_NPM_REGISTRY")
|
|
297
|
-
mise_result=$(_probe_url_with_retry "$DEFAULT_MISE_INSTALL_URL")
|
|
298
|
-
|
|
299
|
-
_print_probe_result "GitHub raw" "$github_result"
|
|
300
|
-
_print_probe_result "RubyGems" "$rubygems_result"
|
|
301
|
-
_print_probe_result "npmjs.com" "$npm_result"
|
|
302
|
-
_print_probe_result "mise.run" "$mise_result"
|
|
303
|
-
|
|
304
|
-
# Step 3: warn on individual source failures
|
|
305
|
-
_is_slow_or_unreachable "$github_result" && print_warning "GitHub is slow/unreachable. Homebrew and install script updates may fail."
|
|
306
|
-
_is_slow_or_unreachable "$rubygems_result" && print_warning "RubyGems is slow/unreachable. gem install may fail."
|
|
307
|
-
_is_slow_or_unreachable "$npm_result" && print_warning "npmjs.com is slow/unreachable. npm install may fail."
|
|
308
|
-
_is_slow_or_unreachable "$mise_result" && print_warning "mise.run is slow/unreachable. mise installation may fail."
|
|
309
|
-
|
|
310
|
-
USE_CN_MIRRORS=false
|
|
311
|
-
MISE_INSTALL_URL="$DEFAULT_MISE_INSTALL_URL"
|
|
312
|
-
RUBYGEMS_INSTALL_URL="$DEFAULT_RUBYGEMS_URL"
|
|
313
|
-
NPM_REGISTRY_URL="$DEFAULT_NPM_REGISTRY"
|
|
314
|
-
NODE_MIRROR_URL=""
|
|
315
|
-
RUBY_VERSION_SPEC="ruby@3"
|
|
316
|
-
print_info "Using global upstream sources."
|
|
317
|
-
fi
|
|
318
|
-
|
|
319
|
-
echo ""
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
# Compare version strings
|
|
324
|
-
version_ge() {
|
|
325
|
-
# Returns 0 (true) if $1 >= $2
|
|
326
|
-
printf '%s\n%s\n' "$2" "$1" | sort -V -C
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
# Check Ruby version
|
|
330
|
-
check_ruby() {
|
|
331
|
-
if command_exists ruby; then
|
|
332
|
-
RUBY_VERSION=$(ruby -e 'puts RUBY_VERSION' 2>/dev/null)
|
|
333
|
-
print_info "Found Ruby version: $RUBY_VERSION"
|
|
334
|
-
|
|
335
|
-
if version_ge "$RUBY_VERSION" "3.1.0"; then
|
|
336
|
-
print_success "Ruby version is compatible (>= 3.1.0)"
|
|
337
|
-
return 0
|
|
338
|
-
else
|
|
339
|
-
print_warning "Ruby version $RUBY_VERSION is too old (need >= 3.1.0)"
|
|
340
|
-
return 1
|
|
341
|
-
fi
|
|
342
|
-
else
|
|
343
|
-
print_warning "Ruby is not installed"
|
|
344
|
-
return 1
|
|
345
|
-
fi
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
# Configure CN mirrors permanently in config files so all subsequent tool
|
|
349
|
-
# invocations (gem, npm, mise) automatically use the right source.
|
|
350
|
-
# Called once after detect_network_region, only when USE_CN_MIRRORS=true.
|
|
351
|
-
restore_mirrors() {
|
|
352
|
-
print_step "Restoring original mirror settings..."
|
|
353
|
-
|
|
354
|
-
# --- gem: restore ~/.gemrc ---
|
|
355
|
-
local gemrc="$HOME/.gemrc"
|
|
356
|
-
local gemrc_bak="$HOME/.gemrc_clackybak"
|
|
357
|
-
if [ -f "$gemrc_bak" ]; then
|
|
358
|
-
mv "$gemrc_bak" "$gemrc"
|
|
359
|
-
print_success "~/.gemrc restored from backup"
|
|
360
|
-
elif [ -f "$gemrc" ]; then
|
|
361
|
-
rm "$gemrc"
|
|
362
|
-
print_success "~/.gemrc removed (gem will use default rubygems.org)"
|
|
363
|
-
else
|
|
364
|
-
print_info "~/.gemrc — nothing to restore"
|
|
365
|
-
fi
|
|
366
|
-
|
|
367
|
-
# --- npm: restore ~/.npmrc ---
|
|
368
|
-
local npmrc="$HOME/.npmrc"
|
|
369
|
-
local npmrc_bak="$HOME/.npmrc_clackybak"
|
|
370
|
-
if [ -f "$npmrc_bak" ]; then
|
|
371
|
-
mv "$npmrc_bak" "$npmrc"
|
|
372
|
-
print_success "~/.npmrc restored from backup"
|
|
373
|
-
elif [ -f "$npmrc" ]; then
|
|
374
|
-
rm "$npmrc"
|
|
375
|
-
print_success "~/.npmrc removed (npm will use default registry)"
|
|
376
|
-
else
|
|
377
|
-
print_info "~/.npmrc — nothing to restore"
|
|
378
|
-
fi
|
|
379
|
-
|
|
380
|
-
# --- mise: unset node.mirror_url ---
|
|
381
|
-
local mise_bin=""
|
|
382
|
-
if command_exists mise; then
|
|
383
|
-
mise_bin="mise"
|
|
384
|
-
elif [ -x "$HOME/.local/bin/mise" ]; then
|
|
385
|
-
mise_bin="$HOME/.local/bin/mise"
|
|
386
|
-
fi
|
|
387
|
-
if [ -n "$mise_bin" ]; then
|
|
388
|
-
"$mise_bin" settings unset node.mirror_url 2>/dev/null && \
|
|
389
|
-
print_success "mise node.mirror_url unset"
|
|
390
|
-
else
|
|
391
|
-
print_info "mise not found — node.mirror_url skipped"
|
|
392
|
-
fi
|
|
393
|
-
|
|
394
|
-
# --- Homebrew CN mirrors: remove from shell rc file ---
|
|
395
|
-
if [ -n "$SHELL_RC" ] && [ -f "$SHELL_RC" ] && grep -q "HOMEBREW_BOTTLE_DOMAIN" "$SHELL_RC" 2>/dev/null; then
|
|
396
|
-
# Remove the comment line and the three export lines added by the installer
|
|
397
|
-
sed -i.bak '/# Homebrew CN mirrors (added by openclacky installer)/d' "$SHELL_RC"
|
|
398
|
-
sed -i.bak '/HOMEBREW_BREW_GIT_REMOTE/d' "$SHELL_RC"
|
|
399
|
-
sed -i.bak '/HOMEBREW_CORE_GIT_REMOTE/d' "$SHELL_RC"
|
|
400
|
-
sed -i.bak '/HOMEBREW_BOTTLE_DOMAIN/d' "$SHELL_RC"
|
|
401
|
-
rm -f "${SHELL_RC}.bak"
|
|
402
|
-
unset HOMEBREW_BREW_GIT_REMOTE HOMEBREW_CORE_GIT_REMOTE HOMEBREW_BOTTLE_DOMAIN
|
|
403
|
-
print_success "Homebrew CN mirrors removed from $SHELL_RC"
|
|
404
|
-
else
|
|
405
|
-
print_info "Homebrew CN mirrors — nothing to restore"
|
|
406
|
-
fi
|
|
407
|
-
|
|
408
|
-
echo ""
|
|
409
|
-
print_success "Done. All mirror settings restored to original."
|
|
410
|
-
echo ""
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
configure_cn_mirrors() {
|
|
414
|
-
[ "$USE_CN_MIRRORS" = true ] || return 0
|
|
415
|
-
|
|
416
|
-
print_step "Configuring CN mirrors (permanent)..."
|
|
417
|
-
|
|
418
|
-
# --- gem: write ~/.gemrc ---
|
|
419
|
-
local gemrc="$HOME/.gemrc"
|
|
420
|
-
if [ -f "$gemrc" ] && grep -q "${CN_RUBYGEMS_URL}" "$gemrc" 2>/dev/null; then
|
|
421
|
-
# Already configured by us — leave it alone
|
|
422
|
-
print_success "gem source already set → ${CN_RUBYGEMS_URL} (~/.gemrc)"
|
|
423
|
-
else
|
|
424
|
-
# Existing file with different content — back it up then generate a clean one
|
|
425
|
-
if [ -f "$gemrc" ]; then
|
|
426
|
-
mv "$gemrc" "$HOME/.gemrc_clackybak"
|
|
427
|
-
print_info "Backed up existing ~/.gemrc → ~/.gemrc_clackybak"
|
|
428
|
-
fi
|
|
429
|
-
cat > "$gemrc" <<GEMRC
|
|
430
|
-
:sources:
|
|
431
|
-
- ${CN_RUBYGEMS_URL}
|
|
432
|
-
GEMRC
|
|
433
|
-
print_success "gem source → ${CN_RUBYGEMS_URL} (~/.gemrc)"
|
|
434
|
-
fi
|
|
435
|
-
|
|
436
|
-
# --- npm: write ~/.npmrc ---
|
|
437
|
-
local npmrc="$HOME/.npmrc"
|
|
438
|
-
local npmrc_bak="$HOME/.npmrc_clackybak"
|
|
439
|
-
if [ -f "$npmrc" ] && grep -q "${NPM_REGISTRY_URL}" "$npmrc" 2>/dev/null; then
|
|
440
|
-
# Already configured by us — leave it alone
|
|
441
|
-
print_success "npm registry already set → ${NPM_REGISTRY_URL} (~/.npmrc)"
|
|
442
|
-
else
|
|
443
|
-
# Back up existing file (once), then write clean config
|
|
444
|
-
if [ -f "$npmrc" ] && [ ! -f "$npmrc_bak" ]; then
|
|
445
|
-
cp "$npmrc" "$npmrc_bak"
|
|
446
|
-
print_info "Backed up existing ~/.npmrc → ~/.npmrc_clackybak"
|
|
447
|
-
fi
|
|
448
|
-
if command_exists npm; then
|
|
449
|
-
npm config set registry "$NPM_REGISTRY_URL" 2>/dev/null && \
|
|
450
|
-
print_success "npm registry → ${NPM_REGISTRY_URL} (~/.npmrc)"
|
|
451
|
-
else
|
|
452
|
-
echo "registry=${NPM_REGISTRY_URL}" >> "$npmrc"
|
|
453
|
-
print_success "npm registry → ${NPM_REGISTRY_URL} (~/.npmrc, pre-set)"
|
|
454
|
-
fi
|
|
455
|
-
fi
|
|
456
|
-
|
|
457
|
-
# --- mise Node mirror ---
|
|
458
|
-
# Applied inside install_mise_runtime() after mise binary is available.
|
|
459
|
-
# NODE_MIRROR_URL is already set; nothing to do here.
|
|
460
|
-
|
|
461
|
-
echo ""
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
# Install via RubyGems
|
|
465
|
-
install_via_gem() {
|
|
466
|
-
print_step "Installing via RubyGems..."
|
|
467
|
-
|
|
468
|
-
if ! command_exists gem; then
|
|
469
|
-
print_error "RubyGems is not available"
|
|
470
|
-
return 1
|
|
471
|
-
fi
|
|
472
|
-
|
|
473
|
-
# Enforce Ruby >= 3.1.0 before attempting gem install
|
|
474
|
-
if ! command_exists ruby; then
|
|
475
|
-
print_error "Ruby is not available"
|
|
476
|
-
return 1
|
|
477
|
-
fi
|
|
478
|
-
RUBY_VERSION=$(ruby -e 'puts RUBY_VERSION' 2>/dev/null)
|
|
479
|
-
if ! version_ge "$RUBY_VERSION" "3.1.0"; then
|
|
480
|
-
print_error "Ruby $RUBY_VERSION is too old (>= 3.1.0 required)"
|
|
481
|
-
return 1
|
|
482
|
-
fi
|
|
483
|
-
|
|
484
|
-
print_info "Installing ${DISPLAY_NAME}..."
|
|
485
|
-
gem install openclacky --no-document
|
|
486
|
-
|
|
487
|
-
if [ $? -eq 0 ]; then
|
|
488
|
-
print_success "${DISPLAY_NAME} installed successfully!"
|
|
489
|
-
install_chrome_devtools_mcp
|
|
490
|
-
return 0
|
|
491
|
-
else
|
|
492
|
-
print_error "Gem installation failed"
|
|
493
|
-
return 1
|
|
494
|
-
fi
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
# Install mise for Ruby version management
|
|
498
|
-
install_mise_runtime() {
|
|
499
|
-
print_info "Installing mise..."
|
|
500
|
-
if ! command_exists mise; then
|
|
501
|
-
if curl -fsSL "$MISE_INSTALL_URL" | sh; then
|
|
502
|
-
# Add mise activation to the current shell's rc file
|
|
503
|
-
local mise_init_line='eval "$(~/.local/bin/mise activate '"$CURRENT_SHELL"')"'
|
|
504
|
-
if [ -f "$SHELL_RC" ]; then
|
|
505
|
-
echo "$mise_init_line" >> "$SHELL_RC"
|
|
506
|
-
else
|
|
507
|
-
echo "$mise_init_line" > "$SHELL_RC"
|
|
508
|
-
fi
|
|
509
|
-
print_info "Added mise activation to $SHELL_RC"
|
|
510
|
-
|
|
511
|
-
export PATH="$HOME/.local/bin:$PATH"
|
|
512
|
-
# Always activate using bash syntax here (this script runs under bash)
|
|
513
|
-
eval "$(~/.local/bin/mise activate bash)"
|
|
514
|
-
|
|
515
|
-
print_success "mise installed successfully"
|
|
516
|
-
else
|
|
517
|
-
print_error "Failed to install mise"
|
|
518
|
-
return 1
|
|
519
|
-
fi
|
|
520
|
-
else
|
|
521
|
-
print_success "mise already installed"
|
|
522
|
-
fi
|
|
523
|
-
|
|
524
|
-
# Apply CN Node mirror permanently — covers any future `mise install node` too.
|
|
525
|
-
if [ "$USE_CN_MIRRORS" = true ] && [ -n "$NODE_MIRROR_URL" ]; then
|
|
526
|
-
~/.local/bin/mise settings node.mirror_url="$NODE_MIRROR_URL" 2>/dev/null || true
|
|
527
|
-
print_info "mise Node mirror → ${NODE_MIRROR_URL}"
|
|
528
|
-
fi
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
install_ruby_via_mise() {
|
|
532
|
-
if check_ruby; then
|
|
533
|
-
print_success "Ruby already installed and compatible — skipping Ruby installation"
|
|
534
|
-
return 0
|
|
535
|
-
fi
|
|
536
|
-
|
|
537
|
-
print_info "Installing Ruby 3 via mise..."
|
|
538
|
-
|
|
539
|
-
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
540
|
-
~/.local/bin/mise settings ruby.compile=false
|
|
541
|
-
~/.local/bin/mise settings ruby.precompiled_url="$CN_RUBY_PRECOMPILED_URL"
|
|
542
|
-
else
|
|
543
|
-
~/.local/bin/mise settings unset ruby.compile >/dev/null 2>&1 || true
|
|
544
|
-
~/.local/bin/mise settings unset ruby.precompiled_url >/dev/null 2>&1 || true
|
|
545
|
-
fi
|
|
546
|
-
|
|
547
|
-
if ~/.local/bin/mise use -g "$RUBY_VERSION_SPEC"; then
|
|
548
|
-
eval "$(~/.local/bin/mise activate bash)"
|
|
549
|
-
print_success "Ruby 3 installed successfully"
|
|
550
|
-
else
|
|
551
|
-
print_error "Failed to install Ruby 3"
|
|
552
|
-
return 1
|
|
553
|
-
fi
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
# Install dependencies and Ruby on macOS
|
|
557
|
-
install_macos_dependencies() {
|
|
558
|
-
print_step "Installing macOS dependencies and Ruby..."
|
|
559
|
-
echo ""
|
|
560
|
-
|
|
561
|
-
# Configure Homebrew CN mirrors before installing (CN mode only)
|
|
562
|
-
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
563
|
-
print_info "Configuring Homebrew CN mirrors..."
|
|
564
|
-
export HOMEBREW_INSTALL_FROM_API=1
|
|
565
|
-
export HOMEBREW_API_DOMAIN="$CN_HOMEBREW_API_DOMAIN"
|
|
566
|
-
export HOMEBREW_BREW_GIT_REMOTE="$CN_HOMEBREW_BREW_GIT_REMOTE"
|
|
567
|
-
export HOMEBREW_CORE_GIT_REMOTE="$CN_HOMEBREW_CORE_GIT_REMOTE"
|
|
568
|
-
export HOMEBREW_BOTTLE_DOMAIN="$CN_HOMEBREW_BOTTLE_DOMAIN"
|
|
569
|
-
|
|
570
|
-
# Persist to shell rc file
|
|
571
|
-
if ! grep -q "HOMEBREW_BOTTLE_DOMAIN" "$SHELL_RC" 2>/dev/null; then
|
|
572
|
-
{
|
|
573
|
-
echo ""
|
|
574
|
-
echo "# Homebrew CN mirrors (added by openclacky installer)"
|
|
575
|
-
echo "export HOMEBREW_INSTALL_FROM_API=1"
|
|
576
|
-
echo "export HOMEBREW_API_DOMAIN=\"${CN_HOMEBREW_API_DOMAIN}\""
|
|
577
|
-
echo "export HOMEBREW_BREW_GIT_REMOTE=\"${CN_HOMEBREW_BREW_GIT_REMOTE}\""
|
|
578
|
-
echo "export HOMEBREW_CORE_GIT_REMOTE=\"${CN_HOMEBREW_CORE_GIT_REMOTE}\""
|
|
579
|
-
echo "export HOMEBREW_BOTTLE_DOMAIN=\"${CN_HOMEBREW_BOTTLE_DOMAIN}\""
|
|
580
|
-
} >> "$SHELL_RC"
|
|
581
|
-
print_success "Homebrew CN mirrors written to $SHELL_RC"
|
|
582
|
-
else
|
|
583
|
-
print_success "Homebrew CN mirrors already configured in $SHELL_RC"
|
|
584
|
-
fi
|
|
585
|
-
fi
|
|
586
|
-
|
|
587
|
-
# Install Homebrew (it will automatically install Xcode Command Line Tools if needed)
|
|
588
|
-
print_info "Checking Homebrew installation..."
|
|
589
|
-
if ! command_exists brew; then
|
|
590
|
-
print_info "Installing Homebrew..."
|
|
591
|
-
local brew_install_url="$HOMEBREW_INSTALL_SCRIPT_URL"
|
|
592
|
-
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
593
|
-
brew_install_url="$CN_HOMEBREW_INSTALL_SCRIPT_URL"
|
|
594
|
-
fi
|
|
595
|
-
/bin/bash -c "$(curl -fsSL "$brew_install_url")"
|
|
596
|
-
|
|
597
|
-
# Add Homebrew to PATH
|
|
598
|
-
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> "$SHELL_RC"
|
|
599
|
-
export PATH="/opt/homebrew/bin:$PATH"
|
|
600
|
-
|
|
601
|
-
print_success "Homebrew installed successfully"
|
|
602
|
-
else
|
|
603
|
-
print_success "Homebrew already installed"
|
|
604
|
-
fi
|
|
605
|
-
|
|
606
|
-
# Install build dependencies
|
|
607
|
-
print_info "Installing build dependencies..."
|
|
608
|
-
if brew install openssl@3 libyaml gmp; then
|
|
609
|
-
print_success "Build dependencies installed"
|
|
610
|
-
else
|
|
611
|
-
print_error "Failed to install build dependencies"
|
|
612
|
-
return 1
|
|
613
|
-
fi
|
|
614
|
-
|
|
615
|
-
# Install mise for Ruby version management
|
|
616
|
-
# Detect current shell before configuring mise
|
|
617
|
-
detect_shell
|
|
618
|
-
|
|
619
|
-
if ! install_mise_runtime; then
|
|
620
|
-
return 1
|
|
621
|
-
fi
|
|
622
|
-
|
|
623
|
-
if ! install_ruby_via_mise; then
|
|
624
|
-
return 1
|
|
625
|
-
fi
|
|
626
|
-
|
|
627
|
-
# Verify Ruby installation
|
|
628
|
-
if check_ruby; then
|
|
629
|
-
return 0
|
|
630
|
-
else
|
|
631
|
-
print_error "Ruby installation verification failed"
|
|
632
|
-
return 1
|
|
633
|
-
fi
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
# Install dependencies and Ruby on Ubuntu/Debian
|
|
637
|
-
install_ubuntu_dependencies() {
|
|
638
|
-
print_step "Installing Ubuntu dependencies and Ruby..."
|
|
639
|
-
echo ""
|
|
640
|
-
|
|
641
|
-
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
642
|
-
print_info "Configuring apt mirror (Aliyun)..."
|
|
643
|
-
local codename="${VERSION_CODENAME:-jammy}"
|
|
644
|
-
local mirror_base="https://mirrors.aliyun.com/ubuntu/"
|
|
645
|
-
local common_components="main restricted universe multiverse"
|
|
646
|
-
sudo tee /etc/apt/sources.list > /dev/null <<EOF
|
|
647
|
-
deb ${mirror_base} ${codename} ${common_components}
|
|
648
|
-
deb ${mirror_base} ${codename}-updates ${common_components}
|
|
649
|
-
deb ${mirror_base} ${codename}-backports ${common_components}
|
|
650
|
-
deb ${mirror_base} ${codename}-security ${common_components}
|
|
651
|
-
EOF
|
|
652
|
-
print_success "Mirror configured"
|
|
653
|
-
else
|
|
654
|
-
print_info "Using default apt sources"
|
|
655
|
-
fi
|
|
656
|
-
|
|
657
|
-
# Update package list
|
|
658
|
-
print_info "Updating package list..."
|
|
659
|
-
if sudo apt update; then
|
|
660
|
-
print_success "Package list updated"
|
|
661
|
-
else
|
|
662
|
-
print_error "Failed to update package list"
|
|
663
|
-
return 1
|
|
664
|
-
fi
|
|
665
|
-
|
|
666
|
-
# Install build dependencies
|
|
667
|
-
print_info "Installing build dependencies..."
|
|
668
|
-
if sudo apt install -y build-essential libssl-dev libyaml-dev zlib1g-dev libgmp-dev git; then
|
|
669
|
-
print_success "Build dependencies installed"
|
|
670
|
-
else
|
|
671
|
-
print_error "Failed to install build dependencies"
|
|
672
|
-
return 1
|
|
673
|
-
fi
|
|
674
|
-
|
|
675
|
-
# Detect current shell before configuring mise
|
|
676
|
-
detect_shell
|
|
677
|
-
|
|
678
|
-
# In WSL, Windows paths (e.g. /mnt/c/Windows/system32) are appended to PATH.
|
|
679
|
-
# mise scans PATH directories for mise.toml and errors on untrusted files found there.
|
|
680
|
-
# Auto-trust the Windows system32 directory to suppress those errors.
|
|
681
|
-
export MISE_TRUSTED_CONFIG_PATHS="/mnt/c/Windows/system32"
|
|
682
|
-
|
|
683
|
-
# Install mise for Ruby version management
|
|
684
|
-
if ! install_mise_runtime; then
|
|
685
|
-
return 1
|
|
686
|
-
fi
|
|
687
|
-
|
|
688
|
-
if ! install_ruby_via_mise; then
|
|
689
|
-
return 1
|
|
690
|
-
fi
|
|
691
|
-
|
|
692
|
-
# Verify Ruby installation
|
|
693
|
-
if check_ruby; then
|
|
694
|
-
return 0
|
|
695
|
-
else
|
|
696
|
-
print_error "Ruby installation verification failed"
|
|
697
|
-
return 1
|
|
698
|
-
fi
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
# Suggest Ruby installation
|
|
702
|
-
# Parse command-line arguments.
|
|
703
|
-
#
|
|
704
|
-
# Supported flags:
|
|
705
|
-
# --brand-name=VALUE Human-readable brand name (e.g. "JohnAI")
|
|
706
|
-
# --command=VALUE CLI command to install as a wrapper (e.g. "johncli")
|
|
707
|
-
#
|
|
708
|
-
# Usage from install command:
|
|
709
|
-
# /bin/bash -c "$(curl -sSL .../install.sh)" -- --brand-name="JohnAI" --command="johncli"
|
|
710
|
-
#
|
|
711
|
-
# Note: bash -c passes positional args starting at $0, so real flags are in $@
|
|
712
|
-
# when invoked with the `--` separator; they land in $1..$N of the script.
|
|
713
|
-
parse_args() {
|
|
714
|
-
for arg in "$0" "$@"; do
|
|
715
|
-
case "$arg" in
|
|
716
|
-
--brand-name=*)
|
|
717
|
-
BRAND_NAME="${arg#--brand-name=}"
|
|
718
|
-
;;
|
|
719
|
-
--command=*)
|
|
720
|
-
BRAND_COMMAND="${arg#--command=}"
|
|
721
|
-
;;
|
|
722
|
-
--restore-mirrors)
|
|
723
|
-
RESTORE_MIRRORS=true
|
|
724
|
-
;;
|
|
725
|
-
esac
|
|
726
|
-
done
|
|
727
|
-
# Global display name: brand name if provided, otherwise fall back to OpenClacky
|
|
728
|
-
DISPLAY_NAME="${BRAND_NAME:-OpenClacky}"
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
# Write brand configuration and install the wrapper command.
|
|
732
|
-
#
|
|
733
|
-
# Creates ~/.clacky/brand.yml with brand metadata and, if a custom command
|
|
734
|
-
# name was requested, installs a thin wrapper script at ~/.local/bin/<command>
|
|
735
|
-
# that simply delegates to openclacky.
|
|
736
|
-
setup_brand() {
|
|
737
|
-
[ -z "$BRAND_NAME" ] && return 0
|
|
738
|
-
|
|
739
|
-
local clacky_dir="$HOME/.clacky"
|
|
740
|
-
local brand_file="$clacky_dir/brand.yml"
|
|
741
|
-
mkdir -p "$clacky_dir"
|
|
742
|
-
|
|
743
|
-
print_step "Configuring brand: $BRAND_NAME"
|
|
744
|
-
|
|
745
|
-
# Write brand.yml — minimal entry; license_key is filled in later via
|
|
746
|
-
# the CLI or WebUI activation flow.
|
|
747
|
-
cat > "$brand_file" <<YAML
|
|
748
|
-
product_name: "${BRAND_NAME}"
|
|
749
|
-
package_name: "${BRAND_COMMAND}"
|
|
750
|
-
YAML
|
|
751
|
-
|
|
752
|
-
print_success "Brand configuration written to $brand_file"
|
|
753
|
-
|
|
754
|
-
# Install wrapper command if a custom command name was provided.
|
|
755
|
-
if [ -n "$BRAND_COMMAND" ]; then
|
|
756
|
-
local bin_dir="$HOME/.local/bin"
|
|
757
|
-
mkdir -p "$bin_dir"
|
|
758
|
-
|
|
759
|
-
local wrapper="$bin_dir/$BRAND_COMMAND"
|
|
760
|
-
cat > "$wrapper" <<WRAPPER
|
|
761
|
-
#!/bin/sh
|
|
762
|
-
exec openclacky "\$@"
|
|
763
|
-
WRAPPER
|
|
764
|
-
chmod +x "$wrapper"
|
|
765
|
-
print_success "Wrapper command installed: $wrapper"
|
|
766
|
-
|
|
767
|
-
# Remind user to add ~/.local/bin to PATH if needed.
|
|
768
|
-
case ":$PATH:" in
|
|
769
|
-
*":$bin_dir:"*) ;;
|
|
770
|
-
*)
|
|
771
|
-
print_warning "Add the following to your shell profile so '$BRAND_COMMAND' is available:"
|
|
772
|
-
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
|
|
773
|
-
;;
|
|
774
|
-
esac
|
|
775
|
-
fi
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
# Main installation logic
|
|
779
|
-
main() {
|
|
780
|
-
parse_args "$@"
|
|
781
|
-
|
|
782
|
-
# --restore-mirrors: undo CN mirror config and exit
|
|
783
|
-
if [ "${RESTORE_MIRRORS:-false}" = true ]; then
|
|
784
|
-
restore_mirrors
|
|
785
|
-
exit 0
|
|
786
|
-
fi
|
|
787
|
-
|
|
788
|
-
echo ""
|
|
789
|
-
echo "${DISPLAY_NAME} Installation"
|
|
790
|
-
echo ""
|
|
791
|
-
|
|
792
|
-
detect_os
|
|
793
|
-
detect_shell
|
|
794
|
-
detect_network_region
|
|
795
|
-
configure_cn_mirrors
|
|
796
|
-
|
|
797
|
-
# Install dependencies and Ruby (always run, handles already-installed gracefully)
|
|
798
|
-
if [ "$OS" = "macOS" ]; then
|
|
799
|
-
if ! install_macos_dependencies; then
|
|
800
|
-
print_error "Failed to install dependencies"
|
|
801
|
-
exit 1
|
|
802
|
-
fi
|
|
803
|
-
elif [ "$OS" = "Linux" ]; then
|
|
804
|
-
if [ "$DISTRO" = "ubuntu" ] || [ "$DISTRO" = "debian" ]; then
|
|
805
|
-
if ! install_ubuntu_dependencies; then
|
|
806
|
-
print_error "Failed to install dependencies"
|
|
807
|
-
exit 1
|
|
808
|
-
fi
|
|
809
|
-
else
|
|
810
|
-
print_error "Unsupported Linux distribution: $DISTRO"
|
|
811
|
-
print_info "Please install Ruby manually and run: gem install openclacky"
|
|
812
|
-
exit 1
|
|
813
|
-
fi
|
|
814
|
-
else
|
|
815
|
-
print_error "Unsupported OS: $OS"
|
|
816
|
-
print_info "Please install Ruby manually and run: gem install openclacky"
|
|
817
|
-
exit 1
|
|
818
|
-
fi
|
|
819
|
-
|
|
820
|
-
# Install via gem
|
|
821
|
-
if install_via_gem; then
|
|
822
|
-
setup_brand
|
|
823
|
-
show_post_install_info
|
|
824
|
-
exit 0
|
|
825
|
-
else
|
|
826
|
-
print_error "Failed to install ${DISPLAY_NAME}"
|
|
827
|
-
exit 1
|
|
828
|
-
fi
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
# Install agent-browser (browser automation tool)
|
|
832
|
-
# This step is optional — failures are silently skipped with a hint.
|
|
833
|
-
install_chrome_devtools_mcp() {
|
|
834
|
-
print_step "Installing chrome-devtools-mcp..."
|
|
835
|
-
|
|
836
|
-
if ! command_exists npm; then
|
|
837
|
-
local mise_bin=""
|
|
838
|
-
if command_exists mise; then
|
|
839
|
-
mise_bin="mise"
|
|
840
|
-
elif [ -x "$HOME/.local/bin/mise" ]; then
|
|
841
|
-
mise_bin="$HOME/.local/bin/mise"
|
|
842
|
-
fi
|
|
843
|
-
|
|
844
|
-
if [ -n "$mise_bin" ]; then
|
|
845
|
-
print_info "Installing Node.js via mise..."
|
|
846
|
-
"$mise_bin" install node@22 > /dev/null 2>&1 || true
|
|
847
|
-
"$mise_bin" use -g node@22 > /dev/null 2>&1 || true
|
|
848
|
-
eval "$("$mise_bin" activate bash 2>/dev/null)" 2>/dev/null || true
|
|
849
|
-
fi
|
|
850
|
-
else
|
|
851
|
-
print_success "Node.js already installed — $(node --version 2>/dev/null)"
|
|
852
|
-
fi
|
|
853
|
-
|
|
854
|
-
if ! command_exists npm; then
|
|
855
|
-
print_warning "Node.js/npm not found. Browser automation will not be available."
|
|
856
|
-
print_info "To enable browser support, install Node.js and run: npm install -g chrome-devtools-mcp"
|
|
857
|
-
return 0
|
|
858
|
-
fi
|
|
859
|
-
|
|
860
|
-
if npm install -g chrome-devtools-mcp > /dev/null 2>&1; then
|
|
861
|
-
print_success "chrome-devtools-mcp installed"
|
|
862
|
-
else
|
|
863
|
-
print_warning "chrome-devtools-mcp installation failed. Browser automation may not work."
|
|
864
|
-
print_info "To install manually: npm install -g chrome-devtools-mcp"
|
|
865
|
-
fi
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
# Post-installation information
|
|
869
|
-
show_post_install_info() {
|
|
870
|
-
local cmd="${BRAND_COMMAND:-openclacky}"
|
|
871
|
-
|
|
872
|
-
echo ""
|
|
873
|
-
echo -e " ${GREEN}${DISPLAY_NAME} installed successfully!${NC}"
|
|
874
|
-
echo ""
|
|
875
|
-
echo " First, reload your shell environment:"
|
|
876
|
-
echo ""
|
|
877
|
-
echo -e " ${YELLOW}source ${SHELL_RC}${NC}"
|
|
878
|
-
echo ""
|
|
879
|
-
echo " Then pick how you want to start:"
|
|
880
|
-
echo ""
|
|
881
|
-
echo -e " ${GREEN}Web UI${NC} (recommended):"
|
|
882
|
-
echo " $cmd server"
|
|
883
|
-
echo " Open http://localhost:7070 in your browser"
|
|
884
|
-
echo ""
|
|
885
|
-
echo -e " ${GREEN}Terminal mode${NC}:"
|
|
886
|
-
echo " $cmd"
|
|
887
|
-
echo ""
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
# Run main installation
|
|
891
|
-
main "$@"
|