@simonyea/holysheep-cli 2.1.40 → 2.1.42

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.
Files changed (45) hide show
  1. package/dist/configure-worker.js +4510 -0
  2. package/dist/index.js +9610 -0
  3. package/dist/process-proxy-inject.js +117 -0
  4. package/package.json +19 -6
  5. package/.gitea/workflows/sanity.yml +0 -125
  6. package/scripts/check-tarball-size.js +0 -44
  7. package/src/commands/balance.js +0 -57
  8. package/src/commands/claude-proxy.js +0 -248
  9. package/src/commands/claude.js +0 -135
  10. package/src/commands/doctor.js +0 -282
  11. package/src/commands/login.js +0 -211
  12. package/src/commands/openclaw.js +0 -258
  13. package/src/commands/reset.js +0 -53
  14. package/src/commands/setup.js +0 -493
  15. package/src/commands/upgrade.js +0 -168
  16. package/src/commands/webui.js +0 -622
  17. package/src/index.js +0 -226
  18. package/src/tools/aider.js +0 -78
  19. package/src/tools/antigravity.js +0 -42
  20. package/src/tools/claude-code.js +0 -228
  21. package/src/tools/claude-process-proxy.js +0 -1030
  22. package/src/tools/codex.js +0 -254
  23. package/src/tools/continue.js +0 -146
  24. package/src/tools/cursor.js +0 -71
  25. package/src/tools/droid.js +0 -281
  26. package/src/tools/env-config.js +0 -185
  27. package/src/tools/gemini-cli.js +0 -82
  28. package/src/tools/hermes.js +0 -354
  29. package/src/tools/index.js +0 -13
  30. package/src/tools/openclaw-bridge.js +0 -987
  31. package/src/tools/openclaw.js +0 -925
  32. package/src/tools/opencode.js +0 -227
  33. package/src/tools/process-proxy-inject.js +0 -142
  34. package/src/utils/config.js +0 -54
  35. package/src/utils/shell.js +0 -342
  36. package/src/utils/which.js +0 -176
  37. package/src/webui/aionui-runtime-fetcher.js +0 -429
  38. package/src/webui/aionui-runtime.js +0 -139
  39. package/src/webui/aionui-wrapper.js +0 -734
  40. package/src/webui/configure-worker.js +0 -67
  41. package/src/webui/server.js +0 -1572
  42. package/src/webui/workspace-runtime.js +0 -288
  43. package/src/webui/workspace-store.js +0 -325
  44. /package/{src/webui → dist}/index.html +0 -0
  45. /package/{src/tools → dist}/pty-hermes-wrapper.py +0 -0
@@ -1,281 +0,0 @@
1
- /**
2
- * Droid CLI 适配器
3
- * 配置文件: ~/.factory/settings.json
4
- *
5
- * 使用 Droid 原生 customModels 配置 HolySheep 的多个模型入口:
6
- * - GPT 走 OpenAI 兼容入口: https://api.holysheep.ai/v1
7
- * - Claude 走 Anthropic 入口: https://api.holysheep.ai
8
- * - MiniMax 走 Anthropic 入口: https://api.holysheep.ai/minimax
9
- *
10
- * Droid 的 GPT-5+ BYOK 校验要求 provider=openai。
11
- * Droid 当前会把这类模型发到 /responses,因此 baseUrl 仍然必须是
12
- * https://api.holysheep.ai/v1,并依赖服务端将 gpt-5.4 的 Responses 请求
13
- * 兼容桥接到 /v1/chat/completions。
14
- */
15
- const fs = require('fs')
16
- const path = require('path')
17
- const os = require('os')
18
-
19
- const CONFIG_DIR = path.join(os.homedir(), '.factory')
20
- const SETTINGS_FILE = path.join(CONFIG_DIR, 'settings.json')
21
- const LEGACY_CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
22
-
23
- // Platform-specific install command. Windows previously read the macOS-only
24
- // `brew install --cask droid` which always fails on fresh Win10/11 boxes —
25
- // users reported this explicitly in 2.1.12/13. Factory ships an official
26
- // winget package; Linux gets the official shell installer. macOS keeps brew.
27
- function installCmdForPlatform() {
28
- if (process.platform === 'win32') {
29
- return 'winget install --id Factory.Droid -e --accept-source-agreements --accept-package-agreements'
30
- }
31
- if (process.platform === 'darwin') {
32
- return 'brew install --cask droid'
33
- }
34
- // Linux — Factory's official installer supports Linux amd64/arm64.
35
- return 'curl -fsSL https://app.factory.ai/install.sh | bash'
36
- }
37
-
38
- const DEFAULT_MODELS = [
39
- {
40
- model: 'gpt-5.4',
41
- id: 'custom:gpt-5.4-0',
42
- baseUrlSuffix: '',
43
- displayName: 'GPT-5.4',
44
- provider: 'openai',
45
- route: 'openai',
46
- },
47
- {
48
- model: 'claude-sonnet-4-6',
49
- id: 'custom:claude-sonnet-4-6-0',
50
- baseUrlSuffix: '',
51
- displayName: 'Sonnet 4.6',
52
- provider: 'anthropic',
53
- route: 'anthropic',
54
- },
55
- {
56
- model: 'claude-opus-4-6',
57
- id: 'custom:claude-opus-4-6-0',
58
- baseUrlSuffix: '',
59
- displayName: 'Opus 4.6',
60
- provider: 'anthropic',
61
- route: 'anthropic',
62
- },
63
- {
64
- model: 'MiniMax-M2.7-highspeed',
65
- id: 'custom:MiniMax-M2.7-highspeed-0',
66
- baseUrlSuffix: '/minimax',
67
- displayName: 'MiniMax 2.7 Highspeed',
68
- provider: 'anthropic',
69
- route: 'anthropic',
70
- },
71
- {
72
- model: 'claude-haiku-4-5',
73
- id: 'custom:claude-haiku-4-5-0',
74
- baseUrlSuffix: '',
75
- displayName: 'Haiku 4.5',
76
- provider: 'anthropic',
77
- route: 'anthropic',
78
- },
79
- ]
80
-
81
- function readSettings() {
82
- try {
83
- if (fs.existsSync(SETTINGS_FILE)) {
84
- return JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf8'))
85
- }
86
- } catch {}
87
- return {}
88
- }
89
-
90
- function writeSettings(data) {
91
- fs.mkdirSync(CONFIG_DIR, { recursive: true })
92
- fs.writeFileSync(SETTINGS_FILE, JSON.stringify(data, null, 2), 'utf8')
93
- }
94
-
95
- function readLegacyConfig() {
96
- try {
97
- if (fs.existsSync(LEGACY_CONFIG_FILE)) {
98
- return JSON.parse(fs.readFileSync(LEGACY_CONFIG_FILE, 'utf8'))
99
- }
100
- } catch {}
101
- return {}
102
- }
103
-
104
- function writeLegacyConfig(data) {
105
- fs.mkdirSync(CONFIG_DIR, { recursive: true })
106
- fs.writeFileSync(LEGACY_CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8')
107
- }
108
-
109
- function isHolySheepModel(item) {
110
- return typeof item?.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai')
111
- }
112
-
113
- function normalizeSelectedModels(selectedModels) {
114
- const selected = new Set(
115
- Array.isArray(selectedModels) && selectedModels.length > 0
116
- ? selectedModels
117
- : DEFAULT_MODELS.map((item) => item.model)
118
- )
119
- const models = DEFAULT_MODELS.filter((item) => selected.has(item.model)).map((item, index) => ({
120
- model: item.model,
121
- id: item.id,
122
- index,
123
- baseUrlSuffix: item.baseUrlSuffix,
124
- displayName: item.displayName,
125
- provider: item.provider,
126
- route: item.route,
127
- }))
128
-
129
- return models.length > 0 ? models : DEFAULT_MODELS.map((item, index) => ({ ...item, index }))
130
- }
131
-
132
- function buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels) {
133
- const anthropicRootUrl = String(baseUrlAnthropic || '').replace(/\/+$/, '')
134
- const openaiRootUrl = String(baseUrlOpenAI || '').replace(/\/+$/, '')
135
- return normalizeSelectedModels(selectedModels).map((item) => ({
136
- model: item.model,
137
- id: item.id,
138
- index: item.index,
139
- baseUrl:
140
- item.route === 'openai'
141
- ? `${openaiRootUrl}${item.baseUrlSuffix}`
142
- : `${anthropicRootUrl}${item.baseUrlSuffix}`,
143
- apiKey,
144
- displayName: item.displayName,
145
- maxOutputTokens: 64000,
146
- noImageSupport: true,
147
- provider: item.provider,
148
- }))
149
- }
150
-
151
- module.exports = {
152
- name: 'Droid CLI',
153
- id: 'droid',
154
- checkInstalled() {
155
- return require('../utils/which').commandExists('droid')
156
- },
157
- isConfigured() {
158
- const settings = readSettings()
159
- const customModels = Array.isArray(settings.customModels) ? settings.customModels : []
160
- if (customModels.some(isHolySheepModel)) return true
161
-
162
- const legacy = readLegacyConfig()
163
- const legacyModels = Array.isArray(legacy.customModels) ? legacy.customModels : []
164
- return legacyModels.some(isHolySheepModel)
165
- },
166
- configure(apiKey, baseUrlAnthropic, baseUrlOpenAI, _primaryModel, selectedModels) {
167
- const nextModels = buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels)
168
-
169
- // [HolySheep fork v2.1.19] Pick a preferred default model. Droid CLI hardcodes
170
- // `claude-opus-4-6` as the default when `sessionDefaultSettings.model` is
171
- // absent, and HolySheep upstream often has no opus accounts available —
172
- // producing "503 No available Claude accounts support claude-opus-4-6" in
173
- // hs web. Prefer sonnet-4-6 when present; fall back to the first HolySheep
174
- // model so the user at least lands on a working route.
175
- const preferredDefault =
176
- nextModels.find((m) => m.id === 'custom:claude-sonnet-4-6-0') ||
177
- nextModels.find((m) => /sonnet/i.test(m.model)) ||
178
- nextModels[0]
179
- const defaultModelId = preferredDefault ? preferredDefault.id : null
180
-
181
- const settings = readSettings()
182
- const preservedModels = Array.isArray(settings.customModels)
183
- ? settings.customModels.filter((item) => !isHolySheepModel(item))
184
- : []
185
- settings.customModels = [
186
- ...nextModels,
187
- ...preservedModels,
188
- ]
189
- settings.logoAnimation = 'off'
190
- if (defaultModelId) {
191
- settings.sessionDefaultSettings = {
192
- ...(settings.sessionDefaultSettings || {}),
193
- model: defaultModelId,
194
- }
195
- }
196
- writeSettings(settings)
197
-
198
- const legacy = readLegacyConfig()
199
- const preservedLegacyModels = Array.isArray(legacy.customModels)
200
- ? legacy.customModels.filter((item) => !isHolySheepModel(item))
201
- : []
202
- legacy.customModels = [
203
- ...nextModels,
204
- ...preservedLegacyModels,
205
- ]
206
- legacy.logoAnimation = 'off'
207
- if (defaultModelId) {
208
- legacy.sessionDefaultSettings = {
209
- ...(legacy.sessionDefaultSettings || {}),
210
- model: defaultModelId,
211
- }
212
- }
213
- writeLegacyConfig(legacy)
214
-
215
- // Windows: also write FACTORY_API_KEY to user env via setx so a freshly
216
- // opened PowerShell / cmd.exe picks it up without requiring the user to
217
- // manually edit env vars. Non-Windows shells don't need this because the
218
- // config.json → settings.json path already wires the key through Factory's
219
- // own auth resolution.
220
- if (process.platform === 'win32') {
221
- try {
222
- const { execSync } = require('child_process')
223
- execSync(`setx FACTORY_API_KEY "${apiKey}"`, { stdio: 'ignore', timeout: 10000 })
224
- } catch {
225
- // setx can fail in locked-down corp images; best-effort only.
226
- // The settings.json / config.json path still works inside Droid CLI itself.
227
- }
228
- }
229
-
230
- return {
231
- file: SETTINGS_FILE,
232
- hot: true,
233
- }
234
- },
235
- reset() {
236
- const settings = readSettings()
237
- // Collect ids of HolySheep customModels BEFORE filtering so we can clean
238
- // up any sessionDefaultSettings.model pointing at them.
239
- const hsIds = new Set(
240
- (Array.isArray(settings.customModels) ? settings.customModels : [])
241
- .filter(isHolySheepModel)
242
- .map((m) => m?.id)
243
- .filter(Boolean)
244
- )
245
- if (Array.isArray(settings.customModels)) {
246
- settings.customModels = settings.customModels.filter((item) => !isHolySheepModel(item))
247
- }
248
- if (
249
- settings.sessionDefaultSettings &&
250
- typeof settings.sessionDefaultSettings === 'object' &&
251
- hsIds.has(settings.sessionDefaultSettings.model)
252
- ) {
253
- delete settings.sessionDefaultSettings.model
254
- }
255
- writeSettings(settings)
256
-
257
- const legacy = readLegacyConfig()
258
- const hsLegacyIds = new Set(
259
- (Array.isArray(legacy.customModels) ? legacy.customModels : [])
260
- .filter(isHolySheepModel)
261
- .map((m) => m?.id)
262
- .filter(Boolean)
263
- )
264
- if (Array.isArray(legacy.customModels)) {
265
- legacy.customModels = legacy.customModels.filter((item) => !isHolySheepModel(item))
266
- }
267
- if (
268
- legacy.sessionDefaultSettings &&
269
- typeof legacy.sessionDefaultSettings === 'object' &&
270
- hsLegacyIds.has(legacy.sessionDefaultSettings.model)
271
- ) {
272
- delete legacy.sessionDefaultSettings.model
273
- }
274
- writeLegacyConfig(legacy)
275
- },
276
- getConfigPath() { return SETTINGS_FILE },
277
- hint: '已写入 ~/.factory/settings.json;重启 Droid 后可见 HolySheep 模型列表',
278
- launchCmd: 'droid',
279
- installCmd: installCmdForPlatform(),
280
- docsUrl: 'https://docs.factory.ai/cli/getting-started/overview',
281
- }
@@ -1,185 +0,0 @@
1
- /**
2
- * 全局环境变量适配器
3
- *
4
- * 一键将 HolySheep API 配置写入系统环境变量,
5
- * 让所有读取标准 env 的编程工具(VS Code Claude 扩展、Cursor、Continue、Cline、Windsurf 等)
6
- * 无需单独配置即可使用 HolySheep 中继。
7
- *
8
- * 写入的环境变量:
9
- * ANTHROPIC_API_KEY — Anthropic SDK 标准 key
10
- * ANTHROPIC_AUTH_TOKEN — Claude Code 优先读取
11
- * ANTHROPIC_BASE_URL — Anthropic API 基地址(不带 /v1)
12
- * OPENAI_API_KEY — OpenAI SDK 标准 key
13
- * OPENAI_BASE_URL — OpenAI API 基地址(带 /v1)
14
- *
15
- * Mac/Linux: 写入 .zshrc / .bashrc / config.fish(holysheep managed 块)
16
- * Windows: 通过 setx 写入用户级环境变量(需重启终端生效)
17
- */
18
- 'use strict'
19
-
20
- const { writeEnvToShell, removeEnvFromShell, getShellRcFiles } = require('../utils/shell')
21
- const { execSync } = require('child_process')
22
- const fs = require('fs')
23
- const path = require('path')
24
- const os = require('os')
25
-
26
- const MANAGED_KEYS = [
27
- 'ANTHROPIC_API_KEY',
28
- 'ANTHROPIC_AUTH_TOKEN',
29
- 'ANTHROPIC_BASE_URL',
30
- 'OPENAI_API_KEY',
31
- 'OPENAI_BASE_URL',
32
- ]
33
-
34
- const MARKER = '# >>> holysheep-cli managed >>>'
35
- const STATE_FILE = path.join(os.homedir(), '.holysheep', 'env-config.json')
36
-
37
- /**
38
- * Windows: 用 PowerShell 写入用户级环境变量(比 setx 更可靠)
39
- */
40
- function winSetEnvVar(key, value) {
41
- try {
42
- execSync(
43
- `powershell.exe -NoProfile -Command "[Environment]::SetEnvironmentVariable('${key}', '${value}', 'User')"`,
44
- { stdio: 'ignore', timeout: 10000, windowsHide: true }
45
- )
46
- return true
47
- } catch {
48
- return false
49
- }
50
- }
51
-
52
- /**
53
- * Windows: 用 PowerShell 删除用户级环境变量
54
- */
55
- function winRemoveEnvVar(key) {
56
- try {
57
- execSync(
58
- `powershell.exe -NoProfile -Command "[Environment]::SetEnvironmentVariable('${key}', $null, 'User')"`,
59
- { stdio: 'ignore', timeout: 10000, windowsHide: true }
60
- )
61
- } catch {}
62
- }
63
-
64
- /**
65
- * Windows: 用 PowerShell 读取用户级环境变量
66
- */
67
- function winGetEnvVar(key) {
68
- try {
69
- const out = execSync(
70
- `powershell.exe -NoProfile -Command "[Environment]::GetEnvironmentVariable('${key}', 'User')"`,
71
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000, windowsHide: true }
72
- )
73
- const val = (out || '').trim()
74
- return val || null
75
- } catch {
76
- return null
77
- }
78
- }
79
-
80
- function isConfiguredInShell() {
81
- if (process.platform === 'win32') {
82
- const val = winGetEnvVar('ANTHROPIC_BASE_URL')
83
- return !!(val && val.includes('holysheep'))
84
- }
85
-
86
- // Mac/Linux: 检查 shell rc 文件里是否有 managed 块
87
- try {
88
- const files = getShellRcFiles()
89
- for (const file of files) {
90
- try {
91
- const content = fs.readFileSync(file, 'utf8')
92
- if (content.includes(MARKER) && content.includes('holysheep')) {
93
- return true
94
- }
95
- } catch {}
96
- }
97
- } catch {}
98
- return false
99
- }
100
-
101
- function saveState(envVars) {
102
- try {
103
- const dir = path.dirname(STATE_FILE)
104
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
105
- fs.writeFileSync(STATE_FILE, JSON.stringify({ configuredAt: new Date().toISOString(), keys: Object.keys(envVars) }, null, 2), 'utf8')
106
- } catch {}
107
- }
108
-
109
- function clearState() {
110
- try { fs.unlinkSync(STATE_FILE) } catch {}
111
- }
112
-
113
- module.exports = {
114
- name: '全局环境变量',
115
- id: 'env-config',
116
-
117
- checkInstalled() {
118
- return true // 不依赖任何 CLI,总是可用
119
- },
120
-
121
- isConfigured() {
122
- return isConfiguredInShell()
123
- },
124
-
125
- configure(apiKey, baseUrlAnthropic, baseUrlOpenAI) {
126
- const envVars = {
127
- ANTHROPIC_API_KEY: apiKey,
128
- ANTHROPIC_AUTH_TOKEN: apiKey,
129
- ANTHROPIC_BASE_URL: baseUrlAnthropic,
130
- OPENAI_API_KEY: apiKey,
131
- OPENAI_BASE_URL: baseUrlOpenAI,
132
- }
133
-
134
- let written
135
- if (process.platform === 'win32') {
136
- // Windows: 用 PowerShell 直接写用户级环境变量
137
- written = []
138
- for (const [k, v] of Object.entries(envVars)) {
139
- if (winSetEnvVar(k, v)) {
140
- written.push(k)
141
- }
142
- }
143
- } else {
144
- // Mac/Linux: 写入 shell rc 文件
145
- written = writeEnvToShell(envVars)
146
- }
147
-
148
- saveState(envVars)
149
-
150
- return {
151
- file: written.join(', ') || 'shell env',
152
- hot: false,
153
- }
154
- },
155
-
156
- reset() {
157
- if (process.platform === 'win32') {
158
- for (const k of MANAGED_KEYS) winRemoveEnvVar(k)
159
- } else {
160
- removeEnvFromShell(MANAGED_KEYS)
161
- }
162
- clearState()
163
- },
164
-
165
- getConfigPath() { return null },
166
-
167
- /**
168
- * 获取已配置的环境变量值(Windows 从注册表读,其他从 process.env 读)
169
- */
170
- getConfiguredValues() {
171
- const result = {}
172
- for (const key of MANAGED_KEYS) {
173
- if (process.platform === 'win32') {
174
- result[key] = winGetEnvVar(key) || null
175
- } else {
176
- result[key] = process.env[key] || null
177
- }
178
- }
179
- return result
180
- },
181
-
182
- hint: '一键配置全局终端环境变量(ANTHROPIC / OPENAI API Key + Base URL)',
183
- launchCmd: null,
184
- docsUrl: 'https://holysheep.ai',
185
- }
@@ -1,82 +0,0 @@
1
- /**
2
- * Gemini CLI 适配器 (@google/gemini-cli)
3
- *
4
- * ⚠️ 重要:Gemini CLI 不支持自定义 base_url/中继
5
- * 它只能连接 Google 官方 Gemini API。
6
- *
7
- * 配置方式:
8
- * 1. settings.json 写入 selectedAuthType = "gemini-api-key"(跳过登录向导)
9
- * 2. 设置环境变量 GEMINI_API_KEY(需要 Google Gemini API Key,从 aistudio.google.com 获取)
10
- *
11
- * HolySheep 暂不支持 Gemini CLI 中继(Gemini CLI 使用 Google 专有协议,非 OpenAI 兼容格式)
12
- * 建议用户使用 Claude Code / Codex / Aider 等支持中继的工具。
13
- */
14
- const fs = require('fs')
15
- const path = require('path')
16
- const os = require('os')
17
-
18
- const GEMINI_DIR = path.join(os.homedir(), '.gemini')
19
- const SETTINGS_FILE = path.join(GEMINI_DIR, 'settings.json')
20
-
21
- function readSettings() {
22
- try {
23
- if (fs.existsSync(SETTINGS_FILE)) {
24
- return JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf8'))
25
- }
26
- } catch {}
27
- return {}
28
- }
29
-
30
- function writeSettings(data) {
31
- if (!fs.existsSync(GEMINI_DIR)) fs.mkdirSync(GEMINI_DIR, { recursive: true })
32
- fs.writeFileSync(SETTINGS_FILE, JSON.stringify(data, null, 2), 'utf8')
33
- }
34
-
35
- module.exports = {
36
- name: 'Gemini CLI',
37
- id: 'gemini-cli',
38
-
39
- checkInstalled() {
40
- return require('../utils/which').commandExists('gemini')
41
- },
42
-
43
- isConfigured() {
44
- // 检查是否设置了 GEMINI_API_KEY 环境变量
45
- if (process.env.GEMINI_API_KEY) return true
46
- // 检查 settings.json 是否已跳过向导
47
- const s = readSettings()
48
- return s.selectedAuthType === 'gemini-api-key'
49
- },
50
-
51
- configure(apiKey, _baseUrlAnthropicNoV1, _baseUrlOpenAI) {
52
- // Gemini CLI 不支持 HolySheep 中继,只能配置为使用官方 Gemini API Key 模式
53
- // 写入 settings.json 跳过认证向导
54
- const settings = readSettings()
55
- settings.selectedAuthType = 'gemini-api-key'
56
- writeSettings(settings)
57
-
58
- // 环境变量:GEMINI_API_KEY 需要用户自己的 Google Gemini API Key
59
- // HolySheep API Key (cr_xxx) 无法用于 Gemini CLI
60
- return {
61
- file: SETTINGS_FILE,
62
- hot: false,
63
- // 不注入 GEMINI_API_KEY,因为 HolySheep key 对 Gemini CLI 无效
64
- // 用户需要手动设置真正的 Gemini API Key
65
- envVars: {},
66
- warning: 'Gemini CLI 需要 Google 官方 Gemini API Key,无法使用 HolySheep 中继。\n请从 https://aistudio.google.com/apikey 获取 API Key 后设置环境变量:\n export GEMINI_API_KEY="your-google-api-key"',
67
- }
68
- },
69
-
70
- reset() {
71
- const settings = readSettings()
72
- delete settings.selectedAuthType
73
- writeSettings(settings)
74
- },
75
-
76
- getConfigPath() { return SETTINGS_FILE },
77
- hint: 'Gemini CLI 不支持 HolySheep 中继,需使用 Google 官方 Gemini API Key',
78
- installCmd: 'npm install -g @google/gemini-cli',
79
- docsUrl: 'https://github.com/google-gemini/gemini-cli',
80
- envVarFormat: 'gemini',
81
- unsupported: true, // 标记为不支持中继
82
- }