@simonyea/holysheep-cli 1.7.69 → 1.7.71

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": "1.7.69",
3
+ "version": "1.7.71",
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",
@@ -88,14 +88,8 @@ async function runClaude(args = []) {
88
88
  NO_PROXY: mergeNoProxy(process.env.NO_PROXY, ['127.0.0.1', 'localhost']),
89
89
  }
90
90
 
91
- const restoreSettings = typeof claudeCodeTool.applyRuntimeSettingsOverride === 'function'
92
- ? claudeCodeTool.applyRuntimeSettingsOverride({
93
- ANTHROPIC_AUTH_TOKEN: apiKey,
94
- ANTHROPIC_BASE_URL: proxyUrl,
95
- CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
96
- HOLYSHEEP_CLAUDE_LAUNCHER: 'hs',
97
- })
98
- : () => {}
91
+ // 不再写 settings.json 只用 env 变量,避免 Claude Code 从两个来源
92
+ // 读到同一个 proxy URL 导致重复请求 + 避免退出时覆盖 WebUI configure 的值
99
93
 
100
94
  if (runtime.launchMode === 'node-inject') {
101
95
  env.NODE_OPTIONS = appendNodeRequire(process.env.NODE_OPTIONS, INJECT_PATH)
@@ -108,7 +102,6 @@ async function runClaude(args = []) {
108
102
  })
109
103
 
110
104
  const cleanup = async () => {
111
- restoreSettings()
112
105
  try {
113
106
  server.close()
114
107
  } catch {}
@@ -168,7 +168,6 @@ module.exports = {
168
168
  const bridge = readConfig()
169
169
  return Boolean(
170
170
  s.env?.ANTHROPIC_AUTH_TOKEN &&
171
- s.env?.ANTHROPIC_BASE_URL === BASE_URL_ANTHROPIC &&
172
171
  bridge.apiKey &&
173
172
  bridge.bridgeSecret &&
174
173
  bridge.controlPlaneUrl &&
@@ -184,7 +183,8 @@ module.exports = {
184
183
  const settings = readSettings()
185
184
  if (!settings.env) settings.env = {}
186
185
  settings.env.ANTHROPIC_AUTH_TOKEN = apiKey
187
- settings.env.ANTHROPIC_BASE_URL = BASE_URL_ANTHROPIC
186
+ // ANTHROPIC_BASE_URL 不写入 settings.json,由 hs claude 运行时通过 env 动态注入
187
+ delete settings.env.ANTHROPIC_BASE_URL
188
188
  settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1'
189
189
  settings.env.HOLYSHEEP_CLAUDE_LAUNCHER = 'hs'
190
190
  if (primaryModel) settings.model = primaryModel
@@ -209,15 +209,26 @@ function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH }) {
209
209
 
210
210
  try {
211
211
  await doForward(getCachedLease(sessionId))
212
- } catch {
213
- try {
214
- const config = readConfig(configPath)
215
- leaseCache.delete(sessionId)
216
- const freshLease = await fetchFreshLease(config, sessionId)
217
- await doForward(freshLease)
218
- } catch (retryError) {
212
+ } catch (err) {
213
+ if (clientRes.headersSent) return
214
+ // 只在没有 lease 缓存时重试(首次连接或 lease 过期)
215
+ // 网络超时/连接错误不重试 — 让 Claude Code 自己处理重试,避免重复 API 请求
216
+ const noLease = !leaseCache.has(sessionId) || (err && err.message && err.message.includes('No session lease'))
217
+ if (noLease) {
218
+ try {
219
+ const config = readConfig(configPath)
220
+ leaseCache.delete(sessionId)
221
+ const freshLease = await fetchFreshLease(config, sessionId)
222
+ await doForward(freshLease)
223
+ } catch (retryError) {
224
+ if (!clientRes.headersSent) {
225
+ clientRes.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' })
226
+ clientRes.end(retryError.message || 'Proxy error')
227
+ }
228
+ }
229
+ } else {
219
230
  clientRes.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' })
220
- clientRes.end(retryError.message || 'Proxy error')
231
+ clientRes.end(err?.message || 'Proxy error')
221
232
  }
222
233
  }
223
234
  })
@@ -244,15 +255,20 @@ function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH }) {
244
255
 
245
256
  try {
246
257
  await doConnect(getCachedLease(sessionId))
247
- } catch {
248
- // lease 失效,拿新 lease 重试一次
249
- try {
250
- const config = readConfig(configPath)
251
- leaseCache.delete(sessionId)
252
- const freshLease = await fetchFreshLease(config, sessionId)
253
- await doConnect(freshLease)
254
- } catch (retryError) {
255
- clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${retryError.message}`)
258
+ } catch (err) {
259
+ const noLease = !leaseCache.has(sessionId) || (err && err.message && err.message.includes('No session lease'))
260
+ if (noLease) {
261
+ try {
262
+ const config = readConfig(configPath)
263
+ leaseCache.delete(sessionId)
264
+ const freshLease = await fetchFreshLease(config, sessionId)
265
+ await doConnect(freshLease)
266
+ } catch (retryError) {
267
+ clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${retryError.message}`)
268
+ clientSocket.destroy()
269
+ }
270
+ } else {
271
+ clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${err?.message || 'Proxy error'}`)
256
272
  clientSocket.destroy()
257
273
  }
258
274
  }
@@ -516,11 +516,10 @@ async function handleToolConfigure(req, res) {
516
516
 
517
517
  const allModelIds = [
518
518
  'gpt-5.4', 'gpt-5.3-codex-spark',
519
- 'claude-sonnet-4-6', 'claude-sonnet-4-6[1m]',
520
- 'claude-opus-4-6', 'claude-opus-4-6[1m]',
519
+ 'claude-sonnet-4-6', 'claude-opus-4-6',
521
520
  'MiniMax-M2.7-highspeed', 'claude-haiku-4-5',
522
521
  ]
523
- const primaryModel = 'claude-sonnet-4-6[1m]'
522
+ const primaryModel = 'claude-sonnet-4-6'
524
523
 
525
524
  sseEmit(res, { type: 'progress', message: `正在配置 ${tool.name}...` })
526
525