yingclaw 2.5.12 → 2.5.14

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
@@ -103,13 +103,15 @@ claw setup # 兼容旧命令:config + code
103
103
 
104
104
  ```
105
105
  ANTHROPIC_BASE_URL
106
- ANTHROPIC_AUTH_TOKEN / ANTHROPIC_API_KEY
106
+ ANTHROPIC_AUTH_TOKEN
107
107
  ANTHROPIC_MODEL
108
108
  ANTHROPIC_DEFAULT_OPUS_MODEL / SONNET_MODEL / HAIKU_MODEL
109
109
  CLAUDE_CODE_SUBAGENT_MODEL
110
110
  CLAUDE_CODE_EFFORT_LEVEL
111
111
  ```
112
112
 
113
+ 新版只写入 `ANTHROPIC_AUTH_TOKEN`,并会清除旧版遗留的 `ANTHROPIC_API_KEY`,避免 Claude Code 同时检测到 token 和 API key 后报 `Auth conflict`。
114
+
113
115
  **桌面接入**(`claw desktop`)默认写入本机 Gateway:
114
116
 
115
117
  - macOS / Windows:写入 `Claude-3p/configLibrary/` 中的 yingclaw entry
package/bin/cli.js CHANGED
@@ -17,6 +17,7 @@ const {
17
17
  buildClaudeEnv,
18
18
  PROVIDERS,
19
19
  CLAUDE_ENV_KEYS,
20
+ CLEAR_CLAUDE_ENV_KEYS,
20
21
  } = require('../lib/config');
21
22
  const { execSync, spawn, spawnSync } = require('child_process');
22
23
  const pkg = require('../package.json');
@@ -567,7 +568,7 @@ program
567
568
  const resetNote = isWin
568
569
  ? '注:当前终端的环境变量还在内存中,重新打开 PowerShell / CMD 后才彻底清除'
569
570
  : '注:当前终端的环境变量还在内存中,重开终端后生效,或在当前终端执行:';
