@raavalabs/claude-statusline 1.0.0
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.
- package/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +303 -0
- package/config.default.json +6 -0
- package/fonts/FONTS.md +159 -0
- package/package.json +49 -0
- package/powerline.py +613 -0
- package/setup.sh +285 -0
package/setup.sh
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Claude Statusline — Setup Script
|
|
4
|
+
# Installs the powerline status line for Claude Code.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ./setup.sh # Install with defaults
|
|
8
|
+
# ./setup.sh --uninstall # Remove the status line
|
|
9
|
+
# ./setup.sh --style tui # Install with specific style
|
|
10
|
+
# ./setup.sh --theme nord # Install with specific theme
|
|
11
|
+
#
|
|
12
|
+
# Supports: Linux, macOS, WSL2, Windows (Git Bash/MSYS2)
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
# ─── Colors ───────────────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
RED='\033[0;31m'
|
|
19
|
+
GREEN='\033[0;32m'
|
|
20
|
+
YELLOW='\033[0;33m'
|
|
21
|
+
BLUE='\033[0;34m'
|
|
22
|
+
CYAN='\033[0;36m'
|
|
23
|
+
BOLD='\033[1m'
|
|
24
|
+
NC='\033[0m'
|
|
25
|
+
|
|
26
|
+
info() { echo -e "${BLUE}[info]${NC} $1"; }
|
|
27
|
+
ok() { echo -e "${GREEN}[ok]${NC} $1"; }
|
|
28
|
+
warn() { echo -e "${YELLOW}[warn]${NC} $1"; }
|
|
29
|
+
err() { echo -e "${RED}[error]${NC} $1"; }
|
|
30
|
+
|
|
31
|
+
# ─── Platform Detection ──────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
detect_platform() {
|
|
34
|
+
case "$(uname -s)" in
|
|
35
|
+
Linux*)
|
|
36
|
+
if grep -qi microsoft /proc/version 2>/dev/null; then
|
|
37
|
+
echo "wsl"
|
|
38
|
+
else
|
|
39
|
+
echo "linux"
|
|
40
|
+
fi
|
|
41
|
+
;;
|
|
42
|
+
Darwin*) echo "macos" ;;
|
|
43
|
+
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
|
|
44
|
+
*) echo "unknown" ;;
|
|
45
|
+
esac
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
PLATFORM=$(detect_platform)
|
|
49
|
+
|
|
50
|
+
# ─── Paths ────────────────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
CLAUDE_DIR="$HOME/.claude"
|
|
53
|
+
STATUSLINE_DIR="$CLAUDE_DIR/statusline"
|
|
54
|
+
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
|
|
55
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
56
|
+
|
|
57
|
+
# ─── Args ─────────────────────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
ACTION="install"
|
|
60
|
+
OPT_STYLE=""
|
|
61
|
+
OPT_THEME=""
|
|
62
|
+
|
|
63
|
+
while [[ $# -gt 0 ]]; do
|
|
64
|
+
case "$1" in
|
|
65
|
+
--uninstall) ACTION="uninstall"; shift ;;
|
|
66
|
+
--style) OPT_STYLE="$2"; shift 2 ;;
|
|
67
|
+
--theme) OPT_THEME="$2"; shift 2 ;;
|
|
68
|
+
--help|-h)
|
|
69
|
+
echo "Usage: ./setup.sh [OPTIONS]"
|
|
70
|
+
echo ""
|
|
71
|
+
echo "Options:"
|
|
72
|
+
echo " --style <name> Set style: powerline, capsule, tui (default: powerline)"
|
|
73
|
+
echo " --theme <name> Set theme: dark, nord, tokyonight, gruvbox (default: dark)"
|
|
74
|
+
echo " --uninstall Remove the status line"
|
|
75
|
+
echo " --help, -h Show this help"
|
|
76
|
+
exit 0
|
|
77
|
+
;;
|
|
78
|
+
*) err "Unknown option: $1"; exit 1 ;;
|
|
79
|
+
esac
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
# ─── Uninstall ────────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
uninstall() {
|
|
85
|
+
info "Removing Claude Statusline..."
|
|
86
|
+
|
|
87
|
+
if [[ -d "$STATUSLINE_DIR" ]]; then
|
|
88
|
+
rm -rf "$STATUSLINE_DIR"
|
|
89
|
+
ok "Removed $STATUSLINE_DIR"
|
|
90
|
+
else
|
|
91
|
+
warn "Status line directory not found — already removed?"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Remove statusLine from settings.json
|
|
95
|
+
if [[ -f "$SETTINGS_FILE" ]]; then
|
|
96
|
+
if command -v python3 &>/dev/null; then
|
|
97
|
+
python3 -c "
|
|
98
|
+
import json, sys
|
|
99
|
+
try:
|
|
100
|
+
with open('$SETTINGS_FILE') as f:
|
|
101
|
+
s = json.load(f)
|
|
102
|
+
if 'statusLine' in s:
|
|
103
|
+
del s['statusLine']
|
|
104
|
+
with open('$SETTINGS_FILE', 'w') as f:
|
|
105
|
+
json.dump(s, f, indent=2)
|
|
106
|
+
print('Removed statusLine from settings.json')
|
|
107
|
+
else:
|
|
108
|
+
print('No statusLine config found in settings.json')
|
|
109
|
+
except Exception as e:
|
|
110
|
+
print(f'Warning: could not update settings.json: {e}', file=sys.stderr)
|
|
111
|
+
"
|
|
112
|
+
else
|
|
113
|
+
warn "Python 3 not found — please manually remove 'statusLine' from $SETTINGS_FILE"
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
ok "Uninstall complete."
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if [[ "$ACTION" == "uninstall" ]]; then
|
|
121
|
+
uninstall
|
|
122
|
+
exit 0
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
# ─── Pre-flight Checks ───────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
echo ""
|
|
128
|
+
echo -e "${BOLD}${CYAN} Claude Statusline Installer${NC}"
|
|
129
|
+
echo -e " ${CYAN}─────────────────────────────${NC}"
|
|
130
|
+
echo ""
|
|
131
|
+
|
|
132
|
+
info "Platform: $PLATFORM"
|
|
133
|
+
|
|
134
|
+
# Check Python 3
|
|
135
|
+
if ! command -v python3 &>/dev/null; then
|
|
136
|
+
err "Python 3 is required but not found."
|
|
137
|
+
echo ""
|
|
138
|
+
case "$PLATFORM" in
|
|
139
|
+
macos) echo " Install: brew install python3" ;;
|
|
140
|
+
linux) echo " Install: sudo apt install python3 (or your distro's package manager)" ;;
|
|
141
|
+
wsl) echo " Install: sudo apt install python3" ;;
|
|
142
|
+
windows) echo " Install: winget install Python.Python.3 (or download from python.org)" ;;
|
|
143
|
+
esac
|
|
144
|
+
exit 1
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
PY_VERSION=$(python3 --version 2>&1 | awk '{print $2}')
|
|
148
|
+
PY_MAJOR=$(echo "$PY_VERSION" | cut -d. -f1)
|
|
149
|
+
PY_MINOR=$(echo "$PY_VERSION" | cut -d. -f2)
|
|
150
|
+
|
|
151
|
+
if [[ "$PY_MAJOR" -lt 3 ]] || [[ "$PY_MAJOR" -eq 3 && "$PY_MINOR" -lt 8 ]]; then
|
|
152
|
+
err "Python 3.8+ required (found $PY_VERSION)"
|
|
153
|
+
exit 1
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
ok "Python $PY_VERSION"
|
|
157
|
+
|
|
158
|
+
# Check Claude Code directory
|
|
159
|
+
if [[ ! -d "$CLAUDE_DIR" ]]; then
|
|
160
|
+
warn "~/.claude directory not found. Is Claude Code installed?"
|
|
161
|
+
echo ""
|
|
162
|
+
echo " Install Claude Code: npm install -g @anthropic-ai/claude-code"
|
|
163
|
+
echo " Then run this setup script again."
|
|
164
|
+
exit 1
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
ok "Claude Code directory found"
|
|
168
|
+
|
|
169
|
+
# ─── Install ──────────────────────────────────────────────────────────────────
|
|
170
|
+
|
|
171
|
+
info "Installing to $STATUSLINE_DIR ..."
|
|
172
|
+
|
|
173
|
+
# Create directory
|
|
174
|
+
mkdir -p "$STATUSLINE_DIR"
|
|
175
|
+
|
|
176
|
+
# Copy script
|
|
177
|
+
cp "$SCRIPT_DIR/powerline.py" "$STATUSLINE_DIR/powerline.py"
|
|
178
|
+
chmod +x "$STATUSLINE_DIR/powerline.py"
|
|
179
|
+
ok "Installed powerline.py"
|
|
180
|
+
|
|
181
|
+
# Copy config (only if doesn't exist — preserve user config)
|
|
182
|
+
if [[ ! -f "$STATUSLINE_DIR/config.json" ]]; then
|
|
183
|
+
CONFIG_SOURCE="$SCRIPT_DIR/config.default.json"
|
|
184
|
+
if [[ ! -f "$CONFIG_SOURCE" ]]; then
|
|
185
|
+
CONFIG_SOURCE="$SCRIPT_DIR/config.json"
|
|
186
|
+
fi
|
|
187
|
+
if [[ -f "$CONFIG_SOURCE" ]]; then
|
|
188
|
+
cp "$CONFIG_SOURCE" "$STATUSLINE_DIR/config.json"
|
|
189
|
+
else
|
|
190
|
+
echo '{"style":"powerline","theme":"dark","path_levels":2,"bar_width":10}' > "$STATUSLINE_DIR/config.json"
|
|
191
|
+
fi
|
|
192
|
+
ok "Created default config.json"
|
|
193
|
+
else
|
|
194
|
+
ok "Existing config.json preserved"
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Apply style/theme overrides
|
|
198
|
+
if [[ -n "$OPT_STYLE" || -n "$OPT_THEME" ]]; then
|
|
199
|
+
python3 -c "
|
|
200
|
+
import json
|
|
201
|
+
with open('$STATUSLINE_DIR/config.json') as f:
|
|
202
|
+
c = json.load(f)
|
|
203
|
+
style = '$OPT_STYLE'
|
|
204
|
+
theme = '$OPT_THEME'
|
|
205
|
+
if style and style in ('powerline', 'capsule', 'tui'):
|
|
206
|
+
c['style'] = style
|
|
207
|
+
if theme and theme in ('dark', 'nord', 'tokyonight', 'gruvbox'):
|
|
208
|
+
c['theme'] = theme
|
|
209
|
+
with open('$STATUSLINE_DIR/config.json', 'w') as f:
|
|
210
|
+
json.dump(c, f, indent=2)
|
|
211
|
+
"
|
|
212
|
+
[[ -n "$OPT_STYLE" ]] && ok "Style set to: $OPT_STYLE"
|
|
213
|
+
[[ -n "$OPT_THEME" ]] && ok "Theme set to: $OPT_THEME"
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
# ─── Update settings.json ────────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
info "Configuring Claude Code settings..."
|
|
219
|
+
|
|
220
|
+
python3 << 'PYEOF'
|
|
221
|
+
import json
|
|
222
|
+
import os
|
|
223
|
+
import sys
|
|
224
|
+
|
|
225
|
+
settings_path = os.path.expanduser("~/.claude/settings.json")
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
with open(settings_path) as f:
|
|
229
|
+
settings = json.load(f)
|
|
230
|
+
except (FileNotFoundError, json.JSONDecodeError):
|
|
231
|
+
settings = {}
|
|
232
|
+
|
|
233
|
+
statusline_config = {
|
|
234
|
+
"type": "command",
|
|
235
|
+
"command": "python3 ~/.claude/statusline/powerline.py",
|
|
236
|
+
"refreshInterval": 5,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
existing = settings.get("statusLine")
|
|
240
|
+
if existing == statusline_config:
|
|
241
|
+
print("Settings already configured — no changes needed.")
|
|
242
|
+
else:
|
|
243
|
+
settings["statusLine"] = statusline_config
|
|
244
|
+
with open(settings_path, "w") as f:
|
|
245
|
+
json.dump(settings, f, indent=2)
|
|
246
|
+
print("Updated settings.json with statusLine config.")
|
|
247
|
+
PYEOF
|
|
248
|
+
|
|
249
|
+
ok "Settings configured"
|
|
250
|
+
|
|
251
|
+
# ─── Verify ───────────────────────────────────────────────────────────────────
|
|
252
|
+
|
|
253
|
+
info "Running verification..."
|
|
254
|
+
|
|
255
|
+
TEST_OUTPUT=$(echo '{"model":{"display_name":"Test"},"cwd":"/test","context_window":{"used_percentage":42}}' | python3 "$STATUSLINE_DIR/powerline.py" 2>&1) || true
|
|
256
|
+
|
|
257
|
+
if [[ -n "$TEST_OUTPUT" ]]; then
|
|
258
|
+
ok "Verification passed — script produces output"
|
|
259
|
+
else
|
|
260
|
+
warn "Script produced no output. Check Python 3 compatibility."
|
|
261
|
+
fi
|
|
262
|
+
|
|
263
|
+
# ─── Done ─────────────────────────────────────────────────────────────────────
|
|
264
|
+
|
|
265
|
+
echo ""
|
|
266
|
+
echo -e "${BOLD}${GREEN} Installation complete!${NC}"
|
|
267
|
+
echo ""
|
|
268
|
+
echo -e " ${CYAN}Files:${NC}"
|
|
269
|
+
echo " Script: $STATUSLINE_DIR/powerline.py"
|
|
270
|
+
echo " Config: $STATUSLINE_DIR/config.json"
|
|
271
|
+
echo " Settings: $SETTINGS_FILE"
|
|
272
|
+
echo ""
|
|
273
|
+
echo -e " ${CYAN}Next steps:${NC}"
|
|
274
|
+
echo " 1. Install a Nerd Font (required for powerline/capsule styles)"
|
|
275
|
+
echo " See: fonts/FONTS.md or README.md for instructions"
|
|
276
|
+
echo ""
|
|
277
|
+
echo " 2. Restart Claude Code to see the status line"
|
|
278
|
+
echo ""
|
|
279
|
+
echo -e " ${CYAN}Configuration:${NC}"
|
|
280
|
+
echo " Edit $STATUSLINE_DIR/config.json to change:"
|
|
281
|
+
echo " style: powerline | capsule | tui"
|
|
282
|
+
echo " theme: dark | nord | tokyonight | gruvbox"
|
|
283
|
+
echo " path_levels: number of directory levels to show (default: 2)"
|
|
284
|
+
echo " bar_width: width of progress bars (default: 10)"
|
|
285
|
+
echo ""
|