ccstatusline-usage 2.1.12 → 2.1.13

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
@@ -64,6 +64,12 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
64
64
 
65
65
  ## 🆕 Recent Updates
66
66
 
67
+ ### [v2.1.13](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.13) - Fix stale API cache causing stuck usage display
68
+
69
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Stale cache expiry** — API usage data older than 10 minutes is now discarded instead of served indefinitely, preventing frozen percentage displays
70
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **429 rate limit handling** — Properly detects HTTP 429 responses and backs off for 120s instead of hammering the API every 30s
71
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Token cache invalidation** — Automatically re-reads OAuth token from Keychain/disk when stale cache expires, recovering from expired tokens
72
+
67
73
  ### [v2.1.12](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.12) - Remove thinking effort bars from model widget
68
74
 
69
75
  - [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
@@ -51473,7 +51473,7 @@ import { execSync as execSync3 } from "child_process";
51473
51473
  import * as fs5 from "fs";
51474
51474
  import * as path4 from "path";
51475
51475
  var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils";
51476
- var PACKAGE_VERSION = "2.1.12";
51476
+ var PACKAGE_VERSION = "2.1.13";
51477
51477
  function getPackageVersion() {
51478
51478
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51479
51479
  return PACKAGE_VERSION;
@@ -54675,6 +54675,7 @@ var LOCK_FILE = path5.join(os6.homedir(), ".cache", "ccstatusline-api.lock");
54675
54675
  var CACHE_MAX_AGE = 180;
54676
54676
  var LOCK_MAX_AGE = 30;
54677
54677
  var TOKEN_CACHE_MAX_AGE = 3600;
54678
+ var STALE_MAX_AGE = 600;
54678
54679
  var cachedData = null;
54679
54680
  var cacheTime = 0;
54680
54681
  var cachedToken = null;
@@ -54719,7 +54720,18 @@ function getToken() {
54719
54720
  }
54720
54721
  function readStaleCache() {
54721
54722
  try {
54722
- return JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54723
+ const data = JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54724
+ if (data.fetchedAt) {
54725
+ const age = Math.floor(Date.now() / 1000) - data.fetchedAt;
54726
+ if (age > STALE_MAX_AGE)
54727
+ return null;
54728
+ } else {
54729
+ const stat = fs6.statSync(CACHE_FILE);
54730
+ const age = Math.floor(Date.now() / 1000) - Math.floor(stat.mtimeMs / 1000);
54731
+ if (age > STALE_MAX_AGE)
54732
+ return null;
54733
+ }
54734
+ return data;
54723
54735
  } catch {
54724
54736
  return null;
54725
54737
  }
@@ -54745,6 +54757,8 @@ function fetchFromApi(token) {
54745
54757
  process.stdout.write(data);
54746
54758
  } else if (res.statusCode === 401) {
54747
54759
  process.exit(2);
54760
+ } else if (res.statusCode === 429) {
54761
+ process.exit(3);
54748
54762
  } else {
54749
54763
  process.exit(1);
54750
54764
  }
@@ -54762,11 +54776,15 @@ function fetchFromApi(token) {
54762
54776
  if (result2.error || !result2.stdout) {
54763
54777
  if (result2.status === 2)
54764
54778
  return "auth-error";
54779
+ if (result2.status === 3)
54780
+ return "rate-limited";
54765
54781
  return null;
54766
54782
  }
54767
54783
  if (result2.status !== 0) {
54768
54784
  if (result2.status === 2)
54769
54785
  return "auth-error";
54786
+ if (result2.status === 3)
54787
+ return "rate-limited";
54770
54788
  return null;
54771
54789
  }
54772
54790
  return result2.stdout;
@@ -54805,6 +54823,10 @@ function fetchApiData() {
54805
54823
  }
54806
54824
  fs6.writeFileSync(LOCK_FILE, "");
54807
54825
  } catch {}
54826
+ const staleBeforeFetch = readStaleCache();
54827
+ if (!staleBeforeFetch) {
54828
+ invalidateTokenCache();
54829
+ }
54808
54830
  const token = getToken();
54809
54831
  if (!token) {
54810
54832
  const stale = readStaleCache();
@@ -54821,6 +54843,16 @@ function fetchApiData() {
54821
54843
  return stale;
54822
54844
  return { error: "api-error" };
54823
54845
  }
54846
+ if (response === "rate-limited") {
54847
+ try {
54848
+ const futureTime = new Date(Date.now() + 90000);
54849
+ fs6.utimesSync(LOCK_FILE, futureTime, futureTime);
54850
+ } catch {}
54851
+ const stale = readStaleCache();
54852
+ if (stale && !stale.error)
54853
+ return stale;
54854
+ return { error: "timeout" };
54855
+ }
54824
54856
  if (!response) {
54825
54857
  const stale = readStaleCache();
54826
54858
  if (stale && !stale.error)
@@ -54848,6 +54880,7 @@ function fetchApiData() {
54848
54880
  return stale;
54849
54881
  return { error: "parse-error" };
54850
54882
  }
54883
+ apiData.fetchedAt = now2;
54851
54884
  try {
54852
54885
  const cacheDir = path5.dirname(CACHE_FILE);
54853
54886
  if (!fs6.existsSync(cacheDir)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.1.12",
3
+ "version": "2.1.13",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",