@simonyea/holysheep-cli 1.7.125 → 1.7.127

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.125",
3
+ "version": "1.7.127",
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",
@@ -46,6 +46,7 @@ function getControlPlaneUrl(config) {
46
46
  }
47
47
 
48
48
  const leaseCache = new Map()
49
+ const MAX_PROXY_RETRIES = 3
49
50
 
50
51
  function isRetryableNodeLeaseError(err) {
51
52
  const message = String(err?.message || '')
@@ -277,29 +278,29 @@ function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH }) {
277
278
  })
278
279
  }
279
280
 
280
- try {
281
- await doForward(getCachedLease(sessionId))
282
- } catch (err) {
283
- if (clientRes.headersSent) return
284
- const shouldRefreshLease =
285
- !leaseCache.has(sessionId) || (err && isRetryableNodeLeaseError(err))
286
- if (shouldRefreshLease) {
287
- try {
281
+ let lastError = null
282
+ for (let attempt = 0; attempt <= MAX_PROXY_RETRIES; attempt++) {
283
+ try {
284
+ if (attempt === 0) {
285
+ await doForward(getCachedLease(sessionId))
286
+ } else {
288
287
  const config = readConfig(configPath)
289
288
  leaseCache.delete(sessionId)
290
289
  const freshLease = await fetchFreshLease(config, sessionId)
291
290
  await doForward(freshLease)
292
- } catch (retryError) {
293
- if (!clientRes.headersSent) {
294
- clientRes.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' })
295
- clientRes.end(retryError.message || 'Proxy error')
296
- }
297
291
  }
298
- } else {
299
- clientRes.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' })
300
- clientRes.end(err?.message || 'Proxy error')
292
+ lastError = null
293
+ break
294
+ } catch (err) {
295
+ lastError = err
296
+ if (clientRes.headersSent) return
297
+ if (!isRetryableNodeLeaseError(err) && attempt > 0) break
301
298
  }
302
299
  }
300
+ if (lastError && !clientRes.headersSent) {
301
+ clientRes.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' })
302
+ clientRes.end(lastError.message || 'Proxy error')
303
+ }
303
304
  })
304
305
 
305
306
  // Hosts that must NOT be tunneled directly — they must go through CRS via
@@ -333,26 +334,28 @@ function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH }) {
333
334
  pipeWithCleanup(clientSocket, upstreamSocket)
334
335
  }
335
336
 
336
- try {
337
- await doConnect(getCachedLease(sessionId))
338
- } catch (err) {
339
- const shouldRefreshLease =
340
- !leaseCache.has(sessionId) || (err && isRetryableNodeLeaseError(err))
341
- if (shouldRefreshLease) {
342
- try {
337
+ let lastError = null
338
+ for (let attempt = 0; attempt <= MAX_PROXY_RETRIES; attempt++) {
339
+ try {
340
+ if (attempt === 0) {
341
+ await doConnect(getCachedLease(sessionId))
342
+ } else {
343
343
  const config = readConfig(configPath)
344
344
  leaseCache.delete(sessionId)
345
345
  const freshLease = await fetchFreshLease(config, sessionId)
346
346
  await doConnect(freshLease)
347
- } catch (retryError) {
348
- clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${retryError.message}`)
349
- clientSocket.destroy()
350
347
  }
351
- } else {
352
- clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${err?.message || 'Proxy error'}`)
353
- clientSocket.destroy()
348
+ lastError = null
349
+ break
350
+ } catch (err) {
351
+ lastError = err
352
+ if (!isRetryableNodeLeaseError(err) && attempt > 0) break
354
353
  }
355
354
  }
355
+ if (lastError) {
356
+ clientSocket.write(`HTTP/1.1 502 Bad Gateway\r\ncontent-type: text/plain; charset=utf-8\r\n\r\n${lastError.message || 'Proxy error'}`)
357
+ clientSocket.destroy()
358
+ }
356
359
  })
357
360
 
358
361
  return server
@@ -162,18 +162,8 @@ function writeJsonConfigIfNeeded(apiKey, baseUrlOpenAI, model) {
162
162
  * Codex RS bug: auth_mode=chatgpt 时 OAuth token 会覆盖自定义 provider 的 api_key
163
163
  */
164
164
  function neutralizeAuthJson() {
165
- try {
166
- if (!fs.existsSync(AUTH_FILE)) return
167
-
168
- const auth = JSON.parse(fs.readFileSync(AUTH_FILE, 'utf8'))
169
-
170
- // 清除所有可能干扰 holysheep provider 的认证信息
171
- auth.auth_mode = 'apikey'
172
- auth.OPENAI_API_KEY = null
173
- delete auth.tokens
174
-
175
- fs.writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), 'utf8')
176
- } catch {}
165
+ // 直接删除 auth.json,避免干扰 config.toml 的 http_headers 认证
166
+ try { fs.unlinkSync(AUTH_FILE) } catch {}
177
167
  }
178
168
 
179
169
  module.exports = {