@goodandready/dsh-clinebot 0.5.33 → 0.6.1
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 +32 -0
- package/README.md +63 -36
- package/README.ru.md +3 -1
- package/README.zh.md +3 -1
- package/lib/adapter-messages.js +237 -0
- package/lib/adapter-stream.js +292 -0
- package/lib/adapter.js +616 -0
- package/lib/client.js +2634 -922
- package/lib/cline-client.js +15 -6
- package/lib/config.js +266 -233
- package/lib/credential-refs.js +104 -84
- package/lib/index.js +569 -502
- package/lib/model-prices.js +117 -0
- package/lib/provider-sync.js +404 -387
- package/lib/proxy-token.js +186 -186
- package/lib/routes/accounts.js +523 -403
- package/lib/routes/models.js +2 -1
- package/lib/routes/settings.js +81 -2
- package/lib/services.js +55 -0
- package/lib/stats-storage.js +378 -165
- package/lib/transport/cline-transport.js +314 -0
- package/lib/tui-settings.js +158 -0
- package/package.json +113 -77
package/lib/credential-refs.js
CHANGED
|
@@ -1,84 +1,104 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Credentials management helper for @goodandready/dsh-clinebot.
|
|
3
|
-
* Isolates DSH Credentials storage and environment resolution.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const DEFAULT_API_KEY_ENV = 'CLINEBOT_API_KEY'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Credentials management helper for @goodandready/dsh-clinebot.
|
|
3
|
+
* Isolates DSH Credentials storage and environment resolution.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const DEFAULT_API_KEY_ENV = 'CLINEBOT_API_KEY'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the optional credentials service without tripping Cordis's
|
|
10
|
+
* strict-proxy guard on undeclared property reads.
|
|
11
|
+
* @param {object | undefined} ctx
|
|
12
|
+
* @returns {object | undefined}
|
|
13
|
+
*/
|
|
14
|
+
function credentialsService(ctx) {
|
|
15
|
+
try {
|
|
16
|
+
const viaGet = typeof ctx?.get === 'function' ? ctx.get('credentials') : undefined
|
|
17
|
+
if (viaGet) return viaGet
|
|
18
|
+
} catch {
|
|
19
|
+
/* strict context refuses get() for a service the fiber does not inject */
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
return ctx ? ctx.credentials : undefined
|
|
23
|
+
} catch {
|
|
24
|
+
return undefined
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function toCredentialRef(name) {
|
|
29
|
+
try {
|
|
30
|
+
const mod = await import('@deepseek-ai/dsh-credentials')
|
|
31
|
+
if (typeof mod.credentialRef === 'function') {
|
|
32
|
+
return mod.credentialRef(name)
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
/* fallback when executed in standalone unit tests outside DSH bundle */
|
|
36
|
+
}
|
|
37
|
+
return typeof name === 'object' && name !== null ? name : { type: 'env', name: String(name || '') }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveApiKey(apiKeyEnv, env = process.env) {
|
|
41
|
+
const name = String(apiKeyEnv || DEFAULT_API_KEY_ENV).trim() || DEFAULT_API_KEY_ENV
|
|
42
|
+
return {
|
|
43
|
+
envName: name,
|
|
44
|
+
value: String(env[name] || ''),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function saveCredentialKey(ctx, apiKeyEnv, apiKey) {
|
|
49
|
+
const name = String(apiKeyEnv || DEFAULT_API_KEY_ENV).trim() || DEFAULT_API_KEY_ENV
|
|
50
|
+
const value = String(apiKey || '').trim()
|
|
51
|
+
|
|
52
|
+
if (!value) {
|
|
53
|
+
throw new Error('API key cannot be empty')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const credentials = credentialsService(ctx)
|
|
57
|
+
if (!credentials || typeof credentials.set !== 'function') {
|
|
58
|
+
throw new Error('DSH credentials service is unavailable in this runtime profile')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const ref = await toCredentialRef(name)
|
|
62
|
+
await credentials.set(ref, value)
|
|
63
|
+
return { ok: true, envName: name }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function deleteCredentialKey(ctx, apiKeyEnv) {
|
|
67
|
+
const name = String(apiKeyEnv || '').trim()
|
|
68
|
+
if (!name) return { ok: false }
|
|
69
|
+
const credentials = credentialsService(ctx)
|
|
70
|
+
if (!credentials) return { ok: false }
|
|
71
|
+
try {
|
|
72
|
+
const ref = await toCredentialRef(name)
|
|
73
|
+
if (typeof credentials.unset === 'function') {
|
|
74
|
+
await credentials.unset(ref)
|
|
75
|
+
return { ok: true, envName: name }
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
ctx?.logger?.warn?.('[dsh-clinebot] Failed unsetting credential: ' + (err?.message || err))
|
|
79
|
+
}
|
|
80
|
+
return { ok: false }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function resolveKeyValue(ctx, apiKeyEnv) {
|
|
84
|
+
const refName = String(apiKeyEnv || DEFAULT_API_KEY_ENV).trim() || DEFAULT_API_KEY_ENV
|
|
85
|
+
const creds = credentialsService(ctx)
|
|
86
|
+
if (creds && typeof creds.resolve === 'function') {
|
|
87
|
+
try {
|
|
88
|
+
const ref = await toCredentialRef(refName)
|
|
89
|
+
const hit = await creds.resolve(ref)
|
|
90
|
+
if (hit?.value) {
|
|
91
|
+
return { envName: refName, value: hit.value, source: 'credentials' }
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
/* miss */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const fromEnv = resolveApiKey(refName)
|
|
99
|
+
if (fromEnv.value) {
|
|
100
|
+
return { ...fromEnv, source: 'env' }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { envName: refName, value: '', source: 'none' }
|
|
104
|
+
}
|