claude-token-saver 2.8.3 → 2.8.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-token-saver",
3
- "version": "2.8.3",
3
+ "version": "2.8.4",
4
4
  "description": "Save tokens on Claude Code — spike diagnosis, 1M-context detection, TTL countdown, statusline. (formerly claude-cache-monitor)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -103,7 +103,7 @@ function formatTimer(remainingSec) {
103
103
  // Defensive: non-finite/NaN inputs (e.g. clock skew, stringified Date) used
104
104
  // to slip through and render as "NaN:NaN" or stretched seconds. Treat any
105
105
  // weird input as expired rather than rendering garbage in the statusline.
106
- if (!Number.isFinite(remainingSec) || remainingSec <= 0) return 'EXPIRED';
106
+ if (!Number.isFinite(remainingSec) || remainingSec <= 0) return padTimer('EXPIRED');
107
107
  const totalSec = Math.max(0, Math.floor(remainingSec));
108
108
  const h = Math.floor(totalSec / 3600);
109
109
  const mRaw = Math.floor((totalSec % 3600) / 60);
@@ -112,8 +112,22 @@ function formatTimer(remainingSec) {
112
112
  // truncation) can never produce m:sss like "4:547".
113
113
  const m = Math.min(59, Math.max(0, mRaw));
114
114
  const s = Math.min(59, Math.max(0, sRaw));
115
- if (h > 0) return `${h}:${String(m).padStart(2, '0')}`;
116
- return `${m}:${String(s).padStart(2, '0')}`;
115
+ if (h > 0) return padTimer(`${h}:${String(m).padStart(2, '0')}`);
116
+ return padTimer(`${m}:${String(s).padStart(2, '0')}`);
117
+ }
118
+
119
+ // Pad timer text to a fixed width so transitions never shrink the visible
120
+ // length. Otherwise `42:38` (5 chars) → `1:00` (4 chars) on activity reset
121
+ // leaves the trailing `8` on screen → fused garbage like `1:008`. Some
122
+ // terminals (JetBrains JediTerm, certain Claude Code render paths) don't
123
+ // fully clear the statusline region between frames, so column-stable output
124
+ // is the only reliable defense — `\x1b[K` and trailing-space padding only
125
+ // help if the cursor lands at the right spot to begin with.
126
+ // "EXPIRED" → "EXPIRED" (7 — already widest, used as the target width)
127
+ // "59:59" → " 59:59 " no — left-pad only so the digits stay right-aligned
128
+ const TIMER_WIDTH = 7;
129
+ function padTimer(s) {
130
+ return s.padStart(TIMER_WIDTH, ' ');
117
131
  }
118
132
 
119
133
  /**