@goodandready/dsh-subscriptions 0.6.3 → 0.6.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/lib/accounts.js +7 -1
- package/lib/http.js +1 -1
- package/lib/import-auth.js +20 -6
- package/lib/index.js +1 -1
- package/lib/routes/accounts.js +0 -1
- package/lib/routes/oauth.js +0 -1
- package/lib/routes/status.js +0 -1
- package/lib/routes.js +1 -9
- package/lib/vendors/claude-cli.js +6 -2
- package/lib/vendors/cody.js +12 -1
- package/package.json +1 -1
package/lib/accounts.js
CHANGED
|
@@ -12,6 +12,8 @@ export function normalizeSlots(slots) {
|
|
|
12
12
|
const out = []
|
|
13
13
|
const seen = new Set()
|
|
14
14
|
for (const slot of Array.isArray(slots) ? slots : []) {
|
|
15
|
+
// User-editable config: a null or non-object entry must be skipped, not crash the plugin.
|
|
16
|
+
if (!slot || typeof slot !== 'object') continue
|
|
15
17
|
if (!isProvider(slot.provider)) continue
|
|
16
18
|
const index = Number(slot.index)
|
|
17
19
|
if (!Number.isInteger(index) || index < 1) continue
|
|
@@ -105,10 +107,14 @@ export function createAccountStore({ credentials, getConfig, fetchImpl, fetchFor
|
|
|
105
107
|
quarantines.delete(ref)
|
|
106
108
|
writeQueues.delete(ref)
|
|
107
109
|
for (const k of [...notifyThresholds.keys()]) { if (k.startsWith(ref + ':')) notifyThresholds.delete(k) }
|
|
108
|
-
for (const k of [...notifyThresholds.keys()]) { if (k.startsWith(ref + ':')) notifyThresholds.delete(k) }
|
|
109
110
|
refreshFailures.delete(ref)
|
|
110
111
|
usage.delete(ref)
|
|
111
112
|
usageFetched.delete(ref)
|
|
113
|
+
// Counters and health must not outlive the account, otherwise a
|
|
114
|
+
// re-added slot inherits stale rotation statistics.
|
|
115
|
+
requestCounts.delete(ref)
|
|
116
|
+
health.delete(ref)
|
|
117
|
+
windows.delete(ref)
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
async function describeRef(ref) {
|
package/lib/http.js
CHANGED
|
@@ -12,7 +12,7 @@ export function writeHtml(res, code, html) {
|
|
|
12
12
|
} catch { /* socket closed */ }
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function readBody(req, maxBytes) {
|
|
15
|
+
export function readBody(req, maxBytes = 64 * 1024) {
|
|
16
16
|
return new Promise((resolve, reject) => {
|
|
17
17
|
const chunks = []
|
|
18
18
|
let size = 0
|
package/lib/import-auth.js
CHANGED
|
@@ -4,8 +4,12 @@ import { join } from 'node:path'
|
|
|
4
4
|
import { readClaudeCredentials } from './vendors/claude-cli.js'
|
|
5
5
|
import { discoverCodingAgentConfigs } from './importers/coding-agents.js'
|
|
6
6
|
|
|
7
|
+
// Test seam: a fixture root overrides the real home for the duration of a
|
|
8
|
+
// public call. Undefined (the default) keeps production behaviour.
|
|
9
|
+
let activeHome = null
|
|
10
|
+
|
|
7
11
|
function homeFile(...parts) {
|
|
8
|
-
return join(homedir(), ...parts)
|
|
12
|
+
return join(activeHome || homedir(), ...parts)
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
async function readJson(path) {
|
|
@@ -17,7 +21,17 @@ async function readJson(path) {
|
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
export async function discoverLocalCliSessions() {
|
|
24
|
+
export async function discoverLocalCliSessions(options = {}) {
|
|
25
|
+
const prevHome = activeHome
|
|
26
|
+
activeHome = options && options.home ? String(options.home) : null
|
|
27
|
+
try {
|
|
28
|
+
return await discoverLocalCliSessionsInner()
|
|
29
|
+
} finally {
|
|
30
|
+
activeHome = prevHome
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function discoverLocalCliSessionsInner() {
|
|
21
35
|
const detected = {}
|
|
22
36
|
|
|
23
37
|
// 1. Codex CLI
|
|
@@ -144,7 +158,7 @@ export async function discoverLocalCliSessions() {
|
|
|
144
158
|
}
|
|
145
159
|
|
|
146
160
|
// 8. Claude CLI Direct Import
|
|
147
|
-
const claudeCreds = await readClaudeCredentials()
|
|
161
|
+
const claudeCreds = await readClaudeCredentials(activeHome)
|
|
148
162
|
if (claudeCreds) {
|
|
149
163
|
detected['claude-cli'] = {
|
|
150
164
|
provider: 'claude',
|
|
@@ -186,13 +200,13 @@ export async function discoverLocalCliSessions() {
|
|
|
186
200
|
return detected
|
|
187
201
|
}
|
|
188
202
|
|
|
189
|
-
export async function loadLocalCliBlob(provider) {
|
|
190
|
-
const discovered = await discoverLocalCliSessions()
|
|
203
|
+
export async function loadLocalCliBlob(provider, options = {}) {
|
|
204
|
+
const discovered = await discoverLocalCliSessions(options)
|
|
191
205
|
const info = discovered[provider]
|
|
192
206
|
if (!info) throw new Error(`no local CLI session found for ${provider}`)
|
|
193
207
|
|
|
194
208
|
if (provider === 'claude-cli' || (provider === 'claude' && info.provider === 'claude')) {
|
|
195
|
-
const creds = await readClaudeCredentials()
|
|
209
|
+
const creds = await readClaudeCredentials(options && options.home)
|
|
196
210
|
if (!creds) throw new Error('Claude CLI credentials not found')
|
|
197
211
|
return {
|
|
198
212
|
accessToken: creds.accessToken,
|
package/lib/index.js
CHANGED
|
@@ -141,7 +141,7 @@ export function apply(ctx, config) {
|
|
|
141
141
|
if (!cfg.ollamaFallback || !models.length) throw err
|
|
142
142
|
const model = cfg.ollamaFallbackModel || models[0].id
|
|
143
143
|
try { ctx.emit && ctx.emit('subscriptions.ollama-fallback', { provider, model, reason: err && err.code || 'EXHAUSTED' }) } catch {}
|
|
144
|
-
try { ctx.log && ctx.log.warn && ctx.log.warn(`[dsh-subscriptions] ${provider}: all accounts exhausted (${err && err.code || 'EXHAUSTED'}),
|
|
144
|
+
try { ctx.log && ctx.log.warn && ctx.log.warn(`[dsh-subscriptions] ${provider}: all accounts exhausted (${err && err.code || 'EXHAUSTED'}), falling back to ollama/${model}`) } catch {}
|
|
145
145
|
try {
|
|
146
146
|
recordHistory({
|
|
147
147
|
provider: 'ollama',
|
package/lib/routes/accounts.js
CHANGED
package/lib/routes/oauth.js
CHANGED
package/lib/routes/status.js
CHANGED
package/lib/routes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { publicConfig } from './config-schema.js'
|
|
2
2
|
import { PROVIDERS, displayName } from './refs.js'
|
|
3
|
-
import { writeHtml, writeJson } from './http.js'
|
|
3
|
+
import { escapeHtml, writeHtml, writeJson } from './http.js'
|
|
4
4
|
import { registerStatusRoutes } from './routes/status.js'
|
|
5
5
|
import { registerOauthRoutes } from './routes/oauth.js'
|
|
6
6
|
import { registerAccountsRoutes } from './routes/accounts.js'
|
|
@@ -11,7 +11,6 @@ export function registerRoutes(ctx, state) {
|
|
|
11
11
|
accountsView,
|
|
12
12
|
history,
|
|
13
13
|
live,
|
|
14
|
-
subscriptions,
|
|
15
14
|
} = state
|
|
16
15
|
|
|
17
16
|
async function configResponse() {
|
|
@@ -101,10 +100,3 @@ function esc(x){return String(x==null?'':x).replace(/&/g,'&').replace(/</g,'
|
|
|
101
100
|
registerAccountsRoutes(ctx, state)
|
|
102
101
|
registerProxyRoutes(ctx, state)
|
|
103
102
|
}
|
|
104
|
-
|
|
105
|
-
export function escapeHtml(text) {
|
|
106
|
-
return String(text)
|
|
107
|
-
.replace(/&/g, '&')
|
|
108
|
-
.replace(/</g, '<')
|
|
109
|
-
.replace(/>/g, '>')
|
|
110
|
-
}
|
|
@@ -2,8 +2,12 @@ import { readFile } from 'node:fs/promises'
|
|
|
2
2
|
import { homedir } from 'node:os'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Read Claude Code CLI credentials. `home` is a test seam: when omitted the
|
|
7
|
+
* real user home is used, so production behaviour is unchanged.
|
|
8
|
+
*/
|
|
9
|
+
export async function readClaudeCredentials(home) {
|
|
10
|
+
const p = join(home || homedir(), '.claude', 'credentials.json')
|
|
7
11
|
try {
|
|
8
12
|
const text = await readFile(p, 'utf8')
|
|
9
13
|
const json = JSON.parse(text)
|
package/lib/vendors/cody.js
CHANGED
|
@@ -16,6 +16,11 @@ export const CODY_MODELS = [
|
|
|
16
16
|
}
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
+
/** Catalog id -> Sourcegraph model name. */
|
|
20
|
+
export const CODY_MODEL_ALIASES = {
|
|
21
|
+
'cody-claude-3.5-sonnet': 'claude-3-5-sonnet',
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
export function providerInfo() {
|
|
20
25
|
return { id, name: 'Sourcegraph Cody' }
|
|
21
26
|
}
|
|
@@ -50,8 +55,14 @@ export async function* streamOnce({ blob, options, fetchImpl, headers, config, s
|
|
|
50
55
|
if (!token) throw new LlmError('Sourcegraph Cody not authenticated', 'AUTH')
|
|
51
56
|
|
|
52
57
|
const url = `${(config && config.apiBase) || CODY_API_BASE}/chat/completions`
|
|
58
|
+
// Catalog ids carry a cody- prefix and dotted versions; the Sourcegraph
|
|
59
|
+
// API expects the bare dashed name (cody-claude-3.5-sonnet -> claude-3-5-sonnet).
|
|
60
|
+
const requested = String(options.model || '').trim()
|
|
61
|
+
const mapped = CODY_MODEL_ALIASES[requested]
|
|
62
|
+
|| requested.replace(/^cody-/, '').replace(/\./g, '-')
|
|
63
|
+
|| 'claude-3-5-sonnet'
|
|
53
64
|
const body = {
|
|
54
|
-
model:
|
|
65
|
+
model: mapped,
|
|
55
66
|
messages: openaiMessages(options),
|
|
56
67
|
stream: true
|
|
57
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-subscriptions",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Use ChatGPT Codex, Claude, Grok, Antigravity, Kimi, GLM, Cursor, Kiro, Copilot, Qwen, ERNIE, Spark, JetBrains, Perplexity, Replit, and Cody subscriptions as DeepSeek Harness LLM providers via OAuth.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|