ctxline-claude 0.0.6 → 0.0.7
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/README.md +6 -6
- package/package.json +4 -4
- package/statusline.js +25 -30
package/README.md
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
<img src="https://img.shields.io/npm/dm/ctxline-claude" alt="npm downloads">
|
|
13
13
|
</a>
|
|
14
14
|
<a href="LICENSE">
|
|
15
|
-
<img src="https://img.shields.io/github/license/MithunWijayasiri/
|
|
15
|
+
<img src="https://img.shields.io/github/license/MithunWijayasiri/ctxline-claude" alt="license">
|
|
16
16
|
</a>
|
|
17
|
-
<a href="https://github.com/MithunWijayasiri/
|
|
18
|
-
<img src="https://img.shields.io/github/stars/MithunWijayasiri/
|
|
17
|
+
<a href="https://github.com/MithunWijayasiri/ctxline-claude/stargazers">
|
|
18
|
+
<img src="https://img.shields.io/github/stars/MithunWijayasiri/ctxline-claude" alt="stars">
|
|
19
19
|
</a>
|
|
20
20
|
</p>
|
|
21
21
|
|
|
@@ -43,8 +43,8 @@ Then restart Claude Code or start a new session. That's it.
|
|
|
43
43
|
**Clone & run the installer:**
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
git clone https://github.com/MithunWijayasiri/
|
|
47
|
-
cd
|
|
46
|
+
git clone https://github.com/MithunWijayasiri/ctxline-claude.git
|
|
47
|
+
cd ctxline-claude
|
|
48
48
|
./install.sh # macOS / Linux
|
|
49
49
|
./install.ps1 # Windows (PowerShell)
|
|
50
50
|
```
|
|
@@ -52,7 +52,7 @@ cd claudecode-statusline
|
|
|
52
52
|
**Manual:** download the script, then point `~/.claude/settings.json` at it.
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
-
curl -o ~/.claude/hooks/statusline.js https://raw.githubusercontent.com/MithunWijayasiri/
|
|
55
|
+
curl -o ~/.claude/hooks/statusline.js https://raw.githubusercontent.com/MithunWijayasiri/ctxline-claude/main/statusline.js
|
|
56
56
|
chmod +x ~/.claude/hooks/statusline.js
|
|
57
57
|
```
|
|
58
58
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ctxline-claude",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "A customizable statusline for Claude Code that tracks context usage and session limits",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ctxline-claude": "bin/install.js"
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
],
|
|
29
29
|
"author": "Mithun Wijayasiri",
|
|
30
30
|
"license": "MIT",
|
|
31
|
-
"homepage": "https://github.com/MithunWijayasiri/
|
|
31
|
+
"homepage": "https://github.com/MithunWijayasiri/ctxline-claude#readme",
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/MithunWijayasiri/
|
|
33
|
+
"url": "https://github.com/MithunWijayasiri/ctxline-claude/issues"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|
|
37
|
-
"url": "https://github.com/MithunWijayasiri/
|
|
37
|
+
"url": "https://github.com/MithunWijayasiri/ctxline-claude.git"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/statusline.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Claude Code Enhanced Statusline
|
|
3
3
|
// Shows: directory | model | context usage | current (5-hour) + weekly usage | current task
|
|
4
4
|
// Auto-detects API key vs subscription usage
|
|
5
|
-
// https://github.com/MithunWijayasiri/
|
|
5
|
+
// https://github.com/MithunWijayasiri/ctxline-claude
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
@@ -109,23 +109,21 @@ function getContextBar(remaining) {
|
|
|
109
109
|
const filled = Math.round((used / 100) * BAR_WIDTH);
|
|
110
110
|
const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(BAR_WIDTH - filled);
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
coloredBar = `${colors.orange}${bar} ${used}%${colors.reset}`;
|
|
119
|
-
} else {
|
|
120
|
-
coloredBar = `${colors.blink}${colors.red}${bar} ${used}%${colors.reset}`;
|
|
121
|
-
}
|
|
112
|
+
// Context color: green <50 / yellow <65 / orange <80 / blink-red >=80.
|
|
113
|
+
let color;
|
|
114
|
+
if (used < 50) color = colors.green;
|
|
115
|
+
else if (used < 65) color = colors.yellow;
|
|
116
|
+
else if (used < 80) color = colors.orange;
|
|
117
|
+
else color = colors.blink + colors.red;
|
|
122
118
|
|
|
123
|
-
|
|
119
|
+
// Compact label form: "C<used> <bar>" (e.g. "C45 ███░░░"), colored as a whole.
|
|
120
|
+
return `${color}C${used} ${bar}${colors.reset}`;
|
|
124
121
|
}
|
|
125
122
|
|
|
126
|
-
// Render
|
|
127
|
-
//
|
|
128
|
-
|
|
123
|
+
// Render a compact usage segment from raw data: "<label><pct> ↺ <countdown>"
|
|
124
|
+
// (e.g. "H81 ↺ 2h21m") — no bar. Called on every read (live or cached) so the reset
|
|
125
|
+
// countdown is always recomputed from resetsAt rather than frozen at fetch time.
|
|
126
|
+
function buildUsageBar(label, percentage, resetsAt) {
|
|
129
127
|
let timeStr = '';
|
|
130
128
|
if (resetsAt) {
|
|
131
129
|
const diffMins = Math.max(0, Math.floor((new Date(resetsAt) - new Date()) / 60000));
|
|
@@ -137,21 +135,18 @@ function buildUsageBar(percentage, resetsAt) {
|
|
|
137
135
|
else timeStr = `${mins}m`;
|
|
138
136
|
}
|
|
139
137
|
|
|
140
|
-
const filledWidth = Math.max(0, Math.min(BAR_WIDTH, Math.round((percentage / 100) * BAR_WIDTH)));
|
|
141
|
-
const filled = '█'.repeat(filledWidth);
|
|
142
|
-
const empty = '░'.repeat(BAR_WIDTH - filledWidth);
|
|
143
138
|
const color = getUsageColor(percentage);
|
|
144
|
-
const timePart = timeStr ? `${colors.dim}
|
|
139
|
+
const timePart = timeStr ? `${colors.dim} ↺ ${timeStr}${colors.reset}` : '';
|
|
145
140
|
|
|
146
|
-
return `${color}${
|
|
141
|
+
return `${color}${label}${percentage}${colors.reset}${timePart}`;
|
|
147
142
|
}
|
|
148
143
|
|
|
149
|
-
// Build both usage
|
|
150
|
-
// null/absent. Returns { current, weekly } where each is a rendered
|
|
144
|
+
// Build both usage segments from raw entries. Each entry is { percentage, resetsAt } or
|
|
145
|
+
// null/absent. Returns { current, weekly } where each is a rendered segment string or null.
|
|
151
146
|
function buildUsageBars(fiveHour, weekly) {
|
|
152
147
|
return {
|
|
153
|
-
current: fiveHour ? buildUsageBar(fiveHour.percentage, fiveHour.resetsAt) : null,
|
|
154
|
-
weekly: weekly ? buildUsageBar(weekly.percentage, weekly.resetsAt) : null
|
|
148
|
+
current: fiveHour ? buildUsageBar('H', fiveHour.percentage, fiveHour.resetsAt) : null,
|
|
149
|
+
weekly: weekly ? buildUsageBar('W', weekly.percentage, weekly.resetsAt) : null
|
|
155
150
|
};
|
|
156
151
|
}
|
|
157
152
|
|
|
@@ -404,10 +399,10 @@ function outputStatus(data, usage) {
|
|
|
404
399
|
const parts = [];
|
|
405
400
|
parts.push(branch ? `${dirname} ${colors.dim}⎇ ${branch}${colors.reset}` : dirname);
|
|
406
401
|
parts.push(effort ? `${model}${getEffortColor(effort)} · ${effort}${colors.reset}` : model);
|
|
407
|
-
parts.push(
|
|
402
|
+
parts.push(contextBar);
|
|
408
403
|
|
|
409
|
-
if (usage?.current) parts.push(
|
|
410
|
-
if (usage?.weekly) parts.push(
|
|
404
|
+
if (usage?.current) parts.push(usage.current);
|
|
405
|
+
if (usage?.weekly) parts.push(usage.weekly);
|
|
411
406
|
|
|
412
407
|
if (task) parts.push(`${colors.dim}${task}${colors.reset}`);
|
|
413
408
|
process.stdout.write(parts.join(' \u2502 '));
|
|
@@ -418,9 +413,9 @@ function outputStatus(data, usage) {
|
|
|
418
413
|
|
|
419
414
|
function outputFallback(usage) {
|
|
420
415
|
const contextBar = getContextBar(undefined);
|
|
421
|
-
const parts = ['~', 'Claude',
|
|
422
|
-
if (usage?.current) parts.push(
|
|
423
|
-
if (usage?.weekly) parts.push(
|
|
416
|
+
const parts = ['~', 'Claude', contextBar];
|
|
417
|
+
if (usage?.current) parts.push(usage.current);
|
|
418
|
+
if (usage?.weekly) parts.push(usage.weekly);
|
|
424
419
|
process.stdout.write(parts.join(' \u2502 '));
|
|
425
420
|
}
|
|
426
421
|
|