cc-cream 0.1.4 → 0.1.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to cc-cream are documented here. Format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.1.5] — 2026-05-29
8
+
9
+ ### Fixed
10
+ - **TTL falsely resets after non-API Claude Code events** (e.g. `/plugin update`). The TTL anchor was the `mtime` of the transcript file, which updates whenever Claude Code writes any event to the transcript — not just API turns. The anchor is now derived from session state: when `total_input_tokens` grows between renders (indicating a real API turn), `last_api_ts` is stored and used as the anchor on subsequent renders. Falls back to transcript mtime only on the first render before any state exists.
11
+ - **Plugin command paths fixed for real** (reverts the `../` change from 0.1.3). The Claude Code plugin validator rejects `..` path traversal; command paths in `plugin.json` resolve from the plugin root, not from `.claude-plugin/`, so `./commands/setup.md` is correct.
12
+
7
13
  ## [0.1.4] — 2026-05-29
8
14
 
9
15
  ### Fixed
@@ -69,6 +75,7 @@ line and prints a colored ≤3-row bar — zero tokens, the model never sees it.
69
75
  - Supports **macOS and Linux**; Windows is a planned fast-follow.
70
76
  - Requires Claude Code **2.1.132+** (`effort` / `thinking` need 2.1.145+).
71
77
 
78
+ [0.1.5]: https://github.com/bart-turczynski/cc-cream/compare/v0.1.4...v0.1.5
72
79
  [0.1.4]: https://github.com/bart-turczynski/cc-cream/compare/v0.1.3...v0.1.4
73
80
  [0.1.3]: https://github.com/bart-turczynski/cc-cream/compare/v0.1.2...v0.1.3
74
81
  [0.1.2]: https://github.com/bart-turczynski/cc-cream/compare/v0.1.1...v0.1.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-cream",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Claude Code cache/context/cost status-line tool",
5
5
  "directories": {
6
6
  "doc": "docs"
package/src/segments.js CHANGED
@@ -56,16 +56,26 @@ function segCache(data, cfg, prevCachePct, recovering) {
56
56
  return { text: `cache:${pct}%`, color };
57
57
  }
58
58
 
59
- function segTtl(data, cfg, ttlMin, now) {
60
- const tp = data?.transcript_path;
61
- if (typeof tp !== 'string' || tp === '') return null;
62
- let mtimeMs;
63
- try {
64
- mtimeMs = fs.statSync(tp).mtimeMs;
65
- } catch {
66
- return null;
59
+ function segTtl(data, cfg, ttlMin, now, prevSessionState) {
60
+ const prevTokens = prevSessionState?.total_input_tokens;
61
+ const curTokens = data?.context_window?.total_input_tokens;
62
+ const tokensGrew = isNum(curTokens) && isNum(prevTokens) && curTokens > prevTokens;
63
+
64
+ let anchorMs;
65
+ if (tokensGrew) {
66
+ anchorMs = now;
67
+ } else if (isNum(prevSessionState?.last_api_ts)) {
68
+ anchorMs = prevSessionState.last_api_ts;
69
+ } else {
70
+ const tp = data?.transcript_path;
71
+ if (typeof tp !== 'string' || tp === '') return null;
72
+ try {
73
+ anchorMs = fs.statSync(tp).mtimeMs;
74
+ } catch {
75
+ return null;
76
+ }
67
77
  }
68
- const elapsedMin = Math.floor(Math.max(0, now - mtimeMs) / 60000);
78
+ const elapsedMin = Math.floor(Math.max(0, now - anchorMs) / 60000);
69
79
  const remainingMin = Math.max(0, ttlMin - elapsedMin);
70
80
  const text = `ttl:${pad2(Math.floor(remainingMin / 60))}:${pad2(remainingMin % 60)}`;
71
81
  const s = cfg.segments.ttl;
@@ -158,7 +168,7 @@ export function renderSegments(data, cfg, ttlMin, now, prevSessionState = null,
158
168
  prevSessionState && isNum(prevSessionState.cache_pct) ? prevSessionState.cache_pct : undefined,
159
169
  prevSessionState?.recovering === true,
160
170
  ),
161
- ttl: segTtl(data, cfg, ttlMin, now),
171
+ ttl: segTtl(data, cfg, ttlMin, now, prevSessionState),
162
172
  cost: segCost(data),
163
173
  '5h': segRate(data?.rate_limits?.five_hour, '5h', cfg, '5h', now),
164
174
  '7d': segRate(data?.rate_limits?.seven_day, '7d', cfg, '7d', now),
package/src/state.js CHANGED
@@ -53,5 +53,11 @@ export function nextSessionPatch(data, prevSessionState, cfg, now) {
53
53
  }
54
54
  const fh = data?.rate_limits?.five_hour;
55
55
  if (fh && isNum(fh.used_percentage)) patch.five_hour_pct = fh.used_percentage;
56
+ const curTokens = data?.context_window?.total_input_tokens;
57
+ const prevTokens = prevSessionState?.total_input_tokens;
58
+ if (isNum(curTokens)) {
59
+ patch.total_input_tokens = curTokens;
60
+ if (isNum(prevTokens) && curTokens > prevTokens) patch.last_api_ts = now;
61
+ }
56
62
  return patch;
57
63
  }