ccstatusline-usage 2.3.7 → 2.3.9

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 CHANGED
@@ -66,6 +66,15 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
66
66
 
67
67
  ## 🆕 Recent Updates
68
68
 
69
+ ### [v2.3.9](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.9) - Medium display size for mid-width terminals
70
+
71
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Three-tier display sizing** — New medium display size for terminals between 134–177 chars wide. Progress bars render at 8 chars (between mobile's 4 and full's 15). Model and Session ID use compact format in medium mode. Weekly Pace pendulum bar scales to halfWidth=4 in medium.
72
+
73
+ ### [v2.3.8](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.8) - Fix off-peak countdown + Windows EEXIST fix
74
+
75
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Off-peak countdown fix** — Friday evening now correctly counts to Monday peak instead of Saturday noon. Added test coverage for the off-peak time calculation logic.
76
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Windows EEXIST fix** — Handle `mkdir` throwing EEXIST on Windows junction points/symlinks when saving config ([#2](https://github.com/pcvelz/ccstatusline-usage/pull/2), thanks [@BenIsLegit](https://github.com/BenIsLegit))
77
+
69
78
  ### [v2.3.7](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.7) - Weekly Pace as default layout
70
79
 
71
80
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Default layout update** — Weekly Pace widget (pendulum mode) is now included in the default status line layout on line 2, between the context bar and off-peak indicator. Model widget color changed to magenta.
@@ -52656,7 +52656,7 @@ class ModelWidget {
52656
52656
  const is1m = modelId?.includes("[1m]") ?? false;
52657
52657
  const suffix = is1m ? "[1m]" : "";
52658
52658
  const cleanDisplayName = modelDisplayName.replace(/\[1m\]/gi, "").replace(/\(1M context\)/gi, "").trim();
52659
- const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD;
52659
+ const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MEDIUM_THRESHOLD;
52660
52660
  if (mobile && modelId) {
52661
52661
  return `M: ${compactModelName(modelId)}${suffix}`;
52662
52662
  }
@@ -52670,7 +52670,7 @@ class ModelWidget {
52670
52670
  return true;
52671
52671
  }
52672
52672
  }
52673
- var MOBILE_THRESHOLD = 80;
52673
+ var MEDIUM_THRESHOLD = 178;
52674
52674
 
52675
52675
  // src/widgets/OutputStyle.ts
52676
52676
  class OutputStyleWidget {
@@ -54074,7 +54074,7 @@ function getTerminalWidth() {
54074
54074
  function canDetectTerminalWidth() {
54075
54075
  return probeTerminalWidth() !== null;
54076
54076
  }
54077
- var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.7";
54077
+ var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.9";
54078
54078
  var init_terminal = () => {};
54079
54079
 
54080
54080
  // src/utils/renderer.ts
@@ -60940,7 +60940,7 @@ class ClaudeSessionIdWidget {
60940
60940
  if (!sessionId) {
60941
60941
  return null;
60942
60942
  }
60943
- const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 80;
60943
+ const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 178;
60944
60944
  if (mobile) {
60945
60945
  return `S: ${sessionId.slice(0, 8)}`;
60946
60946
  }
@@ -61644,17 +61644,29 @@ function getErrorMessage(error48) {
61644
61644
  return "[Parse Error]";
61645
61645
  }
61646
61646
  }
61647
- function isMobileWidth(context) {
61648
- return (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD2;
61647
+ function getDisplaySize(context) {
61648
+ const w = context.terminalWidth ?? 0;
61649
+ if (w > 0 && w < MOBILE_THRESHOLD)
61650
+ return "mobile";
61651
+ if (w >= MOBILE_THRESHOLD && w < MEDIUM_THRESHOLD2)
61652
+ return "medium";
61653
+ return "full";
61654
+ }
61655
+ function getBarWidth(size2) {
61656
+ if (size2 === "mobile")
61657
+ return MOBILE_BAR_WIDTH;
61658
+ if (size2 === "medium")
61659
+ return MEDIUM_BAR_WIDTH;
61660
+ return DEFAULT_BAR_WIDTH;
61649
61661
  }
61650
61662
  function makeProgressBar(percent, width = DEFAULT_BAR_WIDTH) {
61651
61663
  const filled = Math.round(percent / 100 * width);
61652
61664
  const empty2 = width - filled;
61653
61665
  return "[" + "█".repeat(filled) + "░".repeat(empty2) + "]";
61654
61666
  }
61655
- function formatUsageBar(label, shortLabel, percent, mobile) {
61656
- const bar = makeProgressBar(percent, mobile ? MOBILE_BAR_WIDTH : DEFAULT_BAR_WIDTH);
61657
- return `${mobile ? shortLabel : label}: ${bar} ${percent.toFixed(1)}%`;
61667
+ function formatUsageBar(label, shortLabel, percent, size2) {
61668
+ const bar = makeProgressBar(percent, getBarWidth(size2));
61669
+ return `${size2 === "mobile" ? shortLabel : label}: ${bar} ${percent.toFixed(1)}%`;
61658
61670
  }
61659
61671
 
61660
61672
  class SessionUsageWidget {
@@ -61681,7 +61693,7 @@ class SessionUsageWidget {
61681
61693
  return getErrorMessage(data.error);
61682
61694
  if (data.sessionUsage === undefined)
61683
61695
  return null;
61684
- return formatUsageBar("Session", "S", data.sessionUsage, isMobileWidth(context));
61696
+ return formatUsageBar("Session", "S", data.sessionUsage, getDisplaySize(context));
61685
61697
  }
61686
61698
  supportsRawValue() {
61687
61699
  return false;
@@ -61715,7 +61727,7 @@ class WeeklyUsageWidget {
61715
61727
  return getErrorMessage(data.error);
61716
61728
  if (data.weeklyUsage === undefined)
61717
61729
  return null;
61718
- return formatUsageBar("Weekly", "W", data.weeklyUsage, isMobileWidth(context));
61730
+ return formatUsageBar("Weekly", "W", data.weeklyUsage, getDisplaySize(context));
61719
61731
  }
61720
61732
  supportsRawValue() {
61721
61733
  return false;
@@ -61828,10 +61840,10 @@ class ContextBarWidget {
61828
61840
  const percent = total > 0 ? used / total * 100 : 0;
61829
61841
  const usedK = Math.round(used / 1000);
61830
61842
  const totalStr = total >= 1e6 ? `${Math.round(total / 1e6)}M` : `${Math.round(total / 1000)}k`;
61831
- const mobile = isMobileWidth(context);
61832
- const bar = makeProgressBar(percent, mobile ? MOBILE_BAR_WIDTH : DEFAULT_BAR_WIDTH);
61833
- const label = mobile ? "C" : "Context";
61834
- const suffix = mobile ? "" : ` (${Math.round(percent)}%)`;
61843
+ const size2 = getDisplaySize(context);
61844
+ const bar = makeProgressBar(percent, getBarWidth(size2));
61845
+ const label = size2 === "mobile" ? "C" : "Context";
61846
+ const suffix = size2 === "mobile" ? "" : ` (${Math.round(percent)}%)`;
61835
61847
  return `${label}: ${bar} ${usedK}k/${totalStr}${suffix}`;
61836
61848
  }
61837
61849
  supportsRawValue() {
@@ -61841,7 +61853,7 @@ class ContextBarWidget {
61841
61853
  return true;
61842
61854
  }
61843
61855
  }
61844
- var CACHE_FILE2, LOCK_FILE2, CACHE_MAX_AGE2 = 600, LOCK_MAX_AGE2 = 60, TOKEN_CACHE_MAX_AGE = 3600, cachedData = null, cacheTime = 0, cachedToken = null, tokenCacheTime = 0, CRED_FILE, MOBILE_THRESHOLD2 = 80, MOBILE_BAR_WIDTH = 4, DEFAULT_BAR_WIDTH = 15;
61856
+ var CACHE_FILE2, LOCK_FILE2, CACHE_MAX_AGE2 = 600, LOCK_MAX_AGE2 = 60, TOKEN_CACHE_MAX_AGE = 3600, cachedData = null, cacheTime = 0, cachedToken = null, tokenCacheTime = 0, CRED_FILE, MOBILE_THRESHOLD = 134, MEDIUM_THRESHOLD2 = 178, MOBILE_BAR_WIDTH = 4, MEDIUM_BAR_WIDTH = 8, DEFAULT_BAR_WIDTH = 15;
61845
61857
  var init_ApiUsage = __esm(() => {
61846
61858
  CACHE_FILE2 = path7.join(os7.homedir(), ".cache", "ccstatusline-api.json");
61847
61859
  LOCK_FILE2 = path7.join(os7.homedir(), ".cache", "ccstatusline-api.lock");
@@ -62700,10 +62712,13 @@ class WeeklyPaceWidget {
62700
62712
  return null;
62701
62713
  const actualPercent = Math.max(0, Math.min(100, data.weeklyUsage));
62702
62714
  const { delta, dayOfWeek, status } = computePace(actualPercent, window2.elapsedPercent);
62703
- const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD3;
62715
+ const width = context.terminalWidth ?? 0;
62716
+ const mobile = width > 0 && width < MOBILE_THRESHOLD2;
62717
+ const medium = width >= MOBILE_THRESHOLD2 && width < MEDIUM_THRESHOLD3;
62704
62718
  if (displayMode === "pendulum" && !mobile) {
62719
+ const halfWidth = medium ? 4 : 7;
62705
62720
  const sign = delta >= 0 ? "+" : "";
62706
- const barDisplay = `${makePendulumBar(delta)} D${dayOfWeek}/7 ${sign}${Math.round(delta)}%`;
62721
+ const barDisplay = `${makePendulumBar(delta, halfWidth)} D${dayOfWeek}/7 ${sign}${Math.round(delta)}%`;
62707
62722
  return formatRawOrLabeledValue(item, "Pace: ", barDisplay);
62708
62723
  }
62709
62724
  return formatRawOrLabeledValue(item, "", `D${dayOfWeek}/7: ${status}`);
@@ -62720,7 +62735,7 @@ class WeeklyPaceWidget {
62720
62735
  return true;
62721
62736
  }
62722
62737
  }
62723
- var MOBILE_THRESHOLD3 = 80;
62738
+ var MOBILE_THRESHOLD2 = 134, MEDIUM_THRESHOLD3 = 178;
62724
62739
  var init_WeeklyPace = __esm(() => {
62725
62740
  init_usage();
62726
62741
  });
@@ -62748,6 +62763,11 @@ function minutesUntilFlip(now2) {
62748
62763
  const flipHour = peak ? PEAK_END_UTC_HOUR : PEAK_START_UTC_HOUR;
62749
62764
  const target = new Date(now2);
62750
62765
  if (!peak && utcHour >= PEAK_END_UTC_HOUR) {
62766
+ const tomorrow = new Date(now2);
62767
+ tomorrow.setUTCDate(now2.getUTCDate() + 1);
62768
+ if (isWeekend(tomorrow)) {
62769
+ return minutesUntilMondayPeak(now2);
62770
+ }
62751
62771
  target.setUTCDate(now2.getUTCDate() + 1);
62752
62772
  }
62753
62773
  target.setUTCHours(flipHour, 0, 0, 0);
@@ -62791,7 +62811,7 @@ class OffPeakWidget {
62791
62811
  const offPeak = isOffPeak(now2);
62792
62812
  const mins = minutesUntilFlip(now2);
62793
62813
  const countdown = ` (${formatCountdown(mins)} hr)`;
62794
- const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 80;
62814
+ const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 134;
62795
62815
  if (offPeak) {
62796
62816
  return mobile ? `OffPk${countdown}` : `Off-peak${countdown}`;
62797
62817
  }
@@ -63103,8 +63123,16 @@ function getSettingsPaths() {
63103
63123
  settingsBackupPath: path8.join(configDir, backupBaseName)
63104
63124
  };
63105
63125
  }
63126
+ async function ensureDir(dir) {
63127
+ try {
63128
+ await mkdir(dir, { recursive: true });
63129
+ } catch (err) {
63130
+ if (err.code !== "EEXIST")
63131
+ throw err;
63132
+ }
63133
+ }
63106
63134
  async function writeSettingsJson(settings, paths) {
63107
- await mkdir(paths.configDir, { recursive: true });
63135
+ await ensureDir(paths.configDir);
63108
63136
  await writeFile(paths.settingsPath, JSON.stringify(settings, null, 2), "utf-8");
63109
63137
  }
63110
63138
  async function backupBadSettings(paths) {
@@ -63290,7 +63318,7 @@ async function saveClaudeSettings(settings) {
63290
63318
  const settingsPath2 = getClaudeSettingsPath();
63291
63319
  const dir = path9.dirname(settingsPath2);
63292
63320
  await backupClaudeSettings();
63293
- await mkdir2(dir, { recursive: true });
63321
+ await ensureDir(dir);
63294
63322
  await writeFile2(settingsPath2, JSON.stringify(settings, null, 2), "utf-8");
63295
63323
  }
63296
63324
  async function isInstalled() {
@@ -63383,13 +63411,12 @@ async function getExistingStatusLine() {
63383
63411
  return null;
63384
63412
  }
63385
63413
  }
63386
- var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS;
63414
+ var readFile4, writeFile2, CCSTATUSLINE_COMMANDS;
63387
63415
  var init_claude_settings = __esm(() => {
63388
63416
  init_Settings();
63389
63417
  init_config();
63390
63418
  readFile4 = fs11.promises.readFile;
63391
63419
  writeFile2 = fs11.promises.writeFile;
63392
- mkdir2 = fs11.promises.mkdir;
63393
63420
  CCSTATUSLINE_COMMANDS = {
63394
63421
  NPM: "npx -y ccstatusline-usage@latest",
63395
63422
  BUNX: "bunx -y ccstatusline-usage@latest",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.3.7",
3
+ "version": "2.3.9",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",