dsh-ollama-usage 0.1.4 → 0.1.6-beta.0

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/LICENSE CHANGED
File without changes
package/README.md CHANGED
File without changes
package/cordis.patch.yml CHANGED
File without changes
package/lib/client.js CHANGED
@@ -253,6 +253,8 @@ window.__ModuleLoader__.load({
253
253
  if (disposed) return
254
254
  if (res && res.ok && res.value && res.value.usage) {
255
255
  setData(res.value.usage); setHistory(res.value.history || null); setUpdatedAt(res.value.updatedAt || null); setError(''); setPhase('usage')
256
+ // snapshot 数据读自磁盘文件(插件无内存缓存),必然已持久化;服务端字段优先,缺省按不变式置 true
257
+ setPersisted(typeof res.value.persisted === 'boolean' ? res.value.persisted : true)
256
258
  }
257
259
  }).catch(() => {})
258
260
  refresh()
package/lib/index.js CHANGED
@@ -161,20 +161,20 @@ async function checkWithToken(token) {
161
161
  try {
162
162
  res = await fetchUsage(token)
163
163
  } catch (e) {
164
- return { ok: false, error: { code: 'network', message: String((e && e.message) || e) } }
164
+ return fail('network', String((e && e.message) || e))
165
165
  }
166
166
  if (res.status === 401 || res.status === 403) {
167
167
  // 凭证失效:清掉持久化的 token,保留历史
168
168
  const rec = readFile()
169
169
  if (rec && rec.token) writeFile({ token: null, updatedAt: rec.updatedAt, usage: rec.usage, history: rec.history || [] })
170
- return { ok: false, error: { code: 'unauthorized', message: '凭证无效或已过期(' + res.status + '),请重新登录或更换 API Key' } }
170
+ return fail('unauthorized', '凭证无效或已过期(' + res.status + '),请重新登录或更换 API Key')
171
171
  }
172
172
  if (res.status >= 400) {
173
- return { ok: false, error: { code: 'http-error', message: res.body || ('HTTP ' + res.status) } }
173
+ return fail('http-error', res.body || ('HTTP ' + res.status))
174
174
  }
175
175
  const parsed = parseUsage(res.body, res.status)
176
176
  if (!parsed.ok) {
177
- return { ok: false, error: { code: 'internal', message: parsed.message } }
177
+ return fail('internal', parsed.message)
178
178
  }
179
179
  // 持久化:token + 快照 + 历史(保留最近 24 条)
180
180
  const now = new Date().toISOString()
@@ -204,6 +204,17 @@ async function autoRefresh() {
204
204
  * RPC 端点分派
205
205
  * ------------------------------------------------------------------ */
206
206
 
207
+ /**
208
+ * Canonical Connection RPC failure result (mirrors alpha.4's
209
+ * ConnectionRpcFailure: code + message + details object). The alpha.4
210
+ * browser caller (dsh-client-connection parseConnectionResponse) REJECTS
211
+ * failures without a `details` object (`TypeError: connection: invalid
212
+ * server-response failure`), so every error result must carry one.
213
+ */
214
+ function fail(code, message) {
215
+ return { ok: false, error: { code, message, details: {} } }
216
+ }
217
+
207
218
  async function dispatch(endpoint, payload) {
208
219
  if (endpoint === 'check') {
209
220
  const manual = payload && typeof payload.token === 'string' ? payload.token.trim() : ''
@@ -214,14 +225,15 @@ async function dispatch(endpoint, payload) {
214
225
  token = (rec && rec.token) || null
215
226
  }
216
227
  if (!token) token = readLocalToken()
217
- if (!token) return { ok: false, error: { code: 'no-token', message: '未检测到本地登录凭证,也未提供 API Key' } }
228
+ if (!token) return fail('no-token', '未检测到本地登录凭证,也未提供 API Key')
218
229
  return checkWithToken(token)
219
230
  }
220
231
  if (endpoint === 'snapshot') {
221
232
  const rec = readFile()
222
- if (!rec || !rec.usage) return { ok: false, error: { code: 'no-data', message: '暂无持久化的用量数据' } }
233
+ if (!rec || !rec.usage) return fail('no-data', '暂无持久化的用量数据')
223
234
  const usage = withResetTimes(rec.usage, new Date().toISOString())
224
- return { ok: true, value: { tokenPersisted: !!rec.token, updatedAt: rec.updatedAt, history: (rec.history || []).slice(-5), usage } }
235
+ // snapshot 数据读自磁盘文件(插件无内存缓存),必然已持久化;与 check 端点一致地报告 persisted
236
+ return { ok: true, value: { tokenPersisted: !!rec.token, persisted: true, updatedAt: rec.updatedAt, history: (rec.history || []).slice(-5), usage } }
225
237
  }
226
238
  if (endpoint === 'forget') {
227
239
  const rec = readFile()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ollama-usage",
3
- "version": "0.1.4",
3
+ "version": "0.1.6-beta.0",
4
4
  "description": "DeepSeek Harness 插件:可视化 Ollama Cloud 账号用量余量(每 5 小时会话用量 + 周用量),支持侧边栏双横条、设置页面板、API Key 与用量快照持久化、自动刷新与登录引导。Ollama Pro usage & remaining-quota visualization for DeepSeek Harness: 5-hour session + weekly quota bars in the sidebar footer, a full settings panel, persisted API key and usage snapshots, auto-refresh and login guidance.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -19,15 +19,26 @@
19
19
  },
20
20
  "client": {
21
21
  "platform": "web",
22
- "inject": ["slots", "connection", "timer"]
22
+ "inject": [
23
+ "slots",
24
+ "connection",
25
+ "timer"
26
+ ]
23
27
  }
24
28
  },
25
29
  "dshhub": {
26
30
  "schemaVersion": 1,
27
31
  "displayName": "dsh-ollama-usage",
28
32
  "summary": "Ollama Cloud 用量余量可视化:会话(5h)/周用量双横条 + 设置页完整面板,Key 与快照持久化,自动刷新,登录引导。",
29
- "categories": ["用量", "Web UI", "观测"],
30
- "surfaces": ["host", "web"],
33
+ "categories": [
34
+ "用量",
35
+ "Web UI",
36
+ "观测"
37
+ ],
38
+ "surfaces": [
39
+ "host",
40
+ "web"
41
+ ],
31
42
  "capabilities": {
32
43
  "provides": []
33
44
  },
@@ -36,7 +47,9 @@
36
47
  "node": ">=20"
37
48
  },
38
49
  "permissions": {
39
- "network": ["https://ollama.com"]
50
+ "network": [
51
+ "https://ollama.com"
52
+ ]
40
53
  }
41
54
  },
42
55
  "files": [
@@ -46,7 +59,7 @@
46
59
  "LICENSE"
47
60
  ],
48
61
  "dependencies": {
49
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6"
62
+ "@deepseek-ai/dsh-home-paths": "^0.1.2-alpha.4"
50
63
  },
51
64
  "repository": {
52
65
  "type": "git",
@@ -70,6 +83,6 @@
70
83
  ],
71
84
  "license": "MIT",
72
85
  "scripts": {
73
- "test": "DSH_HOME=.tmp-dsh-home HOME=.tmp-home node test/bridge-smoke.mjs"
86
+ "test": "DSH_HOME=.tmp-dsh-home HOME=.tmp-home node test/bridge-smoke.mjs && DSH_HOME=.tmp-env-dsh-home HOME=.tmp-env-home node test/rpc-envelope-alpha4.mjs"
74
87
  }
75
88
  }