cc-context-stats 1.5.0 → 1.5.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/.claude/settings.local.json +4 -1
- package/.github/workflows/release.yml +3 -1
- package/RELEASE_NOTES.md +7 -6
- package/assets/logo/favicon.svg +17 -14
- package/assets/logo/logo-black.svg +19 -18
- package/assets/logo/logo-full.svg +39 -29
- package/assets/logo/logo-icon.svg +20 -19
- package/assets/logo/logo-mark.svg +21 -19
- package/assets/logo/logo-white.svg +19 -18
- package/assets/logo/logo-wordmark.svg +5 -6
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/scripts/statusline-full.sh +10 -2
- package/scripts/statusline-git.sh +8 -1
- package/scripts/statusline-minimal.sh +8 -1
- package/scripts/statusline.js +1 -0
- package/scripts/statusline.py +15 -2
- package/src/claude_statusline/__init__.py +1 -1
- package/src/claude_statusline/formatters/layout.py +17 -2
- package/tests/python/test_layout.py +19 -2
- package/tests/python/test_statusline.py +2 -0
|
@@ -111,7 +111,10 @@
|
|
|
111
111
|
"Read(//Users/montimage/.claude/**)",
|
|
112
112
|
"Bash(git checkout:*)",
|
|
113
113
|
"Bash(npm publish:*)",
|
|
114
|
-
"Bash(npm view:*)"
|
|
114
|
+
"Bash(npm view:*)",
|
|
115
|
+
"WebSearch",
|
|
116
|
+
"Bash(COLUMNS=120 python3 -c \"import shutil; print\\(shutil.get_terminal_size\\(\\).columns\\)\")",
|
|
117
|
+
"Bash(COLUMNS=80 python3 -c \"import shutil; print\\(shutil.get_terminal_size\\(\\).columns\\)\")"
|
|
115
118
|
]
|
|
116
119
|
}
|
|
117
120
|
}
|
|
@@ -69,7 +69,9 @@ jobs:
|
|
|
69
69
|
run: sudo apt-get update && sudo apt-get install -y jq bats
|
|
70
70
|
|
|
71
71
|
- name: Install Python dependencies
|
|
72
|
-
run:
|
|
72
|
+
run: |
|
|
73
|
+
pip install -r requirements-dev.txt
|
|
74
|
+
pip install -e .
|
|
73
75
|
|
|
74
76
|
- name: Install Node.js dependencies
|
|
75
77
|
run: npm ci
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
##
|
|
2
|
-
|
|
3
|
-
### Refactoring
|
|
4
|
-
- **Remove icon and pacman display options from statusline** — Simplify the statusline by removing `icon_mode` config option (`standard`/`pacman`/`off`), activity icons, and pacman meter visualization. Activity tier detection and text labels are preserved for context-stats. Net removal of ~413 lines across 10 files (#13) @luongnv89
|
|
1
|
+
## v1.5.1 — 2026-03-11
|
|
5
2
|
|
|
6
3
|
### Bug Fixes
|
|
7
|
-
- **
|
|
4
|
+
- **Fix session ID disappearing from statusline** — Claude Code runs statusline scripts as piped subprocesses with no real TTY, causing terminal width detection to always return 80 columns. This made `fit_to_width()` drop lower-priority parts like session ID even when the real terminal had plenty of space. Now uses 200 columns as default when no TTY is detected; Claude Code's own UI handles overflow.
|
|
5
|
+
- **Fix CI failures** — Resolve ESLint, Python 3.9 compatibility, and release workflow issues
|
|
6
|
+
|
|
7
|
+
### Other Changes
|
|
8
|
+
- Update logo SVG assets
|
|
8
9
|
|
|
9
|
-
**Full Changelog**: https://github.com/luongnv89/cc-context-stats/compare/v1.
|
|
10
|
+
**Full Changelog**: https://github.com/luongnv89/cc-context-stats/compare/v1.5.0...v1.5.1
|
package/assets/logo/favicon.svg
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<!--
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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"/>
|
|
16
19
|
</svg>
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
|
|
2
|
-
<!-- Black version for light backgrounds -->
|
|
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
3
|
|
|
4
|
-
<!--
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<!-- Pivot -->
|
|
15
|
-
<circle cx="32" cy="38" r="3" fill="#16A34A"/>
|
|
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>
|
|
16
14
|
|
|
17
15
|
<!-- Divider -->
|
|
18
|
-
<line x1="
|
|
16
|
+
<line x1="76" y1="16" x2="76" y2="56" stroke="#1A1A1A" stroke-width="1" opacity="0.2"/>
|
|
19
17
|
|
|
20
|
-
<!-- Wordmark
|
|
21
|
-
<text x="
|
|
22
|
-
<text x="
|
|
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"/>
|
|
23
24
|
</svg>
|
|
@@ -1,30 +1,40 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<!--
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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"/>
|
|
30
40
|
</svg>
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
|
2
|
-
|
|
3
|
-
|
|
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>
|
|
4
9
|
|
|
5
|
-
<!--
|
|
6
|
-
<
|
|
10
|
+
<!-- Background -->
|
|
11
|
+
<rect width="512" height="512" rx="96" fill="#1A1A1A"/>
|
|
7
12
|
|
|
8
|
-
<!--
|
|
9
|
-
<path d="M 96
|
|
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"/>
|
|
10
16
|
|
|
11
|
-
<!--
|
|
12
|
-
<path d="M
|
|
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"/>
|
|
13
20
|
|
|
14
|
-
<!--
|
|
15
|
-
<
|
|
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"/>
|
|
16
24
|
|
|
17
|
-
<!--
|
|
18
|
-
<line x1="
|
|
19
|
-
|
|
20
|
-
<!-- Pivot dot -->
|
|
21
|
-
<circle cx="256" cy="256" r="24" fill="#22C55E"/>
|
|
22
|
-
|
|
23
|
-
<!-- Label dots at zone boundaries -->
|
|
24
|
-
<circle cx="96" cy="352" r="8" fill="#6B7280"/>
|
|
25
|
-
<circle cx="416" cy="352" r="8" fill="#6B7280"/>
|
|
25
|
+
<!-- Baseline -->
|
|
26
|
+
<line x1="96" y1="424" x2="432" y2="424" stroke="#8B7D6B" stroke-width="6" stroke-linecap="round" opacity="0.35"/>
|
|
26
27
|
</svg>
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
-
|
|
3
|
-
|
|
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>
|
|
4
9
|
|
|
5
|
-
<!--
|
|
6
|
-
<
|
|
10
|
+
<!-- Background -->
|
|
11
|
+
<rect width="64" height="64" rx="14" fill="#1A1A1A"/>
|
|
7
12
|
|
|
8
|
-
<!--
|
|
9
|
-
|
|
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"/>
|
|
10
17
|
|
|
11
|
-
<!--
|
|
12
|
-
<path d="M
|
|
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"/>
|
|
13
21
|
|
|
14
|
-
<!--
|
|
15
|
-
<
|
|
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"/>
|
|
16
25
|
|
|
17
|
-
<!--
|
|
18
|
-
<line x1="
|
|
19
|
-
|
|
20
|
-
<!-- Needle pivot center dot -->
|
|
21
|
-
<circle cx="32" cy="32" r="3" fill="#22C55E"/>
|
|
22
|
-
|
|
23
|
-
<!-- Tick marks at zone boundaries -->
|
|
24
|
-
<line x1="12" y1="44" x2="14.5" y2="41.5" stroke="#6B7280" stroke-width="1.5" stroke-linecap="round"/>
|
|
25
|
-
<line x1="52" y1="44" x2="49.5" y2="41.5" stroke="#6B7280" stroke-width="1.5" stroke-linecap="round"/>
|
|
26
|
+
<!-- Baseline -->
|
|
27
|
+
<line x1="10" y1="54" x2="54" y2="54" stroke="#8B7D6B" stroke-width="1" stroke-linecap="round" opacity="0.4"/>
|
|
26
28
|
</svg>
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
|
|
2
|
-
<!-- White version for dark backgrounds — no
|
|
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
3
|
|
|
4
|
-
<!--
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<!-- Pivot -->
|
|
15
|
-
<circle cx="32" cy="38" r="3" fill="#22C55E"/>
|
|
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>
|
|
16
14
|
|
|
17
15
|
<!-- Divider -->
|
|
18
|
-
<line x1="
|
|
16
|
+
<line x1="76" y1="16" x2="76" y2="56" stroke="#FFFFFF" stroke-width="1" opacity="0.2"/>
|
|
19
17
|
|
|
20
|
-
<!-- Wordmark
|
|
21
|
-
<text x="
|
|
22
|
-
<text x="
|
|
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"/>
|
|
23
24
|
</svg>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
|
|
2
|
-
<!--
|
|
3
|
-
<!--
|
|
4
|
-
<text x="0" y="
|
|
5
|
-
|
|
6
|
-
<text x="0" y="44" font-family="'SF Mono', 'Fira Mono', 'Courier New', monospace" font-size="14" font-weight="500" fill="#22C55E" letter-spacing="2">stats</text>
|
|
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>
|
|
7
6
|
</svg>
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cc-context-stats"
|
|
7
|
-
version = "1.5.
|
|
7
|
+
version = "1.5.1"
|
|
8
8
|
description = "Monitor your Claude Code session context in real-time - track token usage and never run out of context"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -116,13 +116,21 @@ visible_width() {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
get_terminal_width() {
|
|
119
|
-
# Return terminal width
|
|
119
|
+
# Return terminal width for fit_to_width truncation.
|
|
120
|
+
# When running inside Claude Code's statusline subprocess, neither $COLUMNS
|
|
121
|
+
# nor tput can detect the real terminal width (they always return 80).
|
|
122
|
+
# If COLUMNS is explicitly set, trust it. Otherwise use 200 as default
|
|
123
|
+
# so no parts are unnecessarily dropped; Claude Code handles overflow.
|
|
120
124
|
if [[ -n "$COLUMNS" ]]; then
|
|
121
125
|
echo "$COLUMNS"
|
|
122
126
|
else
|
|
123
127
|
local cols
|
|
124
128
|
cols=$(tput cols 2>/dev/null || echo 80)
|
|
125
|
-
|
|
129
|
+
if [[ "$cols" -eq 80 ]]; then
|
|
130
|
+
echo 200
|
|
131
|
+
else
|
|
132
|
+
echo "$cols"
|
|
133
|
+
fi
|
|
126
134
|
fi
|
|
127
135
|
}
|
|
128
136
|
|
|
@@ -22,12 +22,19 @@ visible_width() {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
get_terminal_width() {
|
|
25
|
+
# When running inside Claude Code's statusline subprocess, $COLUMNS is not set
|
|
26
|
+
# and tput falls back to 80. If COLUMNS is set, trust it. Otherwise use 200
|
|
27
|
+
# so no parts are dropped; Claude Code handles overflow.
|
|
25
28
|
if [[ -n "$COLUMNS" ]]; then
|
|
26
29
|
echo "$COLUMNS"
|
|
27
30
|
else
|
|
28
31
|
local cols
|
|
29
32
|
cols=$(tput cols 2>/dev/null || echo 80)
|
|
30
|
-
|
|
33
|
+
if [[ "$cols" -eq 80 ]]; then
|
|
34
|
+
echo 200
|
|
35
|
+
else
|
|
36
|
+
echo "$cols"
|
|
37
|
+
fi
|
|
31
38
|
fi
|
|
32
39
|
}
|
|
33
40
|
|
|
@@ -16,12 +16,19 @@ visible_width() {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
get_terminal_width() {
|
|
19
|
+
# When running inside Claude Code's statusline subprocess, $COLUMNS is not set
|
|
20
|
+
# and tput falls back to 80. If COLUMNS is set, trust it. Otherwise use 200
|
|
21
|
+
# so no parts are dropped; Claude Code handles overflow.
|
|
19
22
|
if [[ -n "$COLUMNS" ]]; then
|
|
20
23
|
echo "$COLUMNS"
|
|
21
24
|
else
|
|
22
25
|
local cols
|
|
23
26
|
cols=$(tput cols 2>/dev/null || echo 80)
|
|
24
|
-
|
|
27
|
+
if [[ "$cols" -eq 80 ]]; then
|
|
28
|
+
echo 200
|
|
29
|
+
else
|
|
30
|
+
echo "$cols"
|
|
31
|
+
fi
|
|
25
32
|
fi
|
|
26
33
|
}
|
|
27
34
|
|
package/scripts/statusline.js
CHANGED
package/scripts/statusline.py
CHANGED
|
@@ -51,8 +51,21 @@ def visible_width(s):
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def get_terminal_width():
|
|
54
|
-
"""Return the terminal width in columns
|
|
55
|
-
|
|
54
|
+
"""Return the terminal width in columns.
|
|
55
|
+
|
|
56
|
+
When running inside Claude Code's statusline subprocess, neither $COLUMNS
|
|
57
|
+
nor tput/shutil can detect the real terminal width (they always return 80).
|
|
58
|
+
If COLUMNS is not explicitly set and shutil falls back to 80, we use a
|
|
59
|
+
generous default of 200 so that no parts are unnecessarily dropped;
|
|
60
|
+
Claude Code's own UI handles any overflow/truncation.
|
|
61
|
+
"""
|
|
62
|
+
# If COLUMNS is explicitly set, trust it (real terminal or test override)
|
|
63
|
+
if os.environ.get("COLUMNS"):
|
|
64
|
+
return shutil.get_terminal_size().columns
|
|
65
|
+
# No COLUMNS env var — likely a Claude Code subprocess with no real TTY.
|
|
66
|
+
# shutil will fall back to 80, which is too narrow. Use 200 instead.
|
|
67
|
+
cols = shutil.get_terminal_size(fallback=(200, 24)).columns
|
|
68
|
+
return 200 if cols == 80 else cols
|
|
56
69
|
|
|
57
70
|
|
|
58
71
|
def fit_to_width(parts, max_width):
|
|
@@ -15,8 +15,23 @@ def visible_width(s: str) -> int:
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def get_terminal_width() -> int:
|
|
18
|
-
"""Return the terminal width in columns
|
|
19
|
-
|
|
18
|
+
"""Return the terminal width in columns.
|
|
19
|
+
|
|
20
|
+
When running inside Claude Code's statusline subprocess, neither $COLUMNS
|
|
21
|
+
nor tput/shutil can detect the real terminal width (they always return 80).
|
|
22
|
+
If COLUMNS is not explicitly set and shutil falls back to 80, we use a
|
|
23
|
+
generous default of 200 so that no parts are unnecessarily dropped;
|
|
24
|
+
Claude Code's own UI handles any overflow/truncation.
|
|
25
|
+
"""
|
|
26
|
+
import os
|
|
27
|
+
|
|
28
|
+
# If COLUMNS is explicitly set, trust it (real terminal or test override)
|
|
29
|
+
if os.environ.get("COLUMNS"):
|
|
30
|
+
return shutil.get_terminal_size().columns
|
|
31
|
+
# No COLUMNS env var — likely a Claude Code subprocess with no real TTY.
|
|
32
|
+
# shutil will fall back to 80, which is too narrow. Use 200 instead.
|
|
33
|
+
cols = shutil.get_terminal_size(fallback=(200, 24)).columns
|
|
34
|
+
return 200 if cols == 80 else cols
|
|
20
35
|
|
|
21
36
|
|
|
22
37
|
def fit_to_width(parts: list[str], max_width: int) -> str:
|
|
@@ -38,8 +38,25 @@ class TestVisibleWidth:
|
|
|
38
38
|
class TestGetTerminalWidth:
|
|
39
39
|
"""Tests for get_terminal_width()."""
|
|
40
40
|
|
|
41
|
-
def
|
|
42
|
-
|
|
41
|
+
def test_fallback_to_200_when_no_columns_env(self):
|
|
42
|
+
"""When COLUMNS is not set and shutil returns 80, use 200 (Claude Code subprocess)."""
|
|
43
|
+
with (
|
|
44
|
+
patch("claude_statusline.formatters.layout.shutil.get_terminal_size") as mock,
|
|
45
|
+
patch.dict("os.environ", {}, clear=False),
|
|
46
|
+
):
|
|
47
|
+
# Remove COLUMNS if present
|
|
48
|
+
import os
|
|
49
|
+
|
|
50
|
+
os.environ.pop("COLUMNS", None)
|
|
51
|
+
mock.return_value = type("Size", (), {"columns": 80})()
|
|
52
|
+
assert get_terminal_width() == 200
|
|
53
|
+
|
|
54
|
+
def test_respects_columns_env_80(self):
|
|
55
|
+
"""When COLUMNS=80 is explicitly set, trust it."""
|
|
56
|
+
with (
|
|
57
|
+
patch("claude_statusline.formatters.layout.shutil.get_terminal_size") as mock,
|
|
58
|
+
patch.dict("os.environ", {"COLUMNS": "80"}),
|
|
59
|
+
):
|
|
43
60
|
mock.return_value = type("Size", (), {"columns": 80})()
|
|
44
61
|
assert get_terminal_width() == 80
|
|
45
62
|
|