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.
- package/package.json +9 -1
- package/scripts/context-stats.sh +1 -1
- package/scripts/statusline.js +128 -18
- 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 -163
- 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/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 -304
- package/scripts/statusline-git.sh +0 -88
- package/scripts/statusline-minimal.sh +0 -67
- package/scripts/statusline.py +0 -485
- 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 -512
- package/src/claude_statusline/cli/explain.py +0 -228
- package/src/claude_statusline/cli/statusline.py +0 -169
- 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 -148
- 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/renderer.py +0 -366
- 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/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_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/assets/logo/favicon.svg
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="fav-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
4
|
-
<stop offset="0%" stop-color="#22C55E"/>
|
|
5
|
-
<stop offset="50%" stop-color="#E9AB34"/>
|
|
6
|
-
<stop offset="100%" stop-color="#EF4444"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
</defs>
|
|
9
|
-
|
|
10
|
-
<!-- Background -->
|
|
11
|
-
<rect width="16" height="16" rx="3" fill="#1A1A1A"/>
|
|
12
|
-
|
|
13
|
-
<!-- Simplified wave for 16x16 -->
|
|
14
|
-
<path d="M 2 12 C 4 12, 5 10, 7 8 C 9 6, 10 4, 12 3 C 13 2, 14 3, 14 2.5"
|
|
15
|
-
stroke="url(#fav-grad)" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
|
16
|
-
|
|
17
|
-
<!-- Dot -->
|
|
18
|
-
<circle cx="12" cy="3" r="1.5" fill="#E9AB34"/>
|
|
19
|
-
</svg>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 72" width="360" height="72">
|
|
2
|
-
<!-- Black version for light backgrounds — no background rectangle -->
|
|
3
|
-
|
|
4
|
-
<!-- Mark: Context wave -->
|
|
5
|
-
<g transform="translate(8, 4)">
|
|
6
|
-
<path d="M 10 48 C 16 48, 18 42, 22 40 C 26 38, 28 36, 32 32 C 36 28, 38 22, 42 18 C 46 14, 50 16, 54 14"
|
|
7
|
-
stroke="#1A1A1A" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8
|
-
<path d="M 10 52 C 16 52, 18 46, 22 44 C 26 42, 28 40, 32 36 C 36 32, 38 26, 42 22 C 46 18, 50 20, 54 18"
|
|
9
|
-
stroke="#1A1A1A" stroke-width="1.5" fill="none" stroke-linecap="round" opacity="0.25"/>
|
|
10
|
-
<circle cx="42" cy="18" r="3.5" fill="#1A1A1A"/>
|
|
11
|
-
<circle cx="42" cy="18" r="6" fill="#1A1A1A" opacity="0.12"/>
|
|
12
|
-
<line x1="10" y1="54" x2="54" y2="54" stroke="#1A1A1A" stroke-width="1" stroke-linecap="round" opacity="0.3"/>
|
|
13
|
-
</g>
|
|
14
|
-
|
|
15
|
-
<!-- Divider -->
|
|
16
|
-
<line x1="76" y1="16" x2="76" y2="56" stroke="#1A1A1A" stroke-width="1" opacity="0.2"/>
|
|
17
|
-
|
|
18
|
-
<!-- Wordmark -->
|
|
19
|
-
<text x="90" y="35" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="22" font-weight="700" fill="#1A1A1A" letter-spacing="-0.3">cc-context</text>
|
|
20
|
-
<text x="90" y="55" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="15" font-weight="500" fill="#1A1A1A" letter-spacing="3" opacity="0.6">stats</text>
|
|
21
|
-
|
|
22
|
-
<!-- Right accent bar -->
|
|
23
|
-
<rect x="348" y="20" width="2" height="32" rx="1" fill="#1A1A1A" opacity="0.35"/>
|
|
24
|
-
</svg>
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 72" width="360" height="72">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="full-wave-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
4
|
-
<stop offset="0%" stop-color="#22C55E"/>
|
|
5
|
-
<stop offset="50%" stop-color="#E9AB34"/>
|
|
6
|
-
<stop offset="100%" stop-color="#EF4444"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
</defs>
|
|
9
|
-
|
|
10
|
-
<!-- Background pill -->
|
|
11
|
-
<rect width="360" height="72" rx="14" fill="#1A1A1A"/>
|
|
12
|
-
|
|
13
|
-
<!-- Mark: Context wave in left area -->
|
|
14
|
-
<g transform="translate(8, 4)">
|
|
15
|
-
<!-- Context wave -->
|
|
16
|
-
<path d="M 10 48 C 16 48, 18 42, 22 40 C 26 38, 28 36, 32 32 C 36 28, 38 22, 42 18 C 46 14, 50 16, 54 14"
|
|
17
|
-
stroke="url(#full-wave-grad)" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
18
|
-
|
|
19
|
-
<!-- Echo line -->
|
|
20
|
-
<path d="M 10 52 C 16 52, 18 46, 22 44 C 26 42, 28 40, 32 36 C 36 32, 38 26, 42 22 C 46 18, 50 20, 54 18"
|
|
21
|
-
stroke="url(#full-wave-grad)" stroke-width="1.5" fill="none" stroke-linecap="round" opacity="0.3"/>
|
|
22
|
-
|
|
23
|
-
<!-- Cursor dot -->
|
|
24
|
-
<circle cx="42" cy="18" r="3.5" fill="#E9AB34"/>
|
|
25
|
-
<circle cx="42" cy="18" r="6" fill="#E9AB34" opacity="0.15"/>
|
|
26
|
-
|
|
27
|
-
<!-- Baseline -->
|
|
28
|
-
<line x1="10" y1="54" x2="54" y2="54" stroke="#8B7D6B" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
|
29
|
-
</g>
|
|
30
|
-
|
|
31
|
-
<!-- Divider -->
|
|
32
|
-
<line x1="76" y1="16" x2="76" y2="56" stroke="#8B7D6B" stroke-width="1" opacity="0.25"/>
|
|
33
|
-
|
|
34
|
-
<!-- Wordmark -->
|
|
35
|
-
<text x="90" y="35" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="22" font-weight="700" fill="#FFFFFF" letter-spacing="-0.3">cc-context</text>
|
|
36
|
-
<text x="90" y="55" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="15" font-weight="500" fill="#E9AB34" letter-spacing="3">stats</text>
|
|
37
|
-
|
|
38
|
-
<!-- Right accent bar -->
|
|
39
|
-
<rect x="348" y="20" width="2" height="32" rx="1" fill="#E9AB34" opacity="0.5"/>
|
|
40
|
-
</svg>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="icon-wave-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
4
|
-
<stop offset="0%" stop-color="#22C55E"/>
|
|
5
|
-
<stop offset="50%" stop-color="#E9AB34"/>
|
|
6
|
-
<stop offset="100%" stop-color="#EF4444"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
</defs>
|
|
9
|
-
|
|
10
|
-
<!-- Background -->
|
|
11
|
-
<rect width="512" height="512" rx="96" fill="#1A1A1A"/>
|
|
12
|
-
|
|
13
|
-
<!-- Context wave (scaled up) -->
|
|
14
|
-
<path d="M 96 376 C 144 376, 160 328, 192 312 C 224 296, 240 280, 272 248 C 304 216, 320 168, 352 136 C 384 104, 400 120, 432 104"
|
|
15
|
-
stroke="url(#icon-wave-grad)" stroke-width="24" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
16
|
-
|
|
17
|
-
<!-- Echo line -->
|
|
18
|
-
<path d="M 96 408 C 144 408, 160 360, 192 344 C 224 328, 240 312, 272 280 C 304 248, 320 200, 352 168 C 384 136, 400 152, 432 136"
|
|
19
|
-
stroke="url(#icon-wave-grad)" stroke-width="10" fill="none" stroke-linecap="round" opacity="0.25"/>
|
|
20
|
-
|
|
21
|
-
<!-- Cursor dot -->
|
|
22
|
-
<circle cx="352" cy="136" r="28" fill="#E9AB34"/>
|
|
23
|
-
<circle cx="352" cy="136" r="48" fill="#E9AB34" opacity="0.12"/>
|
|
24
|
-
|
|
25
|
-
<!-- Baseline -->
|
|
26
|
-
<line x1="96" y1="424" x2="432" y2="424" stroke="#8B7D6B" stroke-width="6" stroke-linecap="round" opacity="0.35"/>
|
|
27
|
-
</svg>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="wave-grad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
4
|
-
<stop offset="0%" stop-color="#22C55E"/>
|
|
5
|
-
<stop offset="50%" stop-color="#E9AB34"/>
|
|
6
|
-
<stop offset="100%" stop-color="#EF4444"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
</defs>
|
|
9
|
-
|
|
10
|
-
<!-- Background -->
|
|
11
|
-
<rect width="64" height="64" rx="14" fill="#1A1A1A"/>
|
|
12
|
-
|
|
13
|
-
<!-- Context wave: a flowing curve rising from left (low usage) to right (high usage) -->
|
|
14
|
-
<!-- This represents the context growth graph - the core concept of the tool -->
|
|
15
|
-
<path d="M 10 48 C 16 48, 18 42, 22 40 C 26 38, 28 36, 32 32 C 36 28, 38 22, 42 18 C 46 14, 50 16, 54 14"
|
|
16
|
-
stroke="url(#wave-grad)" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
17
|
-
|
|
18
|
-
<!-- Secondary pulse line (echo effect for depth) -->
|
|
19
|
-
<path d="M 10 52 C 16 52, 18 46, 22 44 C 26 42, 28 40, 32 36 C 36 32, 38 26, 42 22 C 46 18, 50 20, 54 18"
|
|
20
|
-
stroke="url(#wave-grad)" stroke-width="1.5" fill="none" stroke-linecap="round" opacity="0.3"/>
|
|
21
|
-
|
|
22
|
-
<!-- Cursor dot at the "current position" on the wave -->
|
|
23
|
-
<circle cx="42" cy="18" r="3.5" fill="#E9AB34"/>
|
|
24
|
-
<circle cx="42" cy="18" r="6" fill="#E9AB34" opacity="0.15"/>
|
|
25
|
-
|
|
26
|
-
<!-- Baseline -->
|
|
27
|
-
<line x1="10" y1="54" x2="54" y2="54" stroke="#8B7D6B" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
|
28
|
-
</svg>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 72" width="360" height="72">
|
|
2
|
-
<!-- White version for dark backgrounds — no background rectangle -->
|
|
3
|
-
|
|
4
|
-
<!-- Mark: Context wave -->
|
|
5
|
-
<g transform="translate(8, 4)">
|
|
6
|
-
<path d="M 10 48 C 16 48, 18 42, 22 40 C 26 38, 28 36, 32 32 C 36 28, 38 22, 42 18 C 46 14, 50 16, 54 14"
|
|
7
|
-
stroke="#FFFFFF" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8
|
-
<path d="M 10 52 C 16 52, 18 46, 22 44 C 26 42, 28 40, 32 36 C 36 32, 38 26, 42 22 C 46 18, 50 20, 54 18"
|
|
9
|
-
stroke="#FFFFFF" stroke-width="1.5" fill="none" stroke-linecap="round" opacity="0.25"/>
|
|
10
|
-
<circle cx="42" cy="18" r="3.5" fill="#FFFFFF"/>
|
|
11
|
-
<circle cx="42" cy="18" r="6" fill="#FFFFFF" opacity="0.12"/>
|
|
12
|
-
<line x1="10" y1="54" x2="54" y2="54" stroke="#FFFFFF" stroke-width="1" stroke-linecap="round" opacity="0.3"/>
|
|
13
|
-
</g>
|
|
14
|
-
|
|
15
|
-
<!-- Divider -->
|
|
16
|
-
<line x1="76" y1="16" x2="76" y2="56" stroke="#FFFFFF" stroke-width="1" opacity="0.2"/>
|
|
17
|
-
|
|
18
|
-
<!-- Wordmark -->
|
|
19
|
-
<text x="90" y="35" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="22" font-weight="700" fill="#FFFFFF" letter-spacing="-0.3">cc-context</text>
|
|
20
|
-
<text x="90" y="55" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="15" font-weight="500" fill="#FFFFFF" letter-spacing="3" opacity="0.7">stats</text>
|
|
21
|
-
|
|
22
|
-
<!-- Right accent bar -->
|
|
23
|
-
<rect x="348" y="20" width="2" height="32" rx="1" fill="#FFFFFF" opacity="0.4"/>
|
|
24
|
-
</svg>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 52" width="260" height="52">
|
|
2
|
-
<!-- Wordmark only — transparent background -->
|
|
3
|
-
<!-- "cc-context" bold, "stats" in golden amber below -->
|
|
4
|
-
<text x="0" y="30" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="24" font-weight="700" fill="#1A1A1A" letter-spacing="-0.3">cc-context</text>
|
|
5
|
-
<text x="0" y="48" font-family="'SF Mono', 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace" font-size="15" font-weight="500" fill="#E9AB34" letter-spacing="3">stats</text>
|
|
6
|
-
</svg>
|
package/docs/ARCHITECTURE.md
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
cc-context-stats provides real-time context monitoring for Claude Code sessions. It consists of two main components:
|
|
6
|
-
|
|
7
|
-
1. **Status Line** - A compact one-line display integrated into Claude Code's UI
|
|
8
|
-
2. **Context Stats CLI** - A live terminal dashboard with ASCII graphs
|
|
9
|
-
|
|
10
|
-
## System Architecture
|
|
11
|
-
|
|
12
|
-
```mermaid
|
|
13
|
-
graph TD
|
|
14
|
-
CC[Claude Code Host] -->|JSON stdin| SL[Statusline Script]
|
|
15
|
-
SL -->|stdout text| CC
|
|
16
|
-
SL -->|writes CSV| SF[State Files<br/>~/.claude/statusline/]
|
|
17
|
-
SF -->|reads CSV| CS[Context Stats CLI]
|
|
18
|
-
CF[Config File<br/>~/.claude/statusline.conf] -->|reads| SL
|
|
19
|
-
GIT[Git Repository] -->|branch/status| SL
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
┌─────────────┐ JSON stdin ┌──────────────────┐
|
|
24
|
-
│ Claude Code │ ──────────────────> │ Statusline Script │
|
|
25
|
-
│ (host) │ <────────────────── │ (sh/py/js) │
|
|
26
|
-
└─────────────┘ stdout text └──────┬───────────┘
|
|
27
|
-
│ writes
|
|
28
|
-
▼
|
|
29
|
-
┌──────────────────┐
|
|
30
|
-
│ State Files │
|
|
31
|
-
│ ~/.claude/ │
|
|
32
|
-
│ statusline/ │
|
|
33
|
-
└──────┬───────────┘
|
|
34
|
-
│ reads
|
|
35
|
-
▼
|
|
36
|
-
┌──────────────────┐
|
|
37
|
-
│ Context Stats CLI │
|
|
38
|
-
│ (Python/Bash) │
|
|
39
|
-
└──────────────────┘
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Component Details
|
|
43
|
-
|
|
44
|
-
### Status Line Scripts
|
|
45
|
-
|
|
46
|
-
Three implementation languages with identical output:
|
|
47
|
-
|
|
48
|
-
| Script | Language | Dependencies | State Writes |
|
|
49
|
-
| ---------------------- | ---------- | ------------ | ------------ |
|
|
50
|
-
| `statusline-full.sh` | Bash | `jq` | No |
|
|
51
|
-
| `statusline-git.sh` | Bash | `jq` | No |
|
|
52
|
-
| `statusline-minimal.sh`| Bash | `jq` | No |
|
|
53
|
-
| `statusline.py` | Python 3 | None | Yes |
|
|
54
|
-
| `statusline.js` | Node.js 18+| None | Yes |
|
|
55
|
-
|
|
56
|
-
> **Note:** Only the Python and Node.js scripts write state files. The bash scripts provide status line display only, without persisting data for the context-stats CLI.
|
|
57
|
-
|
|
58
|
-
**Data flow:**
|
|
59
|
-
1. Claude Code pipes JSON state via stdin on each refresh
|
|
60
|
-
2. Script parses model info, context tokens, session data
|
|
61
|
-
3. Script reads `~/.claude/statusline.conf` for user preferences
|
|
62
|
-
4. Script checks git status for branch/changes info (5-second timeout)
|
|
63
|
-
5. Python/Node.js scripts write state to `~/.claude/statusline/<session_id>.state`
|
|
64
|
-
6. Script outputs formatted ANSI text to stdout
|
|
65
|
-
|
|
66
|
-
### Context Stats CLI
|
|
67
|
-
|
|
68
|
-
Two implementations of the live dashboard:
|
|
69
|
-
|
|
70
|
-
| Script | Language | Install Method |
|
|
71
|
-
| ------------------ | -------- | ------------------------- |
|
|
72
|
-
| `context-stats.sh` | Bash | Shell installer |
|
|
73
|
-
| `context_stats.py` | Python | `pip install cc-context-stats` |
|
|
74
|
-
|
|
75
|
-
The Python CLI (installed via pip or npm) is the primary implementation, providing live ASCII graphs with zone awareness. The bash script is a standalone alternative installed by the shell installer.
|
|
76
|
-
|
|
77
|
-
### Python Package (`src/claude_statusline/`)
|
|
78
|
-
|
|
79
|
-
The pip-installable package provides both the statusline and context-stats CLI:
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
src/claude_statusline/
|
|
83
|
-
├── __init__.py # Package version and exports
|
|
84
|
-
├── __main__.py # python -m claude_statusline entry
|
|
85
|
-
├── cli/
|
|
86
|
-
│ ├── statusline.py # claude-statusline entry point
|
|
87
|
-
│ └── context_stats.py # context-stats entry point
|
|
88
|
-
├── core/
|
|
89
|
-
│ ├── colors.py # ANSI color management
|
|
90
|
-
│ ├── config.py # Configuration loading
|
|
91
|
-
│ ├── git.py # Git status detection (5s timeout)
|
|
92
|
-
│ └── state.py # State file reading/writing/rotation
|
|
93
|
-
├── formatters/
|
|
94
|
-
│ ├── layout.py # Output width/layout management
|
|
95
|
-
│ ├── time.py # Duration formatting
|
|
96
|
-
│ └── tokens.py # Token count formatting
|
|
97
|
-
├── graphs/
|
|
98
|
-
│ ├── renderer.py # ASCII graph rendering
|
|
99
|
-
│ └── statistics.py # Data statistics
|
|
100
|
-
└── ui/
|
|
101
|
-
├── icons.py # Unicode icons
|
|
102
|
-
└── waiting.py # Waiting animation
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### State Files
|
|
106
|
-
|
|
107
|
-
State files persist token history between statusline refreshes:
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
~/.claude/statusline/statusline.<session_id>.state
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Each line is a CSV record with 14 comma-separated fields (timestamp, token counts, cost, session metadata, and context metrics). See [CSV_FORMAT.md](CSV_FORMAT.md) for the full field specification. The context-stats CLI reads these files to render graphs.
|
|
114
|
-
|
|
115
|
-
**Rotation:** Files are automatically rotated at 10,000 lines, keeping the most recent 5,000 entries. This prevents unbounded file growth during long sessions.
|
|
116
|
-
|
|
117
|
-
**Session ID validation:** IDs are validated to reject path-traversal characters (`/`, `\`, `..`, null bytes).
|
|
118
|
-
|
|
119
|
-
## Data Privacy
|
|
120
|
-
|
|
121
|
-
All data stays local:
|
|
122
|
-
- State files are written to `~/.claude/statusline/`
|
|
123
|
-
- No network requests are made
|
|
124
|
-
- No telemetry or analytics
|
|
125
|
-
|
|
126
|
-
## Configuration
|
|
127
|
-
|
|
128
|
-
User preferences are stored in `~/.claude/statusline.conf` as simple `key=value` pairs. See [Configuration](configuration.md) for details.
|
package/docs/CSV_FORMAT.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# CSV State File Format
|
|
2
|
-
|
|
3
|
-
State files are stored at `~/.claude/statusline/statusline.<session_id>.state`. Each line is a CSV record with 14 comma-separated fields.
|
|
4
|
-
|
|
5
|
-
## Field Specification
|
|
6
|
-
|
|
7
|
-
| Index | Field | Type | Description |
|
|
8
|
-
|-------|-------|------|-------------|
|
|
9
|
-
| 0 | `timestamp` | integer | Unix timestamp in seconds |
|
|
10
|
-
| 1 | `total_input_tokens` | integer | Cumulative input tokens for the session |
|
|
11
|
-
| 2 | `total_output_tokens` | integer | Cumulative output tokens for the session |
|
|
12
|
-
| 3 | `current_input_tokens` | integer | Input tokens for the current request |
|
|
13
|
-
| 4 | `current_output_tokens` | integer | Output tokens for the current request |
|
|
14
|
-
| 5 | `cache_creation` | integer | Cache creation input tokens |
|
|
15
|
-
| 6 | `cache_read` | integer | Cache read input tokens |
|
|
16
|
-
| 7 | `cost_usd` | float | Total session cost in USD |
|
|
17
|
-
| 8 | `lines_added` | integer | Total lines added in session |
|
|
18
|
-
| 9 | `lines_removed` | integer | Total lines removed in session |
|
|
19
|
-
| 10 | `session_id` | string | Session identifier (UUID) |
|
|
20
|
-
| 11 | `model_id` | string | Model identifier (e.g., `claude-opus-4-5`) |
|
|
21
|
-
| 12 | `workspace_project_dir` | string | Project directory path (commas replaced with underscores) |
|
|
22
|
-
| 13 | `context_window_size` | integer | Context window size in tokens |
|
|
23
|
-
|
|
24
|
-
## Constraints
|
|
25
|
-
|
|
26
|
-
- Fields are separated by commas with no quoting or escaping.
|
|
27
|
-
- The `workspace_project_dir` field (index 12) is sanitized before writing: all comma characters (`,`) are replaced with underscores (`_`) to prevent CSV corruption.
|
|
28
|
-
- Numeric fields default to `0` when absent. String fields default to empty string.
|
|
29
|
-
- Lines are newline-terminated (`\n`).
|
|
30
|
-
- Files are append-only.
|
|
31
|
-
- Files are automatically rotated at 10,000 lines (keeps most recent 5,000) by the Python and Node.js statusline scripts.
|
|
32
|
-
- Duplicate entries (same token count as previous line) are skipped to prevent file bloat.
|
|
33
|
-
|
|
34
|
-
## Legacy Format
|
|
35
|
-
|
|
36
|
-
Older state files may contain 2-field lines: `timestamp,total_input_tokens`. The reader defaults all other fields to zero/empty for these lines.
|
|
37
|
-
|
|
38
|
-
## Example
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
1710288000,75000,8500,50000,5000,10000,20000,0.05234,250,45,abc-123-def,claude-opus-4-5,/home/user/my-project,200000
|
|
42
|
-
```
|
package/docs/DEPLOYMENT.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Deployment
|
|
2
|
-
|
|
3
|
-
## Distribution Channels
|
|
4
|
-
|
|
5
|
-
cc-context-stats is distributed through three channels:
|
|
6
|
-
|
|
7
|
-
| Channel | Package Name | Command |
|
|
8
|
-
| ------------ | ----------------- | ------------------------------------ |
|
|
9
|
-
| Shell script | N/A | `curl -fsSL .../install.sh \| bash` |
|
|
10
|
-
| PyPI | `cc-context-stats`| `pip install cc-context-stats` |
|
|
11
|
-
| npm | `cc-context-stats`| `npm install -g cc-context-stats` |
|
|
12
|
-
|
|
13
|
-
Both pip and npm installs provide the `claude-statusline` and `context-stats` CLI commands.
|
|
14
|
-
|
|
15
|
-
## Publishing to PyPI
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Ensure clean build
|
|
19
|
-
rm -rf dist/ build/
|
|
20
|
-
|
|
21
|
-
# Build
|
|
22
|
-
python -m build
|
|
23
|
-
|
|
24
|
-
# Check package
|
|
25
|
-
twine check dist/*
|
|
26
|
-
|
|
27
|
-
# Upload to PyPI
|
|
28
|
-
twine upload dist/*
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Publishing to npm
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# Verify package.json
|
|
35
|
-
npm pack --dry-run
|
|
36
|
-
|
|
37
|
-
# Publish
|
|
38
|
-
npm publish
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Release Workflow
|
|
42
|
-
|
|
43
|
-
The project uses GitHub Actions for automated releases (`.github/workflows/release.yml`):
|
|
44
|
-
|
|
45
|
-
1. Update versions in all locations (see Version Management below)
|
|
46
|
-
2. Update `CHANGELOG.md` with the new version entry
|
|
47
|
-
3. Create and push a version tag: `git tag v1.x.x && git push --tags`
|
|
48
|
-
4. The release workflow automatically:
|
|
49
|
-
- Runs the full test suite (Python, Node.js, Bash)
|
|
50
|
-
- Builds Python and npm packages
|
|
51
|
-
- Creates a GitHub Release with release notes
|
|
52
|
-
|
|
53
|
-
CI is also run on every push and PR via `.github/workflows/ci.yml`.
|
|
54
|
-
|
|
55
|
-
## Version Management
|
|
56
|
-
|
|
57
|
-
Versions must be updated in sync across these files:
|
|
58
|
-
|
|
59
|
-
| File | Field |
|
|
60
|
-
| --- | --- |
|
|
61
|
-
| `pyproject.toml` | `[project] version` |
|
|
62
|
-
| `package.json` | `version` |
|
|
63
|
-
| `src/claude_statusline/__init__.py` | `__version__` |
|
|
64
|
-
| `CHANGELOG.md` | New version entry |
|
|
65
|
-
| `RELEASE_NOTES.md` | Current release notes |
|
|
66
|
-
|
|
67
|
-
## Install Script
|
|
68
|
-
|
|
69
|
-
The `install.sh` script is fetched directly from the `main` branch on GitHub. Changes to the installer take effect immediately for new users running the curl one-liner.
|
|
70
|
-
|
|
71
|
-
The installer embeds the version from `package.json` and the current git commit hash into the installed scripts, preventing version drift between the repository and installed copies.
|
package/docs/DEVELOPMENT.md
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Development Guide
|
|
2
|
-
|
|
3
|
-
## Prerequisites
|
|
4
|
-
|
|
5
|
-
- **Git** - Version control
|
|
6
|
-
- **jq** - JSON processor (for bash scripts)
|
|
7
|
-
- **Python 3.9+** - For Python package and testing
|
|
8
|
-
- **Node.js 18+** - For Node.js script and testing
|
|
9
|
-
- **Bats** - Bash Automated Testing System (optional, for bash tests)
|
|
10
|
-
- **pre-commit** - Git hook framework (optional, for automated code quality)
|
|
11
|
-
|
|
12
|
-
## Setup
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# Clone the repository
|
|
16
|
-
git clone https://github.com/luongnv89/cc-context-stats.git
|
|
17
|
-
cd cc-context-stats
|
|
18
|
-
|
|
19
|
-
# Python setup
|
|
20
|
-
python3 -m venv venv
|
|
21
|
-
source venv/bin/activate
|
|
22
|
-
pip install -r requirements-dev.txt
|
|
23
|
-
pip install -e ".[dev]"
|
|
24
|
-
|
|
25
|
-
# Node.js setup
|
|
26
|
-
npm install
|
|
27
|
-
|
|
28
|
-
# Install pre-commit hooks (optional but recommended)
|
|
29
|
-
pre-commit install
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Project Layout
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
cc-context-stats/
|
|
36
|
-
├── src/claude_statusline/ # Python package source
|
|
37
|
-
│ ├── cli/ # CLI entry points (statusline, context-stats)
|
|
38
|
-
│ ├── core/ # Config, state, git, colors
|
|
39
|
-
│ ├── formatters/ # Token, time, layout formatting
|
|
40
|
-
│ ├── graphs/ # ASCII graph rendering
|
|
41
|
-
│ └── ui/ # Icons, waiting animation
|
|
42
|
-
├── scripts/ # Standalone scripts (sh/py/js)
|
|
43
|
-
│ ├── statusline-full.sh # Full-featured bash statusline
|
|
44
|
-
│ ├── statusline-git.sh # Git-focused bash variant
|
|
45
|
-
│ ├── statusline-minimal.sh # Minimal bash variant
|
|
46
|
-
│ ├── statusline.py # Python standalone statusline
|
|
47
|
-
│ ├── statusline.js # Node.js standalone statusline
|
|
48
|
-
│ └── context-stats.sh # Bash context-stats CLI
|
|
49
|
-
├── tests/
|
|
50
|
-
│ ├── bash/ # Bats tests
|
|
51
|
-
│ ├── python/ # Pytest tests
|
|
52
|
-
│ └── node/ # Jest tests
|
|
53
|
-
├── config/ # Configuration examples
|
|
54
|
-
├── docs/ # Documentation
|
|
55
|
-
├── .github/workflows/ # CI/CD (ci.yml, release.yml)
|
|
56
|
-
├── pyproject.toml # Python build config (hatchling)
|
|
57
|
-
└── package.json # Node.js config
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Running Tests
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
# Python tests
|
|
64
|
-
source venv/bin/activate
|
|
65
|
-
pytest tests/python/ -v
|
|
66
|
-
|
|
67
|
-
# Node.js tests (Jest)
|
|
68
|
-
npm test
|
|
69
|
-
|
|
70
|
-
# Bash integration tests
|
|
71
|
-
bats tests/bash/*.bats
|
|
72
|
-
|
|
73
|
-
# All tests
|
|
74
|
-
pytest && npm test && bats tests/bash/*.bats
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Coverage Reports
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# Python coverage
|
|
81
|
-
pytest tests/python/ -v --cov=scripts --cov-report=html
|
|
82
|
-
|
|
83
|
-
# Node.js coverage
|
|
84
|
-
npm run test:coverage
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Linting & Formatting
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
# Run all checks via pre-commit
|
|
91
|
-
pre-commit run --all-files
|
|
92
|
-
|
|
93
|
-
# Individual tools
|
|
94
|
-
ruff check src/ scripts/statusline.py # Python lint
|
|
95
|
-
ruff format src/ scripts/statusline.py # Python format
|
|
96
|
-
npx eslint scripts/statusline.js # JavaScript lint
|
|
97
|
-
npx prettier --write scripts/statusline.js # JavaScript format
|
|
98
|
-
shellcheck scripts/*.sh install.sh # Bash lint
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Manual Testing
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# Test statusline scripts with mock input
|
|
105
|
-
echo '{"model":{"display_name":"Test"},"cwd":"/test","session_id":"abc123","context":{"tokens_remaining":64000,"context_window":200000}}' | python3 scripts/statusline.py
|
|
106
|
-
|
|
107
|
-
echo '{"model":{"display_name":"Test"}}' | node scripts/statusline.js
|
|
108
|
-
|
|
109
|
-
echo '{"model":{"display_name":"Test"}}' | bash scripts/statusline-full.sh
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Building
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
# Python package
|
|
116
|
-
python -m build
|
|
117
|
-
|
|
118
|
-
# Verify package
|
|
119
|
-
twine check dist/*
|
|
120
|
-
|
|
121
|
-
# npm dry run
|
|
122
|
-
npm pack --dry-run
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## Cross-Script Consistency
|
|
126
|
-
|
|
127
|
-
All three implementations (bash, Python, Node.js) must produce identical output for the same input. When modifying status line behavior:
|
|
128
|
-
|
|
129
|
-
1. Update all three script variants
|
|
130
|
-
2. Run integration tests to verify parity
|
|
131
|
-
3. Test on multiple platforms if possible
|
|
132
|
-
|
|
133
|
-
The delta parity tests (`tests/bash/`) verify that Python and Node.js produce identical deltas for the same CSV state data.
|
|
134
|
-
|
|
135
|
-
## Debugging
|
|
136
|
-
|
|
137
|
-
### State files
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# View current state files
|
|
141
|
-
ls -la ~/.claude/statusline/statusline.*.state
|
|
142
|
-
|
|
143
|
-
# Inspect state content (14 CSV fields per line)
|
|
144
|
-
cat ~/.claude/statusline/statusline.<session_id>.state
|
|
145
|
-
|
|
146
|
-
# Watch state file updates in real-time
|
|
147
|
-
watch -n 1 'tail -5 ~/.claude/statusline/statusline.*.state'
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Verbose testing
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
# Python with verbose output
|
|
154
|
-
pytest tests/python/ -v -s
|
|
155
|
-
|
|
156
|
-
# Node.js with verbose output
|
|
157
|
-
npx jest --verbose
|
|
158
|
-
|
|
159
|
-
# Bats with verbose output
|
|
160
|
-
bats --verbose-run tests/bash/*.bats
|
|
161
|
-
```
|