ccstatusline-usage 2.1.8 → 2.1.12

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 (3) hide show
  1. package/README.md +157 -34
  2. package/dist/ccstatusline.js +110 -149
  3. package/package.json +1 -3
package/README.md CHANGED
@@ -9,21 +9,38 @@
9
9
 
10
10
  </pre>
11
11
 
12
- # ccstatusline
12
+ # ccstatusline-usage
13
13
 
14
14
  **🎨 A highly customizable status line formatter for Claude Code CLI**
15
- *Display model info, git branch, token usage, and other metrics in your terminal*
15
+ *Display model info, git branch, token usage, API usage, and other metrics in your terminal*
16
16
 
17
- [![npm version](https://img.shields.io/npm/v/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
18
- [![npm downloads](https://img.shields.io/npm/dm/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
17
+ > Fork of [sirmalloc/ccstatusline](https://github.com/sirmalloc/ccstatusline) with added **API usage widgets** (session/weekly utilization bars, reset timer, context bar).
18
+
19
+ [![npm version](https://img.shields.io/npm/v/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
20
+ [![npm downloads](https://img.shields.io/npm/dm/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
19
21
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sirmalloc/ccstatusline/blob/main/LICENSE)
20
- [![Node.js Version](https://img.shields.io/node/v/ccstatusline.svg)](https://nodejs.org)
21
- [![install size](https://packagephobia.com/badge?p=ccstatusline)](https://packagephobia.com/result?p=ccstatusline)
22
- [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/sirmalloc/ccstatusline/graphs/commit-activity)
22
+ [![Node.js Version](https://img.shields.io/node/v/ccstatusline-usage.svg)](https://nodejs.org)
23
+ [![install size](https://packagephobia.com/badge?p=ccstatusline-usage)](https://packagephobia.com/result?p=ccstatusline-usage)
24
+ [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/pcvelz/ccstatusline-usage/graphs/commit-activity)
23
25
 
24
26
  [![Mentioned in Awesome Claude Code](https://awesome.re/mentioned-badge.svg)](https://github.com/hesreallyhim/awesome-claude-code)
25
27
  [![ClaudeLog - A comprehensive knowledge base for Claude](https://claudelog.com/img/claude_log_badge.svg)](https://claudelog.com/)
26
28
 
29
+ ## Fork Enhancements
30
+
31
+ This fork adds API-based usage widgets beyond the upstream:
32
+
33
+ - **Session/Weekly Usage** - Real utilization from Anthropic API with progress bars
34
+ - **Reset Timer** - Time until 5-hour session window resets
35
+ - **Context Window Display** - Visual bar showing context usage
36
+ - **Two-line Layout** - Session info on line 1, context on line 2
37
+
38
+ ### Enhanced Status Line Preview
39
+
40
+ ```
41
+ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [███████████████] 100.0% | Extra: €2.50/€50.00 | Model: Opus 4.6 | Session ID: 0109b99d...
42
+ Context: [███████░░░░░░░░] 103k/200k (51%)
43
+ ```
27
44
 
28
45
  ![Demo](https://raw.githubusercontent.com/sirmalloc/ccstatusline/main/screenshots/demo.gif)
29
46
 
@@ -39,6 +56,7 @@
39
56
  - [API Documentation](#-api-documentation)
40
57
  - [Development](#️-development)
41
58
  - [Contributing](#-contributing)
59
+ - [Uninstall](#️-uninstall)
42
60
  - [License](#-license)
43
61
  - [Related Projects](#-related-projects)
44
62
 
@@ -46,6 +64,14 @@
46
64
 
47
65
  ## 🆕 Recent Updates
48
66
 
67
+ ### [v2.1.12](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.12) - Remove thinking effort bars from model widget
68
+
69
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Remove thinking effort bars** — Claude Code now shows thinking intensity natively in its own UI, so the `▌▌▌` bars after the model name have been removed from the Model widget
70
+
71
+ ### [v2.1.11](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.11) - Configurable extra usage balance
72
+
73
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Configurable extra usage balance** — Add `extraUsageBalance` setting (in cents) to `~/.config/ccstatusline/settings.json` to override the API's monthly limit with your actual prepaid balance (e.g., `"extraUsageBalance": 5000` shows `Extra: €0.00/€50.00`)
74
+
49
75
  ### [v2.1.8](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.8) - Windows support for API usage widgets
50
76
 
51
77
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Windows compatibility** — API usage widgets now work on Windows by using `os.homedir()` instead of `process.env.HOME` for credential and cache file paths
@@ -147,10 +173,13 @@
147
173
  ## ✨ Features
148
174
 
149
175
  - **📊 Real-time Metrics** - Display model name, git branch, token usage, session duration, block timer, and more
176
+ - **📈 API Usage Tracking** - Real-time 5-hour session and weekly utilization from Anthropic API with progress bars
177
+ - **⏱️ Reset Timer** - Countdown to when your 5-hour session window resets
150
178
  - **🎨 Fully Customizable** - Choose what to display and customize colors for each element
151
179
  - **⚡ Powerline Support** - Beautiful Powerline-style rendering with arrow separators, caps, and custom fonts
152
180
  - **📐 Multi-line Support** - Configure multiple independent status lines
153
181
  - **🖥️ Interactive TUI** - Built-in configuration interface using React/Ink
182
+ - **🔎 Fast Widget Picker** - Add/change widgets by category with search and ranked matching
154
183
  - **⚙️ Global Options** - Apply consistent formatting across all widgets (padding, separators, bold, background)
155
184
  - **🚀 Cross-platform** - Works seamlessly with both Bun and Node.js
156
185
  - **🔧 Flexible Configuration** - Supports custom Claude Code config directory via `CLAUDE_CONFIG_DIR` environment variable
@@ -165,10 +194,10 @@
165
194
 
166
195
  ```bash
167
196
  # Run the configuration TUI with npm
168
- npx ccstatusline@latest
197
+ npx -y ccstatusline-usage@latest
169
198
 
170
199
  # Or with Bun (faster)
171
- bunx ccstatusline@latest
200
+ bunx -y ccstatusline-usage@latest
172
201
  ```
173
202
 
174
203
  ### Configure ccstatusline
@@ -193,6 +222,24 @@ The interactive configuration tool provides a terminal UI where you can:
193
222
  > $env:CLAUDE_CONFIG_DIR="C:\custom\path\.claude"
194
223
  > ```
195
224
 
225
+ ### Claude Code settings.json format
226
+
227
+ When you install from the TUI, ccstatusline writes a `statusLine` command object to your Claude Code settings:
228
+
229
+ ```json
230
+ {
231
+ "statusLine": {
232
+ "type": "command",
233
+ "command": "npx -y ccstatusline-usage@latest",
234
+ "padding": 0
235
+ }
236
+ }
237
+ ```
238
+
239
+ Other supported command values are:
240
+ - `bunx -y ccstatusline-usage@latest`
241
+ - `ccstatusline` (for self-managed/global installs)
242
+
196
243
  ---
197
244
 
198
245
  ## 🪟 Windows Support
@@ -207,13 +254,13 @@ ccstatusline works seamlessly on Windows with full feature compatibility across
207
254
  irm bun.sh/install.ps1 | iex
208
255
 
209
256
  # Run ccstatusline
210
- bunx ccstatusline@latest
257
+ bunx -y ccstatusline@latest
211
258
  ```
212
259
 
213
260
  #### Option 2: Using Node.js
214
261
  ```powershell
215
262
  # Using npm
216
- npx ccstatusline@latest
263
+ npx -y ccstatusline@latest
217
264
 
218
265
  # Or with Yarn
219
266
  yarn dlx ccstatusline@latest
@@ -274,7 +321,7 @@ winget install Git.Git
274
321
  **Issue**: Permission errors during installation
275
322
  ```powershell
276
323
  # Use non-global installation (recommended)
277
- npx ccstatusline@latest
324
+ npx -y ccstatusline@latest
278
325
 
279
326
  # Or run PowerShell as Administrator for global install
280
327
  ```
@@ -302,7 +349,7 @@ ccstatusline works perfectly in WSL environments:
302
349
  # Install in WSL Ubuntu/Debian
303
350
  curl -fsSL https://bun.sh/install | bash
304
351
  source ~/.bashrc
305
- bunx ccstatusline@latest
352
+ bunx -y ccstatusline@latest
306
353
  ```
307
354
 
308
355
  **WSL Benefits**:
@@ -339,14 +386,22 @@ Configure ccstatusline in your Claude Code settings:
339
386
  **For Bun users**:
340
387
  ```json
341
388
  {
342
- "statusLine": "bunx ccstatusline@latest"
389
+ "statusLine": {
390
+ "type": "command",
391
+ "command": "bunx -y ccstatusline@latest",
392
+ "padding": 0
393
+ }
343
394
  }
344
395
  ```
345
396
 
346
397
  **For npm users**:
347
398
  ```json
348
399
  {
349
- "statusLine": "npx ccstatusline@latest"
400
+ "statusLine": {
401
+ "type": "command",
402
+ "command": "npx -y ccstatusline@latest",
403
+ "padding": 0
404
+ }
350
405
  }
351
406
  ```
352
407
 
@@ -354,11 +409,10 @@ Configure ccstatusline in your Claude Code settings:
354
409
 
355
410
  ### Performance on Windows
356
411
 
357
- ccstatusline is optimized for Windows performance:
358
- - **Bun runtime**: Significantly faster startup times on Windows
359
- - **Caching**: Intelligent caching of git status and file operations
360
- - **Async operations**: Non-blocking command execution
361
- - **Memory efficient**: Minimal resource usage
412
+ ccstatusline includes Windows-specific runtime behavior:
413
+ - **UTF-8 piped output fix**: In piped mode, it attempts to set code page `65001` for reliable symbol rendering
414
+ - **Path compatibility**: Git and CWD widgets handle both `/` and `\` separators
415
+ - **Block timer cache**: Cached block metrics reduce repeated JSONL scanning
362
416
 
363
417
  ### Windows-Specific Widget Behavior
364
418
 
@@ -375,17 +429,31 @@ Some widgets have Windows-specific optimizations:
375
429
 
376
430
  Once configured, ccstatusline automatically formats your Claude Code status line. The status line appears at the bottom of your terminal during Claude Code sessions.
377
431
 
432
+ ### Runtime Modes
433
+
434
+ - **Interactive mode (TUI)**: Launches when there is no stdin input
435
+ - **Piped mode (renderer)**: Parses Claude Code status JSON from stdin and prints one or more formatted lines
436
+
437
+ ```bash
438
+ # Interactive TUI
439
+ bun run start
440
+
441
+ # Piped mode with example payload
442
+ bun run example
443
+ ```
444
+
378
445
  ### 📊 Available Widgets
379
446
 
380
447
  - **Model Name** - Shows the current Claude model (e.g., "Claude 3.5 Sonnet")
381
448
  - **Git Branch** - Displays current git branch name
382
449
  - **Git Changes** - Shows uncommitted insertions/deletions (e.g., "+42,-10")
450
+ - **Git Root Dir** - Shows the git repository root directory name
383
451
  - **Git Worktree** - Shows the name of the current git worktree
384
452
  - **Session Clock** - Shows elapsed time since session start (e.g., "2hr 15m")
385
453
  - **Session Cost** - Shows total session cost in USD (e.g., "$1.23")
386
454
  - **Session Name** - Shows the session name set via `/rename` command in Claude Code
387
455
  - **Block Timer** - Shows time elapsed in current 5-hour block or progress bar
388
- - **Current Working Directory** - Shows current working directory with configurable path segments
456
+ - **Current Working Directory** - Shows current working directory with segment limit, fish-style abbreviation, and optional `~` home abbreviation
389
457
  - **Version** - Shows Claude Code version
390
458
  - **Output Style** - Shows the currently set output style in Claude Code
391
459
  - **Tokens Input** - Shows input tokens used
@@ -393,15 +461,20 @@ Once configured, ccstatusline automatically formats your Claude Code status line
393
461
  - **Tokens Cached** - Shows cached tokens used
394
462
  - **Tokens Total** - Shows total tokens used
395
463
  - **Context Length** - Shows current context length in tokens
396
- - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for Sonnet 4.5 with `[1m]` suffix, 200k otherwise)
397
- - **Context Percentage (usable)** - Shows percentage of usable context (dynamic: 800k for Sonnet 4.5 with `[1m]` suffix, 160k otherwise, accounting for auto-compact at 80%)
464
+ - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for model IDs with `[1m]` suffix, 200k otherwise)
465
+ - **Context Percentage (usable)** - Shows percentage of usable context (dynamic: 800k for model IDs with `[1m]` suffix, 160k otherwise, accounting for auto-compact at 80%)
398
466
  - **Terminal Width** - Shows detected terminal width (for debugging)
399
467
  - **Memory Usage** - Shows system memory usage (used/total, e.g., "Mem: 12.4G/16.0G")
400
468
  - **Battery** - Shows battery percentage on macOS and Linux (only visible when on battery power, hidden when charging)
469
+ - **Claude Session ID** - Shows the current Claude Code session ID (compact: 8-char truncation)
470
+ - **Session Usage** *(ccstatusline-usage)* - Shows 5-hour session API utilization as a progress bar (e.g., "Session: [███░░░░░░░░░░░░] 20%")
471
+ - **Weekly Usage** *(ccstatusline-usage)* - Shows 7-day API utilization as a progress bar (e.g., "Weekly: [██░░░░░░░░░░░░░] 12%")
472
+ - **Reset Timer** *(ccstatusline-usage)* - Shows time until session limit resets (e.g., "4:30 hr"), or extra usage spending when weekly budget is exhausted
473
+ - **Context Bar** *(ccstatusline-usage)* - Shows context window usage as a progress bar (e.g., "Context: [████░░░░░░░░░░░] 50k/200k (25%)")
401
474
  - **Custom Text** - Add your own custom text to the status line
402
475
  - **Custom Command** - Execute shell commands and display their output (refreshes whenever the statusline is updated by Claude Code)
403
- - **Separator** - Visual divider between widgets (customizable: |, -, comma, space)
404
- - **Flex Separator** - Expands to fill available space
476
+ - **Separator** - Visual divider between widgets (customizable: |, -, comma, space; available when Powerline mode is off and no default separator is configured)
477
+ - **Flex Separator** - Expands to fill available space (available when Powerline mode is off)
405
478
 
406
479
  ---
407
480
 
@@ -471,6 +544,23 @@ Some widgets support "raw value" mode which displays just the value without a la
471
544
  - Normal: `Block: 3hr 45m` → Raw: `3hr 45m`
472
545
  - Normal: `Ctx: 18.6k` → Raw: `18.6k`
473
546
 
547
+ ### ⌨️ Widget Editor Keybinds
548
+
549
+ Common controls in the line editor:
550
+ - `a` add widget
551
+ - `i` insert widget
552
+ - `Enter` enter/exit move mode
553
+ - `d` delete selected widget
554
+ - `r` toggle raw value (supported widgets)
555
+ - `m` cycle merge mode (`off` → `merge` → `merge no padding`)
556
+
557
+ Widget-specific shortcuts:
558
+ - **Git widgets**: `h` toggle hide `no git` output
559
+ - **Context % widgets**: `l` toggle used vs remaining display
560
+ - **Block Timer**: `p` cycle display mode (time/full bar/short bar)
561
+ - **Current Working Dir**: `h` home abbreviation, `s` segment editor, `f` fish-style path
562
+ - **Custom Command**: `e` command, `w` max width, `t` timeout, `p` preserve ANSI colors
563
+
474
564
  ---
475
565
 
476
566
  ### 🔧 Custom Widgets
@@ -487,6 +577,8 @@ Execute shell commands and display their output dynamically:
487
577
  - Receives the full Claude Code JSON data via stdin (model info, session ID, transcript path, etc.)
488
578
  - Displays command output inline in your status line
489
579
  - Configurable timeout (default: 1000ms)
580
+ - Optional max-width truncation
581
+ - Optional ANSI color preservation (`preserve colors`)
490
582
  - Examples:
491
583
  - `pwd | xargs basename` - Show current directory name
492
584
  - `node -v` - Display Node.js version
@@ -558,7 +650,7 @@ The documentation will be generated in the `docs/` directory and can be viewed b
558
650
 
559
651
  - [Bun](https://bun.sh) (v1.0+)
560
652
  - Git
561
- - Node.js 18+ (optional, for npm publishing)
653
+ - Node.js 14+ (optional, for running the built `dist/ccstatusline.js` binary or npm publishing)
562
654
 
563
655
  ### Setup
564
656
 
@@ -574,13 +666,38 @@ bun install
574
666
  ### Development Commands
575
667
 
576
668
  ```bash
577
- # Run in TUI mode (configuration)
578
- bun run src/ccstatusline.ts
669
+ # Run in TUI mode
670
+ bun run start
671
+
672
+ # Test piped mode with example payload
673
+ bun run example
674
+
675
+ # Run tests
676
+ bun test
677
+
678
+ # Run typecheck + eslint autofix
679
+ bun run lint
579
680
 
580
681
  # Build for distribution
581
682
  bun run build
683
+
684
+ # Generate TypeDoc documentation
685
+ bun run docs
582
686
  ```
583
687
 
688
+ ### Configuration Files
689
+
690
+ - `~/.config/ccstatusline/settings.json` - ccstatusline UI/render settings
691
+ - `~/.claude/settings.json` - Claude Code settings (`statusLine` command object)
692
+ - `~/.cache/ccstatusline/block-cache-*.json` - block timer cache (keyed by Claude config directory hash)
693
+
694
+ If you use a custom Claude config location, set `CLAUDE_CONFIG_DIR` and ccstatusline will read/write that path instead of `~/.claude`.
695
+
696
+ ### Build Notes
697
+
698
+ - Build target is Node.js 14+ (`dist/ccstatusline.js`)
699
+ - During install, `ink@6.2.0` is patched to fix backspace handling on macOS terminals
700
+
584
701
  ### 📁 Project Structure
585
702
 
586
703
  ```
@@ -631,11 +748,13 @@ Contributions are welcome! Please feel free to submit a Pull Request.
631
748
 
632
749
  ---
633
750
 
634
- ## Support
751
+ ## 🗑️ Uninstall
635
752
 
636
- If ccstatusline is useful to you, consider buying me a coffee:
637
-
638
- <a href="https://www.buymeacoffee.com/sirmalloc" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
753
+ ```bash
754
+ npm uninstall -g ccstatusline-usage
755
+ rm -rf ~/.npm/_npx ~/.config/ccstatusline ~/.cache/ccstatusline*
756
+ jq 'del(.statusLine)' ~/.claude/settings.json > /tmp/cs.json && cat /tmp/cs.json > ~/.claude/settings.json
757
+ ```
639
758
 
640
759
  ---
641
760
 
@@ -651,6 +770,10 @@ If ccstatusline is useful to you, consider buying me a coffee:
651
770
 
652
771
  - GitHub: [@sirmalloc](https://github.com/sirmalloc)
653
772
 
773
+ **PC van Velzen** ([pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage) fork)
774
+
775
+ - GitHub: [@pcvelz](https://github.com/pcvelz)
776
+
654
777
  ---
655
778
 
656
779
  ## 🔗 Related Projects
@@ -688,8 +811,8 @@ Give a ⭐ if this project helped you!
688
811
  [![GitHub forks](https://img.shields.io/github/forks/sirmalloc/ccstatusline?style=social)](https://github.com/sirmalloc/ccstatusline/network/members)
689
812
  [![GitHub watchers](https://img.shields.io/github/watchers/sirmalloc/ccstatusline?style=social)](https://github.com/sirmalloc/ccstatusline/watchers)
690
813
 
691
- [![npm version](https://img.shields.io/npm/v/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
692
- [![npm downloads](https://img.shields.io/npm/dm/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
814
+ [![npm version](https://img.shields.io/npm/v/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
815
+ [![npm downloads](https://img.shields.io/npm/dm/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
693
816
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sirmalloc/ccstatusline/blob/main/LICENSE)
694
817
  [![Made with Bun](https://img.shields.io/badge/Made%20with-Bun-000000.svg?logo=bun)](https://bun.sh)
695
818
 
@@ -32401,8 +32401,8 @@ var require_utils = __commonJS((exports) => {
32401
32401
  }
32402
32402
  return output;
32403
32403
  };
32404
- exports.basename = (path7, { windows } = {}) => {
32405
- const segs = path7.split(windows ? /[\\/]/ : "/");
32404
+ exports.basename = (path6, { windows } = {}) => {
32405
+ const segs = path6.split(windows ? /[\\/]/ : "/");
32406
32406
  const last2 = segs[segs.length - 1];
32407
32407
  if (last2 === "") {
32408
32408
  return segs[segs.length - 2];
@@ -33924,6 +33924,9 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
33924
33924
  if (env.TERM === "xterm-ghostty") {
33925
33925
  return 3;
33926
33926
  }
33927
+ if (env.TERM === "wezterm") {
33928
+ return 3;
33929
+ }
33927
33930
  if ("TERM_PROGRAM" in env) {
33928
33931
  const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
33929
33932
  switch (env.TERM_PROGRAM) {
@@ -51034,6 +51037,7 @@ var SettingsSchema = exports_external.object({
51034
51037
  theme: undefined,
51035
51038
  autoAlign: false
51036
51039
  }),
51040
+ extraUsageBalance: exports_external.number().optional(),
51037
51041
  updatemessage: exports_external.object({
51038
51042
  message: exports_external.string().nullable().optional(),
51039
51043
  remaining: exports_external.number().nullable().optional()
@@ -51469,7 +51473,7 @@ import { execSync as execSync3 } from "child_process";
51469
51473
  import * as fs5 from "fs";
51470
51474
  import * as path4 from "path";
51471
51475
  var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils";
51472
- var PACKAGE_VERSION = "2.1.8";
51476
+ var PACKAGE_VERSION = "2.1.12";
51473
51477
  function getPackageVersion() {
51474
51478
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51475
51479
  return PACKAGE_VERSION;
@@ -52319,9 +52323,6 @@ var shouldInsertInput = (input, key) => {
52319
52323
  };
52320
52324
 
52321
52325
  // src/widgets/Model.ts
52322
- import * as fs6 from "fs";
52323
- import { homedir as homedir4 } from "os";
52324
- import * as path5 from "path";
52325
52326
  var MOBILE_THRESHOLD = 80;
52326
52327
  function compactModelName(name) {
52327
52328
  const stripped = name.replace(/^claude-/, "");
@@ -52332,44 +52333,6 @@ function compactModelName(name) {
52332
52333
  }
52333
52334
  return stripped;
52334
52335
  }
52335
- function getEffortLevel() {
52336
- const envLevel = process.env.CLAUDE_CODE_EFFORT_LEVEL;
52337
- if (envLevel)
52338
- return envLevel.toLowerCase();
52339
- try {
52340
- const configDir = process.env.CLAUDE_CONFIG_DIR ?? path5.join(homedir4(), ".claude");
52341
- const settingsPath = path5.join(configDir, "settings.json");
52342
- const content = fs6.readFileSync(settingsPath, "utf-8");
52343
- const settings = JSON.parse(content);
52344
- if (settings.effortLevel)
52345
- return settings.effortLevel.toLowerCase();
52346
- } catch {}
52347
- return "high";
52348
- }
52349
- function effortToLevel(effort) {
52350
- switch (effort) {
52351
- case "low":
52352
- return 1;
52353
- case "medium":
52354
- return 2;
52355
- default:
52356
- return 3;
52357
- }
52358
- }
52359
- function renderThinkingBars(level, settings) {
52360
- if (level <= 0)
52361
- return "";
52362
- const colorLevel = getColorLevelString(settings.colorLevel);
52363
- const activeChalk = getChalkColor("red", colorLevel);
52364
- const dimChalk = getChalkColor("brightBlack", colorLevel);
52365
- const bars = ["▌", "▌", "▌"];
52366
- return " " + bars.map((bar, i) => {
52367
- if (i < level) {
52368
- return activeChalk ? activeChalk(bar) : bar;
52369
- }
52370
- return dimChalk ? dimChalk(bar) : bar;
52371
- }).join("");
52372
- }
52373
52336
 
52374
52337
  class ModelWidget {
52375
52338
  getDefaultColor() {
@@ -52389,21 +52352,18 @@ class ModelWidget {
52389
52352
  }
52390
52353
  render(item, context, settings) {
52391
52354
  if (context.isPreview) {
52392
- const bars2 = renderThinkingBars(3, settings);
52393
- return item.rawValue ? `Claude${bars2}` : `Model: Claude${bars2}`;
52355
+ return item.rawValue ? "Claude" : "Model: Claude";
52394
52356
  }
52395
52357
  const model = context.data?.model;
52396
52358
  const modelId = typeof model === "string" ? model : model?.id;
52397
52359
  const modelDisplayName = typeof model === "string" ? model : model?.display_name ?? model?.id;
52398
52360
  if (!modelDisplayName)
52399
52361
  return null;
52400
- const level = effortToLevel(getEffortLevel());
52401
- const bars = renderThinkingBars(level, settings);
52402
52362
  const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD;
52403
52363
  if (mobile && modelId) {
52404
- return `M: ${compactModelName(modelId)}${bars}`;
52364
+ return `M: ${compactModelName(modelId)}`;
52405
52365
  }
52406
- return item.rawValue ? `${modelDisplayName}${bars}` : `Model: ${modelDisplayName}${bars}`;
52366
+ return item.rawValue ? modelDisplayName : `Model: ${modelDisplayName}`;
52407
52367
  }
52408
52368
  supportsRawValue() {
52409
52369
  return true;
@@ -54563,27 +54523,27 @@ class CurrentWorkingDirWidget {
54563
54523
  supportsColors(item) {
54564
54524
  return true;
54565
54525
  }
54566
- abbreviateHomeDir(path6) {
54526
+ abbreviateHomeDir(path5) {
54567
54527
  const homeDir = os5.homedir();
54568
- if (path6 === homeDir) {
54528
+ if (path5 === homeDir) {
54569
54529
  return "~";
54570
54530
  }
54571
- if (path6.startsWith(homeDir)) {
54572
- const boundaryChar = path6[homeDir.length];
54531
+ if (path5.startsWith(homeDir)) {
54532
+ const boundaryChar = path5[homeDir.length];
54573
54533
  if (boundaryChar !== "/" && boundaryChar !== "\\") {
54574
- return path6;
54534
+ return path5;
54575
54535
  }
54576
- return "~" + path6.slice(homeDir.length);
54536
+ return "~" + path5.slice(homeDir.length);
54577
54537
  }
54578
- return path6;
54538
+ return path5;
54579
54539
  }
54580
- abbreviatePath(path6) {
54540
+ abbreviatePath(path5) {
54581
54541
  const homeDir = os5.homedir();
54582
- const useBackslash = path6.includes("\\") && !path6.includes("/");
54542
+ const useBackslash = path5.includes("\\") && !path5.includes("/");
54583
54543
  const sep = useBackslash ? "\\" : "/";
54584
- let normalizedPath = path6;
54585
- if (path6.startsWith(homeDir)) {
54586
- normalizedPath = "~" + path6.slice(homeDir.length);
54544
+ let normalizedPath = path5;
54545
+ if (path5.startsWith(homeDir)) {
54546
+ normalizedPath = "~" + path5.slice(homeDir.length);
54587
54547
  }
54588
54548
  const parts = normalizedPath.split(/[\\/]+/).filter((part) => part !== "");
54589
54549
  const abbreviated = parts.map((part, index) => {
@@ -54707,11 +54667,11 @@ import {
54707
54667
  execSync as execSync6,
54708
54668
  spawnSync
54709
54669
  } from "child_process";
54710
- import * as fs7 from "fs";
54670
+ import * as fs6 from "fs";
54711
54671
  import * as os6 from "os";
54712
- import * as path6 from "path";
54713
- var CACHE_FILE = path6.join(os6.homedir(), ".cache", "ccstatusline-api.json");
54714
- var LOCK_FILE = path6.join(os6.homedir(), ".cache", "ccstatusline-api.lock");
54672
+ import * as path5 from "path";
54673
+ var CACHE_FILE = path5.join(os6.homedir(), ".cache", "ccstatusline-api.json");
54674
+ var LOCK_FILE = path5.join(os6.homedir(), ".cache", "ccstatusline-api.lock");
54715
54675
  var CACHE_MAX_AGE = 180;
54716
54676
  var LOCK_MAX_AGE = 30;
54717
54677
  var TOKEN_CACHE_MAX_AGE = 3600;
@@ -54719,10 +54679,10 @@ var cachedData = null;
54719
54679
  var cacheTime = 0;
54720
54680
  var cachedToken = null;
54721
54681
  var tokenCacheTime = 0;
54722
- var CRED_FILE = path6.join(os6.homedir(), ".claude", ".credentials.json");
54682
+ var CRED_FILE = path5.join(os6.homedir(), ".claude", ".credentials.json");
54723
54683
  function readTokenFromFile() {
54724
54684
  try {
54725
- const creds = JSON.parse(fs7.readFileSync(CRED_FILE, "utf8"));
54685
+ const creds = JSON.parse(fs6.readFileSync(CRED_FILE, "utf8"));
54726
54686
  return creds?.claudeAiOauth?.accessToken ?? null;
54727
54687
  } catch {
54728
54688
  return null;
@@ -54759,7 +54719,7 @@ function getToken() {
54759
54719
  }
54760
54720
  function readStaleCache() {
54761
54721
  try {
54762
- return JSON.parse(fs7.readFileSync(CACHE_FILE, "utf8"));
54722
+ return JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54763
54723
  } catch {
54764
54724
  return null;
54765
54725
  }
@@ -54817,10 +54777,10 @@ function fetchApiData() {
54817
54777
  return cachedData;
54818
54778
  }
54819
54779
  try {
54820
- const stat = fs7.statSync(CACHE_FILE);
54780
+ const stat = fs6.statSync(CACHE_FILE);
54821
54781
  const fileAge = now2 - Math.floor(stat.mtimeMs / 1000);
54822
54782
  if (fileAge < CACHE_MAX_AGE) {
54823
- const fileData = JSON.parse(fs7.readFileSync(CACHE_FILE, "utf8"));
54783
+ const fileData = JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54824
54784
  if (!fileData.error) {
54825
54785
  cachedData = fileData;
54826
54786
  cacheTime = now2;
@@ -54829,7 +54789,7 @@ function fetchApiData() {
54829
54789
  }
54830
54790
  } catch {}
54831
54791
  try {
54832
- const lockStat = fs7.statSync(LOCK_FILE);
54792
+ const lockStat = fs6.statSync(LOCK_FILE);
54833
54793
  const lockAge = now2 - Math.floor(lockStat.mtimeMs / 1000);
54834
54794
  if (lockAge < LOCK_MAX_AGE) {
54835
54795
  const stale = readStaleCache();
@@ -54839,11 +54799,11 @@ function fetchApiData() {
54839
54799
  }
54840
54800
  } catch {}
54841
54801
  try {
54842
- const lockDir = path6.dirname(LOCK_FILE);
54843
- if (!fs7.existsSync(lockDir)) {
54844
- fs7.mkdirSync(lockDir, { recursive: true });
54802
+ const lockDir = path5.dirname(LOCK_FILE);
54803
+ if (!fs6.existsSync(lockDir)) {
54804
+ fs6.mkdirSync(lockDir, { recursive: true });
54845
54805
  }
54846
- fs7.writeFileSync(LOCK_FILE, "");
54806
+ fs6.writeFileSync(LOCK_FILE, "");
54847
54807
  } catch {}
54848
54808
  const token = getToken();
54849
54809
  if (!token) {
@@ -54889,11 +54849,11 @@ function fetchApiData() {
54889
54849
  return { error: "parse-error" };
54890
54850
  }
54891
54851
  try {
54892
- const cacheDir = path6.dirname(CACHE_FILE);
54893
- if (!fs7.existsSync(cacheDir)) {
54894
- fs7.mkdirSync(cacheDir, { recursive: true });
54852
+ const cacheDir = path5.dirname(CACHE_FILE);
54853
+ if (!fs6.existsSync(cacheDir)) {
54854
+ fs6.mkdirSync(cacheDir, { recursive: true });
54895
54855
  }
54896
- fs7.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54856
+ fs6.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54897
54857
  } catch {}
54898
54858
  cachedData = apiData;
54899
54859
  cacheTime = now2;
@@ -55025,7 +54985,8 @@ class ResetTimerWidget {
55025
54985
  return getErrorMessage(data.error);
55026
54986
  if (data.extraUsageEnabled && data.weeklyUsage !== undefined && data.weeklyUsage >= 100 && data.extraUsageUsed !== undefined && data.extraUsageLimit !== undefined) {
55027
54987
  const used = formatCents(data.extraUsageUsed);
55028
- const limit = formatCents(data.extraUsageLimit);
54988
+ const displayLimit = settings.extraUsageBalance ?? data.extraUsageLimit;
54989
+ const limit = formatCents(displayLimit);
55029
54990
  return `Extra: ${used}/${limit}`;
55030
54991
  }
55031
54992
  if (!data.sessionResetAt)
@@ -55112,7 +55073,7 @@ class ContextBarWidget {
55112
55073
  }
55113
55074
  }
55114
55075
  // src/widgets/SessionName.ts
55115
- import * as fs8 from "fs";
55076
+ import * as fs7 from "fs";
55116
55077
 
55117
55078
  class SessionNameWidget {
55118
55079
  getDefaultColor() {
@@ -55139,7 +55100,7 @@ class SessionNameWidget {
55139
55100
  return null;
55140
55101
  }
55141
55102
  try {
55142
- const content = fs8.readFileSync(transcriptPath, "utf-8");
55103
+ const content = fs7.readFileSync(transcriptPath, "utf-8");
55143
55104
  const lines = content.split(`
55144
55105
  `);
55145
55106
  for (let i = lines.length - 1;i >= 0; i--) {
@@ -55248,7 +55209,7 @@ class FreeMemoryWidget {
55248
55209
  }
55249
55210
  // src/widgets/Battery.ts
55250
55211
  import { execSync as execSync8 } from "child_process";
55251
- import { readFileSync as readFileSync6 } from "fs";
55212
+ import { readFileSync as readFileSync5 } from "fs";
55252
55213
  function getMacBatteryInfo() {
55253
55214
  try {
55254
55215
  const output = execSync8("pmset -g batt", { encoding: "utf-8", timeout: 2000 });
@@ -55268,8 +55229,8 @@ function getMacBatteryInfo() {
55268
55229
  }
55269
55230
  function getLinuxBatteryInfo() {
55270
55231
  try {
55271
- const capacity = readFileSync6("/sys/class/power_supply/BAT0/capacity", "utf-8").trim();
55272
- const status = readFileSync6("/sys/class/power_supply/BAT0/status", "utf-8").trim().toLowerCase();
55232
+ const capacity = readFileSync5("/sys/class/power_supply/BAT0/capacity", "utf-8").trim();
55233
+ const status = readFileSync5("/sys/class/power_supply/BAT0/status", "utf-8").trim().toLowerCase();
55273
55234
  const percent = parseInt(capacity, 10);
55274
55235
  if (isNaN(percent)) {
55275
55236
  return null;
@@ -59718,44 +59679,44 @@ function renderCompactOutput(preRenderedLines, settings, maxWidth) {
59718
59679
  }
59719
59680
 
59720
59681
  // src/utils/jsonl.ts
59721
- import * as fs9 from "fs";
59682
+ import * as fs8 from "fs";
59722
59683
  import { createHash } from "node:crypto";
59723
59684
  import os9 from "node:os";
59724
- import path8 from "node:path";
59685
+ import path7 from "node:path";
59725
59686
 
59726
59687
  // node_modules/tinyglobby/dist/index.mjs
59727
- import path7, { posix } from "path";
59688
+ import path6, { posix } from "path";
59728
59689
 
59729
59690
  // node_modules/fdir/dist/index.mjs
59730
59691
  import { createRequire as createRequire2 } from "module";
59731
59692
  import { basename as basename2, dirname as dirname3, normalize, relative, resolve as resolve2, sep } from "path";
59732
59693
  import * as nativeFs from "fs";
59733
59694
  var __require2 = /* @__PURE__ */ createRequire2(import.meta.url);
59734
- function cleanPath(path7) {
59735
- let normalized = normalize(path7);
59695
+ function cleanPath(path6) {
59696
+ let normalized = normalize(path6);
59736
59697
  if (normalized.length > 1 && normalized[normalized.length - 1] === sep)
59737
59698
  normalized = normalized.substring(0, normalized.length - 1);
59738
59699
  return normalized;
59739
59700
  }
59740
59701
  var SLASHES_REGEX = /[\\/]/g;
59741
- function convertSlashes(path7, separator) {
59742
- return path7.replace(SLASHES_REGEX, separator);
59702
+ function convertSlashes(path6, separator) {
59703
+ return path6.replace(SLASHES_REGEX, separator);
59743
59704
  }
59744
59705
  var WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
59745
- function isRootDirectory(path7) {
59746
- return path7 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path7);
59706
+ function isRootDirectory(path6) {
59707
+ return path6 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path6);
59747
59708
  }
59748
- function normalizePath(path7, options) {
59709
+ function normalizePath(path6, options) {
59749
59710
  const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
59750
- const pathNeedsCleaning = process.platform === "win32" && path7.includes("/") || path7.startsWith(".");
59711
+ const pathNeedsCleaning = process.platform === "win32" && path6.includes("/") || path6.startsWith(".");
59751
59712
  if (resolvePaths)
59752
- path7 = resolve2(path7);
59713
+ path6 = resolve2(path6);
59753
59714
  if (normalizePath$1 || pathNeedsCleaning)
59754
- path7 = cleanPath(path7);
59755
- if (path7 === ".")
59715
+ path6 = cleanPath(path6);
59716
+ if (path6 === ".")
59756
59717
  return "";
59757
- const needsSeperator = path7[path7.length - 1] !== pathSeparator;
59758
- return convertSlashes(needsSeperator ? path7 + pathSeparator : path7, pathSeparator);
59718
+ const needsSeperator = path6[path6.length - 1] !== pathSeparator;
59719
+ return convertSlashes(needsSeperator ? path6 + pathSeparator : path6, pathSeparator);
59759
59720
  }
59760
59721
  function joinPathWithBasePath(filename, directoryPath) {
59761
59722
  return directoryPath + filename;
@@ -59795,9 +59756,9 @@ var pushDirectory = (directoryPath, paths) => {
59795
59756
  paths.push(directoryPath || ".");
59796
59757
  };
59797
59758
  var pushDirectoryFilter = (directoryPath, paths, filters) => {
59798
- const path7 = directoryPath || ".";
59799
- if (filters.every((filter2) => filter2(path7, true)))
59800
- paths.push(path7);
59759
+ const path6 = directoryPath || ".";
59760
+ if (filters.every((filter2) => filter2(path6, true)))
59761
+ paths.push(path6);
59801
59762
  };
59802
59763
  var empty$2 = () => {};
59803
59764
  function build$6(root, options) {
@@ -59854,29 +59815,29 @@ var empty = () => {};
59854
59815
  function build$3(options) {
59855
59816
  return options.group ? groupFiles : empty;
59856
59817
  }
59857
- var resolveSymlinksAsync = function(path7, state, callback$1) {
59858
- const { queue, fs: fs9, options: { suppressErrors } } = state;
59818
+ var resolveSymlinksAsync = function(path6, state, callback$1) {
59819
+ const { queue, fs: fs8, options: { suppressErrors } } = state;
59859
59820
  queue.enqueue();
59860
- fs9.realpath(path7, (error43, resolvedPath) => {
59821
+ fs8.realpath(path6, (error43, resolvedPath) => {
59861
59822
  if (error43)
59862
59823
  return queue.dequeue(suppressErrors ? null : error43, state);
59863
- fs9.stat(resolvedPath, (error$1, stat) => {
59824
+ fs8.stat(resolvedPath, (error$1, stat) => {
59864
59825
  if (error$1)
59865
59826
  return queue.dequeue(suppressErrors ? null : error$1, state);
59866
- if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
59827
+ if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
59867
59828
  return queue.dequeue(null, state);
59868
59829
  callback$1(stat, resolvedPath);
59869
59830
  queue.dequeue(null, state);
59870
59831
  });
59871
59832
  });
59872
59833
  };
59873
- var resolveSymlinks = function(path7, state, callback$1) {
59874
- const { queue, fs: fs9, options: { suppressErrors } } = state;
59834
+ var resolveSymlinks = function(path6, state, callback$1) {
59835
+ const { queue, fs: fs8, options: { suppressErrors } } = state;
59875
59836
  queue.enqueue();
59876
59837
  try {
59877
- const resolvedPath = fs9.realpathSync(path7);
59878
- const stat = fs9.statSync(resolvedPath);
59879
- if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
59838
+ const resolvedPath = fs8.realpathSync(path6);
59839
+ const stat = fs8.statSync(resolvedPath);
59840
+ if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
59880
59841
  return;
59881
59842
  callback$1(stat, resolvedPath);
59882
59843
  } catch (e) {
@@ -59889,10 +59850,10 @@ function build$2(options, isSynchronous) {
59889
59850
  return null;
59890
59851
  return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
59891
59852
  }
59892
- function isRecursive(path7, resolved, state) {
59853
+ function isRecursive(path6, resolved, state) {
59893
59854
  if (state.options.useRealPaths)
59894
59855
  return isRecursiveUsingRealPaths(resolved, state);
59895
- let parent = dirname3(path7);
59856
+ let parent = dirname3(path6);
59896
59857
  let depth = 1;
59897
59858
  while (parent !== state.root && depth < 2) {
59898
59859
  const resolvedPath = state.symlinks.get(parent);
@@ -59902,7 +59863,7 @@ function isRecursive(path7, resolved, state) {
59902
59863
  else
59903
59864
  parent = dirname3(parent);
59904
59865
  }
59905
- state.symlinks.set(path7, resolved);
59866
+ state.symlinks.set(path6, resolved);
59906
59867
  return depth > 1;
59907
59868
  }
59908
59869
  function isRecursiveUsingRealPaths(resolved, state) {
@@ -59958,23 +59919,23 @@ var walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
59958
59919
  state.queue.enqueue();
59959
59920
  if (currentDepth < 0)
59960
59921
  return state.queue.dequeue(null, state);
59961
- const { fs: fs9 } = state;
59922
+ const { fs: fs8 } = state;
59962
59923
  state.visited.push(crawlPath);
59963
59924
  state.counts.directories++;
59964
- fs9.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
59925
+ fs8.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
59965
59926
  callback$1(entries, directoryPath, currentDepth);
59966
59927
  state.queue.dequeue(state.options.suppressErrors ? null : error43, state);
59967
59928
  });
59968
59929
  };
59969
59930
  var walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
59970
- const { fs: fs9 } = state;
59931
+ const { fs: fs8 } = state;
59971
59932
  if (currentDepth < 0)
59972
59933
  return;
59973
59934
  state.visited.push(crawlPath);
59974
59935
  state.counts.directories++;
59975
59936
  let entries = [];
59976
59937
  try {
59977
- entries = fs9.readdirSync(crawlPath || ".", readdirOpts);
59938
+ entries = fs8.readdirSync(crawlPath || ".", readdirOpts);
59978
59939
  } catch (e) {
59979
59940
  if (!state.options.suppressErrors)
59980
59941
  throw e;
@@ -60080,21 +60041,21 @@ var Walker = class {
60080
60041
  const filename = this.joinPath(entry.name, directoryPath);
60081
60042
  this.pushFile(filename, files, this.state.counts, filters);
60082
60043
  } else if (entry.isDirectory()) {
60083
- let path7 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
60084
- if (exclude && exclude(entry.name, path7))
60044
+ let path6 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
60045
+ if (exclude && exclude(entry.name, path6))
60085
60046
  continue;
60086
- this.pushDirectory(path7, paths, filters);
60087
- this.walkDirectory(this.state, path7, path7, depth - 1, this.walk);
60047
+ this.pushDirectory(path6, paths, filters);
60048
+ this.walkDirectory(this.state, path6, path6, depth - 1, this.walk);
60088
60049
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
60089
- let path7 = joinPathWithBasePath(entry.name, directoryPath);
60090
- this.resolveSymlink(path7, this.state, (stat, resolvedPath) => {
60050
+ let path6 = joinPathWithBasePath(entry.name, directoryPath);
60051
+ this.resolveSymlink(path6, this.state, (stat, resolvedPath) => {
60091
60052
  if (stat.isDirectory()) {
60092
60053
  resolvedPath = normalizePath(resolvedPath, this.state.options);
60093
- if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path7 + pathSeparator))
60054
+ if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path6 + pathSeparator))
60094
60055
  return;
60095
- this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path7 + pathSeparator, depth - 1, this.walk);
60056
+ this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path6 + pathSeparator, depth - 1, this.walk);
60096
60057
  } else {
60097
- resolvedPath = useRealPaths ? resolvedPath : path7;
60058
+ resolvedPath = useRealPaths ? resolvedPath : path6;
60098
60059
  const filename = basename2(resolvedPath);
60099
60060
  const directoryPath$1 = normalizePath(dirname3(resolvedPath), this.state.options);
60100
60061
  resolvedPath = this.joinPath(filename, directoryPath$1);
@@ -60254,7 +60215,7 @@ var Builder = class {
60254
60215
  isMatch2 = globFn(patterns, ...options);
60255
60216
  this.globCache[patterns.join("\x00")] = isMatch2;
60256
60217
  }
60257
- this.options.filters.push((path7) => isMatch2(path7));
60218
+ this.options.filters.push((path6) => isMatch2(path6));
60258
60219
  return this;
60259
60220
  }
60260
60221
  };
@@ -60333,7 +60294,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
60333
60294
  if (!result2.endsWith("*") && expandDirectories)
60334
60295
  result2 += "/**";
60335
60296
  const escapedCwd = escapePath(cwd2);
60336
- if (path7.isAbsolute(result2.replace(ESCAPING_BACKSLASHES, "")))
60297
+ if (path6.isAbsolute(result2.replace(ESCAPING_BACKSLASHES, "")))
60337
60298
  result2 = posix.relative(escapedCwd, result2);
60338
60299
  else
60339
60300
  result2 = posix.normalize(result2);
@@ -60370,7 +60331,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
60370
60331
  }
60371
60332
  props.depthOffset = newCommonPath.length;
60372
60333
  props.commonPath = newCommonPath;
60373
- props.root = newCommonPath.length > 0 ? path7.posix.join(cwd2, ...newCommonPath) : cwd2;
60334
+ props.root = newCommonPath.length > 0 ? path6.posix.join(cwd2, ...newCommonPath) : cwd2;
60374
60335
  }
60375
60336
  return result2;
60376
60337
  }
@@ -60503,25 +60464,25 @@ function globSync(patternsOrOptions, options) {
60503
60464
  ...options,
60504
60465
  patterns: patternsOrOptions
60505
60466
  } : patternsOrOptions;
60506
- const cwd2 = opts.cwd ? path7.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
60467
+ const cwd2 = opts.cwd ? path6.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
60507
60468
  return crawl(opts, cwd2, true);
60508
60469
  }
60509
60470
 
60510
60471
  // src/utils/jsonl.ts
60511
60472
  import { promisify } from "util";
60512
- var readFile4 = promisify(fs9.readFile);
60513
- var readFileSync8 = fs9.readFileSync;
60514
- var statSync5 = fs9.statSync;
60515
- var writeFileSync3 = fs9.writeFileSync;
60516
- var mkdirSync4 = fs9.mkdirSync;
60517
- var existsSync8 = fs9.existsSync;
60473
+ var readFile4 = promisify(fs8.readFile);
60474
+ var readFileSync7 = fs8.readFileSync;
60475
+ var statSync5 = fs8.statSync;
60476
+ var writeFileSync3 = fs8.writeFileSync;
60477
+ var mkdirSync4 = fs8.mkdirSync;
60478
+ var existsSync8 = fs8.existsSync;
60518
60479
  function normalizeConfigDir(configDir) {
60519
- return path8.resolve(configDir);
60480
+ return path7.resolve(configDir);
60520
60481
  }
60521
60482
  function getBlockCachePath(configDir = getClaudeConfigDir()) {
60522
60483
  const normalizedConfigDir = normalizeConfigDir(configDir);
60523
60484
  const configHash = createHash("sha256").update(normalizedConfigDir).digest("hex").slice(0, 16);
60524
- return path8.join(os9.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
60485
+ return path7.join(os9.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
60525
60486
  }
60526
60487
  function readBlockCache(expectedConfigDir) {
60527
60488
  try {
@@ -60530,7 +60491,7 @@ function readBlockCache(expectedConfigDir) {
60530
60491
  if (!existsSync8(cachePath)) {
60531
60492
  return null;
60532
60493
  }
60533
- const content = readFileSync8(cachePath, "utf-8");
60494
+ const content = readFileSync7(cachePath, "utf-8");
60534
60495
  const cache3 = JSON.parse(content);
60535
60496
  if (typeof cache3.startTime !== "string") {
60536
60497
  return null;
@@ -60556,7 +60517,7 @@ function writeBlockCache(startTime, configDir = getClaudeConfigDir()) {
60556
60517
  try {
60557
60518
  const normalizedConfigDir = normalizeConfigDir(configDir);
60558
60519
  const cachePath = getBlockCachePath(normalizedConfigDir);
60559
- const cacheDir = path8.dirname(cachePath);
60520
+ const cacheDir = path7.dirname(cachePath);
60560
60521
  if (!existsSync8(cacheDir)) {
60561
60522
  mkdirSync4(cacheDir, { recursive: true });
60562
60523
  }
@@ -60589,7 +60550,7 @@ function getCachedBlockMetrics(sessionDurationHours = 5) {
60589
60550
  }
60590
60551
  async function getSessionDuration(transcriptPath) {
60591
60552
  try {
60592
- if (!fs9.existsSync(transcriptPath)) {
60553
+ if (!fs8.existsSync(transcriptPath)) {
60593
60554
  return null;
60594
60555
  }
60595
60556
  const content = await readFile4(transcriptPath, "utf-8");
@@ -60641,7 +60602,7 @@ async function getSessionDuration(transcriptPath) {
60641
60602
  }
60642
60603
  async function getTokenMetrics(transcriptPath) {
60643
60604
  try {
60644
- if (!fs9.existsSync(transcriptPath)) {
60605
+ if (!fs8.existsSync(transcriptPath)) {
60645
60606
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
60646
60607
  }
60647
60608
  const content = await readFile4(transcriptPath, "utf-8");
@@ -60694,7 +60655,7 @@ function getBlockMetrics() {
60694
60655
  function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
60695
60656
  const sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
60696
60657
  const now2 = new Date;
60697
- const pattern = path8.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
60658
+ const pattern = path7.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
60698
60659
  const files = globSync([pattern], {
60699
60660
  absolute: true,
60700
60661
  cwd: rootDir
@@ -60788,7 +60749,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
60788
60749
  function getAllTimestampsFromFile(filePath) {
60789
60750
  const timestamps = [];
60790
60751
  try {
60791
- const content = readFileSync8(filePath, "utf-8");
60752
+ const content = readFileSync7(filePath, "utf-8");
60792
60753
  const lines = content.trim().split(`
60793
60754
  `).filter((line) => line.length > 0);
60794
60755
  for (const line of lines) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.1.8",
3
+ "version": "2.1.12",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",
@@ -17,8 +17,6 @@
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",
21
- "publish:safe": "bash scripts/safe-publish.sh",
22
20
  "docs": "typedoc",
23
21
  "docs:clean": "rm -rf docs"
24
22
  },