cc-viewer 1.5.22 → 1.5.24

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/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { readFileSync, writeFileSync, existsSync, realpathSync } from 'node:fs';
3
+ import { readFileSync, writeFileSync, existsSync, realpathSync, unlinkSync } from 'node:fs';
4
4
  import { resolve } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { homedir } from 'node:os';
@@ -114,12 +114,14 @@ function installShellHook(isNative) {
114
114
  let content = existsSync(configPath) ? readFileSync(configPath, 'utf-8') : '';
115
115
 
116
116
  if (content.includes(SHELL_HOOK_START)) {
117
- // Check if existing hook matches desired mode
118
- const isNativeHook = content.includes('ccv run -- claude');
119
- if (!!isNative === !!isNativeHook) {
117
+ const hook = buildShellHook(isNative);
118
+ // Extract existing hook content
119
+ const regex = new RegExp(`${SHELL_HOOK_START}[\\s\\S]*?${SHELL_HOOK_END}`);
120
+ const existingMatch = content.match(regex);
121
+ if (existingMatch && existingMatch[0] === hook) {
120
122
  return { path: configPath, status: 'exists' };
121
123
  }
122
- // Mismatch: remove old hook first
124
+ // Hook content differs: remove old and reinstall
123
125
  removeShellHook();
124
126
  content = existsSync(configPath) ? readFileSync(configPath, 'utf-8') : '';
125
127
  }
@@ -134,18 +136,28 @@ function installShellHook(isNative) {
134
136
  }
135
137
 
136
138
  function removeShellHook() {
139
+ // 扫描所有可能的 shell 配置文件,清理所有遗留 hook
137
140
  const configPath = getShellConfigPath();
138
- try {
139
- if (!existsSync(configPath)) return { path: configPath, status: 'not_found' };
140
- const content = readFileSync(configPath, 'utf-8');
141
- if (!content.includes(SHELL_HOOK_START)) return { path: configPath, status: 'clean' };
142
- const regex = new RegExp(`\\n?${SHELL_HOOK_START}[\\s\\S]*?${SHELL_HOOK_END}\\n?`, 'g');
143
- const newContent = content.replace(regex, '\n');
144
- writeFileSync(configPath, newContent);
145
- return { path: configPath, status: 'removed' };
146
- } catch (err) {
147
- return { path: configPath, status: 'error', error: err.message };
141
+ const allPaths = new Set([configPath]);
142
+ const home = homedir();
143
+ for (const f of ['.zshrc', '.zprofile', '.bashrc', '.bash_profile', '.profile']) {
144
+ allPaths.add(resolve(home, f));
145
+ }
146
+ let lastResult = { path: configPath, status: 'clean' };
147
+ for (const p of allPaths) {
148
+ try {
149
+ if (!existsSync(p)) continue;
150
+ const content = readFileSync(p, 'utf-8');
151
+ if (!content.includes(SHELL_HOOK_START)) continue;
152
+ const regex = new RegExp(`\\n?${SHELL_HOOK_START}[\\s\\S]*?${SHELL_HOOK_END}\\n?`, 'g');
153
+ const newContent = content.replace(regex, '\n');
154
+ writeFileSync(p, newContent);
155
+ lastResult = { path: p, status: 'removed' };
156
+ } catch (err) {
157
+ lastResult = { path: p, status: 'error', error: err.message };
158
+ }
148
159
  }
160
+ return lastResult;
149
161
  }
150
162
 
151
163
  function injectCliJs() {
@@ -386,7 +398,7 @@ const args = process.argv.slice(2);
386
398
 
387
399
  // ccv 自有命令判断
388
400
  const isLogger = args.includes('-logger');
389
- const isUninstall = args.includes('--uninstall');
401
+ const isUninstall = args.includes('--uninstall') || args.includes('-uninstall');
390
402
  const isHelp = args.includes('--help') || args.includes('-h') || args[0] === 'help';
391
403
  const isVersion = args.includes('--v') || args.includes('--version') || args.includes('-v');
392
404
 
@@ -424,6 +436,30 @@ if (isUninstall) {
424
436
  } else {
425
437
  console.log(t('cli.uninstall.hookFail', { error: shellResult.error }));
426
438
  }
439
+
440
+ // 清理 statusLine 配置和脚本(兼容历史版本遗留)
441
+ try {
442
+ const settingsPath = resolve(homedir(), '.claude', 'settings.json');
443
+ if (existsSync(settingsPath)) {
444
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
445
+ if (settings.statusLine?.command?.includes('ccv-statusline')) {
446
+ delete settings.statusLine;
447
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
448
+ console.log('Cleaned statusLine config from settings.json');
449
+ }
450
+ }
451
+ const ccvScript = resolve(homedir(), '.claude', 'ccv-statusline.sh');
452
+ if (existsSync(ccvScript)) {
453
+ unlinkSync(ccvScript);
454
+ console.log('Removed ccv-statusline.sh');
455
+ }
456
+ // 清理 context-window.json
457
+ const ctxFile = resolve(homedir(), '.claude', 'context-window.json');
458
+ if (existsSync(ctxFile)) {
459
+ unlinkSync(ctxFile);
460
+ }
461
+ } catch { }
462
+
427
463
  console.log(t('cli.uninstall.reloadShell'));
428
464
  console.log(t('cli.uninstall.done'));
429
465
  process.exit(0);