cc-context-stats 1.7.0 → 1.8.1

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.
Files changed (102) hide show
  1. package/package.json +9 -1
  2. package/scripts/context-stats.sh +1 -1
  3. package/scripts/statusline.js +128 -18
  4. package/.editorconfig +0 -60
  5. package/.eslintrc.json +0 -35
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -49
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -31
  8. package/.github/PULL_REQUEST_TEMPLATE.md +0 -33
  9. package/.github/dependabot.yml +0 -44
  10. package/.github/workflows/ci.yml +0 -294
  11. package/.github/workflows/release.yml +0 -151
  12. package/.pre-commit-config.yaml +0 -74
  13. package/.prettierrc +0 -33
  14. package/.shellcheckrc +0 -10
  15. package/CHANGELOG.md +0 -163
  16. package/CLAUDE.md +0 -66
  17. package/CODE_OF_CONDUCT.md +0 -59
  18. package/CONTRIBUTING.md +0 -240
  19. package/RELEASE_NOTES.md +0 -19
  20. package/SECURITY.md +0 -44
  21. package/TODOS.md +0 -72
  22. package/assets/logo/favicon.svg +0 -19
  23. package/assets/logo/logo-black.svg +0 -24
  24. package/assets/logo/logo-full.svg +0 -40
  25. package/assets/logo/logo-icon.svg +0 -27
  26. package/assets/logo/logo-mark.svg +0 -28
  27. package/assets/logo/logo-white.svg +0 -24
  28. package/assets/logo/logo-wordmark.svg +0 -6
  29. package/config/settings-example.json +0 -7
  30. package/config/settings-node.json +0 -7
  31. package/config/settings-python.json +0 -7
  32. package/docs/ARCHITECTURE.md +0 -128
  33. package/docs/CSV_FORMAT.md +0 -42
  34. package/docs/DEPLOYMENT.md +0 -71
  35. package/docs/DEVELOPMENT.md +0 -161
  36. package/docs/configuration.md +0 -118
  37. package/docs/context-stats.md +0 -143
  38. package/docs/installation.md +0 -255
  39. package/docs/scripts.md +0 -140
  40. package/docs/troubleshooting.md +0 -278
  41. package/images/claude-statusline-token-graph.gif +0 -0
  42. package/images/claude-statusline.png +0 -0
  43. package/images/context-status-dumbzone.png +0 -0
  44. package/images/context-status.png +0 -0
  45. package/images/statusline-detail.png +0 -0
  46. package/images/token-graph.jpeg +0 -0
  47. package/images/token-graph.png +0 -0
  48. package/images/v1.6.1.png +0 -0
  49. package/install +0 -351
  50. package/install.sh +0 -298
  51. package/jest.config.js +0 -11
  52. package/pyproject.toml +0 -115
  53. package/requirements-dev.txt +0 -12
  54. package/scripts/statusline-full.sh +0 -304
  55. package/scripts/statusline-git.sh +0 -88
  56. package/scripts/statusline-minimal.sh +0 -67
  57. package/scripts/statusline.py +0 -485
  58. package/src/claude_statusline/__init__.py +0 -11
  59. package/src/claude_statusline/__main__.py +0 -6
  60. package/src/claude_statusline/cli/__init__.py +0 -1
  61. package/src/claude_statusline/cli/context_stats.py +0 -512
  62. package/src/claude_statusline/cli/explain.py +0 -228
  63. package/src/claude_statusline/cli/statusline.py +0 -169
  64. package/src/claude_statusline/core/__init__.py +0 -1
  65. package/src/claude_statusline/core/colors.py +0 -124
  66. package/src/claude_statusline/core/config.py +0 -148
  67. package/src/claude_statusline/core/git.py +0 -78
  68. package/src/claude_statusline/core/state.py +0 -323
  69. package/src/claude_statusline/formatters/__init__.py +0 -1
  70. package/src/claude_statusline/formatters/layout.py +0 -67
  71. package/src/claude_statusline/formatters/time.py +0 -50
  72. package/src/claude_statusline/formatters/tokens.py +0 -70
  73. package/src/claude_statusline/graphs/__init__.py +0 -1
  74. package/src/claude_statusline/graphs/renderer.py +0 -366
  75. package/src/claude_statusline/graphs/statistics.py +0 -92
  76. package/src/claude_statusline/ui/__init__.py +0 -1
  77. package/src/claude_statusline/ui/icons.py +0 -93
  78. package/src/claude_statusline/ui/waiting.py +0 -62
  79. package/tests/bash/test_delta_parity.bats +0 -199
  80. package/tests/bash/test_install.bats +0 -29
  81. package/tests/bash/test_parity.bats +0 -315
  82. package/tests/bash/test_statusline_full.bats +0 -139
  83. package/tests/bash/test_statusline_git.bats +0 -42
  84. package/tests/bash/test_statusline_minimal.bats +0 -37
  85. package/tests/fixtures/json/comma_in_path.json +0 -31
  86. package/tests/fixtures/json/high_usage.json +0 -17
  87. package/tests/fixtures/json/low_usage.json +0 -17
  88. package/tests/fixtures/json/medium_usage.json +0 -17
  89. package/tests/fixtures/json/valid_full.json +0 -30
  90. package/tests/fixtures/json/valid_minimal.json +0 -9
  91. package/tests/node/rotation.test.js +0 -89
  92. package/tests/node/statusline.test.js +0 -240
  93. package/tests/python/conftest.py +0 -84
  94. package/tests/python/test_colors.py +0 -105
  95. package/tests/python/test_config_colors.py +0 -78
  96. package/tests/python/test_data_pipeline.py +0 -446
  97. package/tests/python/test_explain.py +0 -177
  98. package/tests/python/test_icons.py +0 -152
  99. package/tests/python/test_layout.py +0 -127
  100. package/tests/python/test_state_rotation_validation.py +0 -232
  101. package/tests/python/test_statusline.py +0 -215
  102. package/tests/python/test_waiting.py +0 -127
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
- };
package/pyproject.toml DELETED
@@ -1,115 +0,0 @@
1
- [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
4
-
5
- [project]
6
- name = "cc-context-stats"
7
- version = "1.7.0"
8
- description = "Monitor your Claude Code session context in real-time - track token usage and never run out of context"
9
- readme = "README.md"
10
- license = { text = "MIT" }
11
- requires-python = ">=3.9"
12
- authors = [
13
- { name = "Nguyen Luong", email = "luongnv89@gmail.com" }
14
- ]
15
- keywords = [
16
- "claude",
17
- "claude-code",
18
- "context",
19
- "tokens",
20
- "monitoring",
21
- "statusline",
22
- "terminal",
23
- "cli",
24
- "dashboard",
25
- ]
26
- classifiers = [
27
- "Development Status :: 4 - Beta",
28
- "Environment :: Console",
29
- "Intended Audience :: Developers",
30
- "License :: OSI Approved :: MIT License",
31
- "Operating System :: OS Independent",
32
- "Programming Language :: Python :: 3",
33
- "Programming Language :: Python :: 3.9",
34
- "Programming Language :: Python :: 3.10",
35
- "Programming Language :: Python :: 3.11",
36
- "Programming Language :: Python :: 3.12",
37
- "Programming Language :: Python :: 3.13",
38
- "Topic :: Software Development :: Libraries :: Python Modules",
39
- "Topic :: Utilities",
40
- ]
41
- dependencies = []
42
-
43
- [project.scripts]
44
- claude-statusline = "claude_statusline.cli.statusline:main"
45
- context-stats = "claude_statusline.cli.context_stats:main"
46
-
47
- [project.urls]
48
- Homepage = "https://github.com/luongnv89/cc-context-stats"
49
- Documentation = "https://github.com/luongnv89/cc-context-stats#readme"
50
- Repository = "https://github.com/luongnv89/cc-context-stats"
51
- Issues = "https://github.com/luongnv89/cc-context-stats/issues"
52
-
53
- [project.optional-dependencies]
54
- dev = [
55
- "pytest>=7.4.0",
56
- "pytest-cov>=4.1.0",
57
- "ruff>=0.1.0",
58
- "mypy>=1.7.0",
59
- "build>=1.0.0",
60
- "twine>=4.0.0",
61
- ]
62
-
63
- [tool.hatch.build.targets.wheel]
64
- packages = ["src/claude_statusline"]
65
-
66
- [tool.hatch.build.targets.sdist]
67
- include = [
68
- "/src",
69
- "/README.md",
70
- "/LICENSE",
71
- ]
72
-
73
- [tool.ruff]
74
- target-version = "py39"
75
- line-length = 100
76
- src = ["src"]
77
-
78
- [tool.ruff.lint]
79
- select = [
80
- "E", # pycodestyle errors
81
- "W", # pycodestyle warnings
82
- "F", # Pyflakes
83
- "I", # isort
84
- "B", # flake8-bugbear
85
- "C4", # flake8-comprehensions
86
- "UP", # pyupgrade
87
- ]
88
- ignore = ["E501"] # line too long (handled by formatter)
89
-
90
- [tool.ruff.format]
91
- quote-style = "double"
92
- indent-style = "space"
93
-
94
- [tool.mypy]
95
- python_version = "3.9"
96
- warn_return_any = true
97
- warn_unused_ignores = true
98
- strict_optional = true
99
- ignore_missing_imports = true
100
-
101
- [tool.pytest.ini_options]
102
- testpaths = ["tests/python"]
103
- addopts = "-v --tb=short"
104
- python_files = ["test_*.py"]
105
- python_functions = ["test_*"]
106
-
107
- [tool.coverage.run]
108
- source = ["src/claude_statusline"]
109
- omit = ["tests/*"]
110
-
111
- [tool.coverage.report]
112
- exclude_lines = [
113
- "pragma: no cover",
114
- "if __name__ == .__main__.:",
115
- ]
@@ -1,12 +0,0 @@
1
- # Development dependencies for claude-statusline
2
-
3
- # Testing
4
- pytest>=7.4.0
5
- pytest-cov>=4.1.0
6
-
7
- # Linting and formatting
8
- ruff>=0.1.0
9
- mypy>=1.7.0
10
-
11
- # Pre-commit hooks
12
- pre-commit>=3.6.0