claude-token-saver 2.8.3 → 2.8.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.en.md CHANGED
@@ -143,6 +143,10 @@ Node.js ≥ 18 · macOS / Windows / Linux / WSL · zero dependencies.
143
143
  - [HN discussion](https://news.ycombinator.com/item?id=47736476) — 168 points, 142 comments
144
144
  - [HNPulse KR](https://www.youtube.com/@HNPulseKR) — Korean HN tech deep-dives
145
145
 
146
+ ## Known environment quirks
147
+
148
+ **IntelliJ Claude Code plugin** — the statusline widget fuses prior and current frames at the character level when emoji are in the output, producing artifacts like `Cache expires 59:548`. v2.8.5+ detects `TERMINAL_EMULATOR=JetBrains-JediTerm` and falls back to text mode automatically (`--icon` is also ignored under IntelliJ). Other terminals (iTerm, Terminal, WSL, etc.) are unaffected.
149
+
146
150
  ## License
147
151
 
148
152
  MIT
package/README.md CHANGED
@@ -103,6 +103,10 @@ Claude Code는 모든 API 응답을 `~/.claude/projects/<dir>/<session>.jsonl`
103
103
 
104
104
  Node.js ≥ 18 · macOS / Linux / Windows / WSL · 의존성 0.
105
105
 
106
+ ## 알려진 환경 이슈
107
+
108
+ **IntelliJ Claude Code plugin** — statusline 위젯이 이전 프레임과 새 프레임을 글자 단위로 잘못 합쳐 `Cache expires 59:548` 같은 합성 잔재가 보이는 버그가 있습니다 (이모지가 들어간 텍스트일 때만). v2.8.5+에서는 `TERMINAL_EMULATOR=JetBrains-JediTerm`을 감지하면 자동으로 text 모드로 폴백해 이모지 없이 출력합니다 (`--icon` 플래그도 IntelliJ에서는 무시). 다른 터미널(iTerm, Terminal, WSL 등)에는 영향 없습니다.
109
+
106
110
  ## 라이선스
107
111
 
108
112
  MIT
package/bin/cli.js CHANGED
@@ -700,10 +700,21 @@ async function main() {
700
700
  const { statuslineDefaults } = await import('../src/config.js');
701
701
  const cfg = statuslineDefaults();
702
702
 
703
+ // IntelliJ's Claude Code plugin renders the statusline through a custom
704
+ // widget that fuses prior frames with the new one when emoji are present,
705
+ // producing garbage like "59:548" that no ANSI escape can clean up
706
+ // (verified: emitting the same output directly into JediTerm renders
707
+ // cleanly, so the bug is in the plugin's render path, not the terminal).
708
+ // Force text mode unconditionally inside IntelliJ — even past an explicit
709
+ // `--icon` flag, since wrappers commonly hardcode `--icon` and the user
710
+ // can't easily edit them; icon mode is just broken there.
711
+ const isIntelliJ = process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
703
712
  // CLI flags take precedence; otherwise fall back to persisted config.
704
- const isIcon = hasFlag('--icon')
705
- ? true
706
- : (hasFlag('--no-icon') || hasFlag('--text') ? false : cfg.icon);
713
+ const isIcon = isIntelliJ
714
+ ? false
715
+ : (hasFlag('--icon')
716
+ ? true
717
+ : (hasFlag('--no-icon') || hasFlag('--text') ? false : cfg.icon));
707
718
  const isVerbose = hasFlag('--verbose')
708
719
  ? true
709
720
  : (hasFlag('--no-verbose') || hasFlag('--compact') ? false : cfg.verbose);
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.5",
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": {
@@ -395,19 +395,8 @@ export function formatReport(data, { color = true, verbose = false, timer = true
395
395
  if (want('saved')) segs.push(saveSeg);
396
396
  if (want('period')) segs.push(periodSeg);
397
397
  // Trailing erase-to-end-of-line so any leftover characters from a previous
398
- // (longer) statusline render don't bleed into ours. Some terminals + the
399
- // Claude Code statusline integration don't fully clear the line on rewrite,
400
- // which surfaced as "Cache expires 4:574" or "Cache expires 43550" — old
401
- // digits from a prior frame leaking past the new shorter timer text.
402
- // \x1b[K is the standard "erase from cursor to EOL" CSI; safe on any
403
- // ANSI-compatible terminal and a no-op when stdout isn't a TTY.
404
- // Defensive overwrite — terminals that miscount emoji width (JetBrains JediTerm
405
- // is the known case, but others surface periodically) leave the cursor at the
406
- // wrong column, which makes trailing `\x1b[K` erase the wrong region and
407
- // leftover bytes from the previous frame fuse with the new one ("4:54" + "8"
408
- // → "4:548"). Appending a run of spaces overwrites those leftover bytes
409
- // positionally without any clear-then-redraw step (so no flicker), and is
410
- // invisible on terminals that already redraw cleanly. `\x1b[K` still mops up
411
- // anything beyond the padding.
412
- return segs.join(' · ') + ' '.repeat(40) + '\x1b[K';
398
+ // (longer) statusline render don't bleed into ours. \x1b[K is the standard
399
+ // "erase from cursor to EOL" CSI; safe on any ANSI-compatible terminal and
400
+ // a no-op when stdout isn't a TTY.
401
+ return segs.join(' · ') + '\x1b[K';
413
402
  }