dsh-deepseek-account 0.1.0 → 0.1.2

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2 - 2026-08-30
4
+
5
+ - Republish the corrected provider-aware sidebar release exclusively through the repository's GitHub Actions Trusted Publisher workflow.
6
+ - Preserve the 0.1.1 runtime behavior without additional Grok or Codex provider changes.
7
+
8
+ ## 0.1.1 - 2026-08-30
9
+
10
+ - Make this plugin the sole owner of the provider-aware sidebar account card without changing Grok or Codex plugin behavior.
11
+ - Read Grok and Codex reset windows through their existing optional local RPCs; show Grok reset time and Codex five-hour and weekly reset times only.
12
+ - Keep DeepSeek balance and official top-up fully functional when Grok or Codex is not installed, and fall back to DeepSeek for unknown custom Providers.
13
+
3
14
  ## 0.1.0 - 2026-08-30
4
15
 
5
16
  - Create an independent DeepSeek Harness account plugin with a loopback-only balance RPC and a credential-isolated Host boundary.
package/README.en.md CHANGED
@@ -3,10 +3,13 @@
3
3
  An independent DeepSeek Harness account plugin that:
4
4
 
5
5
  - shows the balance associated with the configured DeepSeek API key when the current conversation selects DeepSeek or an unknown custom Provider;
6
+ - shows the reset time for Grok usage and the five-hour and weekly reset times for Codex usage when either Provider is selected;
6
7
  - presents CNY/USD total, granted, and topped-up balances in a dedicated settings page;
7
8
  - opens the official DeepSeek Platform for web sign-in and top-up.
8
9
 
9
- The sidebar component returns no content for Grok or Codex, allowing those Provider plugins to display their own usage limits. This plugin never receives web cookies or payment details and never submits a payment.
10
+ The sidebar shows exactly one item for the Provider selected by the current conversation. Grok and Codex data is read on demand through their existing local RPCs; this plugin does not change or take over either Provider plugin's authentication, models, settings, or other behavior. If either optional plugin is absent, only that Provider's quota source is unavailable while DeepSeek balance and top-up continue to work independently. Unknown custom Providers fall back to DeepSeek.
11
+
12
+ Only DeepSeek has a top-up entry. Grok and Codex show reset times only.
10
13
 
11
14
  ## Security boundary
12
15
 
@@ -19,7 +22,7 @@ The top-up destination is fixed to `https://platform.deepseek.com/balance`; sign
19
22
  After the formal release, install the exact version:
20
23
 
21
24
  ```sh
22
- dsh plugin --profile web add dsh-deepseek-account@0.1.0
25
+ dsh plugin --profile web add dsh-deepseek-account@0.1.2
23
26
  dsh web
24
27
  ```
25
28
 
@@ -29,4 +32,4 @@ dsh web
29
32
  npm run check
30
33
  ```
31
34
 
32
- The release branch is `yukiryou/v0.1.0`. `dist/` is generated during build and packaging and is not committed.
35
+ The release branch is `yukiryou/v0.1.2`. `dist/` is generated during build and packaging and is not committed.
package/README.md CHANGED
@@ -3,10 +3,13 @@
3
3
  DeepSeek Harness 的独立账户插件,负责:
4
4
 
5
5
  - 在当前对话选择 DeepSeek 或无法识别的自定义 provider 时显示 API Key 所属账户余额;
6
+ - 在当前对话选择 Grok 时显示额度重置时间,选择 Codex 时显示 5 小时和每周额度重置时间;
6
7
  - 在设置页展示 CNY/USD 总余额、赠送余额和充值余额;
7
8
  - 打开 DeepSeek 官方平台完成网页登录与充值。
8
9
 
9
- 选择 Grok 或 Codex 时,本插件的侧栏卡片返回空内容,由对应 provider 插件展示自己的使用额度。插件不接收网页 Cookie 或支付资料,也不会代替用户提交付款。
10
+ 侧栏始终只展示当前对话所选 provider 的一项信息。Grok 和 Codex 数据通过它们已经存在的本地 RPC 按需读取;本插件不修改或接管两个 provider 插件的登录、模型、设置或其他能力。未安装 Grok/Codex 插件时,仅对应额度显示“来源不可用”,DeepSeek 余额和充值仍可独立使用。无法识别的自定义 provider 默认回退到 DeepSeek。
11
+
12
+ 只有 DeepSeek 提供充值入口。Grok 和 Codex 仅显示额度重置时间。
10
13
 
11
14
  ## 安全边界
12
15
 
@@ -20,14 +23,14 @@ DeepSeek Harness 的独立账户插件,负责:
20
23
  npm run check
21
24
  ```
