ccstatusline-usage 2.0.39 → 2.0.41

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
@@ -40,7 +40,7 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
40
40
  Context: [███████░░░░░░░░] 103k/200k (51%)
41
41
  ```
42
42
 
43
- To use the enhanced configuration, copy `defaults/settings-enhanced.json` to your config directory.
43
+ These widgets are enabled by default. Just install and run!
44
44
 
45
45
  ![Status Bar Demo](screenshots/status-bar-demo.png)
46
46
 
@@ -32383,8 +32383,8 @@ var require_utils = __commonJS((exports) => {
32383
32383
  }
32384
32384
  return output;
32385
32385
  };
32386
- exports.basename = (path7, { windows } = {}) => {
32387
- const segs = path7.split(windows ? /[\\/]/ : "/");
32386
+ exports.basename = (path6, { windows } = {}) => {
32387
+ const segs = path6.split(windows ? /[\\/]/ : "/");
32388
32388
  const last = segs[segs.length - 1];
32389
32389
  if (last === "") {
32390
32390
  return segs[segs.length - 2];
@@ -51450,7 +51450,7 @@ import { execSync as execSync3 } from "child_process";
51450
51450
  import * as fs5 from "fs";
51451
51451
  import * as path4 from "path";
51452
51452
  var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils";
51453
- var PACKAGE_VERSION = "2.0.39";
51453
+ var PACKAGE_VERSION = "2.0.41";
51454
51454
  function getPackageVersion() {
51455
51455
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51456
51456
  return PACKAGE_VERSION;
@@ -53812,83 +53812,8 @@ var CustomTextEditor = ({ widget, onComplete, onCancel }) => {
53812
53812
  };
53813
53813
  // src/widgets/CustomCommand.tsx
53814
53814
  import { execSync as execSync7 } from "child_process";
53815
- import * as fs6 from "fs";
53816
53815
  var import_react30 = __toESM(require_react(), 1);
53817
- import * as path5 from "path";
53818
53816
  var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
53819
- function getPackageDir() {
53820
- const scriptPaths = [
53821
- process.argv[1],
53822
- __require.main?.filename
53823
- ].filter(Boolean);
53824
- for (const scriptPath of scriptPaths) {
53825
- try {
53826
- const realPath = fs6.realpathSync(scriptPath);
53827
- let dir = path5.dirname(realPath);
53828
- for (let i = 0;i < 10; i++) {
53829
- const pkgJson = path5.join(dir, "package.json");
53830
- if (fs6.existsSync(pkgJson)) {
53831
- try {
53832
- const pkg = JSON.parse(fs6.readFileSync(pkgJson, "utf8"));
53833
- if (pkg.name === "ccstatusline-usage") {
53834
- return dir;
53835
- }
53836
- } catch {}
53837
- }
53838
- const scriptsDir = path5.join(dir, "scripts");
53839
- if (fs6.existsSync(path5.join(scriptsDir, "usage.sh"))) {
53840
- return dir;
53841
- }
53842
- dir = path5.dirname(dir);
53843
- }
53844
- } catch {}
53845
- }
53846
- const home = process.env.HOME ?? "";
53847
- const npxPaths = [
53848
- path5.join(home, ".npm", "_npx"),
53849
- path5.join(home, ".cache", "npm", "_npx"),
53850
- path5.join(home, ".local", "share", "npm", "_npx")
53851
- ];
53852
- for (const npxBase of npxPaths) {
53853
- if (fs6.existsSync(npxBase)) {
53854
- try {
53855
- const entries = fs6.readdirSync(npxBase);
53856
- for (const entry of entries) {
53857
- const pkgDir = path5.join(npxBase, entry, "node_modules", "ccstatusline-usage");
53858
- if (fs6.existsSync(path5.join(pkgDir, "scripts", "usage.sh"))) {
53859
- return pkgDir;
53860
- }
53861
- }
53862
- } catch {}
53863
- }
53864
- }
53865
- const globalPaths = [
53866
- "/usr/local/lib/node_modules/ccstatusline-usage",
53867
- "/usr/lib/node_modules/ccstatusline-usage",
53868
- path5.join(home, ".nvm", "versions", "node"),
53869
- path5.join(home, "node_modules", "ccstatusline-usage"),
53870
- path5.join(home, ".local", "lib", "node_modules", "ccstatusline-usage")
53871
- ];
53872
- for (const globalPath of globalPaths) {
53873
- if (globalPath.includes(".nvm")) {
53874
- try {
53875
- if (fs6.existsSync(globalPath)) {
53876
- const versions2 = fs6.readdirSync(globalPath);
53877
- for (const ver of versions2) {
53878
- const pkgDir = path5.join(globalPath, ver, "lib", "node_modules", "ccstatusline-usage");
53879
- if (fs6.existsSync(path5.join(pkgDir, "scripts", "usage.sh"))) {
53880
- return pkgDir;
53881
- }
53882
- }
53883
- }
53884
- } catch {}
53885
- } else if (fs6.existsSync(path5.join(globalPath, "scripts", "usage.sh"))) {
53886
- return globalPath;
53887
- }
53888
- }
53889
- return "";
53890
- }
53891
- var PKG_DIR = getPackageDir();
53892
53817
 
53893
53818
  class CustomCommandWidget {
53894
53819
  getDefaultColor() {
@@ -53901,11 +53826,9 @@ class CustomCommandWidget {
53901
53826
  return "Custom Command";
53902
53827
  }
53903
53828
  getEditorDisplay(item) {
53904
- const displayText = item.label ? item.label : (() => {
53905
- const cmd = item.commandPath ?? "No command";
53906
- const truncatedCmd = cmd.length > 20 ? `${cmd.substring(0, 17)}...` : cmd;
53907
- return `${this.getDisplayName()} (${truncatedCmd})`;
53908
- })();
53829
+ const cmd = item.commandPath ?? "No command";
53830
+ const truncatedCmd = cmd.length > 20 ? `${cmd.substring(0, 17)}...` : cmd;
53831
+ const displayText = `${this.getDisplayName()} (${truncatedCmd})`;
53909
53832
  const modifiers = [];
53910
53833
  if (item.maxWidth) {
53911
53834
  modifiers.push(`max:${item.maxWidth}`);
@@ -53927,17 +53850,6 @@ class CustomCommandWidget {
53927
53850
  }
53928
53851
  return null;
53929
53852
  }
53930
- resolveCommandPath(commandPath) {
53931
- if (commandPath.startsWith("$PKG/") || commandPath.startsWith("$PACKAGE_DIR/")) {
53932
- const relativePath = commandPath.replace(/^\$(PKG|PACKAGE_DIR)\//, "");
53933
- const resolved = path5.join(PKG_DIR, relativePath);
53934
- return resolved;
53935
- }
53936
- if (commandPath.startsWith("$HOME/")) {
53937
- return commandPath.replace("$HOME", process.env.HOME ?? "~");
53938
- }
53939
- return commandPath;
53940
- }
53941
53853
  render(item, context, settings) {
53942
53854
  if (context.isPreview) {
53943
53855
  return item.commandPath ? `[cmd: ${item.commandPath.substring(0, 20)}${item.commandPath.length > 20 ? "..." : ""}]` : "[No command]";
@@ -53945,8 +53857,7 @@ class CustomCommandWidget {
53945
53857
  try {
53946
53858
  const timeout = item.timeout ?? 1000;
53947
53859
  const jsonInput = JSON.stringify(context.data);
53948
- const resolvedPath = this.resolveCommandPath(item.commandPath);
53949
- let output = execSync7(resolvedPath, {
53860
+ let output = execSync7(item.commandPath, {
53950
53861
  encoding: "utf8",
53951
53862
  input: jsonInput,
53952
53863
  timeout,
@@ -54367,13 +54278,13 @@ class CurrentWorkingDirWidget {
54367
54278
  supportsColors(item) {
54368
54279
  return true;
54369
54280
  }
54370
- abbreviatePath(path6) {
54281
+ abbreviatePath(path5) {
54371
54282
  const homeDir = os5.homedir();
54372
- const useBackslash = path6.includes("\\") && !path6.includes("/");
54283
+ const useBackslash = path5.includes("\\") && !path5.includes("/");
54373
54284
  const sep = useBackslash ? "\\" : "/";
54374
- let normalizedPath = path6;
54375
- if (path6.startsWith(homeDir)) {
54376
- normalizedPath = "~" + path6.slice(homeDir.length);
54285
+ let normalizedPath = path5;
54286
+ if (path5.startsWith(homeDir)) {
54287
+ normalizedPath = "~" + path5.slice(homeDir.length);
54377
54288
  }
54378
54289
  const parts = normalizedPath.split(/[\\/]+/).filter((part) => part !== "");
54379
54290
  const abbreviated = parts.map((part, index) => {
@@ -54488,64 +54399,143 @@ class ClaudeSessionIdWidget {
54488
54399
  }
54489
54400
  // src/widgets/ApiUsage.tsx
54490
54401
  import { execSync as execSync8, spawnSync } from "child_process";
54491
- import * as fs7 from "fs";
54492
- import * as path6 from "path";
54493
- var CACHE_FILE = path6.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.json");
54402
+ import * as fs6 from "fs";
54403
+ import * as path5 from "path";
54404
+ var CACHE_FILE = path5.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.json");
54405
+ var LOCK_FILE = path5.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.lock");
54494
54406
  var CACHE_MAX_AGE = 180;
54407
+ var LOCK_MAX_AGE = 30;
54408
+ var TOKEN_CACHE_MAX_AGE = 3600;
54495
54409
  var cachedData = null;
54496
54410
  var cacheTime = 0;
54411
+ var cachedToken = null;
54412
+ var tokenCacheTime = 0;
54497
54413
  function getToken() {
54414
+ const now = Math.floor(Date.now() / 1000);
54415
+ if (cachedToken && now - tokenCacheTime < TOKEN_CACHE_MAX_AGE) {
54416
+ return cachedToken;
54417
+ }
54498
54418
  try {
54499
54419
  const isMac = process.platform === "darwin";
54500
54420
  if (isMac) {
54501
54421
  const result = execSync8('security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null', { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
54502
54422
  const parsed = JSON.parse(result);
54503
- return parsed?.claudeAiOauth?.accessToken ?? null;
54423
+ const token = parsed?.claudeAiOauth?.accessToken ?? null;
54424
+ if (token) {
54425
+ cachedToken = token;
54426
+ tokenCacheTime = now;
54427
+ }
54428
+ return token;
54504
54429
  } else {
54505
- const credFile = path6.join(process.env.HOME ?? "", ".claude", ".credentials.json");
54506
- if (fs7.existsSync(credFile)) {
54507
- const creds = JSON.parse(fs7.readFileSync(credFile, "utf8"));
54508
- return creds?.claudeAiOauth?.accessToken ?? null;
54430
+ const credFile = path5.join(process.env.HOME ?? "", ".claude", ".credentials.json");
54431
+ const creds = JSON.parse(fs6.readFileSync(credFile, "utf8"));
54432
+ const token = creds?.claudeAiOauth?.accessToken ?? null;
54433
+ if (token) {
54434
+ cachedToken = token;
54435
+ tokenCacheTime = now;
54509
54436
  }
54437
+ return token;
54510
54438
  }
54511
- } catch {}
54512
- return null;
54439
+ } catch {
54440
+ return null;
54441
+ }
54442
+ }
54443
+ function readStaleCache() {
54444
+ try {
54445
+ return JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54446
+ } catch {
54447
+ return null;
54448
+ }
54449
+ }
54450
+ function fetchFromApi(token) {
54451
+ const script = `
54452
+ const https = require('https');
54453
+ const options = {
54454
+ hostname: 'api.anthropic.com',
54455
+ path: '/api/oauth/usage',
54456
+ method: 'GET',
54457
+ headers: {
54458
+ 'Authorization': 'Bearer ' + process.env.TOKEN,
54459
+ 'anthropic-beta': 'oauth-2025-04-20'
54460
+ },
54461
+ timeout: 5000
54462
+ };
54463
+ const req = https.request(options, (res) => {
54464
+ let data = '';
54465
+ res.on('data', chunk => data += chunk);
54466
+ res.on('end', () => {
54467
+ if (res.statusCode === 200) {
54468
+ process.stdout.write(data);
54469
+ } else {
54470
+ process.exit(1);
54471
+ }
54472
+ });
54473
+ });
54474
+ req.on('error', () => process.exit(1));
54475
+ req.on('timeout', () => { req.destroy(); process.exit(1); });
54476
+ req.end();
54477
+ `;
54478
+ const result = spawnSync("node", ["-e", script], {
54479
+ encoding: "utf8",
54480
+ timeout: 6000,
54481
+ env: { ...process.env, TOKEN: token }
54482
+ });
54483
+ if (result.error || result.status !== 0 || !result.stdout) {
54484
+ return null;
54485
+ }
54486
+ return result.stdout;
54513
54487
  }
54514
54488
  function fetchApiData() {
54515
54489
  const now = Math.floor(Date.now() / 1000);
54516
- if (cachedData && now - cacheTime < CACHE_MAX_AGE) {
54490
+ if (cachedData && !cachedData.error && now - cacheTime < CACHE_MAX_AGE) {
54517
54491
  return cachedData;
54518
54492
  }
54519
54493
  try {
54520
- if (fs7.existsSync(CACHE_FILE)) {
54521
- const stat = fs7.statSync(CACHE_FILE);
54522
- const fileAge = now - Math.floor(stat.mtimeMs / 1000);
54523
- if (fileAge < CACHE_MAX_AGE) {
54524
- cachedData = JSON.parse(fs7.readFileSync(CACHE_FILE, "utf8"));
54494
+ const stat = fs6.statSync(CACHE_FILE);
54495
+ const fileAge = now - Math.floor(stat.mtimeMs / 1000);
54496
+ if (fileAge < CACHE_MAX_AGE) {
54497
+ const fileData = JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54498
+ if (!fileData.error) {
54499
+ cachedData = fileData;
54525
54500
  cacheTime = now;
54526
- return cachedData;
54501
+ return fileData;
54527
54502
  }
54528
54503
  }
54529
54504
  } catch {}
54505
+ try {
54506
+ const lockStat = fs6.statSync(LOCK_FILE);
54507
+ const lockAge = now - Math.floor(lockStat.mtimeMs / 1000);
54508
+ if (lockAge < LOCK_MAX_AGE) {
54509
+ const stale = readStaleCache();
54510
+ if (stale && !stale.error)
54511
+ return stale;
54512
+ return { error: "timeout" };
54513
+ }
54514
+ } catch {}
54515
+ try {
54516
+ const lockDir = path5.dirname(LOCK_FILE);
54517
+ if (!fs6.existsSync(lockDir)) {
54518
+ fs6.mkdirSync(lockDir, { recursive: true });
54519
+ }
54520
+ fs6.writeFileSync(LOCK_FILE, "");
54521
+ } catch {}
54530
54522
  const token = getToken();
54531
- if (!token)
54532
- return null;
54523
+ if (!token) {
54524
+ const stale = readStaleCache();
54525
+ if (stale && !stale.error)
54526
+ return stale;
54527
+ return { error: "no-credentials" };
54528
+ }
54533
54529
  try {
54534
- const curlResult = spawnSync("curl", [
54535
- "-s",
54536
- "--max-time",
54537
- "5",
54538
- "https://api.anthropic.com/api/oauth/usage",
54539
- "-H",
54540
- `Authorization: Bearer ${token}`,
54541
- "-H",
54542
- "anthropic-beta: oauth-2025-04-20"
54543
- ], { encoding: "utf8", timeout: 5000 });
54544
- if (curlResult.error || curlResult.status !== 0)
54545
- return null;
54546
- const result = curlResult.stdout;
54547
- const data = JSON.parse(result);
54548
- let apiData = {};
54530
+ const response = fetchFromApi(token);
54531
+ if (!response) {
54532
+ const stale = readStaleCache();
54533
+ if (stale && !stale.error)
54534
+ return stale;
54535
+ return { error: "api-error" };
54536
+ }
54537
+ const data = JSON.parse(response);
54538
+ const apiData = {};
54549
54539
  if (data.five_hour) {
54550
54540
  apiData.sessionUsage = data.five_hour.utilization;
54551
54541
  apiData.sessionResetAt = data.five_hour.reset_at;
@@ -54553,18 +54543,39 @@ function fetchApiData() {
54553
54543
  if (data.seven_day) {
54554
54544
  apiData.weeklyUsage = data.seven_day.utilization;
54555
54545
  }
54546
+ if (apiData.sessionUsage === undefined && apiData.weeklyUsage === undefined) {
54547
+ const stale = readStaleCache();
54548
+ if (stale && !stale.error)
54549
+ return stale;
54550
+ return { error: "parse-error" };
54551
+ }
54556
54552
  try {
54557
- const cacheDir = path6.dirname(CACHE_FILE);
54558
- if (!fs7.existsSync(cacheDir)) {
54559
- fs7.mkdirSync(cacheDir, { recursive: true });
54553
+ const cacheDir = path5.dirname(CACHE_FILE);
54554
+ if (!fs6.existsSync(cacheDir)) {
54555
+ fs6.mkdirSync(cacheDir, { recursive: true });
54560
54556
  }
54561
- fs7.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54557
+ fs6.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54562
54558
  } catch {}
54563
54559
  cachedData = apiData;
54564
54560
  cacheTime = now;
54565
54561
  return apiData;
54566
54562
  } catch {
54567
- return null;
54563
+ const stale = readStaleCache();
54564
+ if (stale && !stale.error)
54565
+ return stale;
54566
+ return { error: "parse-error" };
54567
+ }
54568
+ }
54569
+ function getErrorMessage(error43) {
54570
+ switch (error43) {
54571
+ case "no-credentials":
54572
+ return "[No credentials]";
54573
+ case "timeout":
54574
+ return "[Timeout]";
54575
+ case "api-error":
54576
+ return "[API Error]";
54577
+ case "parse-error":
54578
+ return "[Parse Error]";
54568
54579
  }
54569
54580
  }
54570
54581
  function makeProgressBar(percent, width = 15) {
@@ -54583,23 +54594,24 @@ class SessionUsageWidget {
54583
54594
  getDisplayName() {
54584
54595
  return "Session Usage";
54585
54596
  }
54586
- getEditorDisplay() {
54597
+ getEditorDisplay(item) {
54587
54598
  return { displayText: this.getDisplayName() };
54588
54599
  }
54589
- render(item, context) {
54600
+ render(item, context, settings) {
54590
54601
  if (context.isPreview)
54591
54602
  return "Session: [███░░░░░░░░░░░░] 20%";
54592
54603
  const data = fetchApiData();
54593
- if (!data || data.sessionUsage === undefined) {
54604
+ if (data.error)
54605
+ return getErrorMessage(data.error);
54606
+ if (data.sessionUsage === undefined)
54594
54607
  return null;
54595
- }
54596
54608
  const percent = data.sessionUsage;
54597
54609
  return `Session: ${makeProgressBar(percent)} ${percent.toFixed(1)}%`;
54598
54610
  }
54599
54611
  supportsRawValue() {
54600
54612
  return false;
54601
54613
  }
54602
- supportsColors() {
54614
+ supportsColors(item) {
54603
54615
  return true;
54604
54616
  }
54605
54617
  }
@@ -54614,23 +54626,24 @@ class WeeklyUsageWidget {
54614
54626
  getDisplayName() {
54615
54627
  return "Weekly Usage";
54616
54628
  }
54617
- getEditorDisplay() {
54629
+ getEditorDisplay(item) {
54618
54630
  return { displayText: this.getDisplayName() };
54619
54631
  }
54620
- render(item, context) {
54632
+ render(item, context, settings) {
54621
54633
  if (context.isPreview)
54622
54634
  return "Weekly: [██░░░░░░░░░░░░░] 12%";
54623
54635
  const data = fetchApiData();
54624
- if (!data || data.weeklyUsage === undefined) {
54636
+ if (data.error)
54637
+ return getErrorMessage(data.error);
54638
+ if (data.weeklyUsage === undefined)
54625
54639
  return null;
54626
- }
54627
54640
  const percent = data.weeklyUsage;
54628
54641
  return `Weekly: ${makeProgressBar(percent)} ${percent.toFixed(1)}%`;
54629
54642
  }
54630
54643
  supportsRawValue() {
54631
54644
  return false;
54632
54645
  }
54633
- supportsColors() {
54646
+ supportsColors(item) {
54634
54647
  return true;
54635
54648
  }
54636
54649
  }
@@ -54645,16 +54658,17 @@ class ResetTimerWidget {
54645
54658
  getDisplayName() {
54646
54659
  return "Reset Timer";
54647
54660
  }
54648
- getEditorDisplay() {
54661
+ getEditorDisplay(item) {
54649
54662
  return { displayText: this.getDisplayName() };
54650
54663
  }
54651
- render(item, context) {
54664
+ render(item, context, settings) {
54652
54665
  if (context.isPreview)
54653
54666
  return "4:30 hr";
54654
54667
  const data = fetchApiData();
54655
- if (!data || !data.sessionResetAt) {
54668
+ if (data.error)
54669
+ return getErrorMessage(data.error);
54670
+ if (!data.sessionResetAt)
54656
54671
  return null;
54657
- }
54658
54672
  try {
54659
54673
  const resetTime = new Date(data.sessionResetAt).getTime();
54660
54674
  const now = Date.now();
@@ -54671,7 +54685,7 @@ class ResetTimerWidget {
54671
54685
  supportsRawValue() {
54672
54686
  return false;
54673
54687
  }
54674
- supportsColors() {
54688
+ supportsColors(item) {
54675
54689
  return true;
54676
54690
  }
54677
54691
  }
@@ -54686,10 +54700,10 @@ class ContextBarWidget {
54686
54700
  getDisplayName() {
54687
54701
  return "Context Bar";
54688
54702
  }
54689
- getEditorDisplay() {
54703
+ getEditorDisplay(item) {
54690
54704
  return { displayText: this.getDisplayName() };
54691
54705
  }
54692
- render(item, context) {
54706
+ render(item, context, settings) {
54693
54707
  if (context.isPreview)
54694
54708
  return "Context: [████░░░░░░░░░░░] 50k/200k (25%)";
54695
54709
  const cw = context.data?.context_window;
@@ -54713,7 +54727,7 @@ class ContextBarWidget {
54713
54727
  supportsRawValue() {
54714
54728
  return false;
54715
54729
  }
54716
- supportsColors() {
54730
+ supportsColors(item) {
54717
54731
  return true;
54718
54732
  }
54719
54733
  }
@@ -58562,42 +58576,42 @@ var StatusJSONSchema = exports_external.looseObject({
58562
58576
  });
58563
58577
 
58564
58578
  // src/utils/jsonl.ts
58565
- import * as fs8 from "fs";
58566
- import path8 from "node:path";
58579
+ import * as fs7 from "fs";
58580
+ import path7 from "node:path";
58567
58581
 
58568
58582
  // node_modules/tinyglobby/dist/index.mjs
58569
- import path7, { posix } from "path";
58583
+ import path6, { posix } from "path";
58570
58584
 
58571
58585
  // node_modules/fdir/dist/index.mjs
58572
58586
  import { createRequire as createRequire2 } from "module";
58573
- import { basename as basename2, dirname as dirname4, normalize, relative, resolve as resolve2, sep } from "path";
58587
+ import { basename as basename2, dirname as dirname3, normalize, relative, resolve as resolve2, sep } from "path";
58574
58588
  import * as nativeFs from "fs";
58575
58589
  var __require2 = /* @__PURE__ */ createRequire2(import.meta.url);
58576
- function cleanPath(path7) {
58577
- let normalized = normalize(path7);
58590
+ function cleanPath(path6) {
58591
+ let normalized = normalize(path6);
58578
58592
  if (normalized.length > 1 && normalized[normalized.length - 1] === sep)
58579
58593
  normalized = normalized.substring(0, normalized.length - 1);
58580
58594
  return normalized;
58581
58595
  }
58582
58596
  var SLASHES_REGEX = /[\\/]/g;
58583
- function convertSlashes(path7, separator) {
58584
- return path7.replace(SLASHES_REGEX, separator);
58597
+ function convertSlashes(path6, separator) {
58598
+ return path6.replace(SLASHES_REGEX, separator);
58585
58599
  }
58586
58600
  var WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
58587
- function isRootDirectory(path7) {
58588
- return path7 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path7);
58601
+ function isRootDirectory(path6) {
58602
+ return path6 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path6);
58589
58603
  }
58590
- function normalizePath(path7, options) {
58604
+ function normalizePath(path6, options) {
58591
58605
  const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
58592
- const pathNeedsCleaning = process.platform === "win32" && path7.includes("/") || path7.startsWith(".");
58606
+ const pathNeedsCleaning = process.platform === "win32" && path6.includes("/") || path6.startsWith(".");
58593
58607
  if (resolvePaths)
58594
- path7 = resolve2(path7);
58608
+ path6 = resolve2(path6);
58595
58609
  if (normalizePath$1 || pathNeedsCleaning)
58596
- path7 = cleanPath(path7);
58597
- if (path7 === ".")
58610
+ path6 = cleanPath(path6);
58611
+ if (path6 === ".")
58598
58612
  return "";
58599
- const needsSeperator = path7[path7.length - 1] !== pathSeparator;
58600
- return convertSlashes(needsSeperator ? path7 + pathSeparator : path7, pathSeparator);
58613
+ const needsSeperator = path6[path6.length - 1] !== pathSeparator;
58614
+ return convertSlashes(needsSeperator ? path6 + pathSeparator : path6, pathSeparator);
58601
58615
  }
58602
58616
  function joinPathWithBasePath(filename, directoryPath) {
58603
58617
  return directoryPath + filename;
@@ -58637,9 +58651,9 @@ var pushDirectory = (directoryPath, paths) => {
58637
58651
  paths.push(directoryPath || ".");
58638
58652
  };
58639
58653
  var pushDirectoryFilter = (directoryPath, paths, filters) => {
58640
- const path7 = directoryPath || ".";
58641
- if (filters.every((filter) => filter(path7, true)))
58642
- paths.push(path7);
58654
+ const path6 = directoryPath || ".";
58655
+ if (filters.every((filter) => filter(path6, true)))
58656
+ paths.push(path6);
58643
58657
  };
58644
58658
  var empty$2 = () => {};
58645
58659
  function build$6(root, options) {
@@ -58696,29 +58710,29 @@ var empty = () => {};
58696
58710
  function build$3(options) {
58697
58711
  return options.group ? groupFiles : empty;
58698
58712
  }
58699
- var resolveSymlinksAsync = function(path7, state, callback$1) {
58700
- const { queue, fs: fs8, options: { suppressErrors } } = state;
58713
+ var resolveSymlinksAsync = function(path6, state, callback$1) {
58714
+ const { queue, fs: fs7, options: { suppressErrors } } = state;
58701
58715
  queue.enqueue();
58702
- fs8.realpath(path7, (error43, resolvedPath) => {
58716
+ fs7.realpath(path6, (error43, resolvedPath) => {
58703
58717
  if (error43)
58704
58718
  return queue.dequeue(suppressErrors ? null : error43, state);
58705
- fs8.stat(resolvedPath, (error$1, stat) => {
58719
+ fs7.stat(resolvedPath, (error$1, stat) => {
58706
58720
  if (error$1)
58707
58721
  return queue.dequeue(suppressErrors ? null : error$1, state);
58708
- if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
58722
+ if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
58709
58723
  return queue.dequeue(null, state);
58710
58724
  callback$1(stat, resolvedPath);
58711
58725
  queue.dequeue(null, state);
58712
58726
  });
58713
58727
  });
58714
58728
  };
58715
- var resolveSymlinks = function(path7, state, callback$1) {
58716
- const { queue, fs: fs8, options: { suppressErrors } } = state;
58729
+ var resolveSymlinks = function(path6, state, callback$1) {
58730
+ const { queue, fs: fs7, options: { suppressErrors } } = state;
58717
58731
  queue.enqueue();
58718
58732
  try {
58719
- const resolvedPath = fs8.realpathSync(path7);
58720
- const stat = fs8.statSync(resolvedPath);
58721
- if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
58733
+ const resolvedPath = fs7.realpathSync(path6);
58734
+ const stat = fs7.statSync(resolvedPath);
58735
+ if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
58722
58736
  return;
58723
58737
  callback$1(stat, resolvedPath);
58724
58738
  } catch (e) {
@@ -58731,10 +58745,10 @@ function build$2(options, isSynchronous) {
58731
58745
  return null;
58732
58746
  return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
58733
58747
  }
58734
- function isRecursive(path7, resolved, state) {
58748
+ function isRecursive(path6, resolved, state) {
58735
58749
  if (state.options.useRealPaths)
58736
58750
  return isRecursiveUsingRealPaths(resolved, state);
58737
- let parent = dirname4(path7);
58751
+ let parent = dirname3(path6);
58738
58752
  let depth = 1;
58739
58753
  while (parent !== state.root && depth < 2) {
58740
58754
  const resolvedPath = state.symlinks.get(parent);
@@ -58742,9 +58756,9 @@ function isRecursive(path7, resolved, state) {
58742
58756
  if (isSameRoot)
58743
58757
  depth++;
58744
58758
  else
58745
- parent = dirname4(parent);
58759
+ parent = dirname3(parent);
58746
58760
  }
58747
- state.symlinks.set(path7, resolved);
58761
+ state.symlinks.set(path6, resolved);
58748
58762
  return depth > 1;
58749
58763
  }
58750
58764
  function isRecursiveUsingRealPaths(resolved, state) {
@@ -58800,23 +58814,23 @@ var walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58800
58814
  state.queue.enqueue();
58801
58815
  if (currentDepth < 0)
58802
58816
  return state.queue.dequeue(null, state);
58803
- const { fs: fs8 } = state;
58817
+ const { fs: fs7 } = state;
58804
58818
  state.visited.push(crawlPath);
58805
58819
  state.counts.directories++;
58806
- fs8.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
58820
+ fs7.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
58807
58821
  callback$1(entries, directoryPath, currentDepth);
58808
58822
  state.queue.dequeue(state.options.suppressErrors ? null : error43, state);
58809
58823
  });
58810
58824
  };
58811
58825
  var walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58812
- const { fs: fs8 } = state;
58826
+ const { fs: fs7 } = state;
58813
58827
  if (currentDepth < 0)
58814
58828
  return;
58815
58829
  state.visited.push(crawlPath);
58816
58830
  state.counts.directories++;
58817
58831
  let entries = [];
58818
58832
  try {
58819
- entries = fs8.readdirSync(crawlPath || ".", readdirOpts);
58833
+ entries = fs7.readdirSync(crawlPath || ".", readdirOpts);
58820
58834
  } catch (e) {
58821
58835
  if (!state.options.suppressErrors)
58822
58836
  throw e;
@@ -58922,23 +58936,23 @@ var Walker = class {
58922
58936
  const filename = this.joinPath(entry.name, directoryPath);
58923
58937
  this.pushFile(filename, files, this.state.counts, filters);
58924
58938
  } else if (entry.isDirectory()) {
58925
- let path7 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
58926
- if (exclude && exclude(entry.name, path7))
58939
+ let path6 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
58940
+ if (exclude && exclude(entry.name, path6))
58927
58941
  continue;
58928
- this.pushDirectory(path7, paths, filters);
58929
- this.walkDirectory(this.state, path7, path7, depth - 1, this.walk);
58942
+ this.pushDirectory(path6, paths, filters);
58943
+ this.walkDirectory(this.state, path6, path6, depth - 1, this.walk);
58930
58944
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
58931
- let path7 = joinPathWithBasePath(entry.name, directoryPath);
58932
- this.resolveSymlink(path7, this.state, (stat, resolvedPath) => {
58945
+ let path6 = joinPathWithBasePath(entry.name, directoryPath);
58946
+ this.resolveSymlink(path6, this.state, (stat, resolvedPath) => {
58933
58947
  if (stat.isDirectory()) {
58934
58948
  resolvedPath = normalizePath(resolvedPath, this.state.options);
58935
- if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path7 + pathSeparator))
58949
+ if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path6 + pathSeparator))
58936
58950
  return;
58937
- this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path7 + pathSeparator, depth - 1, this.walk);
58951
+ this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path6 + pathSeparator, depth - 1, this.walk);
58938
58952
  } else {
58939
- resolvedPath = useRealPaths ? resolvedPath : path7;
58953
+ resolvedPath = useRealPaths ? resolvedPath : path6;
58940
58954
  const filename = basename2(resolvedPath);
58941
- const directoryPath$1 = normalizePath(dirname4(resolvedPath), this.state.options);
58955
+ const directoryPath$1 = normalizePath(dirname3(resolvedPath), this.state.options);
58942
58956
  resolvedPath = this.joinPath(filename, directoryPath$1);
58943
58957
  this.pushFile(resolvedPath, files, this.state.counts, filters);
58944
58958
  }
@@ -59096,7 +59110,7 @@ var Builder = class {
59096
59110
  isMatch = globFn(patterns, ...options);
59097
59111
  this.globCache[patterns.join("\x00")] = isMatch;
59098
59112
  }
59099
- this.options.filters.push((path7) => isMatch(path7));
59113
+ this.options.filters.push((path6) => isMatch(path6));
59100
59114
  return this;
59101
59115
  }
59102
59116
  };
@@ -59175,7 +59189,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
59175
59189
  if (!result.endsWith("*") && expandDirectories)
59176
59190
  result += "/**";
59177
59191
  const escapedCwd = escapePath(cwd2);
59178
- if (path7.isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")))
59192
+ if (path6.isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")))
59179
59193
  result = posix.relative(escapedCwd, result);
59180
59194
  else
59181
59195
  result = posix.normalize(result);
@@ -59212,7 +59226,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
59212
59226
  }
59213
59227
  props.depthOffset = newCommonPath.length;
59214
59228
  props.commonPath = newCommonPath;
59215
- props.root = newCommonPath.length > 0 ? path7.posix.join(cwd2, ...newCommonPath) : cwd2;
59229
+ props.root = newCommonPath.length > 0 ? path6.posix.join(cwd2, ...newCommonPath) : cwd2;
59216
59230
  }
59217
59231
  return result;
59218
59232
  }
@@ -59345,18 +59359,18 @@ function globSync(patternsOrOptions, options) {
59345
59359
  ...options,
59346
59360
  patterns: patternsOrOptions
59347
59361
  } : patternsOrOptions;
59348
- const cwd2 = opts.cwd ? path7.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
59362
+ const cwd2 = opts.cwd ? path6.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
59349
59363
  return crawl(opts, cwd2, true);
59350
59364
  }
59351
59365
 
59352
59366
  // src/utils/jsonl.ts
59353
59367
  import { promisify } from "util";
59354
- var readFile4 = promisify(fs8.readFile);
59355
- var readFileSync6 = fs8.readFileSync;
59356
- var statSync5 = fs8.statSync;
59368
+ var readFile4 = promisify(fs7.readFile);
59369
+ var readFileSync5 = fs7.readFileSync;
59370
+ var statSync5 = fs7.statSync;
59357
59371
  async function getSessionDuration(transcriptPath) {
59358
59372
  try {
59359
- if (!fs8.existsSync(transcriptPath)) {
59373
+ if (!fs7.existsSync(transcriptPath)) {
59360
59374
  return null;
59361
59375
  }
59362
59376
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59408,7 +59422,7 @@ async function getSessionDuration(transcriptPath) {
59408
59422
  }
59409
59423
  async function getTokenMetrics(transcriptPath) {
59410
59424
  try {
59411
- if (!fs8.existsSync(transcriptPath)) {
59425
+ if (!fs7.existsSync(transcriptPath)) {
59412
59426
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
59413
59427
  }
59414
59428
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59461,7 +59475,7 @@ function getBlockMetrics() {
59461
59475
  function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
59462
59476
  const sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
59463
59477
  const now = new Date;
59464
- const pattern = path8.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
59478
+ const pattern = path7.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
59465
59479
  const files = globSync([pattern], {
59466
59480
  absolute: true,
59467
59481
  cwd: rootDir
@@ -59555,7 +59569,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
59555
59569
  function getAllTimestampsFromFile(filePath) {
59556
59570
  const timestamps = [];
59557
59571
  try {
59558
- const content = readFileSync6(filePath, "utf-8");
59572
+ const content = readFileSync5(filePath, "utf-8");
59559
59573
  const lines = content.trim().split(`
59560
59574
  `).filter((line) => line.length > 0);
59561
59575
  for (const line of lines) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.0.39",
3
+ "version": "2.0.41",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",