@simonyea/holysheep-cli 2.1.19 → 2.1.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "2.1.19",
3
+ "version": "2.1.21",
4
4
  "description": "Claude Code/Cursor/Cline API relay for China \u2014 \u00a51=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
5
5
  "scripts": {
6
6
  "test": "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js",
@@ -206,6 +206,9 @@ function buildAuthHeaders(config, lease) {
206
206
  }
207
207
 
208
208
  function deriveNodeProxyUrl(lease) {
209
+ if (process.env.HS_CLAUDE_NODE_PROXY_OVERRIDE) {
210
+ return String(process.env.HS_CLAUDE_NODE_PROXY_OVERRIDE).replace(/\/+$/, '')
211
+ }
209
212
  if (lease.nodeProxyUrl) return String(lease.nodeProxyUrl)
210
213
  if (!lease.nodeBaseUrl) throw new Error('Lease does not include node proxy information')
211
214
  const upstream = new URL(String(lease.nodeBaseUrl))
@@ -315,18 +318,32 @@ function forwardViaNodeProxy({ nodeProxyUrl, targetUrl, clientReq, clientRes, ex
315
318
  stallTimer = setTimeout(() => failWithAnthropicError('upstream stream stalled'), STALL_TIMEOUT_MS)
316
319
  }
317
320
 
321
+ const finalHeaders = {
322
+ ...clientReq.headers,
323
+ ...extraHeaders,
324
+ host: targetUrl.host,
325
+ connection: 'close',
326
+ }
327
+ if (ENABLE_TIMING_LOG) {
328
+ const hsHeaders = Object.fromEntries(
329
+ Object.entries(finalHeaders).filter(([k]) => /^x-hs-/i.test(k))
330
+ )
331
+ console.error(
332
+ `[hs-claude-proxy] forward.headers ${JSON.stringify({
333
+ target: sanitizeUrl(targetUrl),
334
+ node: sanitizeUrl(nodeProxyUrl),
335
+ hsHeaders,
336
+ clientHeadersKeys: Object.keys(clientReq.headers).slice(0, 20),
337
+ })}`
338
+ )
339
+ }
318
340
  forwardReq = http.request({
319
341
  host: upstream.hostname,
320
342
  port: Number(upstream.port || 80),
321
343
  method: clientReq.method,
322
344
  path: targetUrl.toString(),
323
345
  agent: false,
324
- headers: {
325
- ...clientReq.headers,
326
- ...extraHeaders,
327
- host: targetUrl.host,
328
- connection: 'close',
329
- },
346
+ headers: finalHeaders,
330
347
  }, (forwardRes) => {
331
348
  sawUpstreamResponse = true
332
349
  clearResponseTimer()
@@ -166,6 +166,18 @@ module.exports = {
166
166
  configure(apiKey, baseUrlAnthropic, baseUrlOpenAI, _primaryModel, selectedModels) {
167
167
  const nextModels = buildCustomModels(apiKey, baseUrlAnthropic, baseUrlOpenAI, selectedModels)
168
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
+
169
181
  const settings = readSettings()
170
182
  const preservedModels = Array.isArray(settings.customModels)
171
183
  ? settings.customModels.filter((item) => !isHolySheepModel(item))
@@ -175,6 +187,12 @@ module.exports = {
175
187
  ...preservedModels,
176
188
  ]
177
189
  settings.logoAnimation = 'off'
190
+ if (defaultModelId) {
191
+ settings.sessionDefaultSettings = {
192
+ ...(settings.sessionDefaultSettings || {}),
193
+ model: defaultModelId,
194
+ }
195
+ }
178
196
  writeSettings(settings)
179
197
 
180
198
  const legacy = readLegacyConfig()
@@ -186,6 +204,12 @@ module.exports = {
186
204
  ...preservedLegacyModels,
187
205
  ]
188
206
  legacy.logoAnimation = 'off'
207
+ if (defaultModelId) {
208
+ legacy.sessionDefaultSettings = {
209
+ ...(legacy.sessionDefaultSettings || {}),
210
+ model: defaultModelId,
211
+ }
212
+ }
189
213
  writeLegacyConfig(legacy)
190
214
 
191
215
  // Windows: also write FACTORY_API_KEY to user env via setx so a freshly
@@ -210,15 +234,43 @@ module.exports = {
210
234
  },
211
235
  reset() {
212
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
+ )
213
245
  if (Array.isArray(settings.customModels)) {
214
246
  settings.customModels = settings.customModels.filter((item) => !isHolySheepModel(item))
215
247
  }
248
+ if (
249
+ settings.sessionDefaultSettings &&
250
+ typeof settings.sessionDefaultSettings === 'object' &&
251
+ hsIds.has(settings.sessionDefaultSettings.model)
252
+ ) {
253
+ delete settings.sessionDefaultSettings.model
254
+ }
216
255
  writeSettings(settings)
217
256
 
218
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
+ )
219
264
  if (Array.isArray(legacy.customModels)) {
220
265
  legacy.customModels = legacy.customModels.filter((item) => !isHolySheepModel(item))
221
266
  }
267
+ if (
268
+ legacy.sessionDefaultSettings &&
269
+ typeof legacy.sessionDefaultSettings === 'object' &&
270
+ hsLegacyIds.has(legacy.sessionDefaultSettings.model)
271
+ ) {
272
+ delete legacy.sessionDefaultSettings.model
273
+ }
222
274
  writeLegacyConfig(legacy)
223
275
  },
224
276
  getConfigPath() { return SETTINGS_FILE },
@@ -60,10 +60,10 @@ const VENDOR_DIR = path.join(__dirname, 'vendor', 'aionui')
60
60
  // new CLI release, the next `hs web` invocation on user machines will detect
61
61
  // the version drift and upgrade the cache in place.
62
62
  const DEFAULT_RUNTIME_URL =
63
- 'https://mail.holysheep.ai/app/cli/aionui-runtime-v1.9.18-holysheep-hs15.tar.gz'
63
+ 'https://mail.holysheep.ai/app/cli/aionui-runtime-v1.9.18-holysheep-hs17.tar.gz'
64
64
  const DEFAULT_RUNTIME_SHA256 =
65
- 'ba1c2e18b624171238185d1a95ac9bd9ff0f761acb74d8eea97812cbd15555ee'
66
- const DEFAULT_RUNTIME_VERSION = '1.9.18-holysheep-hs15'
65
+ '28083f135503a27437750c8f692a2700c69f8253aaf19dff259af6d1517572f4'
66
+ const DEFAULT_RUNTIME_VERSION = '1.9.18-holysheep-hs17'
67
67
 
68
68
  function isValidRuntimeDir(dir) {
69
69
  if (!dir) return false