claude-token-saver 2.10.1 → 2.10.2

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/bin/cli.js CHANGED
@@ -446,12 +446,13 @@ async function main() {
446
446
 
447
447
  // Subcommand: harness — manage the project's CLAUDE.md harness rules.
448
448
  // claude-token-saver harness init # write CLAUDE.md (5 sections) + ratchet.md
449
+ // claude-token-saver harness uninit # remove harness block from CLAUDE.md (backup kept)
449
450
  // claude-token-saver harness check # show 🅷 N/5 + which sections are missing
450
451
  // claude-token-saver harness promote "<rule>" # append a rule to ratchet.md
451
452
  // claude-token-saver harness off | on # toggle the statusline 🅷 segment
452
453
  if (args[0] === 'harness') {
453
454
  const sub = args[1];
454
- const { harnessInit, harnessStatus, harnessPromote, findProjectRoot } =
455
+ const { harnessInit, harnessUninit, harnessStatus, harnessPromote, findProjectRoot } =
455
456
  await import('../src/harness.js');
456
457
  const { HARNESS_SECTIONS } = await import('../src/harness-templates.js');
457
458
  const { loadConfig, saveConfig } = await import('../src/config.js');
@@ -557,6 +558,17 @@ async function main() {
557
558
  return;
558
559
  }
559
560
 
561
+ if (sub === 'uninit' || sub === 'remove') {
562
+ const purgeRatchet = args.includes('--purge-ratchet');
563
+ const r = harnessUninit({ purgeRatchet });
564
+ console.log(`Project root: ${r.root}`);
565
+ r.removed.forEach((f) => console.log(` removed: ${f}`));
566
+ r.backedUp.forEach((f) => console.log(` backup: ${f}`));
567
+ r.skipped.forEach((f) => console.log(` skip: ${f}`));
568
+ if (r.removed.length === 0) console.log('Nothing to remove.');
569
+ return;
570
+ }
571
+
560
572
  if (sub === 'off' || sub === 'on') {
561
573
  const cfg = loadConfig();
562
574
  cfg.harness = cfg.harness || {};
@@ -567,7 +579,7 @@ async function main() {
567
579
  }
568
580
 
569
581
  console.error(`Unknown harness subcommand: ${sub}`);
570
- console.error('Usage: claude-token-saver harness [check|init|promote "<rule>"|off|on]');
582
+ console.error('Usage: claude-token-saver harness [check|init|uninit [--purge-ratchet]|promote "<rule>"|off|on]');
571
583
  process.exit(1);
572
584
  }
573
585
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-token-saver",
3
- "version": "2.10.1",
3
+ "version": "2.10.2",
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": {
package/src/harness.js CHANGED
@@ -154,6 +154,54 @@ export function harnessInit({ root = findProjectRoot(), force = false } = {}) {
154
154
  return result;
155
155
  }
156
156
 
157
+ /**
158
+ * harness uninit — remove the harness block from CLAUDE.md (preserves the
159
+ * user's other content). A safety backup is written first. ratchet.md is
160
+ * left intact (user-grown rules) unless `purgeRatchet` is true.
161
+ *
162
+ * Returns { removed: [], backedUp: [], skipped: [] }.
163
+ */
164
+ export function harnessUninit({ root = findProjectRoot(), purgeRatchet = false } = {}) {
165
+ const cmPath = claudeMdPath(root);
166
+ const rmPath = ratchetMdPath(root);
167
+ const result = { removed: [], backedUp: [], skipped: [], root };
168
+
169
+ if (existsSync(cmPath)) {
170
+ const existing = readFileSync(cmPath, 'utf8');
171
+ if (existing.includes(HARNESS_BLOCK_BEGIN)) {
172
+ const stamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
173
+ const bak = `${cmPath}.bak-${stamp}`;
174
+ writeFileSync(bak, existing);
175
+ const re = new RegExp(
176
+ `\\n*${escapeRe(HARNESS_BLOCK_BEGIN)}[\\s\\S]*?${escapeRe(HARNESS_BLOCK_END)}\\n?`,
177
+ 'm',
178
+ );
179
+ const next = existing.replace(re, '').replace(/\n{3,}$/, '\n\n');
180
+ writeFileSync(cmPath, next);
181
+ result.backedUp.push(bak);
182
+ result.removed.push(cmPath + ' (harness block removed)');
183
+ } else {
184
+ result.skipped.push(cmPath + ' (no harness block found)');
185
+ }
186
+ } else {
187
+ result.skipped.push(cmPath + ' (does not exist)');
188
+ }
189
+
190
+ if (purgeRatchet && existsSync(rmPath)) {
191
+ const stamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
192
+ const bak = `${rmPath}.bak-${stamp}`;
193
+ writeFileSync(bak, readFileSync(rmPath, 'utf8'));
194
+ result.backedUp.push(bak);
195
+ // Replace with empty initial template rather than delete (preserves dir).
196
+ writeFileSync(rmPath, harnessRatchetMdInitial());
197
+ result.removed.push(rmPath + ' (reset to initial)');
198
+ } else if (existsSync(rmPath)) {
199
+ result.skipped.push(rmPath + ' (kept; pass --purge-ratchet to reset)');
200
+ }
201
+
202
+ return result;
203
+ }
204
+
157
205
  /**
158
206
  * harness promote — append a one-line rule to .claude/ratchet.md.
159
207
  * Creates the file from the initial template if missing.