cc-cream 0.1.8 → 0.1.10

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,16 @@ 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.10] — 2026-05-29
8
+
9
+ ### Added
10
+ - **Setup reminder after plugin install** (CREAM-cpcwjkxi). Installing the plugin makes the commands available but can't wire the status bar (Claude Code has no install hook to write `settings.json`), so users saw no bar and didn't know to run `/cc-cream:setup`. A `SessionStart` hook (`hooks/hooks.json`, auto-discovered) now emits a one-line `systemMessage` nudging the user to run `/cc-cream:setup` — but **only while cc-cream's statusLine is absent**, so it self-silences once setup runs. `systemMessage` is shown to the user and adds **nothing** to the model context (zero tokens). Degrades safely: missing `settings.json` → nudge; malformed → silent; always exits 0. Biome now also lints `hooks/`.
11
+
12
+ ## [0.1.9] — 2026-05-29
13
+
14
+ ### Fixed
15
+ - **`/cc-cream:setup` and `/cc-cream:uninstall` no longer hang on a y/N prompt** (CREAM-vxbbrypj). The slash commands run `install.js` via Claude Code's bang execution, which has no interactive TTY, so install.js's readline prompts blocked forever — the uninstaller's "delete runtime/state?" prompt was the dead end. install.js now detects a missing TTY and resolves prompts non-interactively: uninstall removes the `statusLine` and **keeps** the runtime/state artifacts (re-run in a terminal or pass `--purge` to delete them); setup overwrites an existing *cc-cream* `statusLine` but never clobbers a foreign one without a terminal or the new `--force`/`--yes` flag. Interactive terminals are unchanged. (Plugin removal still takes two steps — `/cc-cream:uninstall` then `/plugin uninstall cc-cream` — because Claude Code has no plugin-uninstall hook to clean `settings.json` automatically.)
16
+
7
17
  ## [0.1.8] — 2026-05-29
8
18
 
9
19
  ### Added
package/README.md CHANGED
@@ -72,9 +72,10 @@ Then wire it into your settings in one step:
72
72
  ```
73
73
 
74
74
  The `/cc-cream:setup` command runs the consent installer, which writes the
75
- `statusLine` block to `~/.claude/settings.json`. Updates are automatic: when
76
- `/plugin update` drops a new version into the cache, the next render picks it
77
- up without any further action.
75
+ `statusLine` block to `~/.claude/settings.json`. Until you run it, cc-cream
76
+ prints a one-line reminder at the start of each session (it stops once the bar
77
+ is wired). Updates are automatic: when `/plugin update` drops a new version into
78
+ the cache, the next render picks it up without any further action.
78
79
 
79
80
  ### Option 2 — npm
80
81
 
@@ -112,23 +113,29 @@ and you may need to **restart** it for the bar to appear.
112
113
 
113
114
  ### Uninstall
114
115
 
115
- Plugin users:
116
+ Plugin users — two steps (Claude Code can't clean `settings.json` when a plugin
117
+ is removed, so the wiring is cleared separately from the cache):
116
118
  ```
117
- /cc-cream:uninstall
118
- /plugin uninstall cc-cream
119
+ /cc-cream:uninstall # removes the statusLine wiring
120
+ /plugin uninstall cc-cream # drops the plugin from the cache
119
121
  ```
120
122
 
121
123
  npm / manual users:
122
124
  ```bash
123
- cc-cream-setup --uninstall # npm (add --purge to also remove config)
125
+ cc-cream-setup --uninstall # npm (add --purge to also remove runtime + config)
124
126
  node cc-cream/src/install.js --uninstall # manual clone