570
- const unsetCmd = isWin ? null : `unset ${CLAUDE_ENV_KEYS.join(' ')}`;
571
+ const unsetCmd = isWin ? null : `unset ${CLEAR_CLAUDE_ENV_KEYS.join(' ')}`;
571
572
  console.log(boxen(
572
573
  chalk.bold('已清除以下位置中的 Claude Code 终端环境变量:\n\n') +
573
574
  cleared.map(f => chalk.cyan(' • ' + f)).join('\n') +
package/lib/autostart.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const os = require('os');
3
3
  const path = require('path');
4
- const { spawnSync } = require('child_process');
4
+ const { spawn, spawnSync } = require('child_process');
5
5
 
6
6
  const GATEWAY_LAUNCH_AGENT_LABEL = 'com.yingclaw.gateway';
7
7
  const WINDOWS_GATEWAY_STARTUP_SCRIPT = 'yingclaw-gateway.cmd';
@@ -74,6 +74,21 @@ function buildWindowsGatewayStartupScript(options = {}) {
74
74
  ].join('\r\n');
75
75
  }
76
76
 
77
+ function startWindowsGateway(options = {}) {
78
+ const starter = options.starter || spawn;
79
+ const nodePath = options.nodePath || process.execPath;
80
+ const cliPath = options.cliPath || path.join(__dirname, '..', 'bin', 'cli.js');
81
+ const workingDirectory = options.workingDirectory || path.join(__dirname, '..');
82
+ const child = starter(nodePath, [cliPath, 'gateway'], {
83
+ cwd: workingDirectory,
84
+ detached: true,
85
+ stdio: 'ignore',
86
+ windowsHide: true,
87
+ });
88
+ if (child && typeof child.unref === 'function') child.unref();
89
+ return true;
90
+ }
91
+
77
92
  function runLaunchctl(runner, args, options = {}) {
78
93
  const result = runner('launchctl', args, { encoding: 'utf8', stdio: 'pipe' });
79
94
  if (result.status !== 0 && !options.optional) {
@@ -125,9 +140,15 @@ function installGatewayAutostart(options = {}) {
125
140
  const platform = options.platform || process.platform;
126
141
  if (platform === 'win32') {
127
142
  const file = options.file || getWindowsStartupScriptPath(options);
143
+ const runner = options.runner || spawnSync;
144
+ const port = options.port || 18080;
145
+ const wasRunning = isWindowsPortListening(runner, port);
128
146
  fs.mkdirSync(path.dirname(file), { recursive: true });
129
147
  fs.writeFileSync(file, buildWindowsGatewayStartupScript(options), 'utf8');
130
- return { result: 'installed', file };
148
+ const started = !wasRunning && options.startNow !== false
149
+ ? startWindowsGateway(options)
150
+ : false;
151
+ return { result: 'installed', file, started };
131
152
  }
132
153
 
133
154
  if (platform !== 'darwin') {
@@ -211,6 +232,7 @@ module.exports = {
211
232
  GATEWAY_LAUNCH_AGENT_LABEL,
212
233
  buildMacLaunchAgentPlist,
213
234
  buildWindowsGatewayStartupScript,
235
+ startWindowsGateway,
214
236
  getGatewayAutostartStatus,
215
237
  getMacLaunchAgentPath,
216
238
  getWindowsStartupScriptPath,
package/lib/config.js CHANGED
@@ -8,7 +8,6 @@ const WINDOWS_ENV_LABEL = 'Windows 用户环境变量';
8
8
  const CLAUDE_ENV_KEYS = [
9
9
  'ANTHROPIC_BASE_URL',
10
10
  'ANTHROPIC_AUTH_TOKEN',
11
- 'ANTHROPIC_API_KEY',
12
11
  'ANTHROPIC_MODEL',
13
12
  'ANTHROPIC_DEFAULT_OPUS_MODEL',
14
13
  'ANTHROPIC_DEFAULT_SONNET_MODEL',
@@ -16,6 +15,10 @@ const CLAUDE_ENV_KEYS = [
16
15
  'CLAUDE_CODE_SUBAGENT_MODEL',
17
16
  'CLAUDE_CODE_EFFORT_LEVEL',
18
17
  ];
18
+ const LEGACY_CLAUDE_ENV_KEYS = [
19
+ 'ANTHROPIC_API_KEY',
20
+ ];
21
+ const CLEAR_CLAUDE_ENV_KEYS = [...new Set([...CLAUDE_ENV_KEYS, ...LEGACY_CLAUDE_ENV_KEYS])];
19
22
 
20
23
  const PROVIDERS = {
21
24
  deepseek: {
@@ -266,7 +269,6 @@ function buildClaudeEnv({ provider, baseUrl, apiKey, model, fastModel }) {
266
269
  return {
267
270
  ANTHROPIC_BASE_URL: baseUrl,
268
271
  ANTHROPIC_AUTH_TOKEN: apiKey,
269
- ANTHROPIC_API_KEY: apiKey,
270
272
  ANTHROPIC_MODEL: model,
271
273
  ANTHROPIC_DEFAULT_OPUS_MODEL: model,
272
274
  ANTHROPIC_DEFAULT_SONNET_MODEL: model,
@@ -284,7 +286,7 @@ function buildWindowsSetEnvCommands(env) {
284
286
  }
285
287
 
286
288
  function buildWindowsClearEnvCommands() {
287
- return CLAUDE_ENV_KEYS.map((key) => ({
289
+ return CLEAR_CLAUDE_ENV_KEYS.map((key) => ({
288
290
  command: 'reg',
289
291
  args: ['delete', 'HKCU\\Environment', '/V', key, '/F'],
290
292
  }));
@@ -354,7 +356,6 @@ function buildEnvBlock(baseUrl, apiKey, model, fastModel) {
354
356
  '# clawai-start',
355
357
  `export ANTHROPIC_BASE_URL=${shellQuote(env.ANTHROPIC_BASE_URL)}`,
356
358
  `export ANTHROPIC_AUTH_TOKEN=${shellQuote(env.ANTHROPIC_AUTH_TOKEN)}`,
357
- `export ANTHROPIC_API_KEY=${shellQuote(env.ANTHROPIC_API_KEY)}`,
358
359
  `export ANTHROPIC_MODEL=${shellQuote(env.ANTHROPIC_MODEL)}`,
359
360
  `export ANTHROPIC_DEFAULT_OPUS_MODEL=${shellQuote(env.ANTHROPIC_DEFAULT_OPUS_MODEL)}`,
360
361
  `export ANTHROPIC_DEFAULT_SONNET_MODEL=${shellQuote(env.ANTHROPIC_DEFAULT_SONNET_MODEL)}`,
@@ -372,6 +373,7 @@ function writeEnvToZshrc(baseUrl, apiKey, model, fastModel, options = {}) {
372
373
  if (platform === 'win32') {
373
374
  const provider = providerKeyFromBaseUrl(baseUrl);
374
375
  const env = buildClaudeEnv({ provider, baseUrl, apiKey, model, fastModel });
376
+ runWindowsEnvCommands(buildWindowsClearEnvCommands(), options.runner || spawnSync, { ignoreErrors: true });
375
377
  runWindowsEnvCommands(buildWindowsSetEnvCommands(env), options.runner || spawnSync);
376
378
  return { result: 'updated', file: WINDOWS_ENV_LABEL };
377
379
  }
@@ -467,4 +469,5 @@ module.exports = {
467
469
  PROVIDERS,
468
470
  CONFIG_FILE,
469
471
  CLAUDE_ENV_KEYS,
472
+ CLEAR_CLAUDE_ENV_KEYS,
470
473
  };
package/lib/desktop.js CHANGED
@@ -363,11 +363,27 @@ function buildClaudeDesktopOpenCommands(platform = process.platform, options = {
363
363
  const localAppData = options.localAppData
364
364
  || process.env.LOCALAPPDATA
365
365
  || `${options.homeDir || os.homedir()}\\AppData\\Local`;
366
- const claudeDir = `${localAppData}\\AnthropicClaude`;
367
- // taskkill /T 连带杀子进程;start "" /D 切到 Claude 目录后启动 Claude.exe(Squirrel 标准安装位置)
366
+ const fileExists = options.fileExists || fs.existsSync;
367
+ const exeCandidates = [
368
+ `${localAppData}\\Programs\\Claude\\Claude.exe`,
369
+ `${localAppData}\\AnthropicClaude\\Claude.exe`,
370
+ ];
371
+ const updateCandidates = [
372
+ `${localAppData}\\AnthropicClaude\\Update.exe`,
373
+ `${localAppData}\\Programs\\Claude\\Update.exe`,
374
+ ];
375
+ const foundExe = exeCandidates.find((file) => fileExists(file));
376
+ const foundUpdate = foundExe ? null : updateCandidates.find((file) => fileExists(file));
377
+ const fallbackDir = `${localAppData}\\AnthropicClaude`;
378
+ const launchCommand = foundExe
379
+ ? { command: 'cmd', args: ['/c', 'start', '', '/D', path.win32.dirname(foundExe), 'Claude.exe'], optional: true, waitAfter: 800 }
380
+ : foundUpdate
381
+ ? { command: foundUpdate, args: ['--processStart', 'Claude.exe'], optional: true, waitAfter: 800 }
382
+ : { command: 'cmd', args: ['/c', 'start', '', '/D', fallbackDir, 'Claude.exe'], optional: true, waitAfter: 800 };
383
+ // taskkill /T 连带杀子进程;启动路径按实际安装位置选择,找不到时保留旧的 Squirrel 目录兜底
368
384
  return [
369
385
  { command: 'taskkill', args: ['/IM', 'Claude.exe', '/F', '/T'], optional: true, waitAfter: 1500 },
370
- { command: 'cmd', args: ['/c', 'start', '', '/D', claudeDir, 'Claude.exe'], optional: true, waitAfter: 800 },
386
+ launchCommand,
371
387
  ];
372
388
  }
373
389
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yingclaw",
3
- "version": "2.5.12",
3
+ "version": "2.5.14",
4
4
  "description": "Claude Code × 国产大模型一键接入:DeepSeek、Kimi、Qwen、MiniMax、GLM、MiMo",
5
5
  "main": "index.js",
6
6
  "bin": {