aihezu 2.3.2 → 2.3.4
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/bin/aihezu.js +10 -0
- package/commands/ccusage.js +52 -28
- package/package.json +1 -1
package/bin/aihezu.js
CHANGED
|
@@ -28,6 +28,16 @@ function showHelp() {
|
|
|
28
28
|
console.log(' claude Claude Code');
|
|
29
29
|
console.log(' codex Codex');
|
|
30
30
|
console.log(' gemini Google Gemini');
|
|
31
|
+
console.log('\n配置文件与环境变量:');
|
|
32
|
+
console.log(' Claude Code:');
|
|
33
|
+
console.log(' 配置文件: ~/.claude/settings.json');
|
|
34
|
+
console.log(' 环境变量: ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL');
|
|
35
|
+
console.log(' Codex:');
|
|
36
|
+
console.log(' 配置文件: ~/.codex/config.toml, ~/.codex/auth.json');
|
|
37
|
+
console.log(' 环境变量: AIHEZU_OAI_KEY');
|
|
38
|
+
console.log(' Google Gemini:');
|
|
39
|
+
console.log(' 配置文件: ~/.gemini/.env, ~/.gemini/settings.json (可选)');
|
|
40
|
+
console.log(' 环境变量: GEMINI_API_KEY, GOOGLE_GEMINI_BASE_URL');
|
|
31
41
|
console.log('\n示例:');
|
|
32
42
|
console.log(' aihezu install claude');
|
|
33
43
|
console.log(' aihezu clear codex');
|
package/commands/ccusage.js
CHANGED
|
@@ -122,8 +122,8 @@ function usageHint(current, limit) {
|
|
|
122
122
|
const l = asNumber(limit);
|
|
123
123
|
if (c === null || l === null || l <= 0) return '';
|
|
124
124
|
const ratio = c / l;
|
|
125
|
-
if (ratio >= 1) return '
|
|
126
|
-
if (ratio >= 0.9) return '
|
|
125
|
+
if (ratio >= 1) return '[!] 已超出限制';
|
|
126
|
+
if (ratio >= 0.9) return '[!] 接近上限';
|
|
127
127
|
return '';
|
|
128
128
|
}
|
|
129
129
|
|
|
@@ -148,31 +148,31 @@ async function ccusageCommand(args = []) {
|
|
|
148
148
|
|
|
149
149
|
const outputJson = args.includes('--json');
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
// 读取环境变量
|
|
152
|
+
const envBaseUrl = process.env.ANTHROPIC_BASE_URL || '';
|
|
153
|
+
const envAuthToken = process.env.ANTHROPIC_AUTH_TOKEN || '';
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (env) {
|
|
163
|
-
baseUrl = baseUrl || env.ANTHROPIC_BASE_URL || '';
|
|
164
|
-
authToken = authToken || env.ANTHROPIC_AUTH_TOKEN || '';
|
|
165
|
-
sourceHint = `配置文件 (${settingsPath})`;
|
|
166
|
-
}
|
|
155
|
+
// 读取配置文件
|
|
156
|
+
const { env: fileEnv, settingsPath, error } = readClaudeEnvFromSettingsFile();
|
|
157
|
+
if (error) {
|
|
158
|
+
console.log(`[WARN] 读取配置文件失败: ${settingsPath}`);
|
|
159
|
+
console.log(` 错误: ${error.message}`);
|
|
167
160
|
}
|
|
168
161
|
|
|
162
|
+
const fileBaseUrl = fileEnv?.ANTHROPIC_BASE_URL || '';
|
|
163
|
+
const fileAuthToken = fileEnv?.ANTHROPIC_AUTH_TOKEN || '';
|
|
164
|
+
|
|
165
|
+
// 确定最终使用的配置(环境变量优先)
|
|
166
|
+
let baseUrl = envBaseUrl || fileBaseUrl;
|
|
167
|
+
let authToken = envAuthToken || fileAuthToken;
|
|
168
|
+
|
|
169
169
|
baseUrl = normalizeHttpUrl(baseUrl);
|
|
170
170
|
authToken = String(authToken || '').trim();
|
|
171
171
|
|
|
172
172
|
if (!baseUrl || !authToken) {
|
|
173
|
-
console.error('
|
|
174
|
-
console.error('
|
|
175
|
-
console.error('
|
|
173
|
+
console.error('[ERROR] 未找到 ANTHROPIC_BASE_URL 或 ANTHROPIC_AUTH_TOKEN。');
|
|
174
|
+
console.error(' 请先运行: npx aihezu install claude');
|
|
175
|
+
console.error(' 或设置环境变量: ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN');
|
|
176
176
|
process.exit(1);
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -180,7 +180,7 @@ async function ccusageCommand(args = []) {
|
|
|
180
180
|
try {
|
|
181
181
|
origin = new URL(baseUrl).origin;
|
|
182
182
|
} catch (error) {
|
|
183
|
-
console.error('
|
|
183
|
+
console.error('[ERROR] ANTHROPIC_BASE_URL 不是合法的 URL: ' + baseUrl);
|
|
184
184
|
process.exit(1);
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -188,14 +188,38 @@ async function ccusageCommand(args = []) {
|
|
|
188
188
|
const statsUrl = `${origin}/apiStats/api/user-stats`;
|
|
189
189
|
|
|
190
190
|
console.log('');
|
|
191
|
-
console.log('
|
|
192
|
-
console.log(
|
|
193
|
-
console.log(
|
|
191
|
+
console.log('=== Claude Code 用量统计 ===');
|
|
192
|
+
console.log(`域名: ${origin}`);
|
|
193
|
+
console.log('');
|
|
194
|
+
|
|
195
|
+
// 展示配置来源详情
|
|
196
|
+
console.log('=== 配置来源 ===');
|
|
197
|
+
|
|
198
|
+
// 环境变量
|
|
199
|
+
console.log('环境变量:');
|
|
200
|
+
console.log(` ANTHROPIC_BASE_URL: ${envBaseUrl || '(未设置)'}`);
|
|
201
|
+
console.log(` ANTHROPIC_AUTH_TOKEN: ${envAuthToken ? '***' + envAuthToken.slice(-8) : '(未设置)'}`);
|
|
202
|
+
|
|
203
|
+
// 配置文件
|
|
204
|
+
console.log('配置文件 (~/.claude/settings.json):');
|
|
205
|
+
if (error) {
|
|
206
|
+
console.log(` 状态: 读取失败 - ${error.message}`);
|
|
207
|
+
} else if (!fileEnv) {
|
|
208
|
+
console.log(` 状态: 文件不存在或无 env 字段`);
|
|
209
|
+
} else {
|
|
210
|
+
console.log(` ANTHROPIC_BASE_URL: ${fileBaseUrl || '(未设置)'}`);
|
|
211
|
+
console.log(` ANTHROPIC_AUTH_TOKEN: ${fileAuthToken ? '***' + fileAuthToken.slice(-8) : '(未设置)'}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// 最终使用的配置
|
|
215
|
+
console.log('最终使用:');
|
|
216
|
+
console.log(` BASE_URL: ${baseUrl} ${envBaseUrl ? '[环境变量]' : '[配置文件]'}`);
|
|
217
|
+
console.log(` AUTH_TOKEN: ***${authToken.slice(-8)} ${envAuthToken ? '[环境变量]' : '[配置文件]'}`);
|
|
194
218
|
console.log('');
|
|
195
219
|
|
|
196
220
|
const keyIdRes = await postJson(keyIdUrl, { apiKey: authToken });
|
|
197
221
|
if (keyIdRes.statusCode < 200 || keyIdRes.statusCode >= 300) {
|
|
198
|
-
console.error(
|
|
222
|
+
console.error(`[ERROR] 获取 API Key ID 失败 (HTTP ${keyIdRes.statusCode})`);
|
|
199
223
|
if (keyIdRes.raw) console.error(keyIdRes.raw);
|
|
200
224
|
process.exit(1);
|
|
201
225
|
}
|
|
@@ -206,20 +230,20 @@ async function ccusageCommand(args = []) {
|
|
|
206
230
|
null;
|
|
207
231
|
|
|
208
232
|
if (!apiId) {
|
|
209
|
-
console.error('
|
|
233
|
+
console.error('[ERROR] 返回值中未找到 API Key ID。');
|
|
210
234
|
if (keyIdRes.raw) console.error(keyIdRes.raw);
|
|
211
235
|
process.exit(1);
|
|
212
236
|
}
|
|
213
237
|
|
|
214
238
|
const statsRes = await postJson(statsUrl, { apiId });
|
|
215
239
|
if (statsRes.statusCode < 200 || statsRes.statusCode >= 300) {
|
|
216
|
-
console.error(
|
|
240
|
+
console.error(`[ERROR] 获取用量失败 (HTTP ${statsRes.statusCode})`);
|
|
217
241
|
if (statsRes.raw) console.error(statsRes.raw);
|
|
218
242
|
process.exit(1);
|
|
219
243
|
}
|
|
220
244
|
|
|
221
245
|
if (!statsRes.json || typeof statsRes.json !== 'object') {
|
|
222
|
-
console.error('
|
|
246
|
+
console.error('[ERROR] 获取用量失败:返回内容不是合法的 JSON。');
|
|
223
247
|
if (statsRes.raw) console.error(statsRes.raw);
|
|
224
248
|
process.exit(1);
|
|
225
249
|
}
|