@goodandready/dsh-subscriptions 0.6.2 → 0.6.3
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/ui-styles.js +13 -13
- package/package.json +5 -5
- package/lib/atomic-lock.js +0 -35
- package/lib/preflight-tokens.js +0 -23
- package/lib/revocation.js +0 -25
package/lib/ui-styles.js
CHANGED
|
@@ -2,14 +2,14 @@ export const CSS =
|
|
|
2
2
|
'.dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}' +
|
|
3
3
|
'.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}' +
|
|
4
4
|
'.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}' +
|
|
5
|
-
'.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:
|
|
5
|
+
'.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:18px 20px;display:flex}' +
|
|
6
6
|
'.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}' +
|
|
7
7
|
'.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}' +
|
|
8
|
-
'.dsub-name{color:var(--dsw-alias-label-primary);font-size:
|
|
8
|
+
'.dsub-name{color:var(--dsw-alias-label-primary);font-size:16px;font-weight:600;line-height:1.4}' +
|
|
9
9
|
'.dsub-description{color:var(--dsw-alias-label-secondary);font-size:13px}' +
|
|
10
10
|
'.dsub-chev{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}' +
|
|
11
11
|
'.dsub-chevOpen{transform:rotate(180deg)}' +
|
|
12
|
-
'.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0
|
|
12
|
+
'.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 20px;padding-bottom:12px}' +
|
|
13
13
|
'.dsub-block{margin-top:10px}' +
|
|
14
14
|
'.dsub-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px}' +
|
|
15
15
|
'.dsub-grow{flex:1 1 180px;min-width:140px}' +
|
|
@@ -25,13 +25,13 @@ export const CSS =
|
|
|
25
25
|
'.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}' +
|
|
26
26
|
'.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;word-break:break-word;max-width:100%}' +
|
|
27
27
|
'.dsub-hint{overflow-wrap:anywhere;word-break:break-word;max-width:100%}' +
|
|
28
|
-
'.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:
|
|
28
|
+
'.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:7px 14px;font-size:13px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}' +
|
|
29
29
|
'.dsub-btn:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}' +
|
|
30
|
-
'.dsub-inp{height:
|
|
30
|
+
'.dsub-inp{height:36px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;min-width:180px}' +
|
|
31
31
|
'.dsub-inp:focus{outline:none;border-color:var(--dsw-alias-brand-primary)}' +
|
|
32
|
-
'.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:
|
|
32
|
+
'.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:12px 14px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}' +
|
|
33
33
|
'.dsub-cooldown{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-state-warning-primary);color:#000;font-size:11px;font-weight:600}' +
|
|
34
|
-
'.dsub-bar{position:relative;height:
|
|
34
|
+
'.dsub-bar{position:relative;height:10px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}' +
|
|
35
35
|
'.dsub-barFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary);transition:width .2s}' +
|
|
36
36
|
'.dsub-barWarn .dsub-barFill{background:var(--dsw-alias-state-warning-primary)}' +
|
|
37
37
|
'.dsub-barFull .dsub-barFill{background:var(--dsw-alias-state-error-primary)}' +
|
|
@@ -62,11 +62,11 @@ export const CSS =
|
|
|
62
62
|
'.dsub-heroModel{font-size:11.5px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace}' +
|
|
63
63
|
'.dsub-heroBars{display:flex;flex-direction:column;gap:8px;margin-top:10px}' +
|
|
64
64
|
'.dsub-barLabelRow{display:flex;justify-content:space-between;font-size:11.5px;color:var(--dsw-alias-label-secondary);margin-bottom:3px}' +
|
|
65
|
-
'.dsub-barTrack{height:
|
|
65
|
+
'.dsub-barTrack{height:10px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}' +
|
|
66
66
|
'.dsub-barFillGrad{height:100%;border-radius:3px;transition:width .3s ease}' +
|
|
67
|
-
'.dsub-panel-box{margin-top:10px;padding:
|
|
67
|
+
'.dsub-panel-box{margin-top:10px;padding:14px 16px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:8px}' +
|
|
68
68
|
'.dsub-panel-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 5%,transparent)}' +
|
|
69
|
-
'.dsub-panel-title{font-size:
|
|
69
|
+
'.dsub-panel-title{font-size:16px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}' +
|
|
70
70
|
'.dsub-panel-desc{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}' +
|
|
71
71
|
'.dsub-usage-grid{display:flex;flex-direction:column;gap:8px;margin-top:4px}' +
|
|
72
72
|
'.dsub-usage-card{display:flex;flex-direction:column;gap:5px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}' +
|
|
@@ -74,9 +74,9 @@ export const CSS =
|
|
|
74
74
|
'.dsub-usage-track{width:100%;height:8px;border-radius:999px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);overflow:hidden}' +
|
|
75
75
|
'.dsub-usage-fill{height:100%;border-radius:999px;transition:width .3s ease}' +
|
|
76
76
|
'.dsub-usage-meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--dsw-alias-label-secondary)}' +
|
|
77
|
-
'.dsub-tag-ok{border-color:
|
|
78
|
-
'.dsub-tag-warn{border-color:
|
|
79
|
-
'.dsub-tag-bad{border-color:
|
|
77
|
+
'.dsub-tag-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;border-style:solid;border-width:1px}' +
|
|
78
|
+
'.dsub-tag-warn{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary);background:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 8%,transparent);padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;border-style:solid;border-width:1px}' +
|
|
79
|
+
'.dsub-tag-bad{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;border-style:solid;border-width:1px}' +
|
|
80
80
|
'.dsub-slot-meta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2);font-size:12px}' +
|
|
81
81
|
'.dsub-ref-tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}' +
|
|
82
82
|
'.dsub-ref-tag code{padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-family:ui-monospace,monospace;color:var(--dsw-alias-label-primary);font-size:11px}' +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-subscriptions",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
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",
|
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
"bugs": {
|
|
35
35
|
"url": "https://github.com/GooDAnDReaDY/dsh-subscriptions/issues"
|
|
36
36
|
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"test": "eslint lib/ && node --test test/*.test.mjs"
|
|
39
|
+
},
|
|
37
40
|
"dsh": {
|
|
38
41
|
"bundle": {
|
|
39
42
|
"patch": "./cordis.patch.yml"
|
|
@@ -60,8 +63,5 @@
|
|
|
60
63
|
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@deepseek-ai/dsh-llm": "0.1.0-rc.8"
|
|
63
|
-
},
|
|
64
|
-
"scripts": {
|
|
65
|
-
"test": "eslint lib/ && node --test test/*.test.mjs"
|
|
66
66
|
}
|
|
67
|
-
}
|
|
67
|
+
}
|
package/lib/atomic-lock.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { open, unlink } from 'node:fs/promises'
|
|
2
|
-
|
|
3
|
-
export async function withFileLock(filePath, fn, timeoutMs = 5000) {
|
|
4
|
-
const lockPath = `${filePath}.lock`
|
|
5
|
-
const start = Date.now()
|
|
6
|
-
let handle = null
|
|
7
|
-
|
|
8
|
-
while (Date.now() - start < timeoutMs) {
|
|
9
|
-
try {
|
|
10
|
-
handle = await open(lockPath, 'wx')
|
|
11
|
-
break
|
|
12
|
-
} catch (err) {
|
|
13
|
-
if (err.code === 'EEXIST') {
|
|
14
|
-
await new Promise((r) => setTimeout(r, 40))
|
|
15
|
-
continue
|
|
16
|
-
}
|
|
17
|
-
throw err
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!handle) {
|
|
22
|
-
throw new Error(`Failed to acquire lock on ${lockPath} after ${timeoutMs}ms`)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
return await fn()
|
|
27
|
-
} finally {
|
|
28
|
-
try {
|
|
29
|
-
await handle.close()
|
|
30
|
-
await unlink(lockPath)
|
|
31
|
-
} catch {
|
|
32
|
-
// ignore unlock errors
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
package/lib/preflight-tokens.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export function estimateTokens(text) {
|
|
2
|
-
if (!text || typeof text !== 'string') return 0
|
|
3
|
-
// Average English: ~4 chars per token; CJK/Code: ~1.5 - 2 chars per token
|
|
4
|
-
const hasCjk = /[\u4e00-\u9fa5]/.test(text)
|
|
5
|
-
const ratio = hasCjk ? 2 : 3.8
|
|
6
|
-
return Math.max(1, Math.ceil(text.length / ratio))
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function validateContextLimit(messages, contextWindowLimit = 128000) {
|
|
10
|
-
let totalChars = 0
|
|
11
|
-
for (const m of messages || []) {
|
|
12
|
-
const content = typeof m.content === 'string' ? m.content : JSON.stringify(m.content || '')
|
|
13
|
-
totalChars += content.length
|
|
14
|
-
}
|
|
15
|
-
const estimated = estimateTokens(totalChars > 0 ? 'x'.repeat(totalChars) : '')
|
|
16
|
-
const safe = estimated <= contextWindowLimit * 0.95
|
|
17
|
-
return {
|
|
18
|
-
estimatedTokens: estimated,
|
|
19
|
-
limit: contextWindowLimit,
|
|
20
|
-
isSafe: safe,
|
|
21
|
-
marginTokens: Math.max(0, Math.floor(contextWindowLimit * 0.95 - estimated))
|
|
22
|
-
}
|
|
23
|
-
}
|
package/lib/revocation.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
const REVOKED_ERRORS = new Set([
|
|
2
|
-
'invalid_grant',
|
|
3
|
-
'token_revoked',
|
|
4
|
-
'account_deactivated',
|
|
5
|
-
'session_expired'
|
|
6
|
-
])
|
|
7
|
-
|
|
8
|
-
export function isTokenRevokedError(err) {
|
|
9
|
-
if (!err) return false
|
|
10
|
-
const msg = String(err.message || err.error || err.code || '').toLowerCase()
|
|
11
|
-
for (const pattern of REVOKED_ERRORS) {
|
|
12
|
-
if (msg.includes(pattern)) return true
|
|
13
|
-
}
|
|
14
|
-
return false
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function handleAccountRevocation(account) {
|
|
18
|
-
return {
|
|
19
|
-
...account,
|
|
20
|
-
hasToken: false,
|
|
21
|
-
status: 'revoked',
|
|
22
|
-
needsReauth: true,
|
|
23
|
-
revokedAt: Date.now()
|
|
24
|
-
}
|
|
25
|
-
}
|