125
127
  ```
126
128
 
127
129
  Uninstall removes the `statusLine` block **only if it is cc-cream's** — a
128
- statusLine you wired for something else is left untouched. It then offers to
129
- delete the copied runtime and session-state files, and **keeps your
130
- `~/.claude/cc-cream.json` config** unless you add `--purge`. Restart Claude Code
131
- to clear the bar.
130
+ statusLine you wired for something else is left untouched. In a terminal it asks
131
+ before deleting the copied runtime and session-state files; run **non-interactively**
132
+ (as the `/cc-cream:uninstall` slash command does) it leaves those artifacts in
133
+ place — pass `--purge` to remove them and your `~/.claude/cc-cream.json` config.
134
+ Restart Claude Code to clear the bar.
135
+
136
+ Likewise, `cc-cream-setup` run non-interactively will overwrite an existing
137
+ *cc-cream* statusLine but never a foreign one — pass `--force` to replace
138
+ regardless.
132
139
 
133
140
  ## Configuration
134
141
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "cc-cream",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Claude Code cache/context/cost status-line tool",
5
5
  "directories": {
6
6
  "doc": "docs"
7
7
  },
8
8
  "scripts": {
9
- "lint": "biome lint src/",
9
+ "lint": "biome lint src/ hooks/",
10
10
  "knip": "knip",
11
11
  "validate": "command -v claude >/dev/null 2>&1 && claude plugin validate . || echo 'cc-cream: claude CLI not found — skipping plugin validation'",
12
12
  "pretest": "npm run lint && npm run knip && npm run validate",
package/src/install.js CHANGED
@@ -223,12 +223,22 @@ async function uninstall({ purge }) {
223
223
 
224
224
  const artifacts = [runtimeDir, stateFile].filter((p) => fs.existsSync(p));
225
225
  if (artifacts.length) {
226
- const remove = purge || (await ask(`Also delete the copied runtime and session state?\n ${artifacts.join('\n ')}`));
226
+ let remove = purge;
227
+ if (!remove && process.stdin.isTTY) {
228
+ remove = await ask(`Also delete the copied runtime and session state?\n ${artifacts.join('\n ')}`);
229
+ }
227
230
  if (remove) {
228
231
  for (const p of artifacts) fs.rmSync(p, { recursive: true, force: true });
229
232
  console.log('Removed runtime and state files.');
230
- } else {
233
+ } else if (process.stdin.isTTY) {
231
234
  console.log('Left runtime and state files in place.');
235
+ } else {
236
+ // Non-interactive (e.g. run via the /cc-cream:uninstall slash command, which
237
+ // has no TTY): never block on a prompt. The statusLine — the thing that
238
+ // matters — is already removed; keep the artifacts (deletion is destructive)
239
+ // and say how to remove them.
240
+ console.log(`Left runtime and session state in place — no terminal to confirm deletion:\n ${artifacts.join('\n ')}`);
241
+ console.log('Re-run in a terminal, or pass --purge, to remove them.');
232
242
  }
233
243
  }
234
244
  if (purge && fs.existsSync(configFile)) {
@@ -248,6 +258,7 @@ async function main() {
248
258
  return;
249
259
  }
250
260
  const plugin = args.includes('--plugin');
261
+ const force = args.includes('--force') || args.includes('--yes');
251
262
  // First non-flag arg is an optional local source path (manual mode only).
252
263
  const positional = args.filter((a) => !a.startsWith('--'));
253
264
 
@@ -284,7 +295,19 @@ async function main() {
284
295
  // If a replace needs consent, ask now and re-plan with the answer.
285
296
  if (!result.changed && result.needsConsent) {
286
297
  for (const m of result.messages) console.log(m);
287
- const yes = await ask('Replace it with cc-cream?');
298
+ let yes;
299
+ if (process.stdin.isTTY) {
300
+ yes = await ask('Replace it with cc-cream?');
301
+ } else {
302
+ // Non-interactive (e.g. run via the /cc-cream:setup slash command, which has
303
+ // no TTY): never block on a prompt. Safe to overwrite our OWN wiring (an
304
+ // older/other-strategy cc-cream statusLine); never clobber a FOREIGN
305
+ // statusLine without a terminal or an explicit --force.
306
+ yes = force || isCcCreamStatusLine(settings.statusLine);
307
+ console.log(yes
308
+ ? 'Non-interactive: replacing the existing cc-cream statusLine.'
309
+ : 'Non-interactive: left your existing statusLine unchanged. Re-run in a terminal, or pass --force, to replace it.');
310
+ }
288
311
  result = plan(settings, { ...planOpts, consent: yes });
289
312
  }
290
313