openclacky 0.6.1 → 0.6.2
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 +26 -0
- data/README.md +39 -88
- data/homebrew/README.md +96 -0
- data/homebrew/openclacky.rb +24 -0
- data/lib/clacky/agent.rb +17 -70
- data/lib/clacky/cli.rb +90 -1
- data/lib/clacky/tools/file_reader.rb +135 -2
- data/lib/clacky/tools/safe_shell.rb +39 -9
- data/lib/clacky/tools/shell.rb +67 -0
- data/lib/clacky/ui2/components/input_area.rb +175 -59
- data/lib/clacky/ui2/layout_manager.rb +83 -59
- data/lib/clacky/ui2/themes/hacker_theme.rb +2 -2
- data/lib/clacky/ui2/themes/minimal_theme.rb +2 -2
- data/lib/clacky/ui2/ui_controller.rb +80 -20
- data/lib/clacky/ui2.rb +0 -1
- data/lib/clacky/utils/arguments_parser.rb +7 -2
- data/lib/clacky/utils/file_processor.rb +201 -0
- data/lib/clacky/version.rb +1 -1
- data/scripts/install.sh +249 -0
- data/scripts/uninstall.sh +146 -0
- metadata +6 -2
- data/lib/clacky/ui2/components/output_area.rb +0 -112
data/lib/clacky/version.rb
CHANGED
data/scripts/install.sh
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# OpenClacky Installation Script
|
|
3
|
+
# This script automatically detects your system and installs OpenClacky
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors for output
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
GREEN='\033[0;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
BLUE='\033[0;34m'
|
|
12
|
+
NC='\033[0m' # No Color
|
|
13
|
+
|
|
14
|
+
# Print colored messages
|
|
15
|
+
print_info() {
|
|
16
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
print_success() {
|
|
20
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
print_warning() {
|
|
24
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
print_error() {
|
|
28
|
+
echo -e "${RED}✗${NC} $1"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
print_step() {
|
|
32
|
+
echo -e "\n${BLUE}==>${NC} $1"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Detect OS
|
|
36
|
+
detect_os() {
|
|
37
|
+
case "$(uname -s)" in
|
|
38
|
+
Linux*) OS=Linux;;
|
|
39
|
+
Darwin*) OS=macOS;;
|
|
40
|
+
CYGWIN*) OS=Windows;;
|
|
41
|
+
MINGW*) OS=Windows;;
|
|
42
|
+
*) OS=Unknown;;
|
|
43
|
+
esac
|
|
44
|
+
print_info "Detected OS: $OS"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Check if command exists
|
|
48
|
+
command_exists() {
|
|
49
|
+
command -v "$1" >/dev/null 2>&1
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Compare version strings
|
|
53
|
+
version_ge() {
|
|
54
|
+
# Returns 0 (true) if $1 >= $2
|
|
55
|
+
printf '%s\n%s\n' "$2" "$1" | sort -V -C
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Check Ruby version
|
|
59
|
+
check_ruby() {
|
|
60
|
+
if command_exists ruby; then
|
|
61
|
+
RUBY_VERSION=$(ruby -e 'puts RUBY_VERSION' 2>/dev/null)
|
|
62
|
+
print_info "Found Ruby version: $RUBY_VERSION"
|
|
63
|
+
|
|
64
|
+
if version_ge "$RUBY_VERSION" "3.1.0"; then
|
|
65
|
+
print_success "Ruby version is compatible (>= 3.1.0)"
|
|
66
|
+
return 0
|
|
67
|
+
else
|
|
68
|
+
print_warning "Ruby version $RUBY_VERSION is too old (need >= 3.1.0)"
|
|
69
|
+
return 1
|
|
70
|
+
fi
|
|
71
|
+
else
|
|
72
|
+
print_warning "Ruby is not installed"
|
|
73
|
+
return 1
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
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
|
+
# Install via RubyGems
|
|
105
|
+
install_via_gem() {
|
|
106
|
+
print_step "Installing via RubyGems..."
|
|
107
|
+
|
|
108
|
+
if ! command_exists gem; then
|
|
109
|
+
print_error "RubyGems is not available"
|
|
110
|
+
return 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
print_info "Installing OpenClacky gem..."
|
|
114
|
+
gem install openclacky
|
|
115
|
+
|
|
116
|
+
if [ $? -eq 0 ]; then
|
|
117
|
+
print_success "OpenClacky installed successfully via gem!"
|
|
118
|
+
return 0
|
|
119
|
+
else
|
|
120
|
+
print_error "Gem installation failed"
|
|
121
|
+
return 1
|
|
122
|
+
fi
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Suggest Ruby installation
|
|
126
|
+
suggest_ruby_installation() {
|
|
127
|
+
print_step "Ruby Installation Options"
|
|
128
|
+
echo ""
|
|
129
|
+
|
|
130
|
+
if [ "$OS" = "macOS" ]; then
|
|
131
|
+
print_info "Option 1: Install Ruby via Homebrew (Recommended)"
|
|
132
|
+
echo " brew install ruby@3.3"
|
|
133
|
+
echo " export PATH=\"/usr/local/opt/ruby@3.3/bin:\$PATH\""
|
|
134
|
+
echo ""
|
|
135
|
+
print_info "Option 2: Use rbenv"
|
|
136
|
+
echo " brew install rbenv ruby-build"
|
|
137
|
+
echo " rbenv install 3.3.0"
|
|
138
|
+
echo " rbenv global 3.3.0"
|
|
139
|
+
|
|
140
|
+
elif [ "$OS" = "Linux" ]; then
|
|
141
|
+
print_info "Option 1: Use rbenv"
|
|
142
|
+
echo " curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-installer | bash"
|
|
143
|
+
echo " rbenv install 3.3.0"
|
|
144
|
+
echo " rbenv global 3.3.0"
|
|
145
|
+
echo ""
|
|
146
|
+
print_info "Option 2: Use RVM"
|
|
147
|
+
echo " curl -sSL https://get.rvm.io | bash -s stable --ruby"
|
|
148
|
+
echo ""
|
|
149
|
+
print_info "Option 3: Use system package manager"
|
|
150
|
+
echo " # Ubuntu/Debian:"
|
|
151
|
+
echo " sudo apt-get update"
|
|
152
|
+
echo " sudo apt-get install ruby-full"
|
|
153
|
+
echo ""
|
|
154
|
+
echo " # Fedora:"
|
|
155
|
+
echo " sudo dnf install ruby ruby-devel"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
echo ""
|
|
159
|
+
print_info "After installing Ruby, run this script again or use:"
|
|
160
|
+
echo " gem install openclacky"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# Main installation logic
|
|
166
|
+
main() {
|
|
167
|
+
echo ""
|
|
168
|
+
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
169
|
+
echo "║ ║"
|
|
170
|
+
echo "║ 🤖 OpenClacky Installation Script ║"
|
|
171
|
+
echo "║ ║"
|
|
172
|
+
echo "║ AI Agent CLI with Tool Use Capabilities ║"
|
|
173
|
+
echo "║ ║"
|
|
174
|
+
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
175
|
+
echo ""
|
|
176
|
+
|
|
177
|
+
detect_os
|
|
178
|
+
|
|
179
|
+
# Strategy 1: On macOS, try Homebrew first if available
|
|
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
|
|
190
|
+
if check_ruby; then
|
|
191
|
+
if install_via_gem; then
|
|
192
|
+
show_post_install_info
|
|
193
|
+
exit 0
|
|
194
|
+
fi
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Strategy 3: Suggest installation options
|
|
198
|
+
print_error "Could not install OpenClacky automatically"
|
|
199
|
+
echo ""
|
|
200
|
+
print_step "Available Installation Options:"
|
|
201
|
+
echo ""
|
|
202
|
+
|
|
203
|
+
if [ "$OS" = "macOS" ]; then
|
|
204
|
+
if ! command_exists brew; then
|
|
205
|
+
print_info "Option 1: Install via Homebrew (Recommended)"
|
|
206
|
+
echo " If you have Homebrew, install it from: https://brew.sh"
|
|
207
|
+
echo " Then run:"
|
|
208
|
+
echo " brew tap clacky-ai/openclacky"
|
|
209
|
+
echo " brew install openclacky"
|
|
210
|
+
echo ""
|
|
211
|
+
fi
|
|
212
|
+
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
|
+
}
|
|
220
|
+
|
|
221
|
+
# Post-installation information
|
|
222
|
+
show_post_install_info() {
|
|
223
|
+
echo ""
|
|
224
|
+
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
225
|
+
echo "║ ║"
|
|
226
|
+
echo "║ ✨ OpenClacky Installed Successfully! ║"
|
|
227
|
+
echo "║ ║"
|
|
228
|
+
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
229
|
+
echo ""
|
|
230
|
+
print_step "Quick Start Guide:"
|
|
231
|
+
echo ""
|
|
232
|
+
print_info "1. Configure your API key:"
|
|
233
|
+
echo " clacky config set"
|
|
234
|
+
echo ""
|
|
235
|
+
print_info "2. Start chatting:"
|
|
236
|
+
echo " clacky chat"
|
|
237
|
+
echo ""
|
|
238
|
+
print_info "3. Use AI agent mode:"
|
|
239
|
+
echo " clacky agent"
|
|
240
|
+
echo ""
|
|
241
|
+
print_info "4. Get help:"
|
|
242
|
+
echo " clacky help"
|
|
243
|
+
echo ""
|
|
244
|
+
print_success "Happy coding! 🚀"
|
|
245
|
+
echo ""
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
# Run main installation
|
|
249
|
+
main
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# OpenClacky Uninstallation Script
|
|
3
|
+
# This script removes OpenClacky from your system
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors for output
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
GREEN='\033[0;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
BLUE='\033[0;34m'
|
|
12
|
+
NC='\033[0m' # No Color
|
|
13
|
+
|
|
14
|
+
print_info() {
|
|
15
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
print_success() {
|
|
19
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
print_warning() {
|
|
23
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
print_error() {
|
|
27
|
+
echo -e "${RED}✗${NC} $1"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
print_step() {
|
|
31
|
+
echo -e "\n${BLUE}==>${NC} $1"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
command_exists() {
|
|
35
|
+
command -v "$1" >/dev/null 2>&1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Check if OpenClacky is installed
|
|
39
|
+
check_installation() {
|
|
40
|
+
if command_exists clacky || command_exists openclacky; then
|
|
41
|
+
return 0
|
|
42
|
+
else
|
|
43
|
+
return 1
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Uninstall via Homebrew
|
|
48
|
+
uninstall_homebrew() {
|
|
49
|
+
if command_exists brew; then
|
|
50
|
+
if brew list openclacky >/dev/null 2>&1; then
|
|
51
|
+
print_step "Uninstalling via Homebrew..."
|
|
52
|
+
brew uninstall openclacky
|
|
53
|
+
|
|
54
|
+
# Optionally untap
|
|
55
|
+
if brew tap | grep -q "clacky-ai/openclacky"; then
|
|
56
|
+
read -p "$(echo -e ${YELLOW}?${NC}) Remove Homebrew tap (clacky-ai/openclacky)? [y/N] " -n 1 -r
|
|
57
|
+
echo
|
|
58
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
59
|
+
brew untap clacky-ai/openclacky
|
|
60
|
+
print_success "Tap removed"
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
return 0
|
|
65
|
+
fi
|
|
66
|
+
fi
|
|
67
|
+
return 1
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# Uninstall via gem
|
|
71
|
+
uninstall_gem() {
|
|
72
|
+
if command_exists gem; then
|
|
73
|
+
if gem list -i openclacky >/dev/null 2>&1; then
|
|
74
|
+
print_step "Uninstalling via RubyGems..."
|
|
75
|
+
gem uninstall openclacky -x
|
|
76
|
+
return 0
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
return 1
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Remove configuration files
|
|
83
|
+
remove_config() {
|
|
84
|
+
CONFIG_DIR="$HOME/.clacky"
|
|
85
|
+
|
|
86
|
+
if [ -d "$CONFIG_DIR" ]; then
|
|
87
|
+
print_warning "Configuration directory found: $CONFIG_DIR"
|
|
88
|
+
read -p "$(echo -e ${YELLOW}?${NC}) Remove configuration files (including API keys)? [y/N] " -n 1 -r
|
|
89
|
+
echo
|
|
90
|
+
|
|
91
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
92
|
+
rm -rf "$CONFIG_DIR"
|
|
93
|
+
print_success "Configuration removed"
|
|
94
|
+
else
|
|
95
|
+
print_info "Configuration preserved at: $CONFIG_DIR"
|
|
96
|
+
fi
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Main uninstallation
|
|
101
|
+
main() {
|
|
102
|
+
echo ""
|
|
103
|
+
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
104
|
+
echo "║ ║"
|
|
105
|
+
echo "║ 🗑️ OpenClacky Uninstallation ║"
|
|
106
|
+
echo "║ ║"
|
|
107
|
+
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
108
|
+
echo ""
|
|
109
|
+
|
|
110
|
+
if ! check_installation; then
|
|
111
|
+
print_warning "OpenClacky does not appear to be installed"
|
|
112
|
+
exit 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
UNINSTALLED=false
|
|
116
|
+
|
|
117
|
+
# Try Homebrew first
|
|
118
|
+
if uninstall_homebrew; then
|
|
119
|
+
UNINSTALLED=true
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Try gem
|
|
123
|
+
if uninstall_gem; then
|
|
124
|
+
UNINSTALLED=true
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
if [ "$UNINSTALLED" = false ]; then
|
|
128
|
+
print_error "Could not automatically uninstall OpenClacky"
|
|
129
|
+
print_info "You may need to uninstall manually:"
|
|
130
|
+
echo " - Via Homebrew: brew uninstall openclacky"
|
|
131
|
+
echo " - Via RubyGems: gem uninstall openclacky"
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
print_success "OpenClacky uninstalled successfully"
|
|
136
|
+
|
|
137
|
+
# Ask about config removal
|
|
138
|
+
remove_config
|
|
139
|
+
|
|
140
|
+
echo ""
|
|
141
|
+
print_success "Uninstallation complete!"
|
|
142
|
+
print_info "Thank you for using OpenClacky 👋"
|
|
143
|
+
echo ""
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
main
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openclacky
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- windy
|
|
@@ -159,6 +159,8 @@ files:
|
|
|
159
159
|
- clacky-legacy/clacky.gemspec
|
|
160
160
|
- clacky-legacy/clarky.gemspec
|
|
161
161
|
- docs/ui2-architecture.md
|
|
162
|
+
- homebrew/README.md
|
|
163
|
+
- homebrew/openclacky.rb
|
|
162
164
|
- lib/clacky.rb
|
|
163
165
|
- lib/clacky/agent.rb
|
|
164
166
|
- lib/clacky/agent_config.rb
|
|
@@ -193,7 +195,6 @@ files:
|
|
|
193
195
|
- lib/clacky/ui2/components/inline_input.rb
|
|
194
196
|
- lib/clacky/ui2/components/input_area.rb
|
|
195
197
|
- lib/clacky/ui2/components/message_component.rb
|
|
196
|
-
- lib/clacky/ui2/components/output_area.rb
|
|
197
198
|
- lib/clacky/ui2/components/todo_area.rb
|
|
198
199
|
- lib/clacky/ui2/components/tool_component.rb
|
|
199
200
|
- lib/clacky/ui2/components/welcome_banner.rb
|
|
@@ -209,9 +210,12 @@ files:
|
|
|
209
210
|
- lib/clacky/ui2/view_renderer.rb
|
|
210
211
|
- lib/clacky/utils/arguments_parser.rb
|
|
211
212
|
- lib/clacky/utils/file_ignore_helper.rb
|
|
213
|
+
- lib/clacky/utils/file_processor.rb
|
|
212
214
|
- lib/clacky/utils/limit_stack.rb
|
|
213
215
|
- lib/clacky/utils/path_helper.rb
|
|
214
216
|
- lib/clacky/version.rb
|
|
217
|
+
- scripts/install.sh
|
|
218
|
+
- scripts/uninstall.sh
|
|
215
219
|
- sig/clacky.rbs
|
|
216
220
|
homepage: https://github.com/yafeilee/clacky
|
|
217
221
|
licenses:
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "pastel"
|
|
4
|
-
|
|
5
|
-
module Clacky
|
|
6
|
-
module UI2
|
|
7
|
-
module Components
|
|
8
|
-
# OutputArea writes content directly to terminal
|
|
9
|
-
# Terminal handles scrolling natively via scrollback buffer
|
|
10
|
-
class OutputArea
|
|
11
|
-
attr_accessor :height
|
|
12
|
-
|
|
13
|
-
def initialize(height:)
|
|
14
|
-
@height = height
|
|
15
|
-
@pastel = Pastel.new
|
|
16
|
-
@width = TTY::Screen.width
|
|
17
|
-
@last_line_row = nil # Track last line position for updates
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Append single line content directly to terminal (no newline)
|
|
21
|
-
# Multi-line handling is done by LayoutManager
|
|
22
|
-
# @param content [String] Single line content to append
|
|
23
|
-
def append(content)
|
|
24
|
-
return if content.nil?
|
|
25
|
-
|
|
26
|
-
update_width
|
|
27
|
-
print wrap_line(content)
|
|
28
|
-
flush
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Initial render - no-op, output flows naturally
|
|
32
|
-
# @param start_row [Integer] Screen row (ignored)
|
|
33
|
-
def render(start_row:)
|
|
34
|
-
# No-op - output flows naturally from current position
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Update the last line (for progress indicator)
|
|
38
|
-
# Uses carriage return to overwrite current line
|
|
39
|
-
# @param content [String] New content for last line
|
|
40
|
-
def update_last_line(content)
|
|
41
|
-
print "\r"
|
|
42
|
-
clear_line
|
|
43
|
-
print truncate_line(content)
|
|
44
|
-
flush
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Remove the last line from output
|
|
48
|
-
def remove_last_line
|
|
49
|
-
print "\r"
|
|
50
|
-
clear_line
|
|
51
|
-
flush
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Clear - no-op for natural scroll mode
|
|
55
|
-
def clear
|
|
56
|
-
# No-op
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Legacy scroll methods (no-op, terminal handles scrolling)
|
|
60
|
-
def scroll_up(lines = 1); end
|
|
61
|
-
def scroll_down(lines = 1); end
|
|
62
|
-
def scroll_to_top; end
|
|
63
|
-
def scroll_to_bottom; end
|
|
64
|
-
def at_bottom?; true; end
|
|
65
|
-
def scroll_percentage; 0.0; end
|
|
66
|
-
|
|
67
|
-
def visible_range
|
|
68
|
-
{ start: 1, end: @height, total: @height }
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
private
|
|
72
|
-
|
|
73
|
-
# Wrap line to fit screen width (auto line wrap)
|
|
74
|
-
def wrap_line(line)
|
|
75
|
-
return "" if line.nil?
|
|
76
|
-
# Let terminal handle line wrapping naturally
|
|
77
|
-
line
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Truncate line to fit screen width
|
|
81
|
-
def truncate_line(line)
|
|
82
|
-
return "" if line.nil?
|
|
83
|
-
|
|
84
|
-
visible_length = line.gsub(/\e\[[0-9;]*m/, "").length
|
|
85
|
-
|
|
86
|
-
if visible_length > @width
|
|
87
|
-
truncated = line[0...(@width - 3)]
|
|
88
|
-
truncated + @pastel.dim("...")
|
|
89
|
-
else
|
|
90
|
-
line
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def update_width
|
|
95
|
-
@width = TTY::Screen.width
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def move_cursor(row, col)
|
|
99
|
-
print "\e[#{row + 1};#{col + 1}H"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def clear_line
|
|
103
|
-
print "\e[2K"
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def flush
|
|
107
|
-
$stdout.flush
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|