openclacky 0.7.1 → 0.7.3
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 +83 -0
- data/README.md +70 -161
- data/bin/clarky +11 -0
- data/lib/clacky/agent.rb +10 -1
- data/lib/clacky/cli.rb +0 -4
- data/lib/clacky/default_skills/code-explorer/SKILL.md +11 -18
- data/lib/clacky/default_skills/new/SKILL.md +2 -2
- data/lib/clacky/providers.rb +109 -0
- data/lib/clacky/ui2/components/modal_component.rb +8 -6
- data/lib/clacky/ui2/ui_controller.rb +65 -14
- data/lib/clacky/utils/file_processor.rb +13 -18
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky.rb +1 -0
- data/scripts/install.sh +274 -97
- data/scripts/uninstall.sh +12 -12
- metadata +4 -2
- data/.clacky/skills/test-skill/SKILL.md +0 -15
|
@@ -894,11 +894,11 @@ module Clacky
|
|
|
894
894
|
|
|
895
895
|
# Handle submit action
|
|
896
896
|
private def handle_submit(data)
|
|
897
|
-
#
|
|
898
|
-
@input_callback&.call(data[:text], data[:images])
|
|
899
|
-
|
|
900
|
-
# Append the input content to output area after callback completes
|
|
897
|
+
# Append the input content to output area first (so it displays before callback execution)
|
|
901
898
|
@layout.append_output(data[:display]) unless data[:display].empty?
|
|
899
|
+
|
|
900
|
+
# Then call callback (allows interrupting previous agent before processing new input)
|
|
901
|
+
@input_callback&.call(data[:text], data[:images])
|
|
902
902
|
end
|
|
903
903
|
|
|
904
904
|
# Show configuration modal dialog with multi-model support
|
|
@@ -953,14 +953,23 @@ module Clacky
|
|
|
953
953
|
when :add
|
|
954
954
|
new_model = show_model_edit_form(nil, test_callback: test_callback)
|
|
955
955
|
if new_model
|
|
956
|
+
# Determine anthropic_format based on provider
|
|
957
|
+
# For Anthropic provider, use Anthropic API format
|
|
958
|
+
anthropic_format = new_model[:provider] == "anthropic"
|
|
959
|
+
|
|
956
960
|
current_config.add_model(
|
|
957
961
|
model: new_model[:model],
|
|
958
962
|
api_key: new_model[:api_key],
|
|
959
|
-
base_url: new_model[:base_url]
|
|
960
|
-
|
|
963
|
+
base_url: new_model[:base_url],
|
|
964
|
+
anthropic_format: anthropic_format
|
|
961
965
|
)
|
|
962
966
|
# Auto-save after adding
|
|
963
967
|
current_config.save
|
|
968
|
+
# Set newly added model as default
|
|
969
|
+
current_config.switch_model(current_config.models.length - 1)
|
|
970
|
+
current_config.save
|
|
971
|
+
# Return to exit the menu
|
|
972
|
+
return { action: :switch }
|
|
964
973
|
end
|
|
965
974
|
when :edit
|
|
966
975
|
current_model = current_config.current_model
|
|
@@ -1043,9 +1052,40 @@ module Clacky
|
|
|
1043
1052
|
is_new = model.nil?
|
|
1044
1053
|
model ||= {}
|
|
1045
1054
|
|
|
1055
|
+
# For new models, show provider selection first
|
|
1056
|
+
selected_provider = nil
|
|
1057
|
+
if is_new
|
|
1058
|
+
# Build provider choices
|
|
1059
|
+
provider_choices = Clacky::Providers.list.map do |id, name|
|
|
1060
|
+
{ name: name, value: id }
|
|
1061
|
+
end
|
|
1062
|
+
provider_choices << { name: "─" * 40, disabled: true }
|
|
1063
|
+
provider_choices << { name: "Custom (manual configuration)", value: "custom" }
|
|
1064
|
+
|
|
1065
|
+
# Show provider selection
|
|
1066
|
+
selected_provider = modal.show(
|
|
1067
|
+
title: "Select Provider",
|
|
1068
|
+
choices: provider_choices
|
|
1069
|
+
)
|
|
1070
|
+
|
|
1071
|
+
# User cancelled
|
|
1072
|
+
return nil if selected_provider.nil?
|
|
1073
|
+
end
|
|
1074
|
+
|
|
1046
1075
|
# Prepare masked API key for display
|
|
1047
1076
|
masked_key = mask_api_key(model["api_key"])
|
|
1048
1077
|
|
|
1078
|
+
# Pre-fill values from provider preset if selected
|
|
1079
|
+
provider_preset = nil
|
|
1080
|
+
if selected_provider && selected_provider != "custom"
|
|
1081
|
+
provider_preset = Clacky::Providers.get(selected_provider)
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
# Get default values from provider or existing model
|
|
1085
|
+
default_model = provider_preset ? provider_preset["default_model"] : model["model"]
|
|
1086
|
+
default_base_url = provider_preset ? provider_preset["base_url"] : model["base_url"]
|
|
1087
|
+
default_api_key = model["api_key"] || ""
|
|
1088
|
+
|
|
1049
1089
|
# Define fields
|
|
1050
1090
|
fields = [
|
|
1051
1091
|
{
|
|
@@ -1056,13 +1096,13 @@ module Clacky
|
|
|
1056
1096
|
},
|
|
1057
1097
|
{
|
|
1058
1098
|
name: :model,
|
|
1059
|
-
label: "Model #{is_new ? '' : "(current: #{model['model']})"}:",
|
|
1060
|
-
default: ""
|
|
1099
|
+
label: "Model #{is_new && default_model ? "(default: #{default_model})" : (is_new ? '' : "(current: #{model['model']})")}:",
|
|
1100
|
+
default: default_model || ""
|
|
1061
1101
|
},
|
|
1062
1102
|
{
|
|
1063
1103
|
name: :base_url,
|
|
1064
|
-
label: "Base URL #{is_new ? '' : "(current: #{model['base_url']})"}:",
|
|
1065
|
-
default: ""
|
|
1104
|
+
label: "Base URL #{is_new && default_base_url ? "(default: #{default_base_url})" : (is_new ? '' : "(current: #{model['base_url']})")}:",
|
|
1105
|
+
default: default_base_url || ""
|
|
1066
1106
|
}
|
|
1067
1107
|
]
|
|
1068
1108
|
|
|
@@ -1103,20 +1143,31 @@ module Clacky
|
|
|
1103
1143
|
nil
|
|
1104
1144
|
end
|
|
1105
1145
|
|
|
1146
|
+
# Determine modal title based on provider
|
|
1147
|
+
modal_title = if is_new && selected_provider && selected_provider != "custom"
|
|
1148
|
+
provider_name = Clacky::Providers.get(selected_provider)&.dig("name") || selected_provider
|
|
1149
|
+
"Add #{provider_name} Model"
|
|
1150
|
+
elsif is_new
|
|
1151
|
+
"Add Custom Model"
|
|
1152
|
+
else
|
|
1153
|
+
"Edit Model"
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1106
1156
|
# Show modal and collect values
|
|
1107
1157
|
result = modal.show(
|
|
1108
|
-
title:
|
|
1158
|
+
title: modal_title,
|
|
1109
1159
|
fields: fields,
|
|
1110
1160
|
validator: validator
|
|
1111
1161
|
)
|
|
1112
1162
|
|
|
1113
1163
|
return nil if result.nil?
|
|
1114
1164
|
|
|
1115
|
-
# Merge with existing model values
|
|
1165
|
+
# Merge with existing model values or provider defaults
|
|
1116
1166
|
{
|
|
1117
1167
|
api_key: result[:api_key].to_s.empty? ? model["api_key"] : result[:api_key],
|
|
1118
|
-
model: result[:model].to_s.empty? ? model["model"] : result[:model],
|
|
1119
|
-
base_url: result[:base_url].to_s.empty? ? model["base_url"] : result[:base_url]
|
|
1168
|
+
model: result[:model].to_s.empty? ? (model["model"] || default_model) : result[:model],
|
|
1169
|
+
base_url: result[:base_url].to_s.empty? ? (model["base_url"] || default_base_url) : result[:base_url],
|
|
1170
|
+
provider: selected_provider
|
|
1120
1171
|
}
|
|
1121
1172
|
end
|
|
1122
1173
|
|
|
@@ -166,35 +166,30 @@ module Clacky
|
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
# Check if file is binary (not text)
|
|
169
|
-
# @param data [String] File content
|
|
169
|
+
# @param data [String] File content (should be read in binary mode, encoding: ASCII-8BIT)
|
|
170
170
|
# @param sample_size [Integer] Number of bytes to check (default: 8192)
|
|
171
171
|
# @return [Boolean] True if file appears to be binary
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
#
|
|
173
|
+
# Strategy: only trust known magic byte signatures.
|
|
174
|
+
# We intentionally avoid heuristics (byte-ratio, UTF-8 validity, etc.) because
|
|
175
|
+
# they produce false positives on legitimate text files containing multibyte
|
|
176
|
+
# characters (e.g. Chinese, Japanese). Occasionally missing an unlabelled binary
|
|
177
|
+
# is acceptable; misclassifying a real text file is not.
|
|
178
|
+
def binary_file?(data, sample_size: 8192)
|
|
179
|
+
sample = data.b[0, sample_size] || ""
|
|
175
180
|
return false if sample.empty?
|
|
176
181
|
|
|
177
|
-
# Check for known binary signatures
|
|
182
|
+
# Check for known binary file signatures (magic bytes)
|
|
178
183
|
FILE_SIGNATURES.each do |signature, _format|
|
|
179
184
|
return true if sample.start_with?(signature)
|
|
180
185
|
end
|
|
181
186
|
|
|
182
|
-
# Check for WebP (RIFF
|
|
183
|
-
if sample.start_with?("RIFF".b) && sample.
|
|
187
|
+
# Check for WebP (RIFF....WEBP header)
|
|
188
|
+
if sample.start_with?("RIFF".b) && sample.bytesize >= 12 && sample[8..11] == "WEBP".b
|
|
184
189
|
return true
|
|
185
190
|
end
|
|
186
191
|
|
|
187
|
-
|
|
188
|
-
# This prevents short outputs from being incorrectly flagged as binary
|
|
189
|
-
return false if sample.size < min_binary_length
|
|
190
|
-
|
|
191
|
-
# Count non-printable characters (excluding common whitespace)
|
|
192
|
-
non_printable = sample.bytes.count do |byte|
|
|
193
|
-
byte < 32 && ![9, 10, 13].include?(byte) || byte >= 127
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
# If more than 30% non-printable, consider it binary
|
|
197
|
-
(non_printable.to_f / sample.size) > 0.3
|
|
192
|
+
false
|
|
198
193
|
end
|
|
199
194
|
|
|
200
195
|
# Check if a file at the given path is binary (not text)
|
data/lib/clacky/version.rb
CHANGED
data/lib/clacky.rb
CHANGED
data/scripts/install.sh
CHANGED
|
@@ -42,6 +42,17 @@ detect_os() {
|
|
|
42
42
|
*) OS=Unknown;;
|
|
43
43
|
esac
|
|
44
44
|
print_info "Detected OS: $OS"
|
|
45
|
+
|
|
46
|
+
# Detect Linux distribution
|
|
47
|
+
if [ "$OS" = "Linux" ]; then
|
|
48
|
+
if [ -f /etc/os-release ]; then
|
|
49
|
+
. /etc/os-release
|
|
50
|
+
DISTRO=$ID
|
|
51
|
+
print_info "Detected Linux distribution: $DISTRO"
|
|
52
|
+
else
|
|
53
|
+
DISTRO=unknown
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
45
56
|
}
|
|
46
57
|
|
|
47
58
|
# Check if command exists
|
|
@@ -60,7 +71,7 @@ check_ruby() {
|
|
|
60
71
|
if command_exists ruby; then
|
|
61
72
|
RUBY_VERSION=$(ruby -e 'puts RUBY_VERSION' 2>/dev/null)
|
|
62
73
|
print_info "Found Ruby version: $RUBY_VERSION"
|
|
63
|
-
|
|
74
|
+
|
|
64
75
|
if version_ge "$RUBY_VERSION" "3.1.0"; then
|
|
65
76
|
print_success "Ruby version is compatible (>= 3.1.0)"
|
|
66
77
|
return 0
|
|
@@ -74,45 +85,18 @@ check_ruby() {
|
|
|
74
85
|
fi
|
|
75
86
|
}
|
|
76
87
|
|
|
77
|
-
# Install via Homebrew
|
|
78
|
-
install_via_homebrew() {
|
|
79
|
-
print_step "Installing via Homebrew..."
|
|
80
|
-
|
|
81
|
-
if ! command_exists brew; then
|
|
82
|
-
print_error "Homebrew is not installed"
|
|
83
|
-
print_info "Install Homebrew from: https://brew.sh"
|
|
84
|
-
return 1
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
print_info "Adding OpenClacky tap..."
|
|
88
|
-
brew tap clacky-ai/openclacky 2>/dev/null || {
|
|
89
|
-
print_warning "Tap not found or already added, trying direct installation..."
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
print_info "Installing OpenClacky..."
|
|
93
|
-
brew install openclacky
|
|
94
|
-
|
|
95
|
-
if [ $? -eq 0 ]; then
|
|
96
|
-
print_success "OpenClacky installed successfully via Homebrew!"
|
|
97
|
-
return 0
|
|
98
|
-
else
|
|
99
|
-
print_error "Homebrew installation failed"
|
|
100
|
-
return 1
|
|
101
|
-
fi
|
|
102
|
-
}
|
|
103
|
-
|
|
104
88
|
# Install via RubyGems
|
|
105
89
|
install_via_gem() {
|
|
106
90
|
print_step "Installing via RubyGems..."
|
|
107
|
-
|
|
91
|
+
|
|
108
92
|
if ! command_exists gem; then
|
|
109
93
|
print_error "RubyGems is not available"
|
|
110
94
|
return 1
|
|
111
95
|
fi
|
|
112
|
-
|
|
96
|
+
|
|
113
97
|
print_info "Installing OpenClacky gem..."
|
|
114
98
|
gem install openclacky
|
|
115
|
-
|
|
99
|
+
|
|
116
100
|
if [ $? -eq 0 ]; then
|
|
117
101
|
print_success "OpenClacky installed successfully via gem!"
|
|
118
102
|
return 0
|
|
@@ -122,46 +106,237 @@ install_via_gem() {
|
|
|
122
106
|
fi
|
|
123
107
|
}
|
|
124
108
|
|
|
109
|
+
# Install dependencies and Ruby on macOS
|
|
110
|
+
install_macos_dependencies() {
|
|
111
|
+
print_step "Installing macOS dependencies and Ruby..."
|
|
112
|
+
echo ""
|
|
113
|
+
|
|
114
|
+
# Install Homebrew (it will automatically install Xcode Command Line Tools if needed)
|
|
115
|
+
print_info "Checking Homebrew installation..."
|
|
116
|
+
if ! command_exists brew; then
|
|
117
|
+
print_info "Installing Homebrew..."
|
|
118
|
+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
119
|
+
|
|
120
|
+
# Add Homebrew to PATH
|
|
121
|
+
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc
|
|
122
|
+
export PATH="/opt/homebrew/bin:$PATH"
|
|
123
|
+
|
|
124
|
+
print_success "Homebrew installed successfully"
|
|
125
|
+
else
|
|
126
|
+
print_success "Homebrew already installed"
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Install build dependencies
|
|
130
|
+
print_info "Installing build dependencies..."
|
|
131
|
+
if brew install openssl@3 libyaml gmp rust; then
|
|
132
|
+
print_success "Build dependencies installed"
|
|
133
|
+
else
|
|
134
|
+
print_error "Failed to install build dependencies"
|
|
135
|
+
return 1
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Install mise for Ruby version management
|
|
139
|
+
print_info "Installing mise..."
|
|
140
|
+
if ! command_exists mise; then
|
|
141
|
+
if curl https://mise.run | sh; then
|
|
142
|
+
# Add mise to shell
|
|
143
|
+
if [ -f ~/.zshrc ]; then
|
|
144
|
+
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.zshrc
|
|
145
|
+
fi
|
|
146
|
+
if [ -f ~/.bash_profile ]; then
|
|
147
|
+
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bash_profile
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
151
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
152
|
+
|
|
153
|
+
print_success "mise installed successfully"
|
|
154
|
+
else
|
|
155
|
+
print_error "Failed to install mise"
|
|
156
|
+
return 1
|
|
157
|
+
fi
|
|
158
|
+
else
|
|
159
|
+
print_success "mise already installed"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Install Ruby 3 via mise
|
|
163
|
+
print_info "Installing Ruby 3 via mise..."
|
|
164
|
+
if ~/.local/bin/mise use -g ruby@3; then
|
|
165
|
+
# Reload mise
|
|
166
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
167
|
+
print_success "Ruby 3 installed successfully"
|
|
168
|
+
else
|
|
169
|
+
print_error "Failed to install Ruby 3"
|
|
170
|
+
return 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Verify Ruby installation
|
|
174
|
+
if check_ruby; then
|
|
175
|
+
return 0
|
|
176
|
+
else
|
|
177
|
+
print_error "Ruby installation verification failed"
|
|
178
|
+
return 1
|
|
179
|
+
fi
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# Install dependencies and Ruby on Ubuntu/Debian
|
|
183
|
+
install_ubuntu_dependencies() {
|
|
184
|
+
print_step "Installing Ubuntu dependencies and Ruby..."
|
|
185
|
+
echo ""
|
|
186
|
+
|
|
187
|
+
# Update package list
|
|
188
|
+
print_info "Updating package list..."
|
|
189
|
+
if sudo apt update; then
|
|
190
|
+
print_success "Package list updated"
|
|
191
|
+
else
|
|
192
|
+
print_error "Failed to update package list"
|
|
193
|
+
return 1
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Install build dependencies
|
|
197
|
+
print_info "Installing build dependencies..."
|
|
198
|
+
if sudo apt install -y build-essential rustc libssl-dev libyaml-dev zlib1g-dev libgmp-dev git; then
|
|
199
|
+
print_success "Build dependencies installed"
|
|
200
|
+
else
|
|
201
|
+
print_error "Failed to install build dependencies"
|
|
202
|
+
return 1
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Install mise for Ruby version management
|
|
206
|
+
print_info "Installing mise..."
|
|
207
|
+
if ! command_exists mise; then
|
|
208
|
+
if curl https://mise.run | sh; then
|
|
209
|
+
# Add mise to shell
|
|
210
|
+
if [ -f ~/.bashrc ]; then
|
|
211
|
+
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
215
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
216
|
+
|
|
217
|
+
print_success "mise installed successfully"
|
|
218
|
+
else
|
|
219
|
+
print_error "Failed to install mise"
|
|
220
|
+
return 1
|
|
221
|
+
fi
|
|
222
|
+
else
|
|
223
|
+
print_success "mise already installed"
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Install Ruby 3 via mise
|
|
227
|
+
print_info "Installing Ruby 3 via mise..."
|
|
228
|
+
if ~/.local/bin/mise use -g ruby@3; then
|
|
229
|
+
# Reload mise
|
|
230
|
+
eval "$(~/.local/bin/mise activate bash)"
|
|
231
|
+
print_success "Ruby 3 installed successfully"
|
|
232
|
+
else
|
|
233
|
+
print_error "Failed to install Ruby 3"
|
|
234
|
+
return 1
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
# Verify Ruby installation
|
|
238
|
+
if check_ruby; then
|
|
239
|
+
return 0
|
|
240
|
+
else
|
|
241
|
+
print_error "Ruby installation verification failed"
|
|
242
|
+
return 1
|
|
243
|
+
fi
|
|
244
|
+
}
|
|
245
|
+
|
|
125
246
|
# Suggest Ruby installation
|
|
126
247
|
suggest_ruby_installation() {
|
|
127
248
|
print_step "Ruby Installation Options"
|
|
128
249
|
echo ""
|
|
129
|
-
|
|
250
|
+
|
|
130
251
|
if [ "$OS" = "macOS" ]; then
|
|
131
|
-
print_info "
|
|
132
|
-
echo "
|
|
133
|
-
echo "
|
|
252
|
+
print_info "Automatic Installation (Recommended)"
|
|
253
|
+
echo " This script can automatically install Ruby and dependencies for you."
|
|
254
|
+
echo " Uses mise - a fast, polyglot tool version manager."
|
|
255
|
+
echo ""
|
|
256
|
+
read -p "Would you like to install Ruby and dependencies automatically? (y/n) " -n 1 -r
|
|
257
|
+
echo ""
|
|
258
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
259
|
+
install_macos_dependencies
|
|
260
|
+
return $?
|
|
261
|
+
fi
|
|
134
262
|
echo ""
|
|
135
|
-
print_info "
|
|
136
|
-
echo "
|
|
137
|
-
echo "
|
|
138
|
-
echo "
|
|
139
|
-
|
|
263
|
+
print_info "Manual Installation with mise:"
|
|
264
|
+
echo " # Install Homebrew (it will install Xcode Command Line Tools automatically)"
|
|
265
|
+
echo " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
|
266
|
+
echo ""
|
|
267
|
+
echo " # Install dependencies"
|
|
268
|
+
echo " brew install openssl@3 libyaml gmp rust"
|
|
269
|
+
echo ""
|
|
270
|
+
echo " # Install mise"
|
|
271
|
+
echo " curl https://mise.run | sh"
|
|
272
|
+
echo " echo 'eval \"\$(~/.local/bin/mise activate bash)\"' >> ~/.zshrc"
|
|
273
|
+
echo ""
|
|
274
|
+
echo " # Install Ruby 3"
|
|
275
|
+
echo " mise use -g ruby@3"
|
|
276
|
+
|
|
140
277
|
elif [ "$OS" = "Linux" ]; then
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
278
|
+
if [ "$DISTRO" = "ubuntu" ] || [ "$DISTRO" = "debian" ]; then
|
|
279
|
+
print_info "Automatic Installation (Recommended)"
|
|
280
|
+
echo " This script can automatically install Ruby and dependencies for you."
|
|
281
|
+
echo " Uses mise - a fast, polyglot tool version manager."
|
|
282
|
+
echo ""
|
|
283
|
+
read -p "Would you like to install Ruby and dependencies automatically? (y/n) " -n 1 -r
|
|
284
|
+
echo ""
|
|
285
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
286
|
+
install_ubuntu_dependencies
|
|
287
|
+
return $?
|
|
288
|
+
fi
|
|
289
|
+
echo ""
|
|
290
|
+
print_info "Manual Installation with mise (Ubuntu/Debian):"
|
|
291
|
+
echo " # Update and install dependencies"
|
|
292
|
+
echo " sudo apt update"
|
|
293
|
+
echo " sudo apt install -y build-essential rustc libssl-dev libyaml-dev zlib1g-dev libgmp-dev git"
|
|
294
|
+
echo ""
|
|
295
|
+
echo " # Install mise"
|
|
296
|
+
echo " curl https://mise.run | sh"
|
|
297
|
+
echo " echo 'eval \"\$(~/.local/bin/mise activate bash)\"' >> ~/.bashrc"
|
|
298
|
+
echo ""
|
|
299
|
+
echo " # Install Ruby 3"
|
|
300
|
+
echo " mise use -g ruby@3"
|
|
301
|
+
else
|
|
302
|
+
print_info "Manual Installation with mise (Other Linux):"
|
|
303
|
+
echo " # Install build dependencies (adjust for your distribution)"
|
|
304
|
+
echo " # Fedora/RHEL:"
|
|
305
|
+
echo " sudo dnf install -y gcc make openssl-devel libyaml-devel zlib-devel gmp-devel git rust"
|
|
306
|
+
echo ""
|
|
307
|
+
echo " # Install mise"
|
|
308
|
+
echo " curl https://mise.run | sh"
|
|
309
|
+
echo " echo 'eval \"\$(~/.local/bin/mise activate bash)\"' >> ~/.bashrc"
|
|
310
|
+
echo ""
|
|
311
|
+
echo " # Install Ruby 3"
|
|
312
|
+
echo " mise use -g ruby@3"
|
|
313
|
+
fi
|
|
314
|
+
|
|
315
|
+
elif [ "$OS" = "Windows" ]; then
|
|
316
|
+
print_info "Windows Subsystem for Linux (WSL) Installation (Recommended)"
|
|
317
|
+
echo " OpenClacky requires a Unix-like environment. We recommend using WSL."
|
|
318
|
+
echo ""
|
|
319
|
+
echo " 1. Open PowerShell or Windows Command Prompt in administrator mode"
|
|
320
|
+
echo " 2. Install WSL with Ubuntu 24.04:"
|
|
145
321
|
echo ""
|
|
146
|
-
|
|
147
|
-
echo " curl -sSL https://get.rvm.io | bash -s stable --ruby"
|
|
322
|
+
echo " wsl --install --distribution Ubuntu-24.04"
|
|
148
323
|
echo ""
|
|
149
|
-
|
|
150
|
-
echo "
|
|
151
|
-
echo "
|
|
152
|
-
echo " sudo apt-get install ruby-full"
|
|
324
|
+
echo " 3. Restart your computer if prompted"
|
|
325
|
+
echo " 4. Launch Ubuntu from the Start menu"
|
|
326
|
+
echo " 5. Run this installation script again inside Ubuntu:"
|
|
153
327
|
echo ""
|
|
154
|
-
echo "
|
|
155
|
-
echo "
|
|
328
|
+
echo " curl -fsSL https://raw.githubusercontent.com/clacky-ai/open-clacky/main/scripts/install.sh | bash"
|
|
329
|
+
echo ""
|
|
330
|
+
print_info "Learn more about WSL: https://learn.microsoft.com/en-us/windows/wsl/install"
|
|
156
331
|
fi
|
|
157
|
-
|
|
332
|
+
|
|
158
333
|
echo ""
|
|
159
334
|
print_info "After installing Ruby, run this script again or use:"
|
|
160
335
|
echo " gem install openclacky"
|
|
336
|
+
echo ""
|
|
337
|
+
print_info "Learn more about mise: https://mise.jdx.dev"
|
|
161
338
|
}
|
|
162
339
|
|
|
163
|
-
|
|
164
|
-
|
|
165
340
|
# Main installation logic
|
|
166
341
|
main() {
|
|
167
342
|
echo ""
|
|
@@ -173,49 +348,45 @@ main() {
|
|
|
173
348
|
echo "║ ║"
|
|
174
349
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
175
350
|
echo ""
|
|
176
|
-
|
|
351
|
+
|
|
177
352
|
detect_os
|
|
178
|
-
|
|
179
|
-
# Strategy 1:
|
|
180
|
-
if [ "$OS" = "macOS" ] && command_exists brew; then
|
|
181
|
-
print_info "Homebrew detected, using it for installation (recommended)"
|
|
182
|
-
if install_via_homebrew; then
|
|
183
|
-
show_post_install_info
|
|
184
|
-
exit 0
|
|
185
|
-
fi
|
|
186
|
-
print_warning "Homebrew installation failed, trying Ruby gem installation..."
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
# Strategy 2: Check Ruby and install via gem
|
|
353
|
+
|
|
354
|
+
# Strategy 1: Check Ruby and install via gem
|
|
190
355
|
if check_ruby; then
|
|
191
356
|
if install_via_gem; then
|
|
192
357
|
show_post_install_info
|
|
193
358
|
exit 0
|
|
194
359
|
fi
|
|
195
360
|
fi
|
|
196
|
-
|
|
197
|
-
# Strategy
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
361
|
+
|
|
362
|
+
# Strategy 2: Install Ruby on macOS/Ubuntu or suggest options
|
|
363
|
+
if [ "$OS" = "macOS" ] || [ "$OS" = "Linux" ]; then
|
|
364
|
+
print_warning "Ruby not found or version too old"
|
|
365
|
+
echo ""
|
|
366
|
+
if suggest_ruby_installation; then
|
|
367
|
+
# Try installing via gem after Ruby installation
|
|
368
|
+
if install_via_gem; then
|
|
369
|
+
show_post_install_info
|
|
370
|
+
exit 0
|
|
371
|
+
else
|
|
372
|
+
print_error "Failed to install OpenClacky gem"
|
|
373
|
+
exit 1
|
|
374
|
+
fi
|
|
375
|
+
else
|
|
376
|
+
# User declined or installation failed
|
|
377
|
+
print_info "Ruby installation was not completed"
|
|
378
|
+
print_info "Please install Ruby manually and run: gem install openclacky"
|
|
379
|
+
print_info "For more information, visit: https://github.com/clacky-ai/open-clacky"
|
|
380
|
+
exit 1
|
|
211
381
|
fi
|
|
382
|
+
else
|
|
383
|
+
print_error "Could not install OpenClacky automatically"
|
|
384
|
+
echo ""
|
|
385
|
+
suggest_ruby_installation
|
|
386
|
+
echo ""
|
|
387
|
+
print_info "For more information, visit: https://github.com/clacky-ai/open-clacky"
|
|
388
|
+
exit 1
|
|
212
389
|
fi
|
|
213
|
-
|
|
214
|
-
suggest_ruby_installation
|
|
215
|
-
echo ""
|
|
216
|
-
|
|
217
|
-
print_info "For more information, visit: https://github.com/clacky-ai/open-clacky"
|
|
218
|
-
exit 1
|
|
219
390
|
}
|
|
220
391
|
|
|
221
392
|
# Post-installation information
|
|
@@ -227,19 +398,25 @@ show_post_install_info() {
|
|
|
227
398
|
echo "║ ║"
|
|
228
399
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
229
400
|
echo ""
|
|
401
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
402
|
+
echo ""
|
|
403
|
+
echo " ⚠️ ${YELLOW}IMPORTANT: Please restart your terminal${NC}"
|
|
404
|
+
echo ""
|
|
405
|
+
echo " After restarting, type: ${GREEN}openclacky${NC}"
|
|
406
|
+
echo ""
|
|
407
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
408
|
+
echo ""
|
|
230
409
|
print_step "Quick Start Guide:"
|
|
231
410
|
echo ""
|
|
232
411
|
print_info "1. Configure your API key:"
|
|
233
|
-
echo "
|
|
234
|
-
echo ""
|
|
235
|
-
print_info "2. Start chatting:"
|
|
236
|
-
echo " clacky chat"
|
|
412
|
+
echo " openclacky"
|
|
413
|
+
echo " > /config"
|
|
237
414
|
echo ""
|
|
238
|
-
print_info "
|
|
239
|
-
echo "
|
|
415
|
+
print_info "2. Create a new project:"
|
|
416
|
+
echo " > /new your-project-name"
|
|
240
417
|
echo ""
|
|
241
|
-
print_info "
|
|
242
|
-
echo "
|
|
418
|
+
print_info "3. Get help:"
|
|
419
|
+
echo " > /help"
|
|
243
420
|
echo ""
|
|
244
421
|
print_success "Happy coding! 🚀"
|
|
245
422
|
echo ""
|