cc-cream 0.3.1 → 0.3.3
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 +18 -0
- package/README.md +21 -6
- package/package.json +4 -1
- package/src/install.js +22 -2
- package/src/segments.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,24 @@ All notable changes to cc-cream are documented here. Format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.3] — 2026-05-30
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **The post-publish `npx` smoke test now uses `--safe-chain-skip-minimum-package-age`** so the `@manual` "npm indexing" scenario works immediately after a release without waiting for the package-age guard to lift (CREAM-elrbkfot).
|
|
13
|
+
- **TTL segment now displays minutes only** (`ttl:60`, `ttl:8`, `ttl:0`) instead of the previous `HH:MM` format (`ttl:01:00`). Simpler to read at a glance; matches the 60-second refresh cadence (CREAM-vhhdhydn).
|
|
14
|
+
|
|
15
|
+
### Documentation
|
|
16
|
+
- **The `cache` segment's `drop` / `drop_recover` config keys are now documented.** They've been live since cache drop-detection shipped but never appeared in the README — the segment catalog listed `cache` as "neutral" with no mention that it turns red on a sharp hit-rate drop, nor that the trip/recover thresholds are configurable. Added a "`cache` drop detection" subsection, surfaced the keys in the example config, and corrected the catalog color note. This is the documentation outcome of CREAM-wwsdavum (configure-via-`/cc-cream:` command), which is otherwise declined as a dup of the deliberately-closed CREAM-udibxkch.
|
|
17
|
+
|
|
18
|
+
## [0.3.2] — 2026-05-30
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **`npm run coverage` (and the pre-push hook) no longer crash on Node ≥ 26.** `c8@11` does `require('yargs/yargs')`, and yargs 17's `exports` map resolves that to an **extensionless** CJS file; under Node 26's `require(ESM)` loader an extensionless file in a `"type": "module"` package is parsed as ESM, throwing `ReferenceError: require is not defined in ES module scope`. This broke the `simple-git-hooks` pre-push gate, forcing `SKIP_SIMPLE_GIT_HOOKS=1` on every push. Pinned yargs to `^18.0.0` via `overrides` — its `./yargs` export is a proper `.mjs` that Node 26 loads cleanly, and `c8@11` works against it unchanged (all 248 scenarios green under coverage). Dev-only; no runtime-dependency or published-package impact.
|
|
22
|
+
- **The uninstall receipt's cache-path escape hatch is now copy-pasteable.** It printed `…/cc-cream/cc-cream/<version>/src/install.js`, but the receipt reaches the user through the `/cc-cream:uninstall` slash command, whose output Claude Code renders as **markdown — which strips `<version>` as an HTML-like tag**. The user saw `cc-cream//src` (empty version) and pasting it failed with `MODULE_NOT_FOUND`, breaking the documented npm-free recovery path exactly when it's needed. The receipt now prints install.js's own resolved absolute path — via the slash command that's the real versioned cache copy — so it's both version-accurate and free of any stripped placeholder. The README uses a markdown-safe `VERSION` placeholder with an `ls` hint to read off the real one (CREAM-rhtrzwss).
|
|
23
|
+
|
|
24
|
+
### Internal
|
|
25
|
+
- **Internal spec/working docs and the fp-managed `FP_CLAUDE.md` are no longer tracked in git.** `docs/` (PRD, release plan, code-review notes, install-lifecycle notes) and `FP_CLAUDE.md` are local working references, now gitignored and removed from the repo to keep the public tree focused on shipped code. No effect on the published npm package — its `files` allowlist (`src/`, `LICENSE`, `README.md`, `CHANGELOG.md`) never included them.
|
|
26
|
+
|
|
9
27
|
## [0.3.1] — 2026-05-30
|
|
10
28
|
|
|
11
29
|
### Fixed
|
package/README.md
CHANGED
|
@@ -151,14 +151,17 @@ message — restart an already-open session to drop it immediately.
|
|
|
151
151
|
> `statusLine` line still lingers in `settings.json`.
|
|
152
152
|
>
|
|
153
153
|
> To clear that leftover line once the plugin is gone, the **guaranteed** route is
|
|
154
|
-
> the copy of the uninstaller still in the cache — npm-free and always present
|
|
154
|
+
> the copy of the uninstaller still in the cache — npm-free and always present.
|
|
155
|
+
> `VERSION` is the single directory under that path (run the `ls` first to read it
|
|
156
|
+
> off); `/cc-cream:uninstall` also prints the fully-resolved command:
|
|
155
157
|
> ```bash
|
|
156
|
-
>
|
|
158
|
+
> ls ~/.claude/plugins/cache/cc-cream/cc-cream/ # e.g. 0.3.1
|
|
159
|
+
> node ~/.claude/plugins/cache/cc-cream/cc-cream/VERSION/src/install.js --uninstall
|
|
157
160
|
> # add --purge to also remove your config
|
|
158
161
|
> ```
|
|
159
162
|
> The npm bin does the same job, but **not always**: a *freshly published* version
|
|
160
|
-
> is blocked by npm's min-package-age safe-chain guard (it reports "
|
|
161
|
-
>
|
|
163
|
+
> is blocked by npm's min-package-age safe-chain guard (it reports "No versions
|
|
164
|
+
> available") until it ages in, so use it only if the cache route isn't handy:
|
|
162
165
|
> ```bash
|
|
163
166
|
> npx -y -p cc-cream cc-cream-setup --uninstall
|
|
164
167
|
> ```
|
|
@@ -207,7 +210,7 @@ cc-cream-setup --check-config # reports unknown keys / out-of-domain values; e
|
|
|
207
210
|
"percentage": "consumed",
|
|
208
211
|
"segments": {
|
|
209
212
|
"ctx": { "on": true, "row": 1, "order": 2, "amber": 30, "orange": 40, "red": 50, "basis": "window", "ceiling": 200000, "display": "basis" },
|
|
210
|
-
"cache": { "on": true, "row": 1, "order": 3 },
|
|
213
|
+
"cache": { "on": true, "row": 1, "order": 3, "drop": 20, "drop_recover": 80 },
|
|
211
214
|
"write": { "on": false, "row": 1, "order": 3.5 },
|
|
212
215
|
"ttl": { "on": true, "row": 1, "order": 4, "amber": 50, "red": 80 },
|
|
213
216
|
"cost": { "on": true, "row": 1, "order": 5 },
|
|
@@ -251,7 +254,7 @@ Colored segments additionally accept threshold keys. Thresholds mark the
|
|
|
251
254
|
| Segment | Default | Example | Meaning | Color |
|
|
252
255
|
|---|---|---|---|---|
|
|
253
256
|
| `ctx` | on, row 1 | `ctx:19% [38k]` | context-window occupancy + input-token magnitude | `<30` green · `30–40` amber · `40–50` orange · `≥50` red |
|
|
254
|
-
| `cache` | on, row 1 | `cache:95%` | last-turn cache hit rate (reads / total tokens) | neutral |
|
|
257
|
+
| `cache` | on, row 1 | `cache:95%` | last-turn cache hit rate (reads / total tokens) | neutral; **red** on a sharp drop (see below) |
|
|
255
258
|
| `write` | **off**, row 1 | `write:4%` | last-turn cache creation rate (new writes / total tokens) | neutral |
|
|
256
259
|
| `ttl` | on, row 1 | `ttl:00:52` | time remaining before cache expires (counts down to 00:00) | `<50%` green · `50–80%` amber · `≥80%` red |
|
|
257
260
|
| `cost` | on, row 1 | `~$4.50` | session cost incl. subagents; `~` = CC's estimate | neutral; hidden when zero |
|
|
@@ -298,6 +301,18 @@ default row via config must land in a zone to appear on row 1.
|
|
|
298
301
|
|
|
299
302
|
Default: `amber: 30`, `orange: 40`, `red: 50` (percent consumed).
|
|
300
303
|
|
|
304
|
+
### `cache` drop detection
|
|
305
|
+
|
|
306
|
+
The `cache` segment stays neutral while the hit rate is healthy, but turns **red**
|
|
307
|
+
when it falls sharply from one turn to the next — a cue that the prompt cache was
|
|
308
|
+
just invalidated (e.g. an edit far back in context forced a re-read). This relies
|
|
309
|
+
on per-session state, so it only fires when `session_id` is present in stdin.
|
|
310
|
+
|
|
311
|
+
- `drop`: percentage-point fall from the previous turn that trips red. Default `20`
|
|
312
|
+
(95% → 74% trips; 95% → 80% does not).
|
|
313
|
+
- `drop_recover`: once tripped, the segment stays red until the hit rate climbs
|
|
314
|
+
back to at least this value. Default `80`.
|
|
315
|
+
|
|
301
316
|
### `ttl` thresholds
|
|
302
317
|
|
|
303
318
|
Default: `amber: 50`, `red: 80` (percent of the resolved TTL consumed).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-cream",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Claude Code cache/context/cost status-line tool",
|
|
5
5
|
"directories": {
|
|
6
6
|
"doc": "docs"
|
|
@@ -60,5 +60,8 @@
|
|
|
60
60
|
"c8": "^11.0.0",
|
|
61
61
|
"knip": "^6.14.2",
|
|
62
62
|
"simple-git-hooks": "^2.13.1"
|
|
63
|
+
},
|
|
64
|
+
"overrides": {
|
|
65
|
+
"yargs": "^18.0.0"
|
|
63
66
|
}
|
|
64
67
|
}
|
package/src/install.js
CHANGED
|
@@ -21,6 +21,12 @@ import { isEntrypoint } from './utils.js';
|
|
|
21
21
|
|
|
22
22
|
export { writeFileAtomic } from './settings.js';
|
|
23
23
|
|
|
24
|
+
// Absolute path of THIS install.js. When the /cc-cream:uninstall slash command
|
|
25
|
+
// runs it, that's the versioned plugin-cache copy — the durable, npm-free
|
|
26
|
+
// escape hatch we advertise in the uninstall receipt (resolved, not guessed, so
|
|
27
|
+
// it carries the real version and no markdown-stripped placeholder).
|
|
28
|
+
const SELF_PATH = fileURLToPath(import.meta.url);
|
|
29
|
+
|
|
24
30
|
const TRUST_NOTE =
|
|
25
31
|
'The bar appears on your next message — restart only an already-open session, and the workspace must be trusted.';
|
|
26
32
|
|
|
@@ -255,18 +261,32 @@ async function uninstall({ purge }) {
|
|
|
255
261
|
printUninstallReceipt();
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
// Shorten an absolute path under $HOME to a `~/…` form for display. The shell
|
|
265
|
+
// still expands `~`, so the result stays copy-pasteable.
|
|
266
|
+
function tildeify(p) {
|
|
267
|
+
const home = os.homedir();
|
|
268
|
+
return p === home || p.startsWith(`${home}/`) ? `~${p.slice(home.length)}` : p;
|
|
269
|
+
}
|
|
270
|
+
|
|
258
271
|
// The closing receipt. No Claude Code host removal path drops our statusLine OR
|
|
259
272
|
// the version cache, so spell out what's gone, what the host leaves behind, and
|
|
260
273
|
// the npm-free escape hatch (the lingering cache always has a working install.js).
|
|
261
274
|
// See project memory cc-cream-plugin-lifecycle-findings.
|
|
275
|
+
//
|
|
276
|
+
// The escape-hatch line prints SELF_PATH — this install.js's real, resolved
|
|
277
|
+
// location — NOT a `<version>` placeholder. The receipt reaches the user through
|
|
278
|
+
// the slash command, whose output Claude Code renders as markdown; `<version>`
|
|
279
|
+
// was silently stripped to an empty segment (cc-cream//src), breaking copy-paste
|
|
280
|
+
// exactly when it's needed (CREAM-rhtrzwss). Via the slash command SELF_PATH IS
|
|
281
|
+
// the versioned cache copy, so the path is both accurate and markdown-safe.
|
|
262
282
|
function printUninstallReceipt() {
|
|
263
283
|
console.log('\nDone — the bar disappears on your next message (restart an already-open session to drop it now).');
|
|
264
284
|
console.log('The host leaves the rest behind; to fully remove cc-cream:');
|
|
265
285
|
console.log(' • Plugin: /plugin uninstall cc-cream then /plugin marketplace remove cc-cream');
|
|
266
286
|
console.log(' • Version cache (never auto-removed): rm -rf ~/.claude/plugins/cache/cc-cream');
|
|
267
287
|
console.log(' • The /cc-cream:* slash commands linger in this session until you restart Claude Code.');
|
|
268
|
-
console.log('
|
|
269
|
-
console.log(
|
|
288
|
+
console.log('Re-run this uninstall later (e.g. the plugin is gone but the bar lingers) — it lives at:');
|
|
289
|
+
console.log(` node ${tildeify(SELF_PATH)} --uninstall [--purge]`);
|
|
270
290
|
}
|
|
271
291
|
|
|
272
292
|
// `cc-cream-setup --check-config`: lint ~/.claude/cc-cream.json against the
|
package/src/segments.js
CHANGED
|
@@ -63,7 +63,7 @@ function segTtl(cfg, ttlMin, now, anchorMs) {
|
|
|
63
63
|
if (!isNum(anchorMs)) return null;
|
|
64
64
|
const elapsedMin = Math.floor(Math.max(0, now - anchorMs) / 60000);
|
|
65
65
|
const remainingMin = Math.max(0, ttlMin - elapsedMin);
|
|
66
|
-
const text = `ttl:${
|
|
66
|
+
const text = `ttl:${remainingMin}`;
|
|
67
67
|
const s = cfg.segments.ttl;
|
|
68
68
|
const pctTtl = ttlMin > 0 ? (elapsedMin / ttlMin) * 100 : 0;
|
|
69
69
|
return { text, color: band(pctTtl, s.amber, s.red) };
|