-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·248 lines (214 loc) · 7.9 KB
/
install.sh
File metadata and controls
executable file
·248 lines (214 loc) · 7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/bin/bash
# Hourglass Installation Script
# Configures Claude Code's built-in statusLine feature with a context progress bar
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Print functions
info() { printf "${BLUE}[INFO]${NC} %s\n" "$1"; }
success() { printf "${GREEN}[OK]${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$1"; }
error() { printf "${RED}[ERROR]${NC} %s\n" "$1"; exit 1; }
echo ""
echo "╔═══════════════════════════════════════╗"
echo "║ ⏳ Hourglass Installer ║"
echo "║ Claude Code Context Monitor ║"
echo "╚═══════════════════════════════════════╝"
echo ""
# Detect OS
OS="$(uname -s)"
case "$OS" in
Darwin) OS_TYPE="macos" ;;
Linux) OS_TYPE="linux" ;;
*) error "Unsupported operating system: $OS" ;;
esac
info "Detected OS: $OS_TYPE"
# Check for jq and install if missing
install_jq() {
info "Checking for jq..."
if command -v jq &> /dev/null; then
success "jq is already installed ($(jq --version))"
return 0
fi
warn "jq not found. Attempting to install..."
if [ "$OS_TYPE" = "macos" ]; then
if command -v brew &> /dev/null; then
info "Installing jq via Homebrew..."
brew install jq
else
error "Homebrew not found. Please install jq manually: https://stedolan.github.io/jq/download/"
fi
elif [ "$OS_TYPE" = "linux" ]; then
if command -v apt-get &> /dev/null; then
info "Installing jq via apt..."
sudo apt-get update && sudo apt-get install -y jq
elif command -v yum &> /dev/null; then
info "Installing jq via yum..."
sudo yum install -y jq
elif command -v dnf &> /dev/null; then
info "Installing jq via dnf..."
sudo dnf install -y jq
elif command -v pacman &> /dev/null; then
info "Installing jq via pacman..."
sudo pacman -S --noconfirm jq
elif command -v apk &> /dev/null; then
info "Installing jq via apk..."
sudo apk add jq
else
error "Could not detect package manager. Please install jq manually: https://stedolan.github.io/jq/download/"
fi
fi
if command -v jq &> /dev/null; then
success "jq installed successfully"
else
error "Failed to install jq"
fi
}
# Check for Claude Code
check_claude_code() {
info "Checking for Claude Code..."
if command -v claude &> /dev/null; then
success "Claude Code CLI found"
else
warn "Claude Code CLI not found in PATH"
warn "Make sure Claude Code is installed: https://claude.ai/claude-code"
fi
}
# Get the directory where this script is located
get_script_dir() {
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
echo "$(cd -P "$(dirname "$SOURCE")" && pwd)"
}
# Install the statusline script
install_script() {
info "Installing Hourglass statusline script..."
SCRIPT_DIR="$(get_script_dir)"
HOURGLASS_DIR="$HOME/.claude/hourglass"
DEST_SCRIPT="$HOURGLASS_DIR/statusline.sh"
# Create hourglass directory if it doesn't exist
if [ ! -d "$HOURGLASS_DIR" ]; then
info "Creating directory: $HOURGLASS_DIR"
mkdir -p "$HOURGLASS_DIR"
fi
# Copy the script (force overwrite)
info "Copying statusline.sh to $DEST_SCRIPT"
cp -f "$SCRIPT_DIR/scripts/statusline.sh" "$DEST_SCRIPT"
chmod +x "$DEST_SCRIPT"
if [ -x "$DEST_SCRIPT" ]; then
success "Script installed successfully"
else
error "Failed to install script"
fi
}
# Configure Claude Code settings.json
configure_settings() {
info "Configuring Claude Code settings..."
SETTINGS_FILE="$HOME/.claude/settings.json"
STATUSLINE_COMMAND="$HOME/.claude/hourglass/statusline.sh"
# Create .claude directory if it doesn't exist
if [ ! -d "$HOME/.claude" ]; then
info "Creating directory: $HOME/.claude"
mkdir -p "$HOME/.claude"
fi
# Create settings.json if it doesn't exist
if [ ! -f "$SETTINGS_FILE" ]; then
info "Creating new settings.json"
echo '{}' > "$SETTINGS_FILE"
fi
# Check if statusLine is already configured
if jq -e '.statusLine' "$SETTINGS_FILE" > /dev/null 2>&1; then
CURRENT_CMD=$(jq -r '.statusLine.command // ""' "$SETTINGS_FILE")
if [ "$CURRENT_CMD" = "$STATUSLINE_COMMAND" ]; then
success "statusLine already configured correctly"
return 0
else
warn "statusLine already configured with different command: $CURRENT_CMD"
info "Updating to use Hourglass..."
fi
fi
# Add or update statusLine configuration
info "Adding statusLine configuration to settings.json"
TEMP_FILE=$(mktemp)
jq --arg cmd "$STATUSLINE_COMMAND" '.statusLine = {"type": "command", "command": $cmd}' "$SETTINGS_FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$SETTINGS_FILE"
# Verify the configuration was added
if jq -e '.statusLine.command' "$SETTINGS_FILE" > /dev/null 2>&1; then
success "Settings configured successfully"
else
error "Failed to configure settings"
fi
}
# Verify installation
verify_installation() {
info "Verifying installation..."
STATUSLINE_SCRIPT="$HOME/.claude/hourglass/statusline.sh"
SETTINGS_FILE="$HOME/.claude/settings.json"
if [ -x "$STATUSLINE_SCRIPT" ]; then
success "Statusline script is installed and executable"
else
error "Statusline script not found or not executable at $STATUSLINE_SCRIPT"
fi
if jq -e '.statusLine.command' "$SETTINGS_FILE" > /dev/null 2>&1; then
success "Settings.json configured with statusLine"
else
error "statusLine not configured in settings.json"
fi
# Test the script with sample data
info "Testing script with sample data..."
TEST_OUTPUT=$(echo '{"context_window":{"context_window_size":200000,"current_usage":{"input_tokens":50000,"cache_creation_tokens":10000,"cache_read_tokens":5000}}}' | "$STATUSLINE_SCRIPT" 2>/dev/null)
if [ -n "$TEST_OUTPUT" ]; then
success "Script test passed"
echo " Sample output: $TEST_OUTPUT"
else
warn "Script test produced no output (may need real Claude Code context)"
fi
}
# Clean up old plugin installation if present
cleanup_old_installation() {
OLD_PLUGIN="$HOME/.claude/plugins/hourglass"
if [ -L "$OLD_PLUGIN" ] || [ -d "$OLD_PLUGIN" ]; then
info "Found old plugin-style installation at $OLD_PLUGIN"
info "Removing old installation..."
rm -rf "$OLD_PLUGIN"
success "Old installation removed"
fi
}
# Main installation flow
main() {
install_jq
echo ""
check_claude_code
echo ""
cleanup_old_installation
echo ""
install_script
echo ""
configure_settings
echo ""
verify_installation
echo ""
echo "╔═══════════════════════════════════════╗"
echo "║ ✅ Installation Complete! ║"
echo "╚═══════════════════════════════════════╝"
echo ""
success "Hourglass has been installed!"
echo ""
info "Next steps:"
echo " 1. Restart Claude Code to activate the status line"
echo " 2. You should see the context progress bar in your status line"
echo ""
info "The progress bar shows:"
echo " • Green when >= 15% context remaining"
echo " • Red when < 15% context remaining (critical)"
echo ""
}
main "$@"