22
25
 
23
- 仓库开发分支为 `yukiryou/v0.1.0`。`dist/` 由构建和打包流程生成,不提交到 Git。
26
+ 仓库开发分支为 `yukiryou/v0.1.2`。`dist/` 由构建和打包流程生成,不提交到 Git。
24
27
 
25
28
  ## 安装
26
29
 
27
30
  正式发布后安装精确版本:
28
31
 
29
32
  ```sh
30
- dsh plugin --profile web add dsh-deepseek-account@0.1.0
33
+ dsh plugin --profile web add dsh-deepseek-account@0.1.2
31
34
  dsh web
32
35
  ```
33
36
 
@@ -6,7 +6,9 @@ window.__ModuleLoader__.load({
6
6
  const module = { exports: {} }
7
7
  const React = require("react")
8
8
  const namespace = "settings.deepseekAccount"
9
- const channel = "/dsh-deepseek-account"
9
+ const deepSeekChannel = "/dsh-deepseek-account"
10
+ const grokChannel = "/grok-auth"
11
+ const codexChannel = "/dsh-codex"
10
12
  const topUpUrl = "https://platform.deepseek.com/balance"
11
13
  const dictionaries = {
12
14
  zh: {
@@ -15,6 +17,7 @@ window.__ModuleLoader__.load({
15
17
  topUp: "登录并充值", officialNote: "登录和付款仅在 DeepSeek 官方网页完成;插件不读取网页 Cookie,也不会代为提交付款。",
16
18
  updated: "数据更新时间", loading: "正在读取余额…", unavailable: "暂时无法读取余额。", unconfigured: "请先在模型设置中配置 DeepSeek API Key。",
17
19
  unauthorized: "当前 API Key 无效或已失效。", rateLimited: "查询过于频繁,请稍后重试。", stale: "当前展示上一次成功读取的余额。",
20
+ grokQuota: "Grok 额度", codexQuota: "Codex 额度", fiveHour: "5 小时", weekly: "每周", resetsAt: "重置", resetUnknown: "重置时间不可用", sourceUnavailable: "额度来源不可用",
18
21
  },
19
22
  en: {
20
23
  nav: "DeepSeek account", title: "DeepSeek account", description: "View the balance of the account associated with the current API key and open the official DeepSeek Platform to top up.",
@@ -22,21 +25,70 @@ window.__ModuleLoader__.load({
22
25
  topUp: "Sign in and top up", officialNote: "Sign-in and payment happen only on the official DeepSeek website. The plugin never reads web cookies or submits payment.",
23
26
  updated: "Updated", loading: "Reading balance…", unavailable: "The balance is temporarily unavailable.", unconfigured: "Configure a DeepSeek API key in model settings first.",
24
27
  unauthorized: "The current API key was rejected.", rateLimited: "Too many balance requests. Try again later.", stale: "Showing the last successfully verified balance.",
28
+ grokQuota: "Grok quota", codexQuota: "Codex quota", fiveHour: "5-hour", weekly: "Weekly", resetsAt: "Resets", resetUnknown: "Reset time unavailable", sourceUnavailable: "Quota source unavailable",
25
29
  },
26
30
  }
27
31
 
28
- function accountClient(connection) {
32
+ function createAccountClient(connection) {
29
33
  return Object.freeze({
30
- async read(force, signal) {
31
- const result = await connection.rpc.call(channel, "read", { force: force === true }, signal)
32
- if (!plainRecord(result) || result.ok !== true) throw new Error("DeepSeek account RPC failed")
33
- const snapshot = safeSnapshot(result.value)
34
- if (snapshot === undefined) throw new Error("DeepSeek account RPC returned invalid data")
35
- return snapshot
34
+ async read(provider, force, signal) {
35
+ try {
36
+ if (provider === "grok") {
37
+ return safeGrokQuota(await connection.rpc.call(grokChannel, "dashboard", {}, signal))
38
+ ?? { provider, status: "unavailable" }
39
+ }
40
+ if (provider === "codex") {
41
+ return safeCodexUsage(await connection.rpc.call(codexChannel, "usage", {}, signal))
42
+ ?? { provider, status: "unavailable" }
43
+ }
44
+ const result = await connection.rpc.call(deepSeekChannel, "read", { force: force === true }, signal)
45
+ if (!plainRecord(result) || result.ok !== true) return { provider: "deepseek", status: "unavailable" }
46
+ const snapshot = safeSnapshot(result.value)
47
+ return snapshot === undefined
48
+ ? { provider: "deepseek", status: "unavailable" }
49
+ : { provider: "deepseek", ...snapshot }
50
+ } catch {
51
+ return { provider, status: "unavailable" }
52
+ }
36
53
  },
37
54
  })
38
55
  }
39
56
 
57
+ function safeGrokQuota(result) {
58
+ if (!plainRecord(result) || result.ok !== true || !plainRecord(result.value) || result.value.kind !== "dashboard") return undefined
59
+ if (!plainRecord(result.value.dashboard)) return undefined
60
+ const quota = result.value.dashboard.quota
61
+ if (!plainRecord(quota) || quota.state !== "ready") return undefined
62
+ const periodKind = quota.periodKind === "weekly" || quota.periodKind === "monthly" ? quota.periodKind : "current"
63
+ if (quota.resetsAt !== undefined && !validTime(quota.resetsAt)) return undefined
64
+ return {
65
+ provider: "grok",
66
+ status: "ready",
67
+ periodKind,
68
+ ...(quota.resetsAt === undefined ? {} : { resetsAt: quota.resetsAt }),
69
+ }
70
+ }
71
+
72
+ function safeCodexUsage(result) {
73
+ if (!plainRecord(result) || result.ok !== true || !plainRecord(result.value) || !Array.isArray(result.value.rateLimits) || result.value.rateLimits.length > 16) return undefined
74
+ const limit = result.value.rateLimits.find((candidate) => plainRecord(candidate) && candidate.limitId === "codex")
75
+ ?? result.value.rateLimits.find(plainRecord)
76
+ if (!plainRecord(limit)) return undefined
77
+ const windows = [limit.primary, limit.secondary]
78
+ .map(safeCodexWindow)
79
+ .filter((window) => window !== undefined)
80
+ .sort((left, right) => ({ "five-hour": 0, weekly: 1 })[left.kind] - ({ "five-hour": 0, weekly: 1 })[right.kind])
81
+ if (windows.length === 0) return undefined
82
+ return { provider: "codex", status: "ready", windows }
83
+ }
84
+
85
+ function safeCodexWindow(value) {
86
+ if (!plainRecord(value) || typeof value.usedPercent !== "number" || !Number.isFinite(value.usedPercent) || value.usedPercent < 0 || value.usedPercent > 100) return undefined
87
+ const kind = value.windowDurationMins === 300 ? "five-hour" : value.windowDurationMins === 10_080 ? "weekly" : undefined
88
+ if (kind === undefined || !validTimestamp(value.resetsAt)) return undefined
89
+ return { kind, resetsAt: value.resetsAt }
90
+ }
91
+
40
92
  function safeSnapshot(value) {
41
93
  if (!plainRecord(value)) return undefined
42
94
  if (value.status === "ready") return safeReady(value)
@@ -59,15 +111,28 @@ window.__ModuleLoader__.load({
59
111
  return { status: "ready", isAvailable: value.isAvailable, balances, fetchedAt: value.fetchedAt, stale: value.stale }
60
112
  }
61
113
 
62
- function useAccount(client, enabled = true) {
63
- const [state, setState] = React.useState({ status: "loading" })
114
+ function useAccount(client, provider = "deepseek", enabled = true) {
115
+ const [state, setState] = React.useState({ provider, status: "loading" })
64
116
  const [busy, setBusy] = React.useState(false)
65
117
  const refresh = React.useCallback(async (force = false) => {
66
118
  setBusy(true)
67
- try { setState(await client.read(force)) } catch { setState((previous) => previous.status === "ready" ? { status: "unavailable", reason: "network", lastGood: { ...previous, stale: true } } : { status: "unavailable", reason: "network" }) }
119
+ try { setState(await client.read(provider, force)) }
120
+ catch { setState({ provider, status: "unavailable" }) }
68
121
  finally { setBusy(false) }
69
- }, [client])
70
- React.useEffect(() => { if (enabled) void refresh(false) }, [enabled, refresh])
122
+ }, [client, provider])
123
+ React.useEffect(() => {
124
+ if (!enabled) return undefined
125
+ let active = true
126
+ const controller = new AbortController()
127
+ setState({ provider, status: "loading" })
128
+ setBusy(true)
129
+ void client.read(provider, false, controller.signal).then((value) => {
130
+ if (active) setState(value)
131
+ }).finally(() => {
132
+ if (active) setBusy(false)
133
+ })
134
+ return () => { active = false; controller.abort() }
135
+ }, [client, enabled, provider])
71
136
  return { state, busy, refresh }
72
137
  }
73
138
 
@@ -103,31 +168,45 @@ window.__ModuleLoader__.load({
103
168
  }
104
169
 
105
170
  function accountProvider(selected) {
106
- return selected === "grok" ? "grok" : selected === "dsh-codex" ? "codex" : "deepseek"
171
+ return selected === "llm-grok" || selected === "grok" ? "grok" : selected === "dsh-codex" ? "codex" : "deepseek"
107
172
  }
108
173
 
109
174
  function shownSnapshot(state) { return state.status === "ready" ? state : state.lastGood }
110
175
  function mainBalance(snapshot) { return snapshot?.balances.find((item) => item.currency === "CNY") ?? snapshot?.balances[0] }
111
176
  function money(balance) { return balance === undefined ? "—" : `${balance.currency === "CNY" ? "¥" : "$"}${balance.total}` }
112
177
 
178
+ function resetTime(value) { return value === undefined ? undefined : new Date(value).toLocaleString() }
179
+
180
+ function sidebarPresentation(provider, state, t) {
181
+ if (provider === "grok") {
182
+ const reset = state.status === "ready" ? resetTime(state.resetsAt) : undefined
183
+ return { label: t("grokQuota"), symbol: "G", summary: reset === undefined ? t(state.status === "loading" ? "loading" : "sourceUnavailable") : `${t("resetsAt")} ${reset}` }
184
+ }
185
+ if (provider === "codex") {
186
+ const windows = state.status === "ready" ? state.windows : []
187
+ const summary = windows.map((window) => `${t(window.kind === "five-hour" ? "fiveHour" : "weekly")} ${t("resetsAt")} ${resetTime(window.resetsAt)}`).join(" · ")
188
+ return { label: t("codexQuota"), symbol: "C", summary: summary || t(state.status === "loading" ? "loading" : "sourceUnavailable") }
189
+ }
190
+ return { label: t("balance"), symbol: "¥", summary: money(mainBalance(shownSnapshot(state))) }
191
+ }
192
+
113
193
  function SidebarBalance({ wide, ctx, client, t }) {
114
194
  const provider = useActiveAccountProvider(ctx)
115
- const { state, busy, refresh } = useAccount(client, provider === "deepseek")
116
- if (provider !== "deepseek") return null
117
- const summary = money(mainBalance(shownSnapshot(state)))
195
+ const { state, busy, refresh } = useAccount(client, provider)
196
+ const presentation = sidebarPresentation(provider, state, t)
118
197
  return React.createElement("button", {
119
198
  type: "button", className: wide ? "dsh-deepseek-account-card" : "dsh-deepseek-account-rail",
120
- disabled: busy, onClick: () => void refresh(true), "aria-label": `${t("balance")} ${summary}`,
199
+ disabled: busy, onClick: () => void refresh(true), "aria-label": `${presentation.label} ${presentation.summary}`,
121
200
  }, wide
122
201
  ? React.createElement(React.Fragment, null,
123
- React.createElement("span", { className: "dsh-deepseek-account-symbol", "aria-hidden": "true" }, "¥"),
124
- React.createElement("span", { className: "dsh-deepseek-account-copy" }, React.createElement("span", null, t("balance")), React.createElement("small", null, summary)),
202
+ React.createElement("span", { className: "dsh-deepseek-account-symbol", "aria-hidden": "true" }, presentation.symbol),
203
+ React.createElement("span", { className: "dsh-deepseek-account-copy" }, React.createElement("span", null, presentation.label), React.createElement("small", null, presentation.summary)),
125
204
  React.createElement("span", { "aria-hidden": "true" }, busy ? "…" : "↻"))
126
- : React.createElement("span", null, summary))
205
+ : React.createElement("span", null, presentation.symbol))
127
206
  }
128
207
 
129
208
  function AccountSettings({ client, t }) {
130
- const { state, busy, refresh } = useAccount(client)
209
+ const { state, busy, refresh } = useAccount(client, "deepseek")
131
210
  const shown = shownSnapshot(state)
132
211
  const reason = state.status === "unavailable" ? ({
133
212
  "credential-unconfigured": "unconfigured", "credential-unauthorized": "unauthorized", "rate-limited": "rateLimited",
@@ -164,7 +243,7 @@ window.__ModuleLoader__.load({
164
243
  ctx.effect(() => ctx.locale.register(namespace, dictionaries), "deepseek-account: dictionaries")
165
244
  ctx.effect(() => installStyle(), "deepseek-account: styles")
166
245
  const t = ctx.locale.bind(namespace)
167
- const client = accountClient(ctx.connection)
246
+ const client = createAccountClient(ctx.connection)
168
247
  ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
169
248
  name: "sidebar.footer.action", id: "deepseek-account", order: 35, label: t("balance"),
170
249
  inject: () => ({ ctx, client, t }),
@@ -178,6 +257,9 @@ window.__ModuleLoader__.load({
178
257
  module.exports.inject = inject
179
258
  module.exports.apply = apply
180
259
  module.exports.accountProvider = accountProvider
260
+ module.exports.createAccountClient = createAccountClient
261
+ module.exports.safeCodexUsage = safeCodexUsage
262
+ module.exports.safeGrokQuota = safeGrokQuota
181
263
  module.exports.safeSnapshot = safeSnapshot
182
264
  return module.exports
183
265
  },
@@ -186,3 +268,4 @@ window.__ModuleLoader__.load({
186
268
  function plainRecord(value) { return typeof value === "object" && value !== null && !Array.isArray(value) }
187
269
  function validDecimal(value) { return typeof value === "string" && value.length <= 64 && /^\d+(?:\.\d+)?$/u.test(value) }
188
270
  function validTime(value) { return typeof value === "string" && Number.isFinite(Date.parse(value)) }
271
+ function validTimestamp(value) { return Number.isSafeInteger(value) && value >= 0 && Number.isFinite(new Date(value).getTime()) }
@@ -0,0 +1,52 @@
1
+ ## 中文
2
+
3
+ `0.1.1` 修正侧栏职责:`dsh-deepseek-account` 独立拥有账户与额度侧栏,Grok 和 Codex provider 插件保持原有能力不变。
4
+
5
+ ### 功能
6
+
7
+ - 侧栏只显示当前对话所选 Provider 的信息;无法识别的自定义 Provider 回退 DeepSeek。
8
+ - DeepSeek 显示当前 API Key 的余额,并保留官方网页登录与充值入口。
9
+ - Grok 仅显示额度重置时间;Codex 仅显示 5 小时和每周额度重置时间。
10
+ - Grok/Codex 通过各自已经存在的本地 RPC 作为可选数据源,不新增跨插件依赖。
11
+
12
+ ### 兼容性与限制
13
+
14
+ - 未安装 Grok 或 Codex 插件时,`dsh-deepseek-account` 仍可独立读取 DeepSeek 余额和打开充值页;仅所选的缺失 Provider 显示额度来源不可用。
15
+ - 本版本不修改 Grok/Codex 的登录、模型、设置或额度页面。
16
+ - 插件不读取网页 Cookie、账户密码或支付资料,也不会代替用户提交付款。
17
+ - 自动化验证覆盖缺失可选插件、Provider 识别、响应投影、构建和打包;未执行真实账户充值。
18
+
19
+ 安装:
20
+
21
+ ```sh
22
+ dsh plugin --profile web add dsh-deepseek-account@0.1.1
23
+ dsh web
24
+ ```
25
+
26
+ <details>
27
+ <summary>English release notes</summary>
28
+
29
+ `0.1.1` corrects sidebar ownership: `dsh-deepseek-account` independently owns the account/quota sidebar while the Grok and Codex Provider plugins retain their existing behavior unchanged.
30
+
31
+ ### Features
32
+
33
+ - Shows only the current conversation's selected Provider and falls back to DeepSeek for unknown custom Providers.
34
+ - Shows the current API-key balance and official web top-up entry for DeepSeek.
35
+ - Shows only the reset time for Grok, and only the five-hour and weekly reset times for Codex.
36
+ - Reads Grok/Codex through their existing local RPCs as optional data sources without introducing a cross-plugin dependency.
37
+
38
+ ### Compatibility and limits
39
+
40
+ - DeepSeek balance and top-up remain independently functional when Grok or Codex is absent; only the selected missing Provider reports an unavailable quota source.
41
+ - This version does not change Grok/Codex authentication, models, settings, or quota pages.
42
+ - The plugin never reads web cookies, account passwords, or payment details and never submits a payment.
43
+ - Automated validation covers missing optional plugins, Provider recognition, response projection, build, and packaging. No real-account top-up was performed.
44
+
45
+ Install:
46
+
47
+ ```sh
48
+ dsh plugin --profile web add dsh-deepseek-account@0.1.1
49
+ dsh web
50
+ ```
51
+
52
+ </details>
@@ -0,0 +1,50 @@
1
+ ## 中文
2
+
3
+ `0.1.2` 通过仓库绑定的 GitHub Actions Trusted Publisher 工作流重新发布已修正的侧栏职责,并为 npm 包生成可验证的工作流 provenance。
4
+
5
+ ### 功能
6
+
7
+ - `dsh-deepseek-account` 独立拥有账户与额度侧栏,只展示当前对话所选 Provider。
8
+ - DeepSeek 显示 API Key 余额和官方充值入口;未知自定义 Provider 回退 DeepSeek。
9
+ - Grok 仅显示额度重置时间;Codex 仅显示 5 小时和每周额度重置时间。
10
+ - Grok/Codex 仍只是可选现有 RPC 数据源;未安装时不影响 DeepSeek 余额与充值。
11
+
12
+ ### 发布与兼容性
13
+
14
+ - 本版本运行时代码与 `0.1.1` 一致,没有修改 Grok/Codex provider 插件的登录、模型、设置或其他能力。
15
+ - npm 发布只允许由 `yoshino-xiao7/dsh-deepseek-account` 的 `release.yml` 在 `npm-release` 环境通过 OIDC 执行。
16
+ - 自动化验证覆盖缺失可选插件、Provider 识别、响应投影、跨平台构建和打包;未执行真实账户充值。
17
+
18
+ 安装:
19
+
20
+ ```sh
21
+ dsh plugin --profile web add dsh-deepseek-account@0.1.2
22
+ dsh web
23
+ ```
24
+
25
+ <details>
26
+ <summary>English release notes</summary>
27
+
28
+ `0.1.2` republishes the corrected sidebar ownership exclusively through the repository-bound GitHub Actions Trusted Publisher workflow, producing verifiable npm workflow provenance.
29
+
30
+ ### Features
31
+
32
+ - `dsh-deepseek-account` independently owns the account/quota sidebar and shows only the current conversation's selected Provider.
33
+ - DeepSeek shows the API-key balance and official top-up entry; unknown custom Providers fall back to DeepSeek.
34
+ - Grok shows only its reset time; Codex shows only its five-hour and weekly reset times.
35
+ - Grok/Codex remain optional existing RPC data sources. Their absence does not affect DeepSeek balance or top-up.
36
+
37
+ ### Publishing and compatibility
38
+
39
+ - Runtime code is identical to `0.1.1`; this release does not change Grok/Codex authentication, models, settings, or other behavior.
40
+ - npm publication is restricted to `release.yml` in the `npm-release` environment of `yoshino-xiao7/dsh-deepseek-account`, using OIDC.
41
+ - Automated validation covers absent optional plugins, Provider recognition, response projection, cross-platform builds, and packaging. No real-account top-up was performed.
42
+
43
+ Install:
44
+
45
+ ```sh
46
+ dsh plugin --profile web add dsh-deepseek-account@0.1.2
47
+ dsh web
48
+ ```
49
+
50
+ </details>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-deepseek-account",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "DeepSeek account balance and official top-up entry for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "license": "MIT",