ccstatusline-usage 2.3.4 → 2.3.5
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 +19 -13
- package/dist/ccstatusline.js +163 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
[](https://www.npmjs.com/package/ccstatusline-usage)
|
|
20
20
|
[](https://www.npmjs.com/package/ccstatusline-usage)
|
|
21
|
-
[](https://github.com/
|
|
21
|
+
[](https://github.com/pcvelz/ccstatusline-usage/blob/main/LICENSE)
|
|
22
22
|
[](https://nodejs.org)
|
|
23
23
|
[](https://packagephobia.com/result?p=ccstatusline-usage)
|
|
24
24
|
[](https://github.com/pcvelz/ccstatusline-usage/graphs/commit-activity)
|
|
@@ -34,7 +34,7 @@ This fork adds API-based usage widgets beyond the upstream:
|
|
|
34
34
|
- **Weekly Pace** - Pendulum bar showing if you're ahead or behind expected usage pace
|
|
35
35
|
- **Reset Timer** - Time until 5-hour session window resets
|
|
36
36
|
- **Context Window Display** - Visual bar showing context usage
|
|
37
|
-
- **Off Peak** - Shows peak/off-peak
|
|
37
|
+
- **Off Peak** - Shows peak/off-peak status with countdown timer (peak hours drain sessions faster)
|
|
38
38
|
- **Two-line Layout** - Session info on line 1, context on line 2
|
|
39
39
|
|
|
40
40
|
### Enhanced Status Line Preview
|
|
@@ -66,6 +66,12 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
|
|
|
66
66
|
|
|
67
67
|
## 🆕 Recent Updates
|
|
68
68
|
|
|
69
|
+
### [v2.3.5](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.5) - Upstream sync + permanent peak/off-peak widget
|
|
70
|
+
|
|
71
|
+
- [sirmalloc/ccstatusline](https://github.com/sirmalloc/ccstatusline): **Major upstream sync** — 180 commits merged, including Weekly Reset Timer widget, new test infrastructure, Windows support, and various improvements
|
|
72
|
+
- [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Permanent Off-Peak widget** — Widget no longer disappears after the March 28 promo ends; shows peak/off-peak status permanently with countdown timer (Anthropic confirmed peak hours continue to drain sessions faster)
|
|
73
|
+
- [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **README fork branding fix** — Fixed upstream package name references in Windows install commands, WSL section, and dev setup
|
|
74
|
+
|
|
69
75
|
### [v2.3.4](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.4) - Upstream sync + extra usage fix
|
|
70
76
|
|
|
71
77
|
- [sirmalloc/ccstatusline](https://github.com/sirmalloc/ccstatusline): **Native rate_limits support** — Upstream now uses Claude Code 2.1.80's native `rate_limits` field for usage data
|
|
@@ -337,19 +343,19 @@ ccstatusline works seamlessly on Windows with full feature compatibility across
|
|
|
337
343
|
irm bun.sh/install.ps1 | iex
|
|
338
344
|
|
|
339
345
|
# Run ccstatusline
|
|
340
|
-
bunx -y ccstatusline@latest
|
|
346
|
+
bunx -y ccstatusline-usage@latest
|
|
341
347
|
```
|
|
342
348
|
|
|
343
349
|
#### Option 2: Using Node.js
|
|
344
350
|
```powershell
|
|
345
351
|
# Using npm
|
|
346
|
-
npx -y ccstatusline@latest
|
|
352
|
+
npx -y ccstatusline-usage@latest
|
|
347
353
|
|
|
348
354
|
# Or with Yarn
|
|
349
|
-
yarn dlx ccstatusline@latest
|
|
355
|
+
yarn dlx ccstatusline-usage@latest
|
|
350
356
|
|
|
351
357
|
# Or with pnpm
|
|
352
|
-
pnpm dlx ccstatusline@latest
|
|
358
|
+
pnpm dlx ccstatusline-usage@latest
|
|
353
359
|
```
|
|
354
360
|
|
|
355
361
|
### Windows-Specific Features
|
|
@@ -404,7 +410,7 @@ winget install Git.Git
|
|
|
404
410
|
**Issue**: Permission errors during installation
|
|
405
411
|
```powershell
|
|
406
412
|
# Use non-global installation (recommended)
|
|
407
|
-
npx -y ccstatusline@latest
|
|
413
|
+
npx -y ccstatusline-usage@latest
|
|
408
414
|
|
|
409
415
|
# Or run PowerShell as Administrator for global install
|
|
410
416
|
```
|
|
@@ -432,7 +438,7 @@ ccstatusline works perfectly in WSL environments:
|
|
|
432
438
|
# Install in WSL Ubuntu/Debian
|
|
433
439
|
curl -fsSL https://bun.sh/install | bash
|
|
434
440
|
source ~/.bashrc
|
|
435
|
-
bunx -y ccstatusline@latest
|
|
441
|
+
bunx -y ccstatusline-usage@latest
|
|
436
442
|
```
|
|
437
443
|
|
|
438
444
|
**WSL Benefits**:
|
|
@@ -471,7 +477,7 @@ Configure ccstatusline in your Claude Code settings:
|
|
|
471
477
|
{
|
|
472
478
|
"statusLine": {
|
|
473
479
|
"type": "command",
|
|
474
|
-
"command": "bunx -y ccstatusline@latest",
|
|
480
|
+
"command": "bunx -y ccstatusline-usage@latest",
|
|
475
481
|
"padding": 0
|
|
476
482
|
}
|
|
477
483
|
}
|
|
@@ -482,7 +488,7 @@ Configure ccstatusline in your Claude Code settings:
|
|
|
482
488
|
{
|
|
483
489
|
"statusLine": {
|
|
484
490
|
"type": "command",
|
|
485
|
-
"command": "npx -y ccstatusline@latest",
|
|
491
|
+
"command": "npx -y ccstatusline-usage@latest",
|
|
486
492
|
"padding": 0
|
|
487
493
|
}
|
|
488
494
|
}
|
|
@@ -567,7 +573,7 @@ bun run example
|
|
|
567
573
|
- **Skills** - Shows skill activity as last used, total count, or unique list (with optional list limit and hide-when-empty toggle)
|
|
568
574
|
- **Thinking Effort** - Shows the current Claude Code thinking effort level
|
|
569
575
|
- **Vim Mode** - Displays current vim editor mode
|
|
570
|
-
- **Off Peak** *(ccstatusline-usage)* - Shows `Off
|
|
576
|
+
- **Off Peak** *(ccstatusline-usage)* - Shows `Off-peak (X:XX hr)` or `Peak (X:XX hr)` with countdown to next status change. Peak hours (5-11 AM PT weekdays) drain sessions faster per Anthropic's permanent capacity policy
|
|
571
577
|
- **Separator** - Visual divider between widgets (available when Powerline mode is off and no default separator is configured)
|
|
572
578
|
- **Flex Separator** - Expands to fill available space (available when Powerline mode is off)
|
|
573
579
|
|
|
@@ -762,7 +768,7 @@ The documentation will be generated in the `docs/` directory and can be viewed b
|
|
|
762
768
|
|
|
763
769
|
```bash
|
|
764
770
|
# Clone the repository
|
|
765
|
-
git clone https://github.com/
|
|
771
|
+
git clone https://github.com/pcvelz/ccstatusline-usage.git
|
|
766
772
|
cd ccstatusline
|
|
767
773
|
|
|
768
774
|
# Install dependencies
|
|
@@ -922,7 +928,7 @@ Give a ⭐ if this project helped you!
|
|
|
922
928
|
|
|
923
929
|
[](https://www.npmjs.com/package/ccstatusline-usage)
|
|
924
930
|
[](https://www.npmjs.com/package/ccstatusline-usage)
|
|
925
|
-
[](https://github.com/
|
|
931
|
+
[](https://github.com/pcvelz/ccstatusline-usage/blob/main/LICENSE)
|
|
926
932
|
[](https://bun.sh)
|
|
927
933
|
|
|
928
934
|
[](https://github.com/sirmalloc/ccstatusline/issues)
|
package/dist/ccstatusline.js
CHANGED
|
@@ -54072,7 +54072,7 @@ function getTerminalWidth() {
|
|
|
54072
54072
|
function canDetectTerminalWidth() {
|
|
54073
54073
|
return probeTerminalWidth() !== null;
|
|
54074
54074
|
}
|
|
54075
|
-
var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.
|
|
54075
|
+
var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.5";
|
|
54076
54076
|
var init_terminal = () => {};
|
|
54077
54077
|
|
|
54078
54078
|
// src/utils/renderer.ts
|
|
@@ -61846,6 +61846,128 @@ var init_ApiUsage = __esm(() => {
|
|
|
61846
61846
|
CRED_FILE = path7.join(os7.homedir(), ".claude", ".credentials.json");
|
|
61847
61847
|
});
|
|
61848
61848
|
|
|
61849
|
+
// src/widgets/WeeklyResetTimer.ts
|
|
61850
|
+
function makeTimerProgressBar2(percent, width) {
|
|
61851
|
+
const clampedPercent = Math.max(0, Math.min(100, percent));
|
|
61852
|
+
const filledWidth = Math.floor(clampedPercent / 100 * width);
|
|
61853
|
+
const emptyWidth = width - filledWidth;
|
|
61854
|
+
return "█".repeat(filledWidth) + "░".repeat(emptyWidth);
|
|
61855
|
+
}
|
|
61856
|
+
function isWeeklyResetHoursOnly(item) {
|
|
61857
|
+
return isMetadataFlagEnabled(item, "hours");
|
|
61858
|
+
}
|
|
61859
|
+
function toggleWeeklyResetHoursOnly(item) {
|
|
61860
|
+
return toggleMetadataFlag(item, "hours");
|
|
61861
|
+
}
|
|
61862
|
+
function getWeeklyResetModifierText(item) {
|
|
61863
|
+
const displayMode = getUsageDisplayMode(item);
|
|
61864
|
+
const modifiers = [];
|
|
61865
|
+
if (displayMode === "progress") {
|
|
61866
|
+
modifiers.push("progress bar");
|
|
61867
|
+
} else if (displayMode === "progress-short") {
|
|
61868
|
+
modifiers.push("short bar");
|
|
61869
|
+
}
|
|
61870
|
+
if (isUsageInverted(item)) {
|
|
61871
|
+
modifiers.push("inverted");
|
|
61872
|
+
}
|
|
61873
|
+
if (!isUsageProgressMode(displayMode)) {
|
|
61874
|
+
if (isUsageCompact(item)) {
|
|
61875
|
+
modifiers.push("compact");
|
|
61876
|
+
}
|
|
61877
|
+
if (isWeeklyResetHoursOnly(item)) {
|
|
61878
|
+
modifiers.push("hours only");
|
|
61879
|
+
}
|
|
61880
|
+
}
|
|
61881
|
+
return makeModifierText(modifiers);
|
|
61882
|
+
}
|
|
61883
|
+
|
|
61884
|
+
class WeeklyResetTimerWidget {
|
|
61885
|
+
getDefaultColor() {
|
|
61886
|
+
return "brightBlue";
|
|
61887
|
+
}
|
|
61888
|
+
getDescription() {
|
|
61889
|
+
return "Shows time remaining until weekly usage reset";
|
|
61890
|
+
}
|
|
61891
|
+
getDisplayName() {
|
|
61892
|
+
return "Weekly Reset Timer";
|
|
61893
|
+
}
|
|
61894
|
+
getCategory() {
|
|
61895
|
+
return "Usage";
|
|
61896
|
+
}
|
|
61897
|
+
getEditorDisplay(item) {
|
|
61898
|
+
return {
|
|
61899
|
+
displayText: this.getDisplayName(),
|
|
61900
|
+
modifierText: getWeeklyResetModifierText(item)
|
|
61901
|
+
};
|
|
61902
|
+
}
|
|
61903
|
+
handleEditorAction(action, item) {
|
|
61904
|
+
if (action === "toggle-progress") {
|
|
61905
|
+
return cycleUsageDisplayMode(item, ["compact", "hours"]);
|
|
61906
|
+
}
|
|
61907
|
+
if (action === "toggle-invert") {
|
|
61908
|
+
return toggleUsageInverted(item);
|
|
61909
|
+
}
|
|
61910
|
+
if (action === "toggle-compact") {
|
|
61911
|
+
return toggleUsageCompact(item);
|
|
61912
|
+
}
|
|
61913
|
+
if (action === "toggle-hours") {
|
|
61914
|
+
return toggleWeeklyResetHoursOnly(item);
|
|
61915
|
+
}
|
|
61916
|
+
return null;
|
|
61917
|
+
}
|
|
61918
|
+
render(item, context, settings) {
|
|
61919
|
+
const displayMode = getUsageDisplayMode(item);
|
|
61920
|
+
const inverted = isUsageInverted(item);
|
|
61921
|
+
const compact2 = isUsageCompact(item);
|
|
61922
|
+
const useDays = !isWeeklyResetHoursOnly(item);
|
|
61923
|
+
if (context.isPreview) {
|
|
61924
|
+
const previewPercent = inverted ? 90 : 10;
|
|
61925
|
+
if (isUsageProgressMode(displayMode)) {
|
|
61926
|
+
const barWidth = getUsageProgressBarWidth(displayMode);
|
|
61927
|
+
const progressBar = makeTimerProgressBar2(previewPercent, barWidth);
|
|
61928
|
+
return formatRawOrLabeledValue(item, "Weekly Reset ", `[${progressBar}] ${previewPercent.toFixed(1)}%`);
|
|
61929
|
+
}
|
|
61930
|
+
return formatRawOrLabeledValue(item, "Weekly Reset: ", formatUsageDuration(WEEKLY_PREVIEW_DURATION_MS, compact2, useDays));
|
|
61931
|
+
}
|
|
61932
|
+
const usageData = context.usageData ?? {};
|
|
61933
|
+
const window2 = resolveWeeklyUsageWindow(usageData);
|
|
61934
|
+
if (!window2) {
|
|
61935
|
+
if (usageData.error) {
|
|
61936
|
+
return getUsageErrorMessage(usageData.error);
|
|
61937
|
+
}
|
|
61938
|
+
return null;
|
|
61939
|
+
}
|
|
61940
|
+
if (isUsageProgressMode(displayMode)) {
|
|
61941
|
+
const barWidth = getUsageProgressBarWidth(displayMode);
|
|
61942
|
+
const percent = inverted ? window2.remainingPercent : window2.elapsedPercent;
|
|
61943
|
+
const progressBar = makeTimerProgressBar2(percent, barWidth);
|
|
61944
|
+
const percentage = percent.toFixed(1);
|
|
61945
|
+
return formatRawOrLabeledValue(item, "Weekly Reset ", `[${progressBar}] ${percentage}%`);
|
|
61946
|
+
}
|
|
61947
|
+
const remainingTime = formatUsageDuration(window2.remainingMs, compact2, useDays);
|
|
61948
|
+
return formatRawOrLabeledValue(item, "Weekly Reset: ", remainingTime);
|
|
61949
|
+
}
|
|
61950
|
+
getCustomKeybinds(item) {
|
|
61951
|
+
const keybinds = getUsageTimerCustomKeybinds(item);
|
|
61952
|
+
if (!item || !isUsageProgressMode(getUsageDisplayMode(item))) {
|
|
61953
|
+
keybinds.push({ key: "h", label: "(h)ours only", action: "toggle-hours" });
|
|
61954
|
+
}
|
|
61955
|
+
return keybinds;
|
|
61956
|
+
}
|
|
61957
|
+
supportsRawValue() {
|
|
61958
|
+
return true;
|
|
61959
|
+
}
|
|
61960
|
+
supportsColors(item) {
|
|
61961
|
+
return true;
|
|
61962
|
+
}
|
|
61963
|
+
}
|
|
61964
|
+
var WEEKLY_PREVIEW_DURATION_MS;
|
|
61965
|
+
var init_WeeklyResetTimer = __esm(() => {
|
|
61966
|
+
init_usage();
|
|
61967
|
+
init_usage_display();
|
|
61968
|
+
WEEKLY_PREVIEW_DURATION_MS = 36.5 * 60 * 60 * 1000;
|
|
61969
|
+
});
|
|
61970
|
+
|
|
61849
61971
|
// src/widgets/Link.tsx
|
|
61850
61972
|
function isValidHttpUrl(url2) {
|
|
61851
61973
|
try {
|
|
@@ -62602,34 +62724,45 @@ var init_WeeklyPace = __esm(() => {
|
|
|
62602
62724
|
});
|
|
62603
62725
|
|
|
62604
62726
|
// src/widgets/OffPeak.ts
|
|
62605
|
-
function
|
|
62606
|
-
const ms = now2.getTime();
|
|
62607
|
-
if (ms < PROMO_START_MS || ms >= PROMO_END_MS) {
|
|
62608
|
-
return null;
|
|
62609
|
-
}
|
|
62727
|
+
function isWeekend(now2) {
|
|
62610
62728
|
const dayOfWeek = now2.getUTCDay();
|
|
62611
|
-
|
|
62612
|
-
|
|
62613
|
-
|
|
62729
|
+
return dayOfWeek === 0 || dayOfWeek === 6;
|
|
62730
|
+
}
|
|
62731
|
+
function isPeakHour(now2) {
|
|
62614
62732
|
const utcHour = now2.getUTCHours();
|
|
62615
|
-
|
|
62616
|
-
|
|
62733
|
+
return utcHour >= PEAK_START_UTC_HOUR && utcHour < PEAK_END_UTC_HOUR;
|
|
62734
|
+
}
|
|
62735
|
+
function isPromoActive(now2) {
|
|
62736
|
+
const ms = now2.getTime();
|
|
62737
|
+
return ms >= PROMO_START_MS && ms < PROMO_END_MS;
|
|
62738
|
+
}
|
|
62739
|
+
function isOffPeak(now2) {
|
|
62740
|
+
if (isWeekend(now2))
|
|
62741
|
+
return true;
|
|
62742
|
+
return !isPeakHour(now2);
|
|
62617
62743
|
}
|
|
62618
62744
|
function minutesUntilFlip(now2) {
|
|
62619
|
-
|
|
62620
|
-
|
|
62621
|
-
|
|
62622
|
-
return null;
|
|
62745
|
+
if (isWeekend(now2)) {
|
|
62746
|
+
return minutesUntilMondayPeak(now2);
|
|
62747
|
+
}
|
|
62623
62748
|
const utcHour = now2.getUTCHours();
|
|
62624
|
-
const
|
|
62625
|
-
const flipHour =
|
|
62749
|
+
const peak = isPeakHour(now2);
|
|
62750
|
+
const flipHour = peak ? PEAK_END_UTC_HOUR : PEAK_START_UTC_HOUR;
|
|
62626
62751
|
const target = new Date(now2);
|
|
62627
|
-
if (!
|
|
62752
|
+
if (!peak && utcHour >= PEAK_END_UTC_HOUR) {
|
|
62628
62753
|
target.setUTCDate(now2.getUTCDate() + 1);
|
|
62629
62754
|
}
|
|
62630
62755
|
target.setUTCHours(flipHour, 0, 0, 0);
|
|
62631
62756
|
return Math.max(0, Math.round((target.getTime() - now2.getTime()) / 60000));
|
|
62632
62757
|
}
|
|
62758
|
+
function minutesUntilMondayPeak(now2) {
|
|
62759
|
+
const dayOfWeek = now2.getUTCDay();
|
|
62760
|
+
const daysUntilMonday = dayOfWeek === 0 ? 1 : 8 - dayOfWeek;
|
|
62761
|
+
const target = new Date(now2);
|
|
62762
|
+
target.setUTCDate(now2.getUTCDate() + daysUntilMonday);
|
|
62763
|
+
target.setUTCHours(PEAK_START_UTC_HOUR, 0, 0, 0);
|
|
62764
|
+
return Math.max(0, Math.round((target.getTime() - now2.getTime()) / 60000));
|
|
62765
|
+
}
|
|
62633
62766
|
function formatCountdown(minutes) {
|
|
62634
62767
|
const h = Math.floor(minutes / 60);
|
|
62635
62768
|
const m = minutes % 60;
|
|
@@ -62641,7 +62774,7 @@ class OffPeakWidget {
|
|
|
62641
62774
|
return "green";
|
|
62642
62775
|
}
|
|
62643
62776
|
getDescription() {
|
|
62644
|
-
return "Shows peak / off-peak
|
|
62777
|
+
return "Shows peak / off-peak status with countdown timer";
|
|
62645
62778
|
}
|
|
62646
62779
|
getDisplayName() {
|
|
62647
62780
|
return "Off Peak";
|
|
@@ -62654,17 +62787,21 @@ class OffPeakWidget {
|
|
|
62654
62787
|
}
|
|
62655
62788
|
render(item, context, _settings) {
|
|
62656
62789
|
if (context.isPreview) {
|
|
62657
|
-
return item.rawValue ? "Off-peak
|
|
62790
|
+
return item.rawValue ? "Off-peak (3:42 hr)" : "Off-peak (3:42 hr)";
|
|
62658
62791
|
}
|
|
62659
62792
|
const now2 = new Date;
|
|
62660
62793
|
const offPeak = isOffPeak(now2);
|
|
62661
|
-
if (offPeak === null)
|
|
62662
|
-
return null;
|
|
62663
62794
|
const mins = minutesUntilFlip(now2);
|
|
62664
|
-
const countdown =
|
|
62795
|
+
const countdown = ` (${formatCountdown(mins)} hr)`;
|
|
62665
62796
|
const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 80;
|
|
62797
|
+
if (isPromoActive(now2)) {
|
|
62798
|
+
if (offPeak) {
|
|
62799
|
+
return mobile ? `2x${countdown}` : `Off-peak 2x${countdown}`;
|
|
62800
|
+
}
|
|
62801
|
+
return `Peak${countdown}`;
|
|
62802
|
+
}
|
|
62666
62803
|
if (offPeak) {
|
|
62667
|
-
return mobile ? `
|
|
62804
|
+
return mobile ? `OffPk${countdown}` : `Off-peak${countdown}`;
|
|
62668
62805
|
}
|
|
62669
62806
|
return `Peak${countdown}`;
|
|
62670
62807
|
}
|
|
@@ -62696,6 +62833,7 @@ var init_widgets = __esm(async () => {
|
|
|
62696
62833
|
init_FreeMemory();
|
|
62697
62834
|
init_SessionName();
|
|
62698
62835
|
init_ApiUsage();
|
|
62836
|
+
init_WeeklyResetTimer();
|
|
62699
62837
|
init_ThinkingEffort();
|
|
62700
62838
|
init_Battery();
|
|
62701
62839
|
init_VimMode();
|
|
@@ -62756,6 +62894,7 @@ var init_widget_manifest = __esm(async () => {
|
|
|
62756
62894
|
{ type: "session-usage", create: () => new SessionUsageWidget },
|
|
62757
62895
|
{ type: "weekly-usage", create: () => new WeeklyUsageWidget },
|
|
62758
62896
|
{ type: "reset-timer", create: () => new ResetTimerWidget },
|
|
62897
|
+
{ type: "weekly-reset-timer", create: () => new WeeklyResetTimerWidget },
|
|
62759
62898
|
{ type: "context-bar", create: () => new ContextBarWidget },
|
|
62760
62899
|
{ type: "skills", create: () => new SkillsWidget },
|
|
62761
62900
|
{ type: "thinking-effort", create: () => new ThinkingEffortWidget },
|