claude-depester 1.3.6 → 1.4.0

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.md CHANGED
@@ -4,26 +4,17 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/claude-depester.svg)](https://www.npmjs.com/package/claude-depester)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- Patches Claude Code CLI and VS Code extension to replace whimsical loading words with simple 'Thinking'.
7
+ Remove silly thinking words from Claude Code.
8
8
 
9
9
  Instead of seeing "Flibbertigibbeting", "Discombobulating", "Clauding", etc., you'll see a clean "Thinking".
10
10
 
11
- > **Last updated:** 2026-01-28 | **Tested with:** Claude Code 2.1.15 | **Platforms:** Linux, macOS, Windows
11
+ > **Last updated:** 2026-02-10 | **Tested with:** Claude Code 2.1.4 - 2.1.38 | **Platforms:** Linux, macOS, Windows
12
12
  >
13
- > v1.3.6: Add support for VS Code Remote SSH and Cursor Remote SSH (`.vscode-server`, `.cursor-server`)
14
-
15
- **CLI - Spinner:**
16
-
17
- ![Thinking... instead of whimsical words](img/thinking.png)
18
-
19
- **CLI - Completion:**
13
+ > v1.4.0: Fixed MachO binary bloat on macOS with Claude Code 2.1.37+ ([#5](https://github.com/ominiverdi/claude-depester/issues/5)). Added support for new Bun data format. Uses raw file write instead of LIEF write() for MachO/PE repacking.
20
14
 
15
+ ![Thinking... instead of silly words](img/thinking.png)
21
16
  ![Thought for Xs instead of Baked/Brewed/etc](img/thought.png)
22
17
 
23
- **VS Code Extension:**
24
-
25
- ![VS Code extension also patched](img/vscode.png)
26
-
27
18
  ## The Problem
28
19
 
29
20
  Claude Code displays random silly words while thinking:
@@ -54,20 +45,12 @@ npx claude-depester --dry-run
54
45
 
55
46
  # Patch Claude Code
56
47
  npx claude-depester
57
- ```
58
-
59
- Restart Claude Code for changes to take effect.
60
-
61
- ### Auto-patch after updates (recommended)
62
48
 
63
- Add a shell wrapper that patches before each invocation:
64
-
65
- ```bash
66
- # Add to your .bashrc or .zshrc
67
- cl() { npx claude-depester --all --silent --log ; claude "$@" ; }
49
+ # Auto-patch after updates (recommended)
50
+ npx claude-depester --install-hook
68
51
  ```
69
52
 
70
- Then use `cl` instead of `claude`. This ensures patching happens *before* Claude loads.
53
+ That's it! Restart Claude Code for changes to take effect.
71
54
 
72
55
  ## Features
73
56
 
@@ -75,10 +58,9 @@ Then use `cl` instead of `claude`. This ensures patching happens *before* Claude
75
58
  - **Patches completion verbs** ("Baked for 42s" -> "Thought for 42s")
76
59
  - Works with native binaries (Bun-compiled) and npm installations
77
60
  - **Patches VS Code/VSCodium extension webview** (the UI that shows spinner text)
78
- - **Supports remote development** (VS Code Remote SSH, Cursor SSH)
79
61
  - Auto-detects your Claude Code installation
80
62
  - Creates backup before patching (can restore anytime)
81
- - Shell wrapper for reliable auto-patching before Claude loads
63
+ - Optional SessionStart hook for auto-patching after updates
82
64
  - Content-based detection survives version updates
83
65
  - Cross-platform: Linux, macOS, Windows (WSL/Git Bash)
84
66
 
@@ -93,8 +75,6 @@ Then use `cl` instead of `claude`. This ensures patching happens *before* Claude
93
75
  | `npx claude-depester --check` | Check patch status |
94
76
  | `npx claude-depester --restore` | Restore original from backup |
95
77
  | `npx claude-depester --verbose` | Show detailed info |
96
- | `npx claude-depester --debug` | Show detailed debug info (for troubleshooting) |
97
- | `npx claude-depester --log` | Write results to `~/.claude/depester.log` |
98
78
  | `npx claude-depester --install-hook` | Auto-patch after updates |
99
79
  | `npx claude-depester --remove-hook` | Remove auto-patch hook |
100
80
  | `npx claude-depester --hook-status` | Check hook status |
@@ -109,8 +89,6 @@ Then use `cl` instead of `claude`. This ensures patching happens *before* Claude
109
89
  | VS Code extension | `~/.vscode/extensions/anthropic.claude-code-*/` | Fully supported |
110
90
  | VS Code webview | `~/.vscode/extensions/.../webview/index.js` | Fully supported |
111
91
  | VSCodium extension | `~/.vscode-oss/extensions/anthropic.claude-code-*/` | Fully supported |
112
- | VS Code Remote (SSH) | `~/.vscode-server/extensions/anthropic.claude-code-*/` | Fully supported |
113
- | Cursor Remote (SSH) | `~/.cursor-server/extensions/anthropic.claude-code-*/` | Fully supported |
114
92
  | Local npm | `~/.claude/local/node_modules/@anthropic-ai/claude-code/` | Fully supported |
115
93
  | Global npm | `npm root -g`/@anthropic-ai/claude-code/ | Fully supported |
116
94
 
@@ -135,11 +113,9 @@ The tool auto-detects your installation. Use `--list` to see all found installat
135
113
 
136
114
  > **Important for VS Code users:** The extension has TWO places with spinner words - the native binary AND the webview. Use `--all` to patch both!
137
115
 
138
- > **Remote Development (SSH):** When using VS Code Remote or Cursor over SSH, run the tool **on the remote server** to patch `~/.vscode-server` or `~/.cursor-server`.
139
-
140
116
  ## After Claude Code Updates
141
117
 
142
- If you're using the shell wrapper (recommended), patching happens automatically before each session.
118
+ With the hook installed (`--install-hook`), patching happens automatically on startup.
143
119
 
144
120
  Otherwise, just run `npx claude-depester` again after updating.
145
121
 
@@ -151,9 +127,7 @@ npx claude-depester --restore
151
127
 
152
128
  This restores from the backup created during patching.
153
129
 
154
- ## SessionStart Hook (Alternative)
155
-
156
- > **Note:** The shell wrapper is the recommended approach. The SessionStart hook has a limitation: it runs *after* Claude is already loaded into memory, so the patch only takes effect on the *next* session after an update.
130
+ ## How the Hook Works
157
131
 
158
132
  The `--install-hook` command adds a SessionStart hook to `~/.claude/settings.json`:
159
133
 
@@ -165,7 +139,7 @@ The `--install-hook` command adds a SessionStart hook to `~/.claude/settings.jso
165
139
  "hooks": [
166
140
  {
167
141
  "type": "command",
168
- "command": "npx claude-depester --all --silent --log"
142
+ "command": "npx claude-depester --silent"
169
143
  }
170
144
  ]
171
145
  }
@@ -174,12 +148,7 @@ The `--install-hook` command adds a SessionStart hook to `~/.claude/settings.jso
174
148
  }
175
149
  ```
176
150
 
177
- This patches the file on disk at session start, but the current session may still show silly words until you restart. The `--log` flag writes results to `~/.claude/depester.log` (keeps last 50 entries) for troubleshooting.
178
-
179
- To install or update the hook:
180
- ```bash
181
- npx claude-depester --install-hook
182
- > ```
151
+ Every time Claude Code starts, it checks and re-applies the patch if needed.
183
152
 
184
153
  ## Troubleshooting
185
154
 
@@ -222,16 +191,14 @@ Then **fully restart VS Code** (not just reload window).
222
191
 
223
192
  The detection uses content-based matching, so it should survive version updates.
224
193
  If the patch fails:
225
- 1. Run `npx claude-depester --debug` to see detailed diagnostics
226
- 2. Open an issue with your Claude Code version (`claude --version`)
227
- 3. Include the output of `npx claude-depester --debug`
194
+ 1. Open an issue with your Claude Code version (`claude --version`)
195
+ 2. Include the output of `npx claude-depester --dry-run --verbose`
228
196
 
229
197
  ### Want to undo everything
230
198
 
231
199
  ```bash
232
200
  npx claude-depester --restore --all # Restore all installations
233
- npx claude-depester --remove-hook # Remove hook (if installed)
234
- # Remove the shell wrapper from your .bashrc/.zshrc if added
201
+ npx claude-depester --remove-hook # Remove auto-patch hook
235
202
  ```
236
203
 
237
204
  ## Technical Details
@@ -246,13 +213,12 @@ npx claude-depester --remove-hook # Remove hook (if installed)
246
213
  - Spinner words: `["Accomplishing",...,"Zigzagging"]` -> `["Thinking"]`
247
214
  - Completion verbs: `["Baked",...,"Worked"]` -> `["Thought"]`
248
215
 
249
- 4. **Repacking**: Rebuilds the binary with the modified JavaScript
216
+ 4. **Repacking**: Rebuilds the binary with the modified JavaScript. Supports both old (pre-2.1.37) and new Bun data formats (different trailer signatures and module struct sizes)
250
217
 
251
218
  ### File locations
252
219
 
253
220
  - **Backup**: `<original-file>.depester.backup`
254
221
  - **Hook config**: `~/.claude/settings.json`
255
- - **Debug log**: `~/.claude/depester.log` (when using `--log`)
256
222
 
257
223
  ## Requirements
258
224
 
@@ -263,14 +229,14 @@ npx claude-depester --remove-hook # Remove hook (if installed)
263
229
 
264
230
  | Platform | Binary Patching | Webview Patching | Status |
265
231
  |----------|-----------------|------------------|--------|
266
- | Linux x64 | ELF | Yes | Tested |
232
+ | Linux x64 | ELF | Yes | Tested (2.1.27) |
267
233
  | Linux ARM64 | ELF | Yes | Should work |
268
234
  | macOS Intel | MachO | Yes | Should work |
269
- | macOS Apple Silicon | MachO | Yes | Should work |
235
+ | macOS Apple Silicon | MachO | Yes | Tested (2.1.38) |
270
236
  | Windows x64 | PE | Yes | Should work |
271
237
  | Windows ARM64 | PE | Yes | Should work |
272
238
 
273
- The tool uses [node-lief](https://www.npmjs.com/package/node-lief) which has prebuilt binaries for all these platforms.
239
+ Binary repacking uses raw file writes (byte-level section replacement) for MachO and PE formats, avoiding LIEF write() which could produce bloated output. ELF uses LIEF write(). The tool uses [node-lief](https://www.npmjs.com/package/node-lief) for binary parsing on all platforms.
274
240
 
275
241
  ## Contributing
276
242
 
@@ -294,12 +260,6 @@ This project builds upon work by:
294
260
  - [vemv's gist](https://gist.github.com/vemv/c6333d53ede16198a23eb95425051b7b) - Original simple patch idea
295
261
  - [heromantf's bun extractor](https://gist.github.com/heromantf/7db88edcb7b1c0c35067244584a01afc) - Bun binary structure documentation
296
262
 
297
- ## Donors
298
-
299
- Thanks to these generous supporters:
300
-
301
- - [@gyohng](https://github.com/gyohng)
302
-
303
263
  ## License
304
264
 
305
265
  MIT - see [LICENSE](LICENSE)
@@ -9,8 +9,8 @@
9
9
  */
10
10
 
11
11
  const { findCliJs, findAllClaudeCode, getSearchedPaths } = require('../lib/detector');
12
- const { patch, checkStatus, getDebugInfo, restoreBackup } = require('../lib/patcher');
13
- const { installHook, removeHook, getHookStatus, searchHookLogs, appendLog, readLog, LOG_PATH } = require('../lib/hooks');
12
+ const { patch, checkStatus, restoreBackup } = require('../lib/patcher');
13
+ const { installHook, removeHook, getHookStatus } = require('../lib/hooks');
14
14
 
15
15
  const VERSION = require('../package.json').version;
16
16
 
@@ -27,8 +27,6 @@ const flags = {
27
27
  hookStatus: args.includes('--hook-status'),
28
28
  silent: args.includes('--silent') || args.includes('-s'),
29
29
  verbose: args.includes('--verbose'),
30
- debug: args.includes('--debug') || args.includes('-d'),
31
- log: args.includes('--log'),
32
30
  all: args.includes('--all') || args.includes('-a'),
33
31
  list: args.includes('--list') || args.includes('-l')
34
32
  };
@@ -78,8 +76,6 @@ OPTIONS:
78
76
 
79
77
  -s, --silent Suppress output (for hook use)
80
78
  --verbose Show detailed information
81
- -d, --debug Show detailed debug info (for troubleshooting)
82
- --log Write results to ~/.claude/depester.log (keeps last 50 entries)
83
79
  -v, --version Show version
84
80
  -h, --help Show this help
85
81
 
@@ -90,7 +86,6 @@ EXAMPLES:
90
86
  npx claude-depester --check # Check status
91
87
  npx claude-depester --install-hook # Auto-patch after updates
92
88
  npx claude-depester --restore # Undo patch
93
- npx claude-depester --debug # Troubleshoot issues
94
89
 
95
90
  MORE INFO:
96
91
  https://github.com/ominiverdi/claude-depester
@@ -169,9 +164,6 @@ async function main() {
169
164
  const installations = findAllClaudeCode();
170
165
  if (installations.length === 0) {
171
166
  error('No Claude Code installations found.');
172
- if (flags.log) {
173
- appendLog('No installations found', { action: 'patch-all' });
174
- }
175
167
  if (flags.verbose) {
176
168
  showSearchedPaths();
177
169
  }
@@ -183,7 +175,6 @@ async function main() {
183
175
  let successCount = 0;
184
176
  let skipCount = 0;
185
177
  let failCount = 0;
186
- const logResults = [];
187
178
 
188
179
  for (const inst of installations) {
189
180
  log(`${inst.method}:`);
@@ -194,55 +185,28 @@ async function main() {
194
185
  if (success) {
195
186
  log(' -> Restored from backup\n');
196
187
  successCount++;
197
- logResults.push({ path: inst.path, method: inst.method, result: 'restored' });
198
188
  } else {
199
189
  log(' -> No backup found\n');
200
190
  skipCount++;
201
- logResults.push({ path: inst.path, method: inst.method, result: 'no-backup' });
202
191
  }
203
192
  } else {
204
- // Get debug info before patching for the log
205
- const debugBefore = flags.log ? getDebugInfo(inst.path, { type: inst.type }) : null;
206
-
207
193
  const result = patch(inst.path, { dryRun: flags.dryRun, type: inst.type });
208
194
  if (result.success) {
209
195
  if (result.alreadyPatched) {
210
196
  log(' -> Already patched\n');
211
197
  skipCount++;
212
- logResults.push({
213
- path: inst.path,
214
- method: inst.method,
215
- result: 'already-patched',
216
- debug: debugBefore
217
- });
218
198
  } else if (result.dryRun) {
219
199
  const details = formatPatchDetails(result);
220
200
  log(` -> Would patch${details}\n`);
221
201
  successCount++;
222
- logResults.push({ path: inst.path, method: inst.method, result: 'dry-run' });
223
202
  } else {
224
203
  const details = formatPatchDetails(result);
225
204
  log(` -> Patched${details}\n`);
226
205
  successCount++;
227
- logResults.push({
228
- path: inst.path,
229
- method: inst.method,
230
- result: 'patched',
231
- spinnerCount: result.spinnerCount,
232
- completionCount: result.completionCount,
233
- debug: debugBefore
234
- });
235
206
  }
236
207
  } else {
237
208
  log(` -> Failed: ${result.message}\n`);
238
209
  failCount++;
239
- logResults.push({
240
- path: inst.path,
241
- method: inst.method,
242
- result: 'failed',
243
- error: result.message,
244
- debug: debugBefore
245
- });
246
210
  }
247
211
  }
248
212
  }
@@ -251,18 +215,6 @@ async function main() {
251
215
  if (!flags.dryRun && successCount > 0) {
252
216
  log('Restart Claude Code for changes to take effect.');
253
217
  }
254
-
255
- if (flags.log) {
256
- appendLog('Patch all completed', {
257
- action: 'patch-all',
258
- found: installations.length,
259
- patched: successCount,
260
- skipped: skipCount,
261
- failed: failCount,
262
- results: logResults
263
- });
264
- }
265
-
266
218
  process.exit(failCount > 0 ? 1 : 0);
267
219
  }
268
220
 
@@ -286,118 +238,6 @@ async function main() {
286
238
  log(`Detection method: ${cliInfo.method}`);
287
239
  }
288
240
 
289
- // Handle debug
290
- if (flags.debug) {
291
- log('=== DEPESTER DEBUG INFO ===\n');
292
-
293
- // Get debug info for all installations
294
- const installations = findAllClaudeCode();
295
- if (installations.length === 0) {
296
- log('No installations found.\n');
297
- } else {
298
- for (const inst of installations) {
299
- const debug = getDebugInfo(inst.path, { type: inst.type });
300
-
301
- log(`--- ${inst.method} ---`);
302
- log(`Path: ${debug.filePath}`);
303
- log(`File exists: ${debug.fileExists}`);
304
- if (debug.fileExists) {
305
- log(`File size: ${debug.fileSize} bytes`);
306
- log(`File modified: ${debug.fileModified}`);
307
- log(`Is binary: ${debug.isBinary}`);
308
- log(`Is webview: ${debug.isWebview}`);
309
- if (debug.isBinary) {
310
- log(`Binary extraction OK: ${debug.binaryExtractionOk}`);
311
- if (debug.extractedJsSize) {
312
- log(`Extracted JS size: ${debug.extractedJsSize} bytes`);
313
- }
314
- }
315
- log(`Has backup: ${debug.hasBackup}`);
316
- log('');
317
- log('Detection checks:');
318
- log(` Has =["Thinking"]: ${debug.hasReplacementPattern}`);
319
- log(` Has =["Thought"]: ${debug.hasCompletionReplacement}`);
320
- log(` Has original spinner array: ${debug.hasOriginalSpinnerArray}`);
321
- log(` Has original completion array: ${debug.hasOriginalCompletionArray}`);
322
- log(` Marker words found: ${debug.markerWordsFound.length > 0 ? debug.markerWordsFound.join(', ') : 'none'}`);
323
- log(` Completion verbs found: ${debug.completionVerbsFound.length > 0 ? debug.completionVerbsFound.join(', ') : 'none'}`);
324
- log('');
325
- log('Computed status:');
326
- log(` Spinner patched: ${debug.spinnerPatched}`);
327
- log(` Completion patched: ${debug.completionPatched}`);
328
- log(` Has silly words: ${debug.hasSillyWords}`);
329
- }
330
- if (debug.error) {
331
- log(`Error: ${debug.error}`);
332
- }
333
- log('');
334
- }
335
- }
336
-
337
- // Hook status
338
- const hookStatus = getHookStatus();
339
- log('--- Hook Status ---');
340
- log(`Hook installed: ${hookStatus.installed}`);
341
- log(`Settings file: ${hookStatus.settingsPath}`);
342
- log('');
343
-
344
- // Search Claude debug logs for hook activity
345
- log('--- Recent Hook Activity (from Claude logs) ---');
346
- const hookLogs = searchHookLogs(5);
347
- if (hookLogs.length === 0) {
348
- log('No hook activity found in recent Claude debug logs.');
349
- } else {
350
- for (const logFile of hookLogs) {
351
- log(`\nLog: ${logFile.file} (${logFile.timestamp})`);
352
- for (const entry of logFile.entries) {
353
- log(` ${entry.time}: ${entry.message}`);
354
- }
355
- }
356
- }
357
- log('');
358
-
359
- // Show depester's own log
360
- log('--- Depester Log (last 10 entries) ---');
361
- log(`Log file: ${LOG_PATH}`);
362
- const depesterLogs = readLog();
363
- if (depesterLogs.length === 0) {
364
- log('No entries. Enable logging with --log flag.');
365
- } else {
366
- const recent = depesterLogs.slice(-10);
367
- for (const entry of recent) {
368
- log(`\n${entry.timestamp}: ${entry.message}`);
369
- if (entry.data) {
370
- if (entry.data.found !== undefined) {
371
- log(` Found: ${entry.data.found}, Patched: ${entry.data.patched}, Skipped: ${entry.data.skipped}, Failed: ${entry.data.failed}`);
372
- }
373
- // Only show per-installation details if there was a failure or unexpected result
374
- if (entry.data.results) {
375
- const hasIssue = entry.data.results.some(r =>
376
- r.result === 'failed' ||
377
- (r.result === 'already-patched' && r.debug?.markerWordsFound?.length > 0)
378
- );
379
- if (hasIssue) {
380
- for (const r of entry.data.results) {
381
- log(` - ${r.method}: ${r.result}`);
382
- if (r.debug) {
383
- log(` File modified: ${r.debug.fileModified}`);
384
- log(` Has =["Thinking"]: ${r.debug.hasReplacementPattern}`);
385
- log(` Marker words: ${r.debug.markerWordsFound?.length > 0 ? r.debug.markerWordsFound.join(', ') : 'none'}`);
386
- }
387
- if (r.error) {
388
- log(` Error: ${r.error}`);
389
- }
390
- }
391
- }
392
- }
393
- }
394
- }
395
- }
396
- log('');
397
-
398
- process.exit(0);
399
- }
400
-
401
241
  // Handle check
402
242
  if (flags.check) {
403
243
  const status = checkStatus(cliInfo.path, { type: cliInfo.type });