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
|
@@ -0,0 +1,582 @@
|
|
|
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_info() {
|
|
19
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
print_success() {
|
|
23
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
print_warning() {
|
|
27
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
print_error() {
|
|
31
|
+
echo -e "${RED}✗${NC} $1"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
print_step() {
|
|
35
|
+
echo -e "\n${BLUE}==>${NC} $1"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Detect OS
|
|
39
|
+
detect_os() {
|
|
40
|
+
case "$(uname -s)" in
|
|
41
|
+
Linux*) OS=Linux;;
|
|
42
|
+
Darwin*) OS=macOS;;
|
|
43
|
+
CYGWIN*) OS=Windows;;
|
|
44
|
+
MINGW*) OS=Windows;;
|
|
45
|
+
*) OS=Unknown;;
|
|
46
|
+
esac
|
|
47
|
+
print_info "Detected OS: $OS"
|
|
48
|
+
|
|
49
|
+
if [ "$OS" = "Linux" ]; then
|
|
50
|
+
if [ -f /etc/os-release ]; then
|
|
51
|
+
. /etc/os-release
|
|
52
|
+
DISTRO=$ID
|
|
53
|
+
print_info "Detected Linux distribution: $DISTRO"
|
|
54
|
+
else
|
|
55
|
+
DISTRO=unknown
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Check if command exists
|
|
61
|
+
command_exists() {
|
|
62
|
+
command -v "$1" >/dev/null 2>&1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Detect current shell type
|
|
66
|
+
detect_shell() {
|
|
67
|
+
local shell_name
|
|
68
|
+
shell_name=$(basename "$SHELL")
|
|
69
|
+
|
|
70
|
+
case "$shell_name" in
|
|
71
|
+
zsh)
|
|
72
|
+
CURRENT_SHELL="zsh"
|
|
73
|
+
SHELL_RC="$HOME/.zshrc"
|
|
74
|
+
;;
|
|
75
|
+
bash)
|
|
76
|
+
CURRENT_SHELL="bash"
|
|
77
|
+
if [ "$OS" = "macOS" ]; then
|
|
78
|
+
SHELL_RC="$HOME/.bash_profile"
|
|
79
|
+
else
|
|
80
|
+
SHELL_RC="$HOME/.bashrc"
|
|
81
|
+
fi
|
|
82
|
+
;;
|
|
83
|
+
fish)
|
|
84
|
+
CURRENT_SHELL="fish"
|
|
85
|
+
SHELL_RC="$HOME/.config/fish/config.fish"
|
|
86
|
+
;;
|
|
87
|
+
*)
|
|
88
|
+
CURRENT_SHELL="bash"
|
|
89
|
+
SHELL_RC="$HOME/.bashrc"
|
|
90
|
+
;;
|
|
91
|
+
esac
|
|
92
|
+
|
|
93
|
+
print_info "Detected shell: $CURRENT_SHELL (rc file: $SHELL_RC)"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# --------------------------------------------------------------------------
|
|
97
|
+
# Network region detection & mirror selection
|
|
98
|
+
# --------------------------------------------------------------------------
|
|
99
|
+
SLOW_THRESHOLD_MS=5000
|
|
100
|
+
NETWORK_REGION="global"
|
|
101
|
+
USE_CN_MIRRORS=false
|
|
102
|
+
|
|
103
|
+
GITHUB_RAW_BASE_URL="https://raw.githubusercontent.com"
|
|
104
|
+
DEFAULT_RUBYGEMS_URL="https://rubygems.org"
|
|
105
|
+
DEFAULT_MISE_INSTALL_URL="https://mise.run"
|
|
106
|
+
|
|
107
|
+
CN_CDN_BASE_URL="https://oss.1024code.com"
|
|
108
|
+
CN_MISE_INSTALL_URL="${CN_CDN_BASE_URL}/mise.sh"
|
|
109
|
+
CN_RUBY_PRECOMPILED_URL="${CN_CDN_BASE_URL}/ruby/ruby-{version}.{platform}.tar.gz"
|
|
110
|
+
CN_RUBYGEMS_URL="https://mirrors.aliyun.com/rubygems/"
|
|
111
|
+
|
|
112
|
+
# Active values (overridden by detect_network_region)
|
|
113
|
+
MISE_INSTALL_URL="$DEFAULT_MISE_INSTALL_URL"
|
|
114
|
+
RUBYGEMS_INSTALL_URL="$DEFAULT_RUBYGEMS_URL"
|
|
115
|
+
RUBY_VERSION_SPEC="ruby@3" # mise will pick latest stable
|
|
116
|
+
|
|
117
|
+
_probe_url() {
|
|
118
|
+
local url="$1"
|
|
119
|
+
local timeout_sec=5
|
|
120
|
+
local curl_output http_code total_time elapsed_ms
|
|
121
|
+
|
|
122
|
+
curl_output=$(curl -s -o /dev/null -w "%{http_code} %{time_total}" \
|
|
123
|
+
--connect-timeout "$timeout_sec" \
|
|
124
|
+
--max-time "$timeout_sec" \
|
|
125
|
+
"$url" 2>/dev/null) || true
|
|
126
|
+
http_code="${curl_output%% *}"
|
|
127
|
+
total_time="${curl_output#* }"
|
|
128
|
+
|
|
129
|
+
if [ -z "$http_code" ] || [ "$http_code" = "000" ] || [ "$http_code" = "$curl_output" ]; then
|
|
130
|
+
echo "timeout"
|
|
131
|
+
else
|
|
132
|
+
elapsed_ms=$(awk -v seconds="$total_time" 'BEGIN { printf "%d", seconds * 1000 }')
|
|
133
|
+
echo "$elapsed_ms"
|
|
134
|
+
fi
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_is_slow_or_unreachable() {
|
|
138
|
+
local result="$1"
|
|
139
|
+
if [ "$result" = "timeout" ]; then
|
|
140
|
+
return 0
|
|
141
|
+
fi
|
|
142
|
+
[ "$result" -ge "$SLOW_THRESHOLD_MS" ] 2>/dev/null
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_format_probe_time() {
|
|
146
|
+
local result="$1"
|
|
147
|
+
if [ "$result" = "timeout" ]; then
|
|
148
|
+
echo "timeout"
|
|
149
|
+
else
|
|
150
|
+
awk -v ms="$result" 'BEGIN { printf "%.1fs", ms / 1000 }'
|
|
151
|
+
fi
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
_print_probe_result() {
|
|
155
|
+
local label="$1"
|
|
156
|
+
local result="$2"
|
|
157
|
+
|
|
158
|
+
if [ "$result" = "timeout" ]; then
|
|
159
|
+
print_warning "UNREACHABLE ${label}"
|
|
160
|
+
elif _is_slow_or_unreachable "$result"; then
|
|
161
|
+
print_warning "SLOW ($(_format_probe_time "$result")) ${label}"
|
|
162
|
+
else
|
|
163
|
+
print_success "OK ($(_format_probe_time "$result")) ${label}"
|
|
164
|
+
fi
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
_probe_url_with_retry() {
|
|
168
|
+
local url="$1"
|
|
169
|
+
local max_retries="${2:-2}"
|
|
170
|
+
local result
|
|
171
|
+
|
|
172
|
+
for _ in $(seq 1 "$max_retries"); do
|
|
173
|
+
result=$(_probe_url "$url")
|
|
174
|
+
if ! _is_slow_or_unreachable "$result"; then
|
|
175
|
+
echo "$result"
|
|
176
|
+
return 0
|
|
177
|
+
fi
|
|
178
|
+
done
|
|
179
|
+
echo "$result"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
detect_network_region() {
|
|
183
|
+
print_step "Network pre-flight check..."
|
|
184
|
+
echo ""
|
|
185
|
+
|
|
186
|
+
print_info "Detecting network region..."
|
|
187
|
+
local google_result baidu_result
|
|
188
|
+
google_result=$(_probe_url "https://www.google.com")
|
|
189
|
+
baidu_result=$(_probe_url "https://www.baidu.com")
|
|
190
|
+
|
|
191
|
+
_print_probe_result "google.com" "$google_result"
|
|
192
|
+
_print_probe_result "baidu.com" "$baidu_result"
|
|
193
|
+
|
|
194
|
+
local google_ok=false baidu_ok=false
|
|
195
|
+
! _is_slow_or_unreachable "$google_result" && google_ok=true
|
|
196
|
+
! _is_slow_or_unreachable "$baidu_result" && baidu_ok=true
|
|
197
|
+
|
|
198
|
+
if [ "$google_ok" = true ]; then
|
|
199
|
+
NETWORK_REGION="global"
|
|
200
|
+
print_success "Region: global"
|
|
201
|
+
elif [ "$baidu_ok" = true ]; then
|
|
202
|
+
NETWORK_REGION="china"
|
|
203
|
+
print_success "Region: china"
|
|
204
|
+
else
|
|
205
|
+
NETWORK_REGION="unknown"
|
|
206
|
+
print_warning "Region: unknown (both unreachable)"
|
|
207
|
+
fi
|
|
208
|
+
echo ""
|
|
209
|
+
|
|
210
|
+
if [ "$NETWORK_REGION" = "china" ]; then
|
|
211
|
+
local cdn_result mirror_result
|
|
212
|
+
cdn_result=$(_probe_url_with_retry "$CN_MISE_INSTALL_URL")
|
|
213
|
+
mirror_result=$(_probe_url_with_retry "$CN_RUBYGEMS_URL")
|
|
214
|
+
|
|
215
|
+
_print_probe_result "CN CDN (mise/Ruby)" "$cdn_result"
|
|
216
|
+
_print_probe_result "Aliyun (gem)" "$mirror_result"
|
|
217
|
+
|
|
218
|
+
local cdn_ok=false mirror_ok=false
|
|
219
|
+
! _is_slow_or_unreachable "$cdn_result" && cdn_ok=true
|
|
220
|
+
! _is_slow_or_unreachable "$mirror_result" && mirror_ok=true
|
|
221
|
+
|
|
222
|
+
if [ "$cdn_ok" = true ] || [ "$mirror_ok" = true ]; then
|
|
223
|
+
USE_CN_MIRRORS=true
|
|
224
|
+
MISE_INSTALL_URL="$CN_MISE_INSTALL_URL"
|
|
225
|
+
RUBYGEMS_INSTALL_URL="$CN_RUBYGEMS_URL"
|
|
226
|
+
RUBY_VERSION_SPEC="ruby@3.4.8"
|
|
227
|
+
print_info "CN mirrors applied."
|
|
228
|
+
else
|
|
229
|
+
print_warning "CN mirrors unreachable — falling back to global sources."
|
|
230
|
+
fi
|
|
231
|
+
else
|
|
232
|
+
local rubygems_result mise_result
|
|
233
|
+
rubygems_result=$(_probe_url_with_retry "$DEFAULT_RUBYGEMS_URL")
|
|
234
|
+
mise_result=$(_probe_url_with_retry "$DEFAULT_MISE_INSTALL_URL")
|
|
235
|
+
|
|
236
|
+
_print_probe_result "RubyGems" "$rubygems_result"
|
|
237
|
+
_print_probe_result "mise.run" "$mise_result"
|
|
238
|
+
|
|
239
|
+
_is_slow_or_unreachable "$rubygems_result" && print_warning "RubyGems is slow/unreachable."
|
|
240
|
+
_is_slow_or_unreachable "$mise_result" && print_warning "mise.run is slow/unreachable."
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
echo ""
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
# --------------------------------------------------------------------------
|
|
247
|
+
# Version comparison
|
|
248
|
+
# --------------------------------------------------------------------------
|
|
249
|
+
version_ge() {
|
|
250
|
+
printf '%s\n%s\n' "$2" "$1" | sort -V -C
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# --------------------------------------------------------------------------
|
|
254
|
+
# Ruby check (>= 2.6.0)
|
|
255
|
+
# --------------------------------------------------------------------------
|
|
256
|
+
check_ruby() {
|
|
257
|
+
if command_exists ruby; then
|
|
258
|
+
RUBY_VERSION=$(ruby -e 'puts RUBY_VERSION' 2>/dev/null)
|
|
259
|
+
print_info "Found Ruby $RUBY_VERSION"
|
|
260
|
+
|
|
261
|
+
if version_ge "$RUBY_VERSION" "2.6.0"; then
|
|
262
|
+
print_success "Ruby $RUBY_VERSION is compatible (>= 2.6.0)"
|
|
263
|
+
return 0
|
|
264
|
+
else
|
|
265
|
+
print_warning "Ruby $RUBY_VERSION is too old (need >= 2.6.0)"
|
|
266
|
+
return 1
|
|
267
|
+
fi
|
|
268
|
+
else
|
|
269
|
+
print_warning "Ruby not found"
|
|
270
|
+
return 1
|
|
271
|
+
fi
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# --------------------------------------------------------------------------
|
|
275
|
+
# Configure gem source (CN mirror if needed)
|
|
276
|
+
# --------------------------------------------------------------------------
|
|
277
|
+
configure_gem_source() {
|
|
278
|
+
[ "$USE_CN_MIRRORS" = true ] || return 0
|
|
279
|
+
|
|
280
|
+
local gemrc="$HOME/.gemrc"
|
|
281
|
+
if [ -f "$gemrc" ] && grep -q "${CN_RUBYGEMS_URL}" "$gemrc" 2>/dev/null; then
|
|
282
|
+
print_success "gem source already → ${CN_RUBYGEMS_URL}"
|
|
283
|
+
else
|
|
284
|
+
[ -f "$gemrc" ] && mv "$gemrc" "$HOME/.gemrc_clackybak"
|
|
285
|
+
cat > "$gemrc" <<GEMRC
|
|
286
|
+
:sources:
|
|
287
|
+
- ${CN_RUBYGEMS_URL}
|
|
288
|
+
GEMRC
|
|
289
|
+
print_success "gem source → ${CN_RUBYGEMS_URL}"
|
|
290
|
+
fi
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# --------------------------------------------------------------------------
|
|
294
|
+
# mise: install (if missing) and optionally activate
|
|
295
|
+
# --------------------------------------------------------------------------
|
|
296
|
+
install_mise() {
|
|
297
|
+
if ! command_exists mise && [ ! -x "$HOME/.local/bin/mise" ]; then
|
|
298
|
+
print_info "Installing mise..."
|
|
299
|
+
if curl -fsSL "$MISE_INSTALL_URL" | sh; then
|
|
300
|
+
# Add mise activation to shell rc
|
|
301
|
+
local mise_init_line='eval "$(~/.local/bin/mise activate '"$CURRENT_SHELL"')"'
|
|
302
|
+
if [ -f "$SHELL_RC" ]; then
|
|
303
|
+
echo "$mise_init_line" >> "$SHELL_RC"
|
|
304
|
+
else
|
|
305
|
+
echo "$mise_init_line" > "$SHELL_RC"
|
|
306
|
+
fi
|
|
307
|
+
print_info "Added mise activation to $SHELL_RC"
|
|
308
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
309
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
310
|
+
print_success "mise installed"
|
|
311
|
+
else
|
|
312
|
+
print_error "Failed to install mise"
|
|
313
|
+
return 1
|
|
314
|
+
fi
|
|
315
|
+
else
|
|
316
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
317
|
+
eval "$(~/.local/bin/mise activate bash)" 2>/dev/null || true
|
|
318
|
+
print_success "mise already installed"
|
|
319
|
+
fi
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
# --------------------------------------------------------------------------
|
|
323
|
+
# Install Ruby via mise (precompiled when CN mirrors active)
|
|
324
|
+
# --------------------------------------------------------------------------
|
|
325
|
+
install_ruby_via_mise() {
|
|
326
|
+
print_info "Installing Ruby via mise ($RUBY_VERSION_SPEC)..."
|
|
327
|
+
|
|
328
|
+
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
329
|
+
~/.local/bin/mise settings ruby.compile=false
|
|
330
|
+
~/.local/bin/mise settings ruby.precompiled_url="$CN_RUBY_PRECOMPILED_URL"
|
|
331
|
+
print_info "Using precompiled Ruby from CN CDN"
|
|
332
|
+
else
|
|
333
|
+
~/.local/bin/mise settings unset ruby.compile >/dev/null 2>&1 || true
|
|
334
|
+
~/.local/bin/mise settings unset ruby.precompiled_url >/dev/null 2>&1 || true
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
if ~/.local/bin/mise use -g "$RUBY_VERSION_SPEC"; then
|
|
338
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
339
|
+
print_success "Ruby installed via mise"
|
|
340
|
+
else
|
|
341
|
+
print_error "Failed to install Ruby via mise"
|
|
342
|
+
return 1
|
|
343
|
+
fi
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
# --------------------------------------------------------------------------
|
|
347
|
+
# Ensure Ruby >= 2.6 is available (install if needed)
|
|
348
|
+
# --------------------------------------------------------------------------
|
|
349
|
+
ensure_ruby() {
|
|
350
|
+
print_step "Checking Ruby..."
|
|
351
|
+
|
|
352
|
+
if check_ruby; then
|
|
353
|
+
return 0
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
# No suitable Ruby — install via mise
|
|
357
|
+
print_step "Installing Ruby via mise..."
|
|
358
|
+
detect_shell
|
|
359
|
+
|
|
360
|
+
if ! install_mise; then
|
|
361
|
+
return 1
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
if ! install_ruby_via_mise; then
|
|
365
|
+
return 1
|
|
366
|
+
fi
|
|
367
|
+
|
|
368
|
+
# Verify
|
|
369
|
+
if check_ruby; then
|
|
370
|
+
return 0
|
|
371
|
+
else
|
|
372
|
+
print_error "Ruby installation verification failed"
|
|
373
|
+
return 1
|
|
374
|
+
fi
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
# --------------------------------------------------------------------------
|
|
378
|
+
# Linux: install build deps before mise/Ruby (compile fallback)
|
|
379
|
+
# --------------------------------------------------------------------------
|
|
380
|
+
install_linux_build_deps() {
|
|
381
|
+
if [ "$DISTRO" = "ubuntu" ] || [ "$DISTRO" = "debian" ]; then
|
|
382
|
+
print_step "Installing build dependencies..."
|
|
383
|
+
|
|
384
|
+
if [ "$USE_CN_MIRRORS" = true ]; then
|
|
385
|
+
print_info "Configuring apt mirror (Aliyun)..."
|
|
386
|
+
local codename="${VERSION_CODENAME:-jammy}"
|
|
387
|
+
local mirror_base="https://mirrors.aliyun.com/ubuntu/"
|
|
388
|
+
local components="main restricted universe multiverse"
|
|
389
|
+
sudo tee /etc/apt/sources.list > /dev/null <<EOF
|
|
390
|
+
deb ${mirror_base} ${codename} ${components}
|
|
391
|
+
deb ${mirror_base} ${codename}-updates ${components}
|
|
392
|
+
deb ${mirror_base} ${codename}-backports ${components}
|
|
393
|
+
deb ${mirror_base} ${codename}-security ${components}
|
|
394
|
+
EOF
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
sudo apt update
|
|
398
|
+
sudo apt install -y build-essential libssl-dev libyaml-dev zlib1g-dev libgmp-dev git
|
|
399
|
+
print_success "Build dependencies installed"
|
|
400
|
+
fi
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
# --------------------------------------------------------------------------
|
|
404
|
+
# Set GEM_HOME to user directory when system Ruby gem dir is not writable
|
|
405
|
+
# (avoids needing sudo for gem install)
|
|
406
|
+
# --------------------------------------------------------------------------
|
|
407
|
+
setup_gem_home() {
|
|
408
|
+
local gem_dir
|
|
409
|
+
gem_dir=$(gem environment gemdir 2>/dev/null || true)
|
|
410
|
+
|
|
411
|
+
# Gem dir is writable (e.g. mise-managed Ruby) — nothing to do
|
|
412
|
+
if [ -w "$gem_dir" ]; then
|
|
413
|
+
return 0
|
|
414
|
+
fi
|
|
415
|
+
|
|
416
|
+
# System Ruby: redirect gems to ~/.gem/ruby/<api_version>
|
|
417
|
+
local ruby_api
|
|
418
|
+
ruby_api=$(ruby -e 'puts RbConfig::CONFIG["ruby_version"]' 2>/dev/null)
|
|
419
|
+
|
|
420
|
+
export GEM_HOME="$HOME/.gem/ruby/${ruby_api}"
|
|
421
|
+
export GEM_PATH="$HOME/.gem/ruby/${ruby_api}"
|
|
422
|
+
export PATH="$HOME/.gem/ruby/${ruby_api}/bin:$PATH"
|
|
423
|
+
|
|
424
|
+
print_info "System Ruby detected — gems will install to ~/.gem/ruby/${ruby_api}"
|
|
425
|
+
|
|
426
|
+
# Persist to shell rc (use $HOME so the line is portable)
|
|
427
|
+
if [ -n "$SHELL_RC" ] && ! grep -q "GEM_HOME" "$SHELL_RC" 2>/dev/null; then
|
|
428
|
+
{
|
|
429
|
+
echo ""
|
|
430
|
+
echo "# Ruby user gem dir (added by openclacky installer)"
|
|
431
|
+
echo "export GEM_HOME=\"\$HOME/.gem/ruby/${ruby_api}\""
|
|
432
|
+
echo "export GEM_PATH=\"\$HOME/.gem/ruby/${ruby_api}\""
|
|
433
|
+
echo "export PATH=\"\$HOME/.gem/ruby/${ruby_api}/bin:\$PATH\""
|
|
434
|
+
} >> "$SHELL_RC"
|
|
435
|
+
print_info "GEM_HOME written to $SHELL_RC"
|
|
436
|
+
fi
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
# --------------------------------------------------------------------------
|
|
440
|
+
# gem install openclacky
|
|
441
|
+
# --------------------------------------------------------------------------
|
|
442
|
+
install_via_gem() {
|
|
443
|
+
print_step "Installing ${DISPLAY_NAME} via gem..."
|
|
444
|
+
|
|
445
|
+
configure_gem_source
|
|
446
|
+
setup_gem_home
|
|
447
|
+
|
|
448
|
+
gem install openclacky --no-document
|
|
449
|
+
|
|
450
|
+
if [ $? -eq 0 ]; then
|
|
451
|
+
print_success "${DISPLAY_NAME} installed successfully!"
|
|
452
|
+
return 0
|
|
453
|
+
else
|
|
454
|
+
print_error "gem install failed"
|
|
455
|
+
return 1
|
|
456
|
+
fi
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# --------------------------------------------------------------------------
|
|
460
|
+
# Parse CLI args
|
|
461
|
+
# --------------------------------------------------------------------------
|
|
462
|
+
parse_args() {
|
|
463
|
+
for arg in "$0" "$@"; do
|
|
464
|
+
case "$arg" in
|
|
465
|
+
--brand-name=*)
|
|
466
|
+
BRAND_NAME="${arg#--brand-name=}"
|
|
467
|
+
;;
|
|
468
|
+
--command=*)
|
|
469
|
+
BRAND_COMMAND="${arg#--command=}"
|
|
470
|
+
;;
|
|
471
|
+
esac
|
|
472
|
+
done
|
|
473
|
+
DISPLAY_NAME="${BRAND_NAME:-OpenClacky}"
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
# --------------------------------------------------------------------------
|
|
477
|
+
# Brand setup
|
|
478
|
+
# --------------------------------------------------------------------------
|
|
479
|
+
setup_brand() {
|
|
480
|
+
[ -z "$BRAND_NAME" ] && return 0
|
|
481
|
+
|
|
482
|
+
local clacky_dir="$HOME/.clacky"
|
|
483
|
+
local brand_file="$clacky_dir/brand.yml"
|
|
484
|
+
mkdir -p "$clacky_dir"
|
|
485
|
+
|
|
486
|
+
print_step "Configuring brand: $BRAND_NAME"
|
|
487
|
+
|
|
488
|
+
cat > "$brand_file" <<YAML
|
|
489
|
+
product_name: "${BRAND_NAME}"
|
|
490
|
+
package_name: "${BRAND_COMMAND}"
|
|
491
|
+
YAML
|
|
492
|
+
print_success "Brand config written to $brand_file"
|
|
493
|
+
|
|
494
|
+
if [ -n "$BRAND_COMMAND" ]; then
|
|
495
|
+
local bin_dir="$HOME/.local/bin"
|
|
496
|
+
mkdir -p "$bin_dir"
|
|
497
|
+
local wrapper="$bin_dir/$BRAND_COMMAND"
|
|
498
|
+
cat > "$wrapper" <<WRAPPER
|
|
499
|
+
#!/bin/sh
|
|
500
|
+
exec openclacky "\$@"
|
|
501
|
+
WRAPPER
|
|
502
|
+
chmod +x "$wrapper"
|
|
503
|
+
print_success "Wrapper installed: $wrapper"
|
|
504
|
+
|
|
505
|
+
case ":$PATH:" in
|
|
506
|
+
*":$bin_dir:"*) ;;
|
|
507
|
+
*)
|
|
508
|
+
print_warning "Add to your shell profile: export PATH=\"\$HOME/.local/bin:\$PATH\""
|
|
509
|
+
;;
|
|
510
|
+
esac
|
|
511
|
+
fi
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
# --------------------------------------------------------------------------
|
|
515
|
+
# Post-install info
|
|
516
|
+
# --------------------------------------------------------------------------
|
|
517
|
+
show_post_install_info() {
|
|
518
|
+
local cmd="${BRAND_COMMAND:-openclacky}"
|
|
519
|
+
|
|
520
|
+
echo ""
|
|
521
|
+
echo -e " ${GREEN}${DISPLAY_NAME} installed successfully!${NC}"
|
|
522
|
+
echo ""
|
|
523
|
+
echo " Reload your shell:"
|
|
524
|
+
echo ""
|
|
525
|
+
echo -e " ${YELLOW}source ${SHELL_RC}${NC}"
|
|
526
|
+
echo ""
|
|
527
|
+
echo -e " ${GREEN}Web UI${NC} (recommended):"
|
|
528
|
+
echo " $cmd server"
|
|
529
|
+
echo " Open http://localhost:7070"
|
|
530
|
+
echo ""
|
|
531
|
+
echo -e " ${GREEN}Terminal${NC}:"
|
|
532
|
+
echo " $cmd"
|
|
533
|
+
echo ""
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
# --------------------------------------------------------------------------
|
|
537
|
+
# Main
|
|
538
|
+
# --------------------------------------------------------------------------
|
|
539
|
+
main() {
|
|
540
|
+
parse_args "$@"
|
|
541
|
+
|
|
542
|
+
echo ""
|
|
543
|
+
echo "${DISPLAY_NAME} Installation"
|
|
544
|
+
echo ""
|
|
545
|
+
|
|
546
|
+
detect_os
|
|
547
|
+
detect_shell
|
|
548
|
+
detect_network_region
|
|
549
|
+
|
|
550
|
+
# Linux: install build deps first (needed if mise has to compile Ruby)
|
|
551
|
+
if [ "$OS" = "Linux" ]; then
|
|
552
|
+
if [ "$DISTRO" = "ubuntu" ] || [ "$DISTRO" = "debian" ]; then
|
|
553
|
+
install_linux_build_deps
|
|
554
|
+
else
|
|
555
|
+
print_error "Unsupported Linux distribution: $DISTRO"
|
|
556
|
+
print_info "Please install Ruby >= 2.6.0 manually and run: gem install openclacky"
|
|
557
|
+
exit 1
|
|
558
|
+
fi
|
|
559
|
+
# WSL: auto-trust Windows system32 to suppress mise warnings
|
|
560
|
+
export MISE_TRUSTED_CONFIG_PATHS="/mnt/c/Windows/system32"
|
|
561
|
+
elif [ "$OS" != "macOS" ]; then
|
|
562
|
+
print_error "Unsupported OS: $OS"
|
|
563
|
+
print_info "Please install Ruby >= 2.6.0 manually and run: gem install openclacky"
|
|
564
|
+
exit 1
|
|
565
|
+
fi
|
|
566
|
+
|
|
567
|
+
if ! ensure_ruby; then
|
|
568
|
+
print_error "Could not install a compatible Ruby"
|
|
569
|
+
exit 1
|
|
570
|
+
fi
|
|
571
|
+
|
|
572
|
+
if install_via_gem; then
|
|
573
|
+
setup_brand
|
|
574
|
+
show_post_install_info
|
|
575
|
+
exit 0
|
|
576
|
+
else
|
|
577
|
+
print_error "Failed to install ${DISPLAY_NAME}"
|
|
578
|
+
exit 1
|
|
579
|
+
fi
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
main "$@"
|
metadata
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openclacky
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- windy
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: faraday
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
18
|
version: '2.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '2.9'
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
24
|
-
- - "
|
|
26
|
+
- - ">="
|
|
25
27
|
- !ruby/object:Gem::Version
|
|
26
28
|
version: '2.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '2.9'
|
|
27
32
|
- !ruby/object:Gem::Dependency
|
|
28
33
|
name: faraday-multipart
|
|
29
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -151,19 +156,19 @@ dependencies:
|
|
|
151
156
|
- !ruby/object:Gem::Version
|
|
152
157
|
version: 0.1.0
|
|
153
158
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name: websocket
|
|
159
|
+
name: websocket
|
|
155
160
|
requirement: !ruby/object:Gem::Requirement
|
|
156
161
|
requirements:
|
|
157
162
|
- - "~>"
|
|
158
163
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
164
|
+
version: '1.2'
|
|
160
165
|
type: :runtime
|
|
161
166
|
prerelease: false
|
|
162
167
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
168
|
requirements:
|
|
164
169
|
- - "~>"
|
|
165
170
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
171
|
+
version: '1.2'
|
|
167
172
|
- !ruby/object:Gem::Dependency
|
|
168
173
|
name: webrick
|
|
169
174
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -212,6 +217,26 @@ dependencies:
|
|
|
212
217
|
- - "<"
|
|
213
218
|
- !ruby/object:Gem::Version
|
|
214
219
|
version: '4'
|
|
220
|
+
- !ruby/object:Gem::Dependency
|
|
221
|
+
name: rouge
|
|
222
|
+
requirement: !ruby/object:Gem::Requirement
|
|
223
|
+
requirements:
|
|
224
|
+
- - ">="
|
|
225
|
+
- !ruby/object:Gem::Version
|
|
226
|
+
version: '3.14'
|
|
227
|
+
- - "<"
|
|
228
|
+
- !ruby/object:Gem::Version
|
|
229
|
+
version: '4.0'
|
|
230
|
+
type: :runtime
|
|
231
|
+
prerelease: false
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
requirements:
|
|
234
|
+
- - ">="
|
|
235
|
+
- !ruby/object:Gem::Version
|
|
236
|
+
version: '3.14'
|
|
237
|
+
- - "<"
|
|
238
|
+
- !ruby/object:Gem::Version
|
|
239
|
+
version: '4.0'
|
|
215
240
|
- !ruby/object:Gem::Dependency
|
|
216
241
|
name: chunky_png
|
|
217
242
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -233,8 +258,8 @@ email:
|
|
|
233
258
|
- yafei@dao42.com
|
|
234
259
|
executables:
|
|
235
260
|
- clacky
|
|
236
|
-
- openclacky
|
|
237
261
|
- clarky
|
|
262
|
+
- openclacky
|
|
238
263
|
extensions: []
|
|
239
264
|
extra_rdoc_files: []
|
|
240
265
|
files:
|
|
@@ -464,7 +489,7 @@ files:
|
|
|
464
489
|
- lib/clacky/web/ws.js
|
|
465
490
|
- scripts/install.ps1
|
|
466
491
|
- scripts/install.sh
|
|
467
|
-
- scripts/
|
|
492
|
+
- scripts/install_simple.sh
|
|
468
493
|
- scripts/uninstall.sh
|
|
469
494
|
- sig/clacky.rbs
|
|
470
495
|
homepage: https://github.com/yafeilee/clacky
|
|
@@ -474,7 +499,6 @@ metadata:
|
|
|
474
499
|
homepage_uri: https://github.com/yafeilee/clacky
|
|
475
500
|
source_code_uri: https://github.com/yafeilee/clacky
|
|
476
501
|
changelog_uri: https://github.com/yafeilee/clacky/blob/main/CHANGELOG.md
|
|
477
|
-
post_install_message:
|
|
478
502
|
rdoc_options: []
|
|
479
503
|
require_paths:
|
|
480
504
|
- lib
|
|
@@ -489,8 +513,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
489
513
|
- !ruby/object:Gem::Version
|
|
490
514
|
version: '0'
|
|
491
515
|
requirements: []
|
|
492
|
-
rubygems_version:
|
|
493
|
-
signing_key:
|
|
516
|
+
rubygems_version: 4.0.4
|
|
494
517
|
specification_version: 4
|
|
495
518
|
summary: A command-line interface for AI models (Claude, OpenAI, etc.)
|
|
496
519
|
test_files: []
|