yymaxapi 1.0.118 → 1.0.120

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
@@ -16,7 +16,7 @@ npx yymaxapi@latest
16
16
  npx yymaxapi@latest speed-test
17
17
  ```
18
18
  或在具体配置命令后追加 `--speed-test`,按测速结果手动选点。
19
- 如需直接切换到其他云翼域名,可在预设/一键激活命令后追加 `--endpoint-url https://yunyi.cfd`,也兼容 `--base-url https://你的域名/claude` 这种写法。
19
+ 如需直接切换到其他云翼域名,可在预设/一键激活命令后追加 `--endpoint-url https://yunyi.yun`,也兼容 `--base-url https://你的域名/claude` 这种写法。
20
20
 
21
21
  **方式二:一键配置 Claude**
22
22
  ```bash
package/bin/yymaxapi.js CHANGED
@@ -1646,12 +1646,18 @@ function invalidateGatewayEnvCache() {
1646
1646
  function isWslAvailable() {
1647
1647
  if (process.platform !== 'win32') return false;
1648
1648
  if (_wslAvailCache !== null) return _wslAvailCache;
1649
- try {
1650
- execFileSync('wsl', ['echo', 'ok'], { encoding: 'utf8', timeout: 5000, stdio: 'pipe' });
1651
- _wslAvailCache = true;
1652
- } catch {
1653
- _wslAvailCache = false;
1649
+ const probes = [
1650
+ 'wsl -- echo ok',
1651
+ 'wsl -u root -- echo ok'
1652
+ ];
1653
+ for (const cmd of probes) {
1654
+ const result = safeExec(cmd, { timeout: 5000 });
1655
+ if (result.ok && String(result.output || result.stdout || '').includes('ok')) {
1656
+ _wslAvailCache = true;
1657
+ return _wslAvailCache;
1658
+ }
1654
1659
  }
1660
+ _wslAvailCache = false;
1655
1661
  return _wslAvailCache;
1656
1662
  }
1657
1663
 
@@ -3840,7 +3846,7 @@ function scoreHermesWslCandidate(candidate) {
3840
3846
  }
3841
3847
 
3842
3848
  function getHermesWslMirrorInfo(options = {}) {
3843
- if (process.platform !== 'win32' || !isWslAvailable()) {
3849
+ if (process.platform !== 'win32') {
3844
3850
  return {
3845
3851
  dataDir: null,
3846
3852
  sourceConfigPath: null,
@@ -3886,7 +3892,8 @@ function getHermesWslMirrorInfo(options = {}) {
3886
3892
  sourceConfigPath,
3887
3893
  configPath: candidate.configPath,
3888
3894
  envPath: candidate.envPath,
3889
- target: candidate.target
3895
+ target: candidate.target,
3896
+ commandPath: selected?.commandPath || probeHermesWslCommand(candidate.target)
3890
3897
  };
3891
3898
  }
3892
3899
 
@@ -4109,6 +4116,36 @@ function readHermesCliConfig() {
4109
4116
  };
4110
4117
  }
4111
4118
 
4119
+ function buildHermesCliConfigFromRaw(configRaw, envRaw, configPath = '', envPath = '') {
4120
+ const parsed = parseSimpleYamlConfig(configRaw);
4121
+ const envEntries = parseEnvFile(envRaw);
4122
+ const modelConfig = parsed?.model && typeof parsed.model === 'object' ? parsed.model : {};
4123
+ const modelId = String(modelConfig.default || '').trim() || getDefaultClaudeModel().id;
4124
+ const provider = String(modelConfig.provider || '').trim().toLowerCase();
4125
+ const type = resolveHermesModelType(modelId, provider);
4126
+ const apiKey = type === 'codex'
4127
+ ? (envEntries.OPENAI_API_KEY || '')
4128
+ : (envEntries.ANTHROPIC_API_KEY || envEntries.ANTHROPIC_TOKEN || '');
4129
+
4130
+ return {
4131
+ configPath,
4132
+ envPath,
4133
+ configured: !!configRaw || !!envRaw,
4134
+ modelId,
4135
+ provider,
4136
+ type,
4137
+ baseUrl: String(modelConfig.base_url || '').trim(),
4138
+ apiKey
4139
+ };
4140
+ }
4141
+
4142
+ function readHermesWslCliConfig(wslMirror = getHermesWslMirrorInfo()) {
4143
+ const configPath = wslMirror.sourceConfigPath || wslMirror.configPath;
4144
+ const configRaw = readWslTextFile(configPath, wslMirror.target);
4145
+ const envRaw = readWslTextFile(wslMirror.envPath, wslMirror.target);
4146
+ return buildHermesCliConfigFromRaw(configRaw, envRaw, configPath, wslMirror.envPath);
4147
+ }
4148
+
4112
4149
  function getOpencodeConfigPath() {
4113
4150
  const home = os.homedir();
4114
4151
  return process.platform === 'win32'
@@ -4368,6 +4405,9 @@ function testCodexCliConnection() {
4368
4405
 
4369
4406
  function testHermesCliConnection() {
4370
4407
  const cliBinary = resolveCommandBinary('hermes');
4408
+ if (!cliBinary && process.platform === 'win32') {
4409
+ return testHermesWslCliConnection();
4410
+ }
4371
4411
  if (!cliBinary) return { name: 'Hermes CLI', status: 'skipped', detail: '未安装 hermes 命令' };
4372
4412
 
4373
4413
  const config = readHermesCliConfig();
@@ -4413,6 +4453,40 @@ function testHermesCliConnection() {
4413
4453
  };
4414
4454
  }
4415
4455
 
4456
+ function testHermesWslCliConnection() {
4457
+ const wslMirror = getHermesWslMirrorInfo();
4458
+ const commandPath = wslMirror.commandPath || probeHermesWslCommand(wslMirror.target || {});
4459
+ if (!commandPath) return { name: 'Hermes CLI (WSL)', status: 'skipped', detail: '未检测到 WSL 内 hermes 命令' };
4460
+
4461
+ const config = readHermesWslCliConfig(wslMirror);
4462
+ if (!config.configured) return { name: 'Hermes CLI (WSL)', status: 'skipped', detail: '未检测到 WSL ~/.hermes/config.yaml 或 ~/.hermes/.env' };
4463
+ if (!config.apiKey) return { name: 'Hermes CLI (WSL)', status: 'failed', detail: 'Hermes 配置缺少 API Key' };
4464
+
4465
+ const providerArg = config.provider === 'anthropic' ? ' --provider anthropic' : '';
4466
+ const command = [
4467
+ `export HERMES_HOME=${shellQuote(wslMirror.dataDir)}`,
4468
+ 'export NODE_TLS_REJECT_UNAUTHORIZED=0',
4469
+ 'export NODE_NO_WARNINGS=1',
4470
+ 'set -a',
4471
+ `[ -f "$HERMES_HOME/.env" ] && . "$HERMES_HOME/.env"`,
4472
+ 'set +a',
4473
+ `${shellQuote(commandPath)} chat -Q -q ${shellQuote('请只回复 OK')}${providerArg}`
4474
+ ].join('; ');
4475
+ const result = runWslCommand(command, { timeout: 120000, maxBuffer: 1024 * 1024 }, { ...(wslMirror.target || {}), login: true });
4476
+ const combined = cleanCliTestOutput(`${result.output || ''}\n${result.stdout || ''}\n${result.stderr || ''}`);
4477
+ const reply = extractHermesCliReply(combined);
4478
+
4479
+ if (result.ok && /^OK$/i.test(reply) && !looksLikeCliTestError(combined)) {
4480
+ return { name: 'Hermes CLI (WSL)', status: 'success', detail: 'OK' };
4481
+ }
4482
+
4483
+ return {
4484
+ name: 'Hermes CLI (WSL)',
4485
+ status: 'failed',
4486
+ detail: reply || summarizeCliTestOutput(combined) || result.error || '命令执行失败'
4487
+ };
4488
+ }
4489
+
4416
4490
  async function testAdditionalCliConnections(args = {}, options = {}) {
4417
4491
  if (args['no-app-test'] || args.noAppTest) return;
4418
4492
 
@@ -13,8 +13,8 @@
13
13
  ```json5
