@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 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:14px 16px;display:flex}' +
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:15px;font-weight:600;line-height:1.4}' +
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 16px;padding-bottom:12px}' +
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:5px 12px;font-size:12.5px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}' +
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:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;min-width:180px}' +
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:10px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}' +
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:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}' +
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:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}' +
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:12px 14px;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}' +
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:13px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}' +
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:color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
78
- '.dsub-tag-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 40%,transparent);color:var(--dsw-alias-state-warning-primary);background:color-mix(in srgb,var(--dsw-alias-state-warning-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
79
- '.dsub-tag-bad{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}' +
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.2",
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
+ }
@@ -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
- }
@@ -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
- }