@goodandready/dsh-clinebot 0.5.2 → 0.5.4

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/CHANGELOG.md CHANGED
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.4
4
+
5
+ ### Fixed
6
+ - **Peer gate on DSH 0.2.0-rc.1** (#58): DSH skips a profile bundle whose `peerDependencies` exclude the running version, so this plugin was absent from the profile with no error in the UI. Every `@deepseek-ai/dsh-*` peer now names both the 0.1.7-rc.2 and 0.2.0-rc.1 lines, because semver does not admit a prerelease of the next minor into a range that does not name it.
7
+
3
8
  All notable changes to `@goodandready/dsh-clinebot` will be documented in this file.
4
9
 
5
10
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
11
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
12
 
13
+ ## [0.5.3] - 2026-09-28
14
+
15
+ ### Fixed
16
+ - **Proxy Token Routing via DSH llm-pi-ai & Dual Bearer Auth (Issue #150, GitHub #11)**: In `@deepseek-ai/dsh-llm-pi-ai@0.1.7-rc.2`, the streaming runner (`streamWithSnapshot`) resolves request authorization strictly from `profile.apiKeyEnv` and completely ignores the literal `apiKey` field in the provider descriptor. When `proxyMode` is active, `upsertPiAiProvider` now correctly registers `apiKeyEnv: LOCAL_PROXY_KEY_ENV` (`CLINEBOT_LOCAL_PROXY_TOKEN`), while `lib/proxy-token.js` populates the credential store with the generated token value. In addition, `isAuthorizedProxyRequest` now accepts requests authenticated with either `CLINEBOT_LOCAL_PROXY_TOKEN` or any valid account key configured in the active account pool, ensuring uninterrupted communication across streaming, non-streaming, and diagnostic invocations without HTTP 401 Unauthorized rejections.
17
+
8
18
  ## [0.5.2] - 2026-09-28
9
19
 
10
20
  ### Security
@@ -215,7 +215,7 @@ export async function upsertPiAiProvider(ctx, cfg, activeModelIds) {
215
215
 
216
216
  const providerObj = buildPiAiProvider({
217
217
  baseUrl: effectiveBaseUrl,
218
- apiKeyEnv: activeAcc?.apiKeyEnv || pub.apiKeyEnv,
218
+ apiKeyEnv: isProxy ? LOCAL_PROXY_KEY_ENV : (activeAcc?.apiKeyEnv || pub.apiKeyEnv),
219
219
  apiKey: localToken,
220
220
  models: modelsToRegister.length ? modelsToRegister : allModels,
221
221
  customModels: [...(pub.dynamicModels || []), ...(pub.customModels || [])],
@@ -24,9 +24,9 @@ import { getAllModels, DEFAULT_MODEL_ID } from '../models.js'
24
24
  import { getLocalProxyToken } from '../proxy-token.js'
25
25
 
26
26
  const require = createRequire(import.meta.url)
27
- let packageVersion = '0.5.2'
27
+ let packageVersion = '0.5.3'
28
28
  try {
29
- packageVersion = require('../../package.json').version || '0.5.2'
29
+ packageVersion = require('../../package.json').version || '0.5.3'
30
30
  } catch (err) {
31
31
  /* fallback to default version if manifest is unreadable */
32
32
  }
@@ -44,12 +44,22 @@ export function hasDisallowedBrowserOrigin(req) {
44
44
  return false
45
45
  }
46
46
 
47
- export function isAuthorizedProxyRequest(req) {
47
+ export function isAuthorizedProxyRequest(req, accountPool = []) {
48
48
  const auth = req.headers?.['authorization'] || ''
49
49
  const match = auth.match(/^Bearer\s+(.+)$/i)
50
50
  if (!match) return false
51
51
  const token = match[1].trim()
52
- return Boolean(token && token === getLocalProxyToken())
52
+ if (!token) return false
53
+ const localToken = getLocalProxyToken()
54
+ if (localToken && token === localToken) {
55
+ return true
56
+ }
57
+ if (Array.isArray(accountPool) && accountPool.length > 0) {
58
+ if (accountPool.some((acc) => acc.value && acc.value === token)) {
59
+ return true
60
+ }
61
+ }
62
+ return false
53
63
  }
54
64
 
55
65
  export function registerProxyRoutes(ctx, { live, getSettingsApi, syncProviderState }) {
@@ -70,7 +80,8 @@ export function registerProxyRoutes(ctx, { live, getSettingsApi, syncProviderSta
70
80
  return writeJson(res, 403, { ok: false, error: 'Cross-site or browser requests to proxy are forbidden' })
71
81
  }
72
82
 
73
- if (!isAuthorizedProxyRequest(req)) {
83
+ const pool = await resolveAccountPool(ctx, live())
84
+ if (!isAuthorizedProxyRequest(req, pool)) {
74
85
  return writeJson(res, 401, { ok: false, error: 'Unauthorized: missing or invalid bearer token' })
75
86
  }
76
87
 
@@ -114,7 +125,6 @@ export function registerProxyRoutes(ctx, { live, getSettingsApi, syncProviderSta
114
125
  }
115
126
 
116
127
  const isStreaming = Boolean(body.stream)
117
- const pool = await resolveAccountPool(ctx, cfg)
118
128
  const configuredAccounts = pool.filter(a => a.present && a.value)
119
129
 
120
130
  const maxRetries = Math.max(1, configuredAccounts.length)
@@ -345,7 +355,8 @@ export function registerProxyRoutes(ctx, { live, getSettingsApi, syncProviderSta
345
355
  return writeJson(res, 403, { ok: false, error: 'Cross-site or browser requests to proxy are forbidden' })
346
356
  }
347
357
 
348
- if (!isAuthorizedProxyRequest(req)) {
358
+ const pool = await resolveAccountPool(ctx, live())
359
+ if (!isAuthorizedProxyRequest(req, pool)) {
349
360
  return writeJson(res, 401, { ok: false, error: 'Unauthorized: missing or invalid bearer token' })
350
361
  }
351
362
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-clinebot",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "DeepSeek Harness companion for ClineBot / ClinePass: dynamic subscription models sync, quota exhaustion warnings, session metrics, dedicated settings page, live usage limits, and /cline slash-command.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -59,8 +59,8 @@
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@deepseek-ai/cordis": "^4.0.1",
62
- "@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
63
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
62
+ "@deepseek-ai/dsh-credentials": "^0.1.7-rc.2 || ^0.2.0-rc.1",
63
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1",
64
64
  "@deepseek-ai/schemastery": "^3.18.1"
65
65
  },
66
66
  "devDependencies": {