14
14
  {
15
15
  "endpoints": [
16
- { "name": "默认主节点", "url": "https://yunyi.cfd" },
17
- { "name": "CF国外节点1", "url": "https://cdn2.yunyi.cfd" }
16
+ { "name": "默认主节点", "url": "https://yunyi.yun" },
17
+ { "name": "CF国外节点1", "url": "https://cdn2.yunyi.yun" }
18
18
  ],
19
19
  "fallbackEndpoints": [
20
20
  { "name": "备用节点1", "url": "http://47.99.42.193" },
@@ -75,7 +75,7 @@ npx yymaxapi@latest
75
75
  ```json
76
76
  {
77
77
  "provider": "anthropic",
78
- "base_url": "https://yunyi.cfd/claude",
78
+ "base_url": "https://yunyi.yun/claude",
79
79
  "api": "anthropic-messages",
80
80
  "api_key": "<你的云翼 API Key>",
81
81
  "model": {
@@ -90,7 +90,7 @@ npx yymaxapi@latest
90
90
  ```json
91
91
  {
92
92
  "provider": "openai",
93
- "base_url": "https://yunyi.cfd/codex",
93
+ "base_url": "https://yunyi.yun/codex",
94
94
  "api": "openai-completions",
95
95
  "api_key": "<你的云翼 API Key>",
96
96
  "model": {
@@ -121,7 +121,7 @@ npx yymaxapi@latest
121
121
  ```json
122
122
  {
123
123
  "provider": "anthropic",
124
- "base_url": "https://yunyi.cfd/claude",
124
+ "base_url": "https://yunyi.yun/claude",
125
125
  "api": "anthropic-messages",
126
126
  "api_key": "<你的云翼 API Key>",
127
127
  "model": {
@@ -136,7 +136,7 @@ npx yymaxapi@latest
136
136
  ```json
137
137
  {
138
138
  "provider": "openai",
139
- "base_url": "https://yunyi.cfd/codex",
139
+ "base_url": "https://yunyi.yun/codex",
140
140
  "api": "openai-completions",
141
141
  "api_key": "<你的云翼 API Key>",
142
142
  "model": {
@@ -152,10 +152,10 @@ npx yymaxapi@latest
152
152
 
153
153
  ```json
154
154
  {
155
- "apiBaseUrl": "https://yunyi.cfd/claude",
155
+ "apiBaseUrl": "https://yunyi.yun/claude",
156
156
  "env": {
157
157
  "ANTHROPIC_API_KEY": "<你的云翼 API Key>",
158
- "ANTHROPIC_BASE_URL": "https://yunyi.cfd/claude"
158
+ "ANTHROPIC_BASE_URL": "https://yunyi.yun/claude"
159
159
  }
160
160
  }
161
161
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yymaxapi",
3
- "version": "1.0.118",
3
+ "version": "1.0.120",
4
4
  "description": "跨平台 OpenClaw/Clawdbot 配置管理工具 - 管理中转地址、模型切换、API Keys、测速优化",
5
5
  "main": "bin/yymaxapi.js",
6
6
  "bin": {