cc-context-stats 1.8.0 → 1.8.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.
- package/package.json +8 -1
- package/scripts/context-stats.sh +1 -1
- package/.editorconfig +0 -60
- package/.eslintrc.json +0 -35
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -49
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -31
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -33
- package/.github/dependabot.yml +0 -44
- package/.github/workflows/ci.yml +0 -294
- package/.github/workflows/release.yml +0 -151
- package/.pre-commit-config.yaml +0 -74
- package/.prettierrc +0 -33
- package/.shellcheckrc +0 -10
- package/CHANGELOG.md +0 -187
- package/CLAUDE.md +0 -66
- package/CODE_OF_CONDUCT.md +0 -59
- package/CONTRIBUTING.md +0 -240
- package/RELEASE_NOTES.md +0 -19
- package/SECURITY.md +0 -44
- package/TODOS.md +0 -72
- package/assets/logo/favicon.svg +0 -19
- package/assets/logo/logo-black.svg +0 -24
- package/assets/logo/logo-full.svg +0 -40
- package/assets/logo/logo-icon.svg +0 -27
- package/assets/logo/logo-mark.svg +0 -28
- package/assets/logo/logo-white.svg +0 -24
- package/assets/logo/logo-wordmark.svg +0 -6
- package/config/settings-example.json +0 -7
- package/config/settings-node.json +0 -7
- package/config/settings-python.json +0 -7
- package/docs/ARCHITECTURE.md +0 -128
- package/docs/CSV_FORMAT.md +0 -42
- package/docs/DEPLOYMENT.md +0 -71
- package/docs/DEVELOPMENT.md +0 -161
- package/docs/MODEL_INTELLIGENCE.md +0 -396
- package/docs/configuration.md +0 -118
- package/docs/context-stats.md +0 -143
- package/docs/installation.md +0 -255
- package/docs/scripts.md +0 -140
- package/docs/troubleshooting.md +0 -278
- package/images/claude-statusline-token-graph.gif +0 -0
- package/images/claude-statusline.png +0 -0
- package/images/context-status-dumbzone.png +0 -0
- package/images/context-status.png +0 -0
- package/images/statusline-detail.png +0 -0
- package/images/token-graph.jpeg +0 -0
- package/images/token-graph.png +0 -0
- package/images/v1.6.1.png +0 -0
- package/install +0 -351
- package/install.sh +0 -298
- package/jest.config.js +0 -11
- package/pyproject.toml +0 -115
- package/requirements-dev.txt +0 -12
- package/scripts/statusline-full.sh +0 -438
- package/scripts/statusline-git.sh +0 -88
- package/scripts/statusline-minimal.sh +0 -67
- package/scripts/statusline.py +0 -569
- package/src/claude_statusline/__init__.py +0 -11
- package/src/claude_statusline/__main__.py +0 -6
- package/src/claude_statusline/cli/__init__.py +0 -1
- package/src/claude_statusline/cli/context_stats.py +0 -542
- package/src/claude_statusline/cli/explain.py +0 -228
- package/src/claude_statusline/cli/statusline.py +0 -184
- package/src/claude_statusline/core/__init__.py +0 -1
- package/src/claude_statusline/core/colors.py +0 -124
- package/src/claude_statusline/core/config.py +0 -165
- package/src/claude_statusline/core/git.py +0 -78
- package/src/claude_statusline/core/state.py +0 -323
- package/src/claude_statusline/formatters/__init__.py +0 -1
- package/src/claude_statusline/formatters/layout.py +0 -67
- package/src/claude_statusline/formatters/time.py +0 -50
- package/src/claude_statusline/formatters/tokens.py +0 -70
- package/src/claude_statusline/graphs/__init__.py +0 -1
- package/src/claude_statusline/graphs/intelligence.py +0 -162
- package/src/claude_statusline/graphs/renderer.py +0 -401
- package/src/claude_statusline/graphs/statistics.py +0 -92
- package/src/claude_statusline/ui/__init__.py +0 -1
- package/src/claude_statusline/ui/icons.py +0 -93
- package/src/claude_statusline/ui/waiting.py +0 -62
- package/tests/bash/test_delta_parity.bats +0 -199
- package/tests/bash/test_install.bats +0 -29
- package/tests/bash/test_parity.bats +0 -315
- package/tests/bash/test_statusline_full.bats +0 -139
- package/tests/bash/test_statusline_git.bats +0 -42
- package/tests/bash/test_statusline_minimal.bats +0 -37
- package/tests/fixtures/json/comma_in_path.json +0 -31
- package/tests/fixtures/json/high_usage.json +0 -17
- package/tests/fixtures/json/low_usage.json +0 -17
- package/tests/fixtures/json/medium_usage.json +0 -17
- package/tests/fixtures/json/valid_full.json +0 -30
- package/tests/fixtures/json/valid_minimal.json +0 -9
- package/tests/fixtures/mi_test_vectors.json +0 -140
- package/tests/node/intelligence.test.js +0 -98
- package/tests/node/rotation.test.js +0 -89
- package/tests/node/statusline.test.js +0 -240
- package/tests/python/conftest.py +0 -84
- package/tests/python/test_colors.py +0 -105
- package/tests/python/test_config_colors.py +0 -78
- package/tests/python/test_data_pipeline.py +0 -446
- package/tests/python/test_explain.py +0 -177
- package/tests/python/test_icons.py +0 -152
- package/tests/python/test_intelligence.py +0 -314
- package/tests/python/test_layout.py +0 -127
- package/tests/python/test_state_rotation_validation.py +0 -232
- package/tests/python/test_statusline.py +0 -215
- package/tests/python/test_waiting.py +0 -127
package/install
DELETED
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# Claude Code Status Line Installer
|
|
4
|
-
# Installs and configures a status line for Claude Code
|
|
5
|
-
#
|
|
6
|
-
# Usage:
|
|
7
|
-
# Local: ./install.sh
|
|
8
|
-
# Remote: curl -fsSL https://raw.githubusercontent.com/luongnv89/claude-statusline/main/install.sh | bash
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
set -e
|
|
12
|
-
|
|
13
|
-
# Colors for output
|
|
14
|
-
RED='\033[0;31m'
|
|
15
|
-
GREEN='\033[0;32m'
|
|
16
|
-
YELLOW='\033[0;33m'
|
|
17
|
-
BLUE='\033[0;34m'
|
|
18
|
-
RESET='\033[0m'
|
|
19
|
-
|
|
20
|
-
CLAUDE_DIR="$HOME/.claude"
|
|
21
|
-
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
|
|
22
|
-
LOCAL_BIN="$HOME/.local/bin"
|
|
23
|
-
|
|
24
|
-
# GitHub repository info for remote installation
|
|
25
|
-
GITHUB_RAW_URL="https://raw.githubusercontent.com/luongnv89/claude-statusline/main"
|
|
26
|
-
GITHUB_API_URL="https://api.github.com/repos/luongnv89/claude-statusline"
|
|
27
|
-
|
|
28
|
-
# Detect if running from pipe (curl) or locally
|
|
29
|
-
detect_install_mode() {
|
|
30
|
-
# Check if we have a valid script file with scripts directory
|
|
31
|
-
if [ -n "${BASH_SOURCE[0]}" ] && [ -f "${BASH_SOURCE[0]}" ]; then
|
|
32
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
33
|
-
if [ -d "$SCRIPT_DIR/scripts" ]; then
|
|
34
|
-
INSTALL_MODE="local"
|
|
35
|
-
INTERACTIVE=true
|
|
36
|
-
[ -t 0 ] || INTERACTIVE=false
|
|
37
|
-
return
|
|
38
|
-
fi
|
|
39
|
-
fi
|
|
40
|
-
# Running from curl/pipe or script directory not found
|
|
41
|
-
INSTALL_MODE="remote"
|
|
42
|
-
INTERACTIVE=false
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
echo -e "${BLUE}Claude Code Status Line Installer${RESET}"
|
|
46
|
-
echo "=================================="
|
|
47
|
-
echo
|
|
48
|
-
|
|
49
|
-
detect_install_mode
|
|
50
|
-
|
|
51
|
-
if [ "$INSTALL_MODE" = "remote" ]; then
|
|
52
|
-
echo -e "${YELLOW}Remote installation mode${RESET}"
|
|
53
|
-
echo "Downloading from GitHub..."
|
|
54
|
-
echo
|
|
55
|
-
else
|
|
56
|
-
echo -e "${GREEN}Local installation mode${RESET}"
|
|
57
|
-
echo
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Check for curl (required for remote installation)
|
|
61
|
-
check_curl() {
|
|
62
|
-
if [ "$INSTALL_MODE" = "remote" ]; then
|
|
63
|
-
if ! command -v curl &>/dev/null; then
|
|
64
|
-
echo -e "${RED}Error: 'curl' is required for remote installation${RESET}"
|
|
65
|
-
exit 1
|
|
66
|
-
fi
|
|
67
|
-
fi
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
# Check for jq (required for bash scripts)
|
|
71
|
-
check_jq() {
|
|
72
|
-
if ! command -v jq &>/dev/null; then
|
|
73
|
-
echo -e "${YELLOW}Warning: 'jq' is not installed.${RESET}"
|
|
74
|
-
echo "jq is required for bash status line scripts."
|
|
75
|
-
echo
|
|
76
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
77
|
-
echo "Install with: brew install jq"
|
|
78
|
-
else
|
|
79
|
-
echo "Install with: sudo apt install jq (Debian/Ubuntu)"
|
|
80
|
-
echo " or: sudo yum install jq (RHEL/CentOS)"
|
|
81
|
-
fi
|
|
82
|
-
echo
|
|
83
|
-
if [ "$INTERACTIVE" = true ]; then
|
|
84
|
-
read -p "Continue anyway? (y/n) " -n 1 -r
|
|
85
|
-
echo
|
|
86
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
87
|
-
exit 1
|
|
88
|
-
fi
|
|
89
|
-
fi
|
|
90
|
-
else
|
|
91
|
-
echo -e "${GREEN}✓${RESET} jq is installed"
|
|
92
|
-
fi
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# Download a file from GitHub
|
|
96
|
-
download_file() {
|
|
97
|
-
local remote_path="$1"
|
|
98
|
-
local dest_path="$2"
|
|
99
|
-
local url="$GITHUB_RAW_URL/$remote_path"
|
|
100
|
-
|
|
101
|
-
if curl -fsSL "$url" -o "$dest_path"; then
|
|
102
|
-
chmod +x "$dest_path"
|
|
103
|
-
return 0
|
|
104
|
-
else
|
|
105
|
-
echo -e "${RED}Error: Failed to download $remote_path${RESET}"
|
|
106
|
-
return 1
|
|
107
|
-
fi
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
# Get latest commit hash from GitHub
|
|
111
|
-
get_remote_commit_hash() {
|
|
112
|
-
local hash
|
|
113
|
-
hash=$(curl -fsSL "$GITHUB_API_URL/commits/main" 2>/dev/null | grep -m1 '"sha"' | cut -d'"' -f4 | head -c7)
|
|
114
|
-
echo "${hash:-unknown}"
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# Select script type
|
|
118
|
-
select_script() {
|
|
119
|
-
echo
|
|
120
|
-
echo "Available status line scripts:"
|
|
121
|
-
echo " 1) minimal - Simple: model + directory"
|
|
122
|
-
echo " 2) git - With git branch info"
|
|
123
|
-
echo " 3) full - Full featured with context usage (recommended)"
|
|
124
|
-
echo " 4) python - Python version (full featured)"
|
|
125
|
-
echo " 5) node - Node.js version (full featured)"
|
|
126
|
-
echo
|
|
127
|
-
|
|
128
|
-
if [ "$INTERACTIVE" = true ]; then
|
|
129
|
-
read -rp "Select script [1-5, default: 3]: " choice
|
|
130
|
-
else
|
|
131
|
-
echo "Non-interactive mode detected. Using default: full (3)"
|
|
132
|
-
choice=3
|
|
133
|
-
fi
|
|
134
|
-
|
|
135
|
-
case ${choice:-3} in
|
|
136
|
-
1)
|
|
137
|
-
SCRIPT_REMOTE="scripts/statusline-minimal.sh"
|
|
138
|
-
SCRIPT_NAME="statusline.sh"
|
|
139
|
-
;;
|
|
140
|
-
2)
|
|
141
|
-
SCRIPT_REMOTE="scripts/statusline-git.sh"
|
|
142
|
-
SCRIPT_NAME="statusline.sh"
|
|
143
|
-
;;
|
|
144
|
-
3)
|
|
145
|
-
SCRIPT_REMOTE="scripts/statusline-full.sh"
|
|
146
|
-
SCRIPT_NAME="statusline.sh"
|
|
147
|
-
;;
|
|
148
|
-
4)
|
|
149
|
-
SCRIPT_REMOTE="scripts/statusline.py"
|
|
150
|
-
SCRIPT_NAME="statusline.py"
|
|
151
|
-
;;
|
|
152
|
-
5)
|
|
153
|
-
SCRIPT_REMOTE="scripts/statusline.js"
|
|
154
|
-
SCRIPT_NAME="statusline.js"
|
|
155
|
-
;;
|
|
156
|
-
*)
|
|
157
|
-
echo -e "${RED}Invalid choice${RESET}"
|
|
158
|
-
exit 1
|
|
159
|
-
;;
|
|
160
|
-
esac
|
|
161
|
-
|
|
162
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
163
|
-
SCRIPT_SRC="$SCRIPT_DIR/$SCRIPT_REMOTE"
|
|
164
|
-
fi
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
# Create .claude directory if needed
|
|
168
|
-
ensure_claude_dir() {
|
|
169
|
-
if [ ! -d "$CLAUDE_DIR" ]; then
|
|
170
|
-
echo -e "${YELLOW}Creating $CLAUDE_DIR directory...${RESET}"
|
|
171
|
-
mkdir -p "$CLAUDE_DIR"
|
|
172
|
-
fi
|
|
173
|
-
echo -e "${GREEN}✓${RESET} Claude directory exists: $CLAUDE_DIR"
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
# Install/copy script
|
|
177
|
-
install_script() {
|
|
178
|
-
DEST="$CLAUDE_DIR/$SCRIPT_NAME"
|
|
179
|
-
|
|
180
|
-
if [ -f "$DEST" ]; then
|
|
181
|
-
echo
|
|
182
|
-
echo -e "${YELLOW}Warning: $DEST already exists${RESET}"
|
|
183
|
-
if [ "$INTERACTIVE" = true ]; then
|
|
184
|
-
read -p "Overwrite? (y/n) " -n 1 -r
|
|
185
|
-
echo
|
|
186
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
187
|
-
echo "Keeping existing script."
|
|
188
|
-
return
|
|
189
|
-
fi
|
|
190
|
-
else
|
|
191
|
-
echo "Overwriting in non-interactive mode..."
|
|
192
|
-
fi
|
|
193
|
-
fi
|
|
194
|
-
|
|
195
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
196
|
-
cp "$SCRIPT_SRC" "$DEST"
|
|
197
|
-
chmod +x "$DEST"
|
|
198
|
-
else
|
|
199
|
-
download_file "$SCRIPT_REMOTE" "$DEST"
|
|
200
|
-
fi
|
|
201
|
-
echo -e "${GREEN}✓${RESET} Installed: $DEST"
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
# Install token-graph CLI tool
|
|
205
|
-
install_token_graph() {
|
|
206
|
-
echo
|
|
207
|
-
|
|
208
|
-
# Create ~/.local/bin if it doesn't exist
|
|
209
|
-
if [ ! -d "$LOCAL_BIN" ]; then
|
|
210
|
-
echo -e "${YELLOW}Creating $LOCAL_BIN directory...${RESET}"
|
|
211
|
-
mkdir -p "$LOCAL_BIN"
|
|
212
|
-
fi
|
|
213
|
-
|
|
214
|
-
DEST="$LOCAL_BIN/token-graph"
|
|
215
|
-
|
|
216
|
-
if [ -f "$DEST" ]; then
|
|
217
|
-
echo -e "${YELLOW}Warning: $DEST already exists${RESET}"
|
|
218
|
-
if [ "$INTERACTIVE" = true ]; then
|
|
219
|
-
read -p "Overwrite? (y/n) " -n 1 -r
|
|
220
|
-
echo
|
|
221
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
222
|
-
echo "Keeping existing token-graph."
|
|
223
|
-
return
|
|
224
|
-
fi
|
|
225
|
-
else
|
|
226
|
-
echo "Overwriting in non-interactive mode..."
|
|
227
|
-
fi
|
|
228
|
-
fi
|
|
229
|
-
|
|
230
|
-
# Get commit hash for version embedding
|
|
231
|
-
local commit_hash
|
|
232
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
233
|
-
commit_hash=$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
234
|
-
cp "$SCRIPT_DIR/scripts/token-graph.sh" "$DEST"
|
|
235
|
-
else
|
|
236
|
-
commit_hash=$(get_remote_commit_hash)
|
|
237
|
-
download_file "scripts/token-graph.sh" "$DEST"
|
|
238
|
-
fi
|
|
239
|
-
|
|
240
|
-
# Embed version and commit hash
|
|
241
|
-
local pkg_version
|
|
242
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
243
|
-
pkg_version=$(grep -o '"version": *"[^"]*"' "$SCRIPT_DIR/package.json" | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
244
|
-
else
|
|
245
|
-
pkg_version=$(curl -fsSL "${GITHUB_RAW_URL}/package.json" 2>/dev/null | grep -o '"version": *"[^"]*"' | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
246
|
-
fi
|
|
247
|
-
[ -n "$pkg_version" ] && sed -i.bak "s/VERSION=\"[^\"]*\"/VERSION=\"$pkg_version\"/" "$DEST" && rm -f "$DEST.bak"
|
|
248
|
-
sed -i.bak "s/COMMIT_HASH=\"dev\"/COMMIT_HASH=\"$commit_hash\"/" "$DEST" && rm -f "$DEST.bak"
|
|
249
|
-
chmod +x "$DEST"
|
|
250
|
-
echo -e "${GREEN}✓${RESET} Installed: $DEST (v${pkg_version:-1.6.0}-$commit_hash)"
|
|
251
|
-
|
|
252
|
-
# Check if ~/.local/bin is in PATH
|
|
253
|
-
if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then
|
|
254
|
-
echo
|
|
255
|
-
echo -e "${YELLOW}Note: $LOCAL_BIN is not in your PATH${RESET}"
|
|
256
|
-
echo "Add it to your shell configuration:"
|
|
257
|
-
echo
|
|
258
|
-
if [[ "$SHELL" == *"zsh"* ]]; then
|
|
259
|
-
echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.zshrc"
|
|
260
|
-
echo " source ~/.zshrc"
|
|
261
|
-
else
|
|
262
|
-
echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.bashrc"
|
|
263
|
-
echo " source ~/.bashrc"
|
|
264
|
-
fi
|
|
265
|
-
fi
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
# Create config file with defaults if it doesn't exist
|
|
269
|
-
create_config() {
|
|
270
|
-
CONFIG_FILE="$CLAUDE_DIR/statusline.conf"
|
|
271
|
-
|
|
272
|
-
if [ -f "$CONFIG_FILE" ]; then
|
|
273
|
-
echo -e "${GREEN}✓${RESET} Config file exists: $CONFIG_FILE"
|
|
274
|
-
return
|
|
275
|
-
fi
|
|
276
|
-
|
|
277
|
-
cat >"$CONFIG_FILE" <<'EOF'
|
|
278
|
-
# Autocompact setting - sync with Claude Code's /config
|
|
279
|
-
autocompact=true
|
|
280
|
-
|
|
281
|
-
# Token display format
|
|
282
|
-
token_detail=true
|
|
283
|
-
|
|
284
|
-
# Show token delta since last refresh (adds file I/O on every refresh)
|
|
285
|
-
# Disable if you don't need it to reduce overhead
|
|
286
|
-
show_delta=true
|
|
287
|
-
|
|
288
|
-
# Show session_id in status line
|
|
289
|
-
show_session=true
|
|
290
|
-
EOF
|
|
291
|
-
echo -e "${GREEN}✓${RESET} Created config file: $CONFIG_FILE"
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
# Update settings.json
|
|
295
|
-
update_settings() {
|
|
296
|
-
echo
|
|
297
|
-
|
|
298
|
-
# Create settings file if it doesn't exist
|
|
299
|
-
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
300
|
-
echo '{}' >"$SETTINGS_FILE"
|
|
301
|
-
echo -e "${GREEN}✓${RESET} Created $SETTINGS_FILE"
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
|
-
# Check if jq is available for JSON manipulation
|
|
305
|
-
if command -v jq &>/dev/null; then
|
|
306
|
-
# Backup existing settings
|
|
307
|
-
cp "$SETTINGS_FILE" "$SETTINGS_FILE.backup"
|
|
308
|
-
|
|
309
|
-
# Add/update statusLine configuration
|
|
310
|
-
SCRIPT_PATH="$HOME/.claude/$SCRIPT_NAME"
|
|
311
|
-
jq --arg cmd "$SCRIPT_PATH" '.statusLine = {"type": "command", "command": $cmd}' \
|
|
312
|
-
"$SETTINGS_FILE.backup" >"$SETTINGS_FILE"
|
|
313
|
-
|
|
314
|
-
rm "$SETTINGS_FILE.backup"
|
|
315
|
-
echo -e "${GREEN}✓${RESET} Updated settings.json with statusLine configuration"
|
|
316
|
-
else
|
|
317
|
-
echo -e "${YELLOW}Note: Could not update settings.json (jq not installed)${RESET}"
|
|
318
|
-
echo
|
|
319
|
-
echo "Please add this to $SETTINGS_FILE manually:"
|
|
320
|
-
echo
|
|
321
|
-
echo ' "statusLine": {'
|
|
322
|
-
echo ' "type": "command",'
|
|
323
|
-
echo " \"command\": \"~/.claude/$SCRIPT_NAME\""
|
|
324
|
-
echo ' }'
|
|
325
|
-
fi
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
# Main installation
|
|
329
|
-
main() {
|
|
330
|
-
check_curl
|
|
331
|
-
check_jq
|
|
332
|
-
ensure_claude_dir
|
|
333
|
-
select_script
|
|
334
|
-
install_script
|
|
335
|
-
install_token_graph
|
|
336
|
-
create_config
|
|
337
|
-
update_settings
|
|
338
|
-
|
|
339
|
-
echo
|
|
340
|
-
echo -e "${GREEN}Installation complete!${RESET}"
|
|
341
|
-
echo
|
|
342
|
-
echo "Your status line is now configured."
|
|
343
|
-
echo "Restart Claude Code to see the changes."
|
|
344
|
-
echo
|
|
345
|
-
echo "To customize, edit: $CLAUDE_DIR/$SCRIPT_NAME"
|
|
346
|
-
echo "To change settings, edit: $CLAUDE_DIR/statusline.conf"
|
|
347
|
-
echo
|
|
348
|
-
echo "Run 'token-graph' to visualize token usage for any session."
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
main
|
package/install.sh
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# Claude Code Context Stats Installer
|
|
4
|
-
# Installs and configures context monitoring for Claude Code
|
|
5
|
-
#
|
|
6
|
-
# Features:
|
|
7
|
-
# - Real-time context usage monitoring (status line integration)
|
|
8
|
-
# - Live dashboard with context-stats CLI tool
|
|
9
|
-
# - Automatic detection of Smart Zone, Dumb Zone, and Wrap Up Zone
|
|
10
|
-
# - Local data storage in ~/.claude/statusline/
|
|
11
|
-
#
|
|
12
|
-
# Usage:
|
|
13
|
-
# Local: ./install.sh
|
|
14
|
-
# Remote: curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/install.sh | bash
|
|
15
|
-
#
|
|
16
|
-
# Requirements:
|
|
17
|
-
# - curl (for remote installation)
|
|
18
|
-
# - jq (for JSON configuration, optional but recommended)
|
|
19
|
-
#
|
|
20
|
-
# What gets installed:
|
|
21
|
-
# - ~/.claude/statusline.sh - Status line command
|
|
22
|
-
# - ~/.local/bin/context-stats - CLI tool for live context monitoring
|
|
23
|
-
# - ~/.claude/statusline.conf - Configuration file
|
|
24
|
-
# - ~/.claude/settings.json - Claude Code settings updated
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
set -e
|
|
28
|
-
|
|
29
|
-
# Colors for output
|
|
30
|
-
RED='\033[0;31m'
|
|
31
|
-
GREEN='\033[0;32m'
|
|
32
|
-
YELLOW='\033[0;33m'
|
|
33
|
-
BLUE='\033[0;34m'
|
|
34
|
-
RESET='\033[0m'
|
|
35
|
-
|
|
36
|
-
CLAUDE_DIR="$HOME/.claude"
|
|
37
|
-
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
|
|
38
|
-
LOCAL_BIN="$HOME/.local/bin"
|
|
39
|
-
|
|
40
|
-
# GitHub repository info for remote installation
|
|
41
|
-
GITHUB_RAW_URL="https://raw.githubusercontent.com/luongnv89/cc-context-stats/main"
|
|
42
|
-
GITHUB_API_URL="https://api.github.com/repos/luongnv89/cc-context-stats"
|
|
43
|
-
|
|
44
|
-
# Detect if running from pipe (curl) or locally
|
|
45
|
-
detect_install_mode() {
|
|
46
|
-
# Check if we have a valid script file with scripts directory
|
|
47
|
-
if [ -n "${BASH_SOURCE[0]}" ] && [ -f "${BASH_SOURCE[0]}" ]; then
|
|
48
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
49
|
-
if [ -d "$SCRIPT_DIR/scripts" ]; then
|
|
50
|
-
INSTALL_MODE="local"
|
|
51
|
-
INTERACTIVE=true
|
|
52
|
-
[ -t 0 ] || INTERACTIVE=false
|
|
53
|
-
return
|
|
54
|
-
fi
|
|
55
|
-
fi
|
|
56
|
-
# Running from curl/pipe or script directory not found
|
|
57
|
-
INSTALL_MODE="remote"
|
|
58
|
-
INTERACTIVE=false
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
echo -e "${BLUE}Claude Code Status Line Installer${RESET}"
|
|
62
|
-
echo "=================================="
|
|
63
|
-
echo
|
|
64
|
-
|
|
65
|
-
detect_install_mode
|
|
66
|
-
|
|
67
|
-
if [ "$INSTALL_MODE" = "remote" ]; then
|
|
68
|
-
echo -e "${YELLOW}Remote installation mode${RESET}"
|
|
69
|
-
echo "Downloading from GitHub..."
|
|
70
|
-
echo
|
|
71
|
-
else
|
|
72
|
-
echo -e "${GREEN}Local installation mode${RESET}"
|
|
73
|
-
echo
|
|
74
|
-
fi
|
|
75
|
-
|
|
76
|
-
# Check for curl (required for remote installation)
|
|
77
|
-
check_curl() {
|
|
78
|
-
if [ "$INSTALL_MODE" = "remote" ]; then
|
|
79
|
-
if ! command -v curl &>/dev/null; then
|
|
80
|
-
echo -e "${RED}Error: 'curl' is required for remote installation${RESET}"
|
|
81
|
-
exit 1
|
|
82
|
-
fi
|
|
83
|
-
fi
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
# Check for jq (required for bash scripts)
|
|
87
|
-
check_jq() {
|
|
88
|
-
if ! command -v jq &>/dev/null; then
|
|
89
|
-
echo -e "${YELLOW}Warning: 'jq' is not installed.${RESET}"
|
|
90
|
-
echo "jq is required for bash status line scripts."
|
|
91
|
-
echo
|
|
92
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
93
|
-
echo "Install with: brew install jq"
|
|
94
|
-
else
|
|
95
|
-
echo "Install with: sudo apt install jq (Debian/Ubuntu)"
|
|
96
|
-
echo " or: sudo yum install jq (RHEL/CentOS)"
|
|
97
|
-
fi
|
|
98
|
-
echo
|
|
99
|
-
if [ "$INTERACTIVE" = true ]; then
|
|
100
|
-
read -p "Continue anyway? (y/n) " -n 1 -r
|
|
101
|
-
echo
|
|
102
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
103
|
-
exit 1
|
|
104
|
-
fi
|
|
105
|
-
fi
|
|
106
|
-
else
|
|
107
|
-
echo -e "${GREEN}✓${RESET} jq is installed"
|
|
108
|
-
fi
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
# Download a file from GitHub
|
|
112
|
-
download_file() {
|
|
113
|
-
local remote_path="$1"
|
|
114
|
-
local dest_path="$2"
|
|
115
|
-
local url="$GITHUB_RAW_URL/$remote_path"
|
|
116
|
-
|
|
117
|
-
if curl -fsSL "$url" -o "$dest_path"; then
|
|
118
|
-
chmod +x "$dest_path"
|
|
119
|
-
return 0
|
|
120
|
-
else
|
|
121
|
-
echo -e "${RED}Error: Failed to download $remote_path${RESET}"
|
|
122
|
-
return 1
|
|
123
|
-
fi
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
# Get latest commit hash from GitHub
|
|
127
|
-
get_remote_commit_hash() {
|
|
128
|
-
local hash
|
|
129
|
-
hash=$(curl -fsSL "$GITHUB_API_URL/commits/main" 2>/dev/null | grep -m1 '"sha"' | cut -d'"' -f4 | head -c7)
|
|
130
|
-
echo "${hash:-unknown}"
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
# Set script to install (full featured bash script)
|
|
134
|
-
select_script() {
|
|
135
|
-
SCRIPT_REMOTE="scripts/statusline-full.sh"
|
|
136
|
-
SCRIPT_NAME="statusline.sh"
|
|
137
|
-
|
|
138
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
139
|
-
SCRIPT_SRC="$SCRIPT_DIR/$SCRIPT_REMOTE"
|
|
140
|
-
fi
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
# Create .claude directory if needed
|
|
144
|
-
ensure_claude_dir() {
|
|
145
|
-
if [ ! -d "$CLAUDE_DIR" ]; then
|
|
146
|
-
echo -e "${YELLOW}Creating $CLAUDE_DIR directory...${RESET}"
|
|
147
|
-
mkdir -p "$CLAUDE_DIR"
|
|
148
|
-
fi
|
|
149
|
-
echo -e "${GREEN}✓${RESET} Claude directory exists: $CLAUDE_DIR"
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
# Install/copy script
|
|
153
|
-
install_script() {
|
|
154
|
-
DEST="$CLAUDE_DIR/$SCRIPT_NAME"
|
|
155
|
-
|
|
156
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
157
|
-
cp "$SCRIPT_SRC" "$DEST"
|
|
158
|
-
chmod +x "$DEST"
|
|
159
|
-
else
|
|
160
|
-
download_file "$SCRIPT_REMOTE" "$DEST"
|
|
161
|
-
fi
|
|
162
|
-
echo -e "${GREEN}✓${RESET} Installed: $DEST"
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
# Install context-stats CLI tool
|
|
166
|
-
install_context_stats() {
|
|
167
|
-
# Create ~/.local/bin if it doesn't exist
|
|
168
|
-
if [ ! -d "$LOCAL_BIN" ]; then
|
|
169
|
-
mkdir -p "$LOCAL_BIN"
|
|
170
|
-
fi
|
|
171
|
-
|
|
172
|
-
DEST="$LOCAL_BIN/context-stats"
|
|
173
|
-
|
|
174
|
-
# Get commit hash for version embedding
|
|
175
|
-
local commit_hash
|
|
176
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
177
|
-
commit_hash=$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
178
|
-
cp "$SCRIPT_DIR/scripts/context-stats.sh" "$DEST"
|
|
179
|
-
else
|
|
180
|
-
commit_hash=$(get_remote_commit_hash)
|
|
181
|
-
download_file "scripts/context-stats.sh" "$DEST"
|
|
182
|
-
fi
|
|
183
|
-
|
|
184
|
-
# Embed version and commit hash
|
|
185
|
-
local pkg_version
|
|
186
|
-
if [ "$INSTALL_MODE" = "local" ]; then
|
|
187
|
-
pkg_version=$(grep -o '"version": *"[^"]*"' "$SCRIPT_DIR/package.json" | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
188
|
-
else
|
|
189
|
-
pkg_version=$(curl -fsSL "${GITHUB_RAW_URL}/package.json" 2>/dev/null | grep -o '"version": *"[^"]*"' | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
190
|
-
fi
|
|
191
|
-
[ -n "$pkg_version" ] && sed -i.bak "s/VERSION=\"[^\"]*\"/VERSION=\"$pkg_version\"/" "$DEST" && rm -f "$DEST.bak"
|
|
192
|
-
sed -i.bak "s/COMMIT_HASH=\"dev\"/COMMIT_HASH=\"$commit_hash\"/" "$DEST" && rm -f "$DEST.bak"
|
|
193
|
-
chmod +x "$DEST"
|
|
194
|
-
echo -e "${GREEN}✓${RESET} Installed: $DEST"
|
|
195
|
-
|
|
196
|
-
# Check if ~/.local/bin is in PATH
|
|
197
|
-
if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then
|
|
198
|
-
echo
|
|
199
|
-
echo -e "${YELLOW}Note: $LOCAL_BIN is not in your PATH${RESET}"
|
|
200
|
-
echo "Add it to your shell configuration:"
|
|
201
|
-
echo
|
|
202
|
-
if [[ "$SHELL" == *"zsh"* ]]; then
|
|
203
|
-
echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.zshrc"
|
|
204
|
-
echo " source ~/.zshrc"
|
|
205
|
-
else
|
|
206
|
-
echo " echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.bashrc"
|
|
207
|
-
echo " source ~/.bashrc"
|
|
208
|
-
fi
|
|
209
|
-
fi
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
# Create config file with defaults if it doesn't exist
|
|
213
|
-
create_config() {
|
|
214
|
-
CONFIG_FILE="$CLAUDE_DIR/statusline.conf"
|
|
215
|
-
|
|
216
|
-
if [ -f "$CONFIG_FILE" ]; then
|
|
217
|
-
echo -e "${GREEN}✓${RESET} Config file exists: $CONFIG_FILE"
|
|
218
|
-
return
|
|
219
|
-
fi
|
|
220
|
-
|
|
221
|
-
cat >"$CONFIG_FILE" <<'EOF'
|
|
222
|
-
# Autocompact setting - sync with Claude Code's /config
|
|
223
|
-
autocompact=true
|
|
224
|
-
|
|
225
|
-
# Token display format
|
|
226
|
-
token_detail=true
|
|
227
|
-
|
|
228
|
-
# Show token delta since last refresh (adds file I/O on every refresh)
|
|
229
|
-
# Disable if you don't need it to reduce overhead
|
|
230
|
-
show_delta=true
|
|
231
|
-
|
|
232
|
-
# Show session_id in status line
|
|
233
|
-
show_session=true
|
|
234
|
-
|
|
235
|
-
# Disable rotating text animations
|
|
236
|
-
reduced_motion=false
|
|
237
|
-
EOF
|
|
238
|
-
echo -e "${GREEN}✓${RESET} Created config file: $CONFIG_FILE"
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
# Update settings.json
|
|
242
|
-
update_settings() {
|
|
243
|
-
echo
|
|
244
|
-
|
|
245
|
-
# Create settings file if it doesn't exist
|
|
246
|
-
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
247
|
-
echo '{}' >"$SETTINGS_FILE"
|
|
248
|
-
echo -e "${GREEN}✓${RESET} Created $SETTINGS_FILE"
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
# Check if jq is available for JSON manipulation
|
|
252
|
-
if command -v jq &>/dev/null; then
|
|
253
|
-
# Backup existing settings
|
|
254
|
-
cp "$SETTINGS_FILE" "$SETTINGS_FILE.backup"
|
|
255
|
-
|
|
256
|
-
# Add/update statusLine configuration
|
|
257
|
-
SCRIPT_PATH="$HOME/.claude/$SCRIPT_NAME"
|
|
258
|
-
jq --arg cmd "$SCRIPT_PATH" '.statusLine = {"type": "command", "command": $cmd}' \
|
|
259
|
-
"$SETTINGS_FILE.backup" >"$SETTINGS_FILE"
|
|
260
|
-
|
|
261
|
-
rm "$SETTINGS_FILE.backup"
|
|
262
|
-
echo -e "${GREEN}✓${RESET} Updated settings.json with statusLine configuration"
|
|
263
|
-
else
|
|
264
|
-
echo -e "${YELLOW}Note: Could not update settings.json (jq not installed)${RESET}"
|
|
265
|
-
echo
|
|
266
|
-
echo "Please add this to $SETTINGS_FILE manually:"
|
|
267
|
-
echo
|
|
268
|
-
echo ' "statusLine": {'
|
|
269
|
-
echo ' "type": "command",'
|
|
270
|
-
echo " \"command\": \"~/.claude/$SCRIPT_NAME\""
|
|
271
|
-
echo ' }'
|
|
272
|
-
fi
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
# Main installation
|
|
276
|
-
main() {
|
|
277
|
-
check_curl
|
|
278
|
-
check_jq
|
|
279
|
-
ensure_claude_dir
|
|
280
|
-
select_script
|
|
281
|
-
install_script
|
|
282
|
-
install_context_stats
|
|
283
|
-
create_config
|
|
284
|
-
update_settings
|
|
285
|
-
|
|
286
|
-
echo
|
|
287
|
-
echo -e "${GREEN}Installation complete!${RESET}"
|
|
288
|
-
echo
|
|
289
|
-
echo "Your status line is now configured."
|
|
290
|
-
echo "Restart Claude Code to see the changes."
|
|
291
|
-
echo
|
|
292
|
-
echo "To customize, edit: $CLAUDE_DIR/$SCRIPT_NAME"
|
|
293
|
-
echo "To change settings, edit: $CLAUDE_DIR/statusline.conf"
|
|
294
|
-
echo
|
|
295
|
-
echo "Run 'context-stats' to visualize token usage for any session."
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
main
|
package/jest.config.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** @type {import('jest').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
testMatch: ['**/tests/node/**/*.test.js'],
|
|
5
|
-
collectCoverageFrom: ['scripts/statusline.js'],
|
|
6
|
-
coverageDirectory: 'coverage/node',
|
|
7
|
-
coverageReporters: ['text', 'lcov', 'html'],
|
|
8
|
-
modulePathIgnorePatterns: ['<rootDir>/tests/fixtures/'],
|
|
9
|
-
verbose: true,
|
|
10
|
-
testTimeout: 10000,
|
|
11
|
-
};
|