yingclaw 2.4.5 → 2.5.1

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
@@ -72,7 +72,6 @@ claw config # 配置 API 连接
72
72
  claw code # 接入 Claude Code 终端
73
73
  claw desktop # 接入 Claude 桌面应用
74
74
  claw switch # 快速切换厂商或模型
75
- claw prompt # 配置系统提示词(按模型独立保存)
76
75
  claw status # 查看当前配置,验证 Key 是否有效
77
76
  claw update # 检查并升级到最新版本
78
77
 
@@ -82,6 +81,7 @@ claw reset # 清除所有 yingclaw 配置
82
81
 
83
82
  claw install-claude # 安装 Claude Code
84
83
  claw setup # 兼容旧命令:config + code
84
+
85
85
  ```
86
86
 
87
87
  ## 平台支持
package/bin/cli.js CHANGED
@@ -5,8 +5,6 @@ const { select, input, confirm } = require('@inquirer/prompts');
5
5
  const {
6
6
  loadConfig,
7
7
  saveConfig,
8
- getSystemPrompt,
9
- setSystemPrompt,
10
8
  writeEnvToZshrc,
11
9
  clearClaudeCodeEnv,
12
10
  fetchModels,
@@ -23,7 +21,7 @@ const {
23
21
  const { execSync, spawn, spawnSync } = require('child_process');
24
22
  const pkg = require('../package.json');
25
23
  const { buildMenuStatusLines, buildStatusView } = require('../lib/panel');
26
- const { buildClaudeInstallCommand } = require('../lib/install');
24
+ const { buildClaudeInstallCommand, checkNodeEnv, getNodeInstallGuide, getInstallFailureHints } = require('../lib/install');
27
25
  const { clearClaudeDesktopConfig, isDesktopConfigured, openClaudeDesktop, writeClaudeDesktopConfig } = require('../lib/desktop');
28
26
  const { runDoctorChecks, summarize, STATUS_OK, STATUS_FAIL, STATUS_WARN, STATUS_INFO } = require('../lib/doctor');
29
27
 
@@ -237,14 +235,6 @@ async function showStatus() {
237
235
  env: process.env,
238
236
  });
239
237
 
240
- const systemPromptText = getSystemPrompt(config);
241
- if (systemPromptText) {
242
- const preview = systemPromptText.length > 60 ? systemPromptText.slice(0, 60) + '…' : systemPromptText;
243
- view.lines.push({ label: '系统提示词', value: preview });
244
- } else {
245
- view.lines.push({ label: '系统提示词', value: '未配置' });
246
- }
247
-
248
238
  const lines = view.lines.map(({ label, value }) => {
249
239
  const coloredValue = label === '厂商'
250
240
  ? chalk.white.bold(value)
@@ -364,7 +354,7 @@ async function runConfigFlow({ writeCodeEnv = false } = {}) {
364
354
  cfg = customConfig || { provider: providerKey, model, fastModel, apiKey, baseUrl: provider.baseUrl, availableModels };
365
355
  saveConfig(cfg);
366
356
  if (writeCodeEnv) {
367
- ({ file } = writeEnvToZshrc(cfg.baseUrl, cfg.apiKey, cfg.model, cfg.fastModel, { systemPrompt: getSystemPrompt(cfg) }));
357
+ ({ file } = writeEnvToZshrc(cfg.baseUrl, cfg.apiKey, cfg.model, cfg.fastModel));
368
358
  }
369
359
  spinner.succeed(chalk.green(writeCodeEnv ? 'API 连接已保存,Claude Code 终端已接入' : 'API 连接已保存'));
370
360
  } catch (e) {
@@ -412,6 +402,31 @@ program
412
402
  if (!yes) return;
413
403
  } catch {}
414
404
 
405
+ // 检查 npm / Node.js 环境
406
+ const nodeEnv = checkNodeEnv();
407
+ if (!nodeEnv.npmOk) {
408
+ console.log(boxen(
409
+ chalk.bold.red('未检测到 npm,无法安装 Claude Code\n\n') +
410
+ chalk.dim('Claude Code 通过 npm 安装,需要先安装 Node.js(含 npm)。\n\n') +
411
+ chalk.bold('安装方式:\n') +
412
+ getNodeInstallGuide().map(l => chalk.cyan(' ' + l)).join('\n') +
413
+ '\n\n' + chalk.dim('安装完成后重新运行 claw install-claude'),
414
+ { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'red', margin: { top: 1, bottom: 1 } }
415
+ ));
416
+ return;
417
+ }
418
+ if (!nodeEnv.nodeOk) {
419
+ console.log(boxen(
420
+ chalk.bold.yellow(`Node.js 版本过低(当前 v${nodeEnv.nodeVersion},需要 ≥18)\n\n`) +
421
+ chalk.dim('Claude Code 要求 Node.js ≥18,当前版本可能导致安装或运行失败。\n\n') +
422
+ chalk.bold('升级方式:\n') +
423
+ getNodeInstallGuide().map(l => chalk.cyan(' ' + l)).join('\n'),
424
+ { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'yellow', margin: { top: 1, bottom: 1 } }
425
+ ));
426
+ const proceed = await confirm({ message: '仍然尝试安装?', default: false });
427
+ if (!proceed) return;
428
+ }
429
+
415
430
  const network = await select({ loop: false,
416
431
  message: chalk.cyan('你的网络环境'),
417
432
  choices: [
@@ -433,10 +448,9 @@ program
433
448
  console.log(chalk.green('\n✔ Claude Code 安装成功!'));
434
449
  } else {
435
450
  console.log(chalk.red('\n✘ 安装失败'));
451
+ const hints = getInstallFailureHints(result, chalk);
436
452
  console.log(boxen(
437
- chalk.bold('手动安装:\n\n') +
438
- chalk.cyan('npm config set registry https://registry.npmmirror.com\n') +
439
- chalk.cyan('npm install -g @anthropic-ai/claude-code'),
453
+ hints.join(''),
440
454
  { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'yellow', margin: { top: 1, bottom: 1 } }
441
455
  ));
442
456
  return;
@@ -492,7 +506,7 @@ program
492
506
  const spinner = ora('写入 Claude Code 终端环境变量...').start();
493
507
  let file;
494
508
  try {
495
- ({ file } = writeEnvToZshrc(config.baseUrl, config.apiKey, config.model, config.fastModel, { systemPrompt: getSystemPrompt(config) }));
509
+ ({ file } = writeEnvToZshrc(config.baseUrl, config.apiKey, config.model, config.fastModel));
496
510
  spinner.succeed(chalk.green(`Claude Code 终端已接入 → ${file}`));
497
511
  } catch (e) {
498
512
  spinner.fail(chalk.red(`写入失败: ${e.message}`));
@@ -643,105 +657,6 @@ program
643
657
  await offerDesktopSync(chalk, ora, newConfig);
644
658
  });
645
659
 
646
- program
647
- .command('prompt')
648
- .description('配置系统提示词')
649
- .action(async () => {
650
- const chalk = (await import('chalk')).default;
651
- const ora = (await import('ora')).default;
652
- const boxen = (await import('boxen')).default;
653
-
654
- console.log(await getBanner());
655
-
656
- const config = loadConfig();
657
- if (!config) {
658
- console.log(chalk.red('\n未配置 API 连接,请先运行: claw config\n'));
659
- return;
660
- }
661
-
662
- const provider = PROVIDERS[config.provider];
663
- const providerName = config.providerName || provider?.name || config.provider;
664
- const currentPrompt = getSystemPrompt(config);
665
-
666
- console.log(chalk.dim(` 当前模型:${providerName} · ${config.model}\n`));
667
-
668
- if (currentPrompt) {
669
- const preview = currentPrompt.length > 300 ? currentPrompt.slice(0, 300) + '\n...' : currentPrompt;
670
- console.log(boxen(
671
- chalk.bold('当前系统提示词\n\n') + chalk.dim(preview),
672
- { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'cyan', margin: { top: 1, bottom: 1 } }
673
- ));
674
- } else {
675
- console.log(chalk.dim(' 当前模型未配置系统提示词\n'));
676
- }
677
-
678
- const action = await select({ loop: false,
679
- message: chalk.cyan('操作'),
680
- choices: [
681
- { name: currentPrompt ? '✏️ 编辑系统提示词' : '✏️ 设置系统提示词', value: 'edit' },
682
- ...(currentPrompt ? [{ name: '🗑 清除当前模型提示词', value: 'clear' }] : []),
683
- { name: chalk.dim('↩ 返回'), value: '__BACK__' },
684
- ],
685
- });
686
-
687
- if (action === '__BACK__') return;
688
-
689
- if (action === 'clear') {
690
- const yes = await confirm({ message: '确定清除该模型的系统提示词?', default: false });
691
- if (!yes) { console.log(chalk.dim('已取消')); return; }
692
- const spinner = ora('清除中...').start();
693
- setSystemPrompt(config, null);
694
- saveConfig(config);
695
- try {
696
- writeEnvToZshrc(config.baseUrl, config.apiKey, config.model, config.fastModel, {});
697
- } catch {}
698
- spinner.succeed(chalk.green('系统提示词已清除'));
699
- return;
700
- }
701
-
702
- if (currentPrompt) {
703
- console.log(chalk.dim(' 直接输入新内容覆盖,留空并回车取消'));
704
- }
705
-
706
- const newPrompt = await input({
707
- message: chalk.cyan('系统提示词'),
708
- default: currentPrompt || undefined,
709
- validate: () => true,
710
- });
711
-
712
- if (!newPrompt || !newPrompt.trim()) {
713
- console.log(chalk.dim('内容为空,已取消'));
714
- return;
715
- }
716
-
717
- const spinner = ora('保存中...').start();
718
- setSystemPrompt(config, newPrompt);
719
- saveConfig(config);
720
-
721
- // 无论是否已有 clawai 块,都同步写入 shell RC / PowerShell Profile
722
- let rcFile;
723
- try {
724
- ({ file: rcFile } = writeEnvToZshrc(config.baseUrl, config.apiKey, config.model, config.fastModel, { systemPrompt: getSystemPrompt(config) }));
725
- } catch {}
726
-
727
- spinner.succeed(chalk.green('系统提示词已保存'));
728
-
729
- if (process.platform === 'win32') {
730
- console.log(boxen(
731
- chalk.dim('• 通过菜单"启动 Claude Code"立即生效\n') +
732
- chalk.dim('• 直接运行 claude 需重新打开 PowerShell 后生效\n') +
733
- chalk.dim(' (已写入 PowerShell Profile,新窗口自动加载)'),
734
- { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'green', margin: { top: 1, bottom: 1 } }
735
- ));
736
- } else {
737
- console.log(boxen(
738
- chalk.dim('• 通过菜单"启动 Claude Code"立即生效\n') +
739
- chalk.dim('• 终端直接运行 claude 需先执行:') + chalk.cyan(`source ${rcFile || '~/.zshrc'}`),
740
- { padding: { top: 0, bottom: 0, left: 2, right: 2 }, borderStyle: 'round', borderColor: 'green', margin: { top: 1, bottom: 1 } }
741
- ));
742
- }
743
- });
744
-
745
660
  program
746
661
  .command('status')
747
662
  .description('查看当前配置和 Key 有效性')
@@ -1174,7 +1089,6 @@ async function runMenu() {
1174
1089
  { name: '📦 安装 Claude Code', value: 'install' },
1175
1090
  { name: config ? '🔑 重新配置 API 连接' : '🔑 配置 API 连接', value: 'config' },
1176
1091
  { name: '🔄 切换厂商或模型', value: 'switch', disabled: disabledHint },
1177
- { name: getSystemPrompt(config) ? '📝 系统提示词(已配置)' : '📝 配置系统提示词', value: 'prompt', disabled: !config && '需先配置 API 连接' },
1178
1092
  { name: '💻 接入 Claude Code 终端', value: 'code', disabled: disabledHint },
1179
1093
  { name: '🖥 接入 Claude 桌面应用', value: 'desktop', disabled: disabledHint },
1180
1094
  { name: '📊 查看当前配置', value: 'status', disabled: !config && '需先配置 API 连接' },
@@ -1201,17 +1115,12 @@ async function runMenu() {
1201
1115
  if (resolvedAction === 'launch') {
1202
1116
  const cfg = loadConfig();
1203
1117
  if (!cfg || getConfigValidationMessage(cfg)) continue;
1204
- const systemPromptText = getSystemPrompt(cfg);
1205
- const launchArgs = systemPromptText ? ['--append-system-prompt', systemPromptText] : [];
1206
- if (systemPromptText) {
1207
- const preview = systemPromptText.length > 40 ? systemPromptText.slice(0, 40) + '…' : systemPromptText;
1208
- console.log(chalk.dim(` 系统提示词已启用:${preview}`));
1209
- }
1210
1118
  await new Promise((resolve) => {
1211
- // Windows 用显式 cmd.exe 调用,避免 shell:true 的参数拼接警告和转义问题
1212
- const child = process.platform === 'win32'
1213
- ? spawn('cmd.exe', ['/d', '/c', 'claude', ...launchArgs], { stdio: 'inherit', env: { ...process.env, ...buildClaudeEnv(cfg) } })
1214
- : spawn('claude', launchArgs, { stdio: 'inherit', env: { ...process.env, ...buildClaudeEnv(cfg) } });
1119
+ const child = spawn('claude', [], {
1120
+ stdio: 'inherit',
1121
+ env: { ...process.env, ...buildClaudeEnv(cfg) },
1122
+ shell: process.platform === 'win32',
1123
+ });
1215
1124
  child.on('error', () => {
1216
1125
  console.log(chalk.yellow('\nClaude Code 未找到,请先选择"安装 Claude Code"'));
1217
1126
  resolve();
@@ -1227,7 +1136,6 @@ async function runMenu() {
1227
1136
  code: 'code',
1228
1137
  'code-reset': 'code-reset',
1229
1138
  switch: 'switch',
1230
- prompt: 'prompt',
1231
1139
  desktop: 'desktop',
1232
1140
  'desktop-reset': 'desktop-reset',
1233
1141
  status: 'status',
package/lib/config.js CHANGED
@@ -128,26 +128,6 @@ function normalizeAnthropicBaseUrl(baseUrl) {
128
128
  return url.toString().replace(/\/+$/, '');
129
129
  }
130
130
 
131
- function systemPromptKey(config) {
132
- return `${config.provider}::${config.model}`;
133
- }
134
-
135
- function getSystemPrompt(config) {
136
- if (!config?.systemPrompts) return null;
137
- return config.systemPrompts[systemPromptKey(config)] || null;
138
- }
139
-
140
- function setSystemPrompt(config, prompt) {
141
- const key = systemPromptKey(config);
142
- if (!config.systemPrompts) config.systemPrompts = {};
143
- if (prompt && prompt.trim()) {
144
- config.systemPrompts[key] = prompt.trim();
145
- } else {
146
- delete config.systemPrompts[key];
147
- if (Object.keys(config.systemPrompts).length === 0) delete config.systemPrompts;
148
- }
149
- }
150
-
151
131
  function buildModelUrlCandidates(baseUrl) {
152
132
  let url;
153
133
  try { url = new URL(normalizeAnthropicBaseUrl(baseUrl)); } catch { return []; }
@@ -344,10 +324,10 @@ function shellQuote(value) {
344
324
  }
345
325
 
346
326
  // 构造完整的 clawai 环境变量块
347
- function buildEnvBlock(baseUrl, apiKey, model, fastModel, systemPrompt) {
327
+ function buildEnvBlock(baseUrl, apiKey, model, fastModel) {
348
328
  const provider = providerKeyFromBaseUrl(baseUrl);
349
329
  const env = buildClaudeEnv({ provider, baseUrl, apiKey, model, fastModel });
350
- const lines = [
330
+ return [
351
331
  '',
352
332
  '# clawai-start',
353
333
  `export ANTHROPIC_BASE_URL=${shellQuote(env.ANTHROPIC_BASE_URL)}`,
@@ -359,47 +339,9 @@ function buildEnvBlock(baseUrl, apiKey, model, fastModel, systemPrompt) {
359
339
  `export ANTHROPIC_DEFAULT_HAIKU_MODEL=${shellQuote(env.ANTHROPIC_DEFAULT_HAIKU_MODEL)}`,
360
340
  `export CLAUDE_CODE_SUBAGENT_MODEL=${shellQuote(env.CLAUDE_CODE_SUBAGENT_MODEL)}`,
361
341
  `export CLAUDE_CODE_EFFORT_LEVEL=${shellQuote(env.CLAUDE_CODE_EFFORT_LEVEL)}`,
362
- ];
363
-
364
- if (systemPrompt && systemPrompt.trim()) {
365
- lines.push(`_claw_system_prompt=${shellQuote(systemPrompt.trim())}`);
366
- lines.push(`claude() { command claude --append-system-prompt "$_claw_system_prompt" "$@"; }`);
367
- }
368
-
369
- lines.push('# clawai-end', '');
370
- return lines.join('\n');
371
- }
372
-
373
- function buildPsBlock(systemPrompt) {
374
- const escaped = systemPrompt.replace(/'/g, "''");
375
- return [
376
- '',
377
- '# clawai-start',
378
- `$_claw_system_prompt = '${escaped}'`,
379
- `function claude { $claudePath = (Get-Command -Name claude.cmd -ErrorAction SilentlyContinue)?.Source; if (-not $claudePath) { $claudePath = 'claude' }; & $claudePath --append-system-prompt $_claw_system_prompt @args }`,
380
342
  '# clawai-end',
381
343
  '',
382
- ].join('\r\n');
383
- }
384
-
385
- function writePowerShellProfile(systemPrompt, options = {}) {
386
- const homeDir = options.homeDir || os.homedir();
387
- const profilePaths = [
388
- path.join(homeDir, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1'),
389
- path.join(homeDir, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1'),
390
- ];
391
- const written = [];
392
- for (const profilePath of profilePaths) {
393
- try {
394
- fs.mkdirSync(path.dirname(profilePath), { recursive: true });
395
- const current = fs.existsSync(profilePath) ? fs.readFileSync(profilePath, 'utf8') : '';
396
- const cleaned = current.replace(/\r?\n?# clawai-start[\s\S]*?# clawai-end\r?\n?/g, '');
397
- const next = (systemPrompt && systemPrompt.trim()) ? cleaned + buildPsBlock(systemPrompt) : cleaned;
398
- fs.writeFileSync(profilePath, next, 'utf8');
399
- written.push(profilePath);
400
- } catch {}
401
- }
402
- return written;
344
+ ].join('\n');
403
345
  }
404
346
 
405
347
  // 写入或更新 shell 配置文件中的环境变量块
@@ -409,7 +351,6 @@ function writeEnvToZshrc(baseUrl, apiKey, model, fastModel, options = {}) {
409
351
  const provider = providerKeyFromBaseUrl(baseUrl);
410
352
  const env = buildClaudeEnv({ provider, baseUrl, apiKey, model, fastModel });
411
353
  runWindowsEnvCommands(buildWindowsSetEnvCommands(env), options.runner || spawnSync);
412
- writePowerShellProfile(options.systemPrompt, options);
413
354
  return { result: 'updated', file: WINDOWS_ENV_LABEL };
414
355
  }
415
356
 
@@ -423,7 +364,7 @@ function writeEnvToZshrc(baseUrl, apiKey, model, fastModel, options = {}) {
423
364
  rcFile = path.join(os.homedir(), '.zshrc');
424
365
  }
425
366
 
426
- const block = buildEnvBlock(baseUrl, apiKey, model, fastModel, options.systemPrompt);
367
+ const block = buildEnvBlock(baseUrl, apiKey, model, fastModel);
427
368
  const current = fs.existsSync(rcFile) ? fs.readFileSync(rcFile, 'utf8') : '';
428
369
 
429
370
  // 兼容旧版(# clawai 单行块)和新版(# clawai-start...# clawai-end 多行块)
@@ -483,11 +424,7 @@ function resetConfig(options = {}) {
483
424
  module.exports = {
484
425
  loadConfig,
485
426
  saveConfig,
486
- getSystemPrompt,
487
- setSystemPrompt,
488
427
  writeEnvToZshrc,
489
- writePowerShellProfile,
490
- buildPsBlock,
491
428
  buildWindowsSetEnvCommands,
492
429
  buildWindowsClearEnvCommands,
493
430
  clearClaudeCodeEnv,
package/lib/install.js CHANGED
@@ -1,3 +1,5 @@
1
+ const { execSync } = require('child_process');
2
+
1
3
  function buildClaudeInstallCommand(network) {
2
4
  const args = ['install', '-g', '@anthropic-ai/claude-code'];
3
5
  if (network === 'cn') {
@@ -6,4 +8,87 @@ function buildClaudeInstallCommand(network) {
6
8
  return { command: 'npm', args };
7
9
  }
8
10
 
9
- module.exports = { buildClaudeInstallCommand };
11
+ function checkNodeEnv() {
12
+ const nodeVersion = process.versions.node;
13
+ const nodeMajor = parseInt(nodeVersion.split('.')[0], 10);
14
+
15
+ let npmVersion = null;
16
+ try {
17
+ // Windows 上 npm 是 .cmd 文件,必须加 shell: true 才能找到
18
+ npmVersion = execSync('npm --version', {
19
+ encoding: 'utf8',
20
+ stdio: ['ignore', 'pipe', 'ignore'],
21
+ shell: process.platform === 'win32',
22
+ }).trim();
23
+ } catch {}
24
+
25
+ return {
26
+ nodeVersion,
27
+ nodeMajor,
28
+ nodeOk: nodeMajor >= 18,
29
+ npmVersion,
30
+ npmOk: !!npmVersion,
31
+ };
32
+ }
33
+
34
+ function getNodeInstallGuide() {
35
+ const platform = process.platform;
36
+ if (platform === 'darwin') {
37
+ return [
38
+ 'Homebrew: brew install node',
39
+ '官方安装包: https://nodejs.org (选 LTS 版本)',
40
+ ];
41
+ }
42
+ if (platform === 'win32') {
43
+ return [
44
+ '官方安装包: https://nodejs.org (选 LTS 版本)',
45
+ 'winget: winget install OpenJS.NodeJS.LTS',
46
+ ];
47
+ }
48
+ return [
49
+ 'Ubuntu/Debian: sudo apt install nodejs npm',
50
+ 'CentOS/RHEL: sudo yum install nodejs npm',
51
+ 'nvm(推荐): https://github.com/nvm-sh/nvm',
52
+ ];
53
+ }
54
+
55
+ /**
56
+ * 根据 spawnSync 结果判断失败原因,返回对应的提示内容(chalk 字符串数组)。
57
+ * @param {object} result spawnSync 返回值
58
+ * @param {Function} chalk chalk 实例
59
+ * @returns {string[]}
60
+ */
61
+ function getInstallFailureHints(result, chalk) {
62
+ // spawnSync 找不到命令(npm 在执行时消失或环境问题)
63
+ if (result.status === null && result.error?.code === 'ENOENT') {
64
+ return [
65
+ chalk.bold.red('npm 命令未找到\n\n'),
66
+ chalk.dim('安装 Node.js 后重试:\n'),
67
+ ...getNodeInstallGuide().map(l => chalk.cyan(' ' + l)),
68
+ ];
69
+ }
70
+
71
+ // 尝试从 stderr 判断权限错误(stdio inherit 时 stderr 为 null,兜底靠文字提示)
72
+ const stderr = result.stderr ? result.stderr.toString() : '';
73
+ if (stderr.includes('EACCES') || stderr.includes('permission denied') || stderr.includes('Access is denied')) {
74
+ const fixes = process.platform === 'win32'
75
+ ? ['以管理员身份运行 PowerShell / CMD,然后重试']
76
+ : [
77
+ 'sudo npm install -g @anthropic-ai/claude-code',
78
+ '或修复 npm 全局目录权限:https://docs.npmjs.com/resolving-eacces-permissions-errors',
79
+ ];
80
+ return [
81
+ chalk.bold.red('权限不足(EACCES)\n\n'),
82
+ ...fixes.map(l => chalk.cyan(' ' + l)),
83
+ ];
84
+ }
85
+
86
+ // 通用失败:显示手动安装命令
87
+ return [
88
+ chalk.bold('手动安装:\n\n'),
89
+ chalk.cyan('npm config set registry https://registry.npmmirror.com\n'),
90
+ chalk.cyan('npm install -g @anthropic-ai/claude-code'),
91
+ ];
92
+ }
93
+
94
+ module.exports = { buildClaudeInstallCommand, checkNodeEnv, getNodeInstallGuide, getInstallFailureHints };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yingclaw",
3
- "version": "2.4.5",
3
+ "version": "2.5.1",
4
4
  "description": "Claude Code × 国产大模型一键接入:DeepSeek、Kimi、Qwen、MiniMax、GLM、MiMo",
5
5
  "main": "index.js",
6
6
  "bin": {