ccstatusline 2.0.13 → 2.0.14
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 +208 -0
- package/dist/ccstatusline.js +71 -14
- package/package.json +8 -5
package/README.md
CHANGED
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
- [Recent Updates](#-recent-updates)
|
|
35
35
|
- [Features](#-features)
|
|
36
36
|
- [Quick Start](#-quick-start)
|
|
37
|
+
- [Windows Support](#-windows-support)
|
|
37
38
|
- [Usage](#-usage)
|
|
39
|
+
- [API Documentation](#-api-documentation)
|
|
38
40
|
- [Development](#️-development)
|
|
39
41
|
- [Contributing](#-contributing)
|
|
40
42
|
- [License](#-license)
|
|
@@ -44,6 +46,10 @@
|
|
|
44
46
|
|
|
45
47
|
## 🆕 Recent Updates
|
|
46
48
|
|
|
49
|
+
### v2.0.14 - Add remaining mode toggle to Context Percentage widgets
|
|
50
|
+
|
|
51
|
+
- **Remaining Mode** - You can now toggle the Context Percentage widgets between usage percentage and remaining percentage when configuring them in the TUI by pressing the 'l' key.
|
|
52
|
+
|
|
47
53
|
### v2.0.12 - Custom Text widget now supports emojis
|
|
48
54
|
|
|
49
55
|
- **👾 Emoji Support** - You can now paste emoji into the custom text widget. You can also turn on the merge option to get emoji labels for your widgets like this:
|
|
@@ -145,6 +151,176 @@ The interactive configuration tool provides a terminal UI where you can:
|
|
|
145
151
|
|
|
146
152
|
---
|
|
147
153
|
|
|
154
|
+
## 🪟 Windows Support
|
|
155
|
+
|
|
156
|
+
ccstatusline works seamlessly on Windows with full feature compatibility across PowerShell (5.1+ and 7+), Command Prompt, and Windows Subsystem for Linux (WSL).
|
|
157
|
+
|
|
158
|
+
### Installation on Windows
|
|
159
|
+
|
|
160
|
+
#### Option 1: Using Bun (Recommended)
|
|
161
|
+
```powershell
|
|
162
|
+
# Install Bun for Windows
|
|
163
|
+
irm bun.sh/install.ps1 | iex
|
|
164
|
+
|
|
165
|
+
# Run ccstatusline
|
|
166
|
+
bunx ccstatusline@latest
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Option 2: Using Node.js
|
|
170
|
+
```powershell
|
|
171
|
+
# Using npm
|
|
172
|
+
npx ccstatusline@latest
|
|
173
|
+
|
|
174
|
+
# Or with Yarn
|
|
175
|
+
yarn dlx ccstatusline@latest
|
|
176
|
+
|
|
177
|
+
# Or with pnpm
|
|
178
|
+
pnpm dlx ccstatusline@latest
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Windows-Specific Features
|
|
182
|
+
|
|
183
|
+
#### Powerline Font Support
|
|
184
|
+
For optimal Powerline rendering on Windows:
|
|
185
|
+
|
|
186
|
+
**Windows Terminal** (Recommended):
|
|
187
|
+
- Supports Powerline fonts natively
|
|
188
|
+
- Download from [Microsoft Store](https://aka.ms/terminal)
|
|
189
|
+
- Auto-detects compatible fonts
|
|
190
|
+
|
|
191
|
+
**PowerShell/Command Prompt**:
|
|
192
|
+
```powershell
|
|
193
|
+
# Install JetBrains Mono Nerd Font via winget
|
|
194
|
+
winget install DEVCOM.JetBrainsMonoNerdFont
|
|
195
|
+
|
|
196
|
+
# Alternative: Install base JetBrains Mono font
|
|
197
|
+
winget install "JetBrains.JetBrainsMono"
|
|
198
|
+
|
|
199
|
+
# Or download manually from: https://www.nerdfonts.com/font-downloads
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Path Handling
|
|
203
|
+
ccstatusline automatically handles Windows-specific paths:
|
|
204
|
+
- Git repositories work with both `/` and `\` path separators
|
|
205
|
+
- Current Working Directory widget displays Windows-style paths correctly
|
|
206
|
+
- Full support for mapped network drives and UNC paths
|
|
207
|
+
- Handles Windows drive letters (C:, D:, etc.)
|
|
208
|
+
|
|
209
|
+
### Windows Troubleshooting
|
|
210
|
+
|
|
211
|
+
#### Common Issues & Solutions
|
|
212
|
+
|
|
213
|
+
**Issue**: Powerline symbols showing as question marks or boxes
|
|
214
|
+
```powershell
|
|
215
|
+
# Solution: Install a compatible Nerd Font
|
|
216
|
+
winget install JetBrainsMono.NerdFont
|
|
217
|
+
# Then set the font in your terminal settings
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Issue**: Git commands not recognized
|
|
221
|
+
```powershell
|
|
222
|
+
# Check if Git is installed and in PATH
|
|
223
|
+
git --version
|
|
224
|
+
|
|
225
|
+
# If not found, install Git:
|
|
226
|
+
winget install Git.Git
|
|
227
|
+
# Or download from: https://git-scm.com/download/win
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Issue**: Permission errors during installation
|
|
231
|
+
```powershell
|
|
232
|
+
# Use non-global installation (recommended)
|
|
233
|
+
npx ccstatusline@latest
|
|
234
|
+
|
|
235
|
+
# Or run PowerShell as Administrator for global install
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Issue**: "Execution Policy" errors in PowerShell
|
|
239
|
+
```powershell
|
|
240
|
+
# Temporarily allow script execution
|
|
241
|
+
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Issue**: Windows Defender blocking execution
|
|
245
|
+
```powershell
|
|
246
|
+
# If Windows Defender flags the binary:
|
|
247
|
+
# 1. Open Windows Security
|
|
248
|
+
# 2. Go to "Virus & threat protection"
|
|
249
|
+
# 3. Add exclusion for the ccstatusline binary location
|
|
250
|
+
# Or use temporary bypass (not recommended for production):
|
|
251
|
+
Add-MpPreference -ExclusionPath "$env:USERPROFILE\.bun\bin"
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### Windows Subsystem for Linux (WSL)
|
|
255
|
+
ccstatusline works perfectly in WSL environments:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Install in WSL Ubuntu/Debian
|
|
259
|
+
curl -fsSL https://bun.sh/install | bash
|
|
260
|
+
source ~/.bashrc
|
|
261
|
+
bunx ccstatusline@latest
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**WSL Benefits**:
|
|
265
|
+
- Native Unix-style path handling
|
|
266
|
+
- Better font rendering in WSL terminals
|
|
267
|
+
- Seamless integration with Linux development workflows
|
|
268
|
+
|
|
269
|
+
### Windows Terminal Configuration
|
|
270
|
+
|
|
271
|
+
For the best experience, configure Windows Terminal with these recommended settings:
|
|
272
|
+
|
|
273
|
+
#### Terminal Settings (settings.json)
|
|
274
|
+
```json
|
|
275
|
+
{
|
|
276
|
+
"profiles": {
|
|
277
|
+
"defaults": {
|
|
278
|
+
"font": {
|
|
279
|
+
"face": "JetBrainsMono Nerd Font",
|
|
280
|
+
"size": 12
|
|
281
|
+
},
|
|
282
|
+
"colorScheme": "One Half Dark"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### Claude Code Integration
|
|
289
|
+
Configure ccstatusline in your Claude Code settings:
|
|
290
|
+
|
|
291
|
+
**For Bun users** (Windows: `%USERPROFILE%\.claude\settings.json`):
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"statusLine": "bunx ccstatusline@latest"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**For npm users**:
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"statusLine": "npx ccstatusline@latest"
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Performance on Windows
|
|
306
|
+
|
|
307
|
+
ccstatusline is optimized for Windows performance:
|
|
308
|
+
- **Bun runtime**: Significantly faster startup times on Windows
|
|
309
|
+
- **Caching**: Intelligent caching of git status and file operations
|
|
310
|
+
- **Async operations**: Non-blocking command execution
|
|
311
|
+
- **Memory efficient**: Minimal resource usage
|
|
312
|
+
|
|
313
|
+
### Windows-Specific Widget Behavior
|
|
314
|
+
|
|
315
|
+
Some widgets have Windows-specific optimizations:
|
|
316
|
+
|
|
317
|
+
- **Current Working Directory**: Displays Windows drive letters and UNC paths
|
|
318
|
+
- **Git Widgets**: Handle Windows line endings (CRLF) automatically
|
|
319
|
+
- **Custom Commands**: Support both PowerShell and cmd.exe commands
|
|
320
|
+
- **Block Timer**: Accounts for Windows timezone handling
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
148
324
|
## 📖 Usage
|
|
149
325
|
|
|
150
326
|
Once configured, ccstatusline automatically formats your Claude Code status line. The status line appears at the bottom of your terminal during Claude Code sessions.
|
|
@@ -291,6 +467,38 @@ When terminal width is detected, status lines automatically truncate with ellips
|
|
|
291
467
|
|
|
292
468
|
---
|
|
293
469
|
|
|
470
|
+
## 📖 API Documentation
|
|
471
|
+
|
|
472
|
+
Complete API documentation is generated using TypeDoc and includes detailed information about:
|
|
473
|
+
|
|
474
|
+
- **Core Types**: Configuration interfaces, widget definitions, and render contexts
|
|
475
|
+
- **Widget System**: All available widgets and their customization options
|
|
476
|
+
- **Utility Functions**: Helper functions for rendering, configuration, and terminal handling
|
|
477
|
+
- **Status Line Rendering**: Core rendering engine and formatting options
|
|
478
|
+
|
|
479
|
+
### Generating Documentation
|
|
480
|
+
|
|
481
|
+
To generate the API documentation locally:
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
# Generate documentation
|
|
485
|
+
bun run docs
|
|
486
|
+
|
|
487
|
+
# Clean generated documentation
|
|
488
|
+
bun run docs:clean
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
The documentation will be generated in the `docs/` directory and can be viewed by opening `docs/index.html` in your web browser.
|
|
492
|
+
|
|
493
|
+
### Documentation Structure
|
|
494
|
+
|
|
495
|
+
- **Types**: Core TypeScript interfaces and type definitions
|
|
496
|
+
- **Widgets**: Individual widget implementations and their APIs
|
|
497
|
+
- **Utils**: Utility functions for configuration, rendering, and terminal operations
|
|
498
|
+
- **Main Module**: Primary entry point and orchestration functions
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
294
502
|
## 🛠️ Development
|
|
295
503
|
|
|
296
504
|
### Prerequisites
|
package/dist/ccstatusline.js
CHANGED
|
@@ -51374,7 +51374,7 @@ import { execSync as execSync3 } from "child_process";
|
|
|
51374
51374
|
import * as fs5 from "fs";
|
|
51375
51375
|
import * as path4 from "path";
|
|
51376
51376
|
var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
|
|
51377
|
-
var PACKAGE_VERSION = "2.0.
|
|
51377
|
+
var PACKAGE_VERSION = "2.0.14";
|
|
51378
51378
|
function getPackageVersion() {
|
|
51379
51379
|
if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
|
|
51380
51380
|
return PACKAGE_VERSION;
|
|
@@ -53308,23 +53308,52 @@ class ContextPercentageWidget {
|
|
|
53308
53308
|
return "blue";
|
|
53309
53309
|
}
|
|
53310
53310
|
getDescription() {
|
|
53311
|
-
return "Shows percentage of context window used (of 200k tokens)";
|
|
53311
|
+
return "Shows percentage of context window used or remaining (of 200k tokens)";
|
|
53312
53312
|
}
|
|
53313
53313
|
getDisplayName() {
|
|
53314
53314
|
return "Context %";
|
|
53315
53315
|
}
|
|
53316
53316
|
getEditorDisplay(item) {
|
|
53317
|
-
|
|
53317
|
+
const isInverse = item.metadata?.inverse === "true";
|
|
53318
|
+
const modifiers = [];
|
|
53319
|
+
if (isInverse) {
|
|
53320
|
+
modifiers.push("remaining");
|
|
53321
|
+
}
|
|
53322
|
+
return {
|
|
53323
|
+
displayText: this.getDisplayName(),
|
|
53324
|
+
modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
|
|
53325
|
+
};
|
|
53326
|
+
}
|
|
53327
|
+
handleEditorAction(action, item) {
|
|
53328
|
+
if (action === "toggle-inverse") {
|
|
53329
|
+
const currentState = item.metadata?.inverse === "true";
|
|
53330
|
+
return {
|
|
53331
|
+
...item,
|
|
53332
|
+
metadata: {
|
|
53333
|
+
...item.metadata,
|
|
53334
|
+
inverse: (!currentState).toString()
|
|
53335
|
+
}
|
|
53336
|
+
};
|
|
53337
|
+
}
|
|
53338
|
+
return null;
|
|
53318
53339
|
}
|
|
53319
53340
|
render(item, context, settings) {
|
|
53341
|
+
const isInverse = item.metadata?.inverse === "true";
|
|
53320
53342
|
if (context.isPreview) {
|
|
53321
|
-
|
|
53343
|
+
const previewValue = isInverse ? "90.7%" : "9.3%";
|
|
53344
|
+
return item.rawValue ? previewValue : `Ctx: ${previewValue}`;
|
|
53322
53345
|
} else if (context.tokenMetrics) {
|
|
53323
|
-
const
|
|
53324
|
-
|
|
53346
|
+
const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / 200000 * 100);
|
|
53347
|
+
const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
|
|
53348
|
+
return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
|
|
53325
53349
|
}
|
|
53326
53350
|
return null;
|
|
53327
53351
|
}
|
|
53352
|
+
getCustomKeybinds() {
|
|
53353
|
+
return [
|
|
53354
|
+
{ key: "l", label: "(l)eft/remaining", action: "toggle-inverse" }
|
|
53355
|
+
];
|
|
53356
|
+
}
|
|
53328
53357
|
supportsRawValue() {
|
|
53329
53358
|
return true;
|
|
53330
53359
|
}
|
|
@@ -53338,23 +53367,52 @@ class ContextPercentageUsableWidget {
|
|
|
53338
53367
|
return "green";
|
|
53339
53368
|
}
|
|
53340
53369
|
getDescription() {
|
|
53341
|
-
return "Shows percentage of usable context window used (of 160k tokens before auto-compact)";
|
|
53370
|
+
return "Shows percentage of usable context window used or remaining (of 160k tokens before auto-compact)";
|
|
53342
53371
|
}
|
|
53343
53372
|
getDisplayName() {
|
|
53344
53373
|
return "Context % (usable)";
|
|
53345
53374
|
}
|
|
53346
53375
|
getEditorDisplay(item) {
|
|
53347
|
-
|
|
53376
|
+
const isInverse = item.metadata?.inverse === "true";
|
|
53377
|
+
const modifiers = [];
|
|
53378
|
+
if (isInverse) {
|
|
53379
|
+
modifiers.push("remaining");
|
|
53380
|
+
}
|
|
53381
|
+
return {
|
|
53382
|
+
displayText: this.getDisplayName(),
|
|
53383
|
+
modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
|
|
53384
|
+
};
|
|
53385
|
+
}
|
|
53386
|
+
handleEditorAction(action, item) {
|
|
53387
|
+
if (action === "toggle-inverse") {
|
|
53388
|
+
const currentState = item.metadata?.inverse === "true";
|
|
53389
|
+
return {
|
|
53390
|
+
...item,
|
|
53391
|
+
metadata: {
|
|
53392
|
+
...item.metadata,
|
|
53393
|
+
inverse: (!currentState).toString()
|
|
53394
|
+
}
|
|
53395
|
+
};
|
|
53396
|
+
}
|
|
53397
|
+
return null;
|
|
53348
53398
|
}
|
|
53349
53399
|
render(item, context, settings) {
|
|
53400
|
+
const isInverse = item.metadata?.inverse === "true";
|
|
53350
53401
|
if (context.isPreview) {
|
|
53351
|
-
|
|
53402
|
+
const previewValue = isInverse ? "88.4%" : "11.6%";
|
|
53403
|
+
return item.rawValue ? previewValue : `Ctx(u): ${previewValue}`;
|
|
53352
53404
|
} else if (context.tokenMetrics) {
|
|
53353
|
-
const
|
|
53354
|
-
|
|
53405
|
+
const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / 160000 * 100);
|
|
53406
|
+
const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
|
|
53407
|
+
return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
|
|
53355
53408
|
}
|
|
53356
53409
|
return null;
|
|
53357
53410
|
}
|
|
53411
|
+
getCustomKeybinds() {
|
|
53412
|
+
return [
|
|
53413
|
+
{ key: "l", label: "(l)eft/remaining", action: "toggle-inverse" }
|
|
53414
|
+
];
|
|
53415
|
+
}
|
|
53358
53416
|
supportsRawValue() {
|
|
53359
53417
|
return true;
|
|
53360
53418
|
}
|
|
@@ -53379,10 +53437,9 @@ class SessionClockWidget {
|
|
|
53379
53437
|
render(item, context, settings) {
|
|
53380
53438
|
if (context.isPreview) {
|
|
53381
53439
|
return item.rawValue ? "2hr 15m" : "Session: 2hr 15m";
|
|
53382
|
-
} else if (context.sessionDuration) {
|
|
53383
|
-
return item.rawValue ? context.sessionDuration : `Session: ${context.sessionDuration}`;
|
|
53384
53440
|
}
|
|
53385
|
-
|
|
53441
|
+
const duration3 = context.sessionDuration ?? "0m";
|
|
53442
|
+
return item.rawValue ? duration3 : `Session: ${duration3}`;
|
|
53386
53443
|
}
|
|
53387
53444
|
supportsRawValue() {
|
|
53388
53445
|
return true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccstatusline",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
4
4
|
"description": "A customizable status line formatter for Claude Code CLI",
|
|
5
5
|
"module": "src/ccstatusline.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -17,12 +17,15 @@
|
|
|
17
17
|
"example": "cat scripts/payload.example.json | bun start",
|
|
18
18
|
"prepublishOnly": "bun run build",
|
|
19
19
|
"lint": "bun tsc --noEmit; eslint . --config eslint.config.js --max-warnings=999999 --fix",
|
|
20
|
-
"test": "bun vitest"
|
|
20
|
+
"test": "bun vitest",
|
|
21
|
+
"docs": "typedoc",
|
|
22
|
+
"docs:clean": "rm -rf docs"
|
|
21
23
|
},
|
|
22
24
|
"devDependencies": {
|
|
23
25
|
"@eslint/js": "^9.33.0",
|
|
24
26
|
"@stylistic/eslint-plugin": "^5.2.3",
|
|
25
27
|
"@types/bun": "latest",
|
|
28
|
+
"@types/pluralize": "^0.0.33",
|
|
26
29
|
"@types/react": "^19.1.10",
|
|
27
30
|
"chalk": "^5.5.0",
|
|
28
31
|
"eslint": "^9.33.0",
|
|
@@ -34,16 +37,16 @@
|
|
|
34
37
|
"ink": "^6.2.0",
|
|
35
38
|
"ink-gradient": "^3.0.0",
|
|
36
39
|
"ink-select-input": "^6.2.0",
|
|
40
|
+
"pluralize": "^8.0.0",
|
|
37
41
|
"react": "^19.1.1",
|
|
38
42
|
"react-devtools-core": "^6.1.5",
|
|
39
43
|
"strip-ansi": "^7.1.0",
|
|
40
44
|
"tinyglobby": "^0.2.14",
|
|
45
|
+
"typedoc": "^0.28.12",
|
|
41
46
|
"typescript": "^5.9.2",
|
|
42
47
|
"typescript-eslint": "^8.39.1",
|
|
43
48
|
"vitest": "^3.2.4",
|
|
44
|
-
"zod": "^4.0.17"
|
|
45
|
-
"pluralize": "^8.0.0",
|
|
46
|
-
"@types/pluralize": "^0.0.33"
|
|
49
|
+
"zod": "^4.0.17"
|
|
47
50
|
},
|
|
48
51
|
"keywords": [
|
|
49
52
|
"claude",
|