@simonyea/holysheep-cli 1.6.9 → 1.6.10
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 +1 -0
- package/package.json +1 -1
- package/src/tools/droid.js +56 -17
- package/src/tools/openclaw.js +1 -1
package/README.md
CHANGED
|
@@ -218,6 +218,7 @@ A: OpenClaw 需要 Node.js 20+,运行 `node --version` 确认版本后重试
|
|
|
218
218
|
|
|
219
219
|
## Changelog
|
|
220
220
|
|
|
221
|
+
- **v1.6.10** — 将可运行的 OpenClaw runtime(含 npx 回退)视为已安装,避免 Windows/Node 环境下重复提示安装;同时修复 Droid CLI 的 GPT `/v1` 接入地址并同步写入 `~/.factory/config.json`
|
|
221
222
|
- **v1.6.9** — 保留 OpenClaw 的 MiniMax 配置,并为 MiniMax 使用独立 provider id,避免与 Claude provider 冲突;在 OpenClaw 2026.3.13 下改为提示精确 `/model` 切换命令,而不是停止配置 MiniMax
|
|
222
223
|
- **v1.6.8** — 修复 Codex 重复写入 `config.toml` 导致的 duplicate key,并修复 OpenClaw 在 Windows 下的安装检测;针对 OpenClaw 2026.3.13 的模型路由回归,临时跳过 MiniMax 避免 `model not allowed`
|
|
223
224
|
- **v1.6.7** — OpenClaw 配置新增 `MiniMax-M2.7-highspeed`,并补齐节点迁移脚本中的 SSH 代理账号创建逻辑
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simonyea/holysheep-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.10",
|
|
4
4
|
"description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openai-china",
|
package/src/tools/droid.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 配置文件: ~/.factory/settings.json
|
|
4
4
|
*
|
|
5
5
|
* 使用 Droid 原生 customModels 配置 HolySheep 的多个模型入口:
|
|
6
|
-
* - GPT 走 OpenAI 兼容入口: https://api.holysheep.ai/
|
|
6
|
+
* - GPT 走 OpenAI 兼容入口: https://api.holysheep.ai/v1
|
|
7
7
|
* - Claude 走 Anthropic 入口: https://api.holysheep.ai
|
|
8
8
|
* - MiniMax 走 Anthropic 入口: https://api.holysheep.ai/minimax
|
|
9
9
|
*/
|
|
@@ -13,12 +13,13 @@ const os = require('os')
|
|
|
13
13
|
|
|
14
14
|
const CONFIG_DIR = path.join(os.homedir(), '.factory')
|
|
15
15
|
const SETTINGS_FILE = path.join(CONFIG_DIR, 'settings.json')
|
|
16
|
+
const LEGACY_CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
|
|
16
17
|
|
|
17
18
|
const DEFAULT_MODELS = [
|
|
18
19
|
{
|
|
19
20
|
model: 'gpt-5.4',
|
|
20
21
|
id: 'custom:gpt-5.4-0',
|
|
21
|
-
baseUrlSuffix: '
|
|
22
|
+
baseUrlSuffix: '',
|
|
22
23
|
displayName: 'GPT-5.4',
|
|
23
24
|
provider: 'openai',
|
|
24
25
|
},
|
|
@@ -66,6 +67,24 @@ function writeSettings(data) {
|
|
|
66
67
|
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(data, null, 2), 'utf8')
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
function readLegacyConfig() {
|
|
71
|
+
try {
|
|
72
|
+
if (fs.existsSync(LEGACY_CONFIG_FILE)) {
|
|
73
|
+
return JSON.parse(fs.readFileSync(LEGACY_CONFIG_FILE, 'utf8'))
|
|
74
|
+
}
|
|
75
|
+
} catch {}
|
|
76
|
+
return {}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function writeLegacyConfig(data) {
|
|
80
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true })
|
|
81
|
+
fs.writeFileSync(LEGACY_CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isHolySheepModel(item) {
|
|
85
|
+
return typeof item?.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai')
|
|
86
|
+
}
|
|
87
|
+
|
|
69
88
|
function normalizeSelectedModels(selectedModels) {
|
|
70
89
|
const selected = new Set(
|
|
71
90
|
Array.isArray(selectedModels) && selectedModels.length > 0
|
|
@@ -84,13 +103,17 @@ function normalizeSelectedModels(selectedModels) {
|
|
|
84
103
|
return models.length > 0 ? models : DEFAULT_MODELS.map((item, index) => ({ ...item, index }))
|
|
85
104
|
}
|
|
86
105
|
|
|
87
|
-
function buildCustomModels(apiKey, baseUrlAnthropic, selectedModels) {
|
|
88
|
-
const
|
|
106
|
+
function buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels) {
|
|
107
|
+
const anthropicRootUrl = String(baseUrlAnthropic || '').replace(/\/+$/, '')
|
|
108
|
+
const openaiRootUrl = String(baseUrlOpenAI || '').replace(/\/+$/, '')
|
|
89
109
|
return normalizeSelectedModels(selectedModels).map((item) => ({
|
|
90
110
|
model: item.model,
|
|
91
111
|
id: item.id,
|
|
92
112
|
index: item.index,
|
|
93
|
-
baseUrl:
|
|
113
|
+
baseUrl:
|
|
114
|
+
item.provider === 'openai'
|
|
115
|
+
? `${openaiRootUrl}${item.baseUrlSuffix}`
|
|
116
|
+
: `${anthropicRootUrl}${item.baseUrlSuffix}`,
|
|
94
117
|
apiKey,
|
|
95
118
|
displayName: item.displayName,
|
|
96
119
|
maxOutputTokens: 64000,
|
|
@@ -108,25 +131,37 @@ module.exports = {
|
|
|
108
131
|
isConfigured() {
|
|
109
132
|
const settings = readSettings()
|
|
110
133
|
const customModels = Array.isArray(settings.customModels) ? settings.customModels : []
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
)
|
|
134
|
+
if (customModels.some(isHolySheepModel)) return true
|
|
135
|
+
|
|
136
|
+
const legacy = readLegacyConfig()
|
|
137
|
+
const legacyModels = Array.isArray(legacy.customModels) ? legacy.customModels : []
|
|
138
|
+
return legacyModels.some(isHolySheepModel)
|
|
114
139
|
},
|
|
115
|
-
configure(apiKey, baseUrlAnthropic,
|
|
140
|
+
configure(apiKey, baseUrlAnthropic, baseUrlOpenAI, _primaryModel, selectedModels) {
|
|
141
|
+
const nextModels = buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels)
|
|
142
|
+
|
|
116
143
|
const settings = readSettings()
|
|
117
144
|
const preservedModels = Array.isArray(settings.customModels)
|
|
118
|
-
? settings.customModels.filter(
|
|
119
|
-
(item) => !(typeof item.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai'))
|
|
120
|
-
)
|
|
145
|
+
? settings.customModels.filter((item) => !isHolySheepModel(item))
|
|
121
146
|
: []
|
|
122
|
-
|
|
123
147
|
settings.customModels = [
|
|
124
|
-
...
|
|
148
|
+
...nextModels,
|
|
125
149
|
...preservedModels,
|
|
126
150
|
]
|
|
127
151
|
settings.logoAnimation = 'off'
|
|
128
152
|
writeSettings(settings)
|
|
129
153
|
|
|
154
|
+
const legacy = readLegacyConfig()
|
|
155
|
+
const preservedLegacyModels = Array.isArray(legacy.customModels)
|
|
156
|
+
? legacy.customModels.filter((item) => !isHolySheepModel(item))
|
|
157
|
+
: []
|
|
158
|
+
legacy.customModels = [
|
|
159
|
+
...nextModels,
|
|
160
|
+
...preservedLegacyModels,
|
|
161
|
+
]
|
|
162
|
+
legacy.logoAnimation = 'off'
|
|
163
|
+
writeLegacyConfig(legacy)
|
|
164
|
+
|
|
130
165
|
return {
|
|
131
166
|
file: SETTINGS_FILE,
|
|
132
167
|
hot: true,
|
|
@@ -135,11 +170,15 @@ module.exports = {
|
|
|
135
170
|
reset() {
|
|
136
171
|
const settings = readSettings()
|
|
137
172
|
if (Array.isArray(settings.customModels)) {
|
|
138
|
-
settings.customModels = settings.customModels.filter(
|
|
139
|
-
(item) => !(typeof item.baseUrl === 'string' && item.baseUrl.includes('api.holysheep.ai'))
|
|
140
|
-
)
|
|
173
|
+
settings.customModels = settings.customModels.filter((item) => !isHolySheepModel(item))
|
|
141
174
|
}
|
|
142
175
|
writeSettings(settings)
|
|
176
|
+
|
|
177
|
+
const legacy = readLegacyConfig()
|
|
178
|
+
if (Array.isArray(legacy.customModels)) {
|
|
179
|
+
legacy.customModels = legacy.customModels.filter((item) => !isHolySheepModel(item))
|
|
180
|
+
}
|
|
181
|
+
writeLegacyConfig(legacy)
|
|
143
182
|
},
|
|
144
183
|
getConfigPath() { return SETTINGS_FILE },
|
|
145
184
|
hint: '已写入 ~/.factory/settings.json;重启 Droid 后可见 HolySheep 模型列表',
|