deepseek-harness-wallet 0.3.11 → 0.3.13

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
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 0.3.13 - Unreleased
6
+
7
+ - 合并新版工作区选择修复与完整的 Harness 0.1.5-alpha.1 适配;0.3.12 因发布时间早于最后修复提交,保留为过渡版本。 / Include the final workspace-selection fix and complete Harness 0.1.5-alpha.1 adaptation; 0.3.12 remains a transitional release because it predates the final fix.
8
+
9
+ ## 0.3.12 - 2026-09-09
10
+
11
+ - 修复新版宿主中钱包模型目录调用缺少 `remote.session` 注入而中断工作区/会话界面的问题。 / Declare the remote session dependency required by model-directory calls so workspace/session rendering does not fail on newer hosts.
12
+ - 增加 DSH `0.1.5-alpha.1` 的精确兼容声明;健康检查只对清单中明确记录的版本显示兼容,未来版本保持“尚未验证”。 / Declare exact DSH `0.1.5-alpha.1` compatibility; health checks keep unverified future releases unknown instead of assuming every newer host is compatible.
13
+ - 更新中英文介绍、兼容验证范围、源码位置、账本容量和汇率估算说明,区分钱包功能与宿主删除能力。 / Refresh bilingual feature and compatibility descriptions, source paths, ledger bounds, and currency-estimate limitations; distinguish wallet features from host-provided deletion.
14
+
5
15
  ## 0.3.11 - 2026-09-05
6
16
 
7
17
  - 切换账户时清除旧余额并启动独立刷新,取消旧请求并忽略其迟到成功或失败;删除当前账户后重新读取宿主凭据对应的余额。 / Clear cached balance on account switches, start a fresh request, and discard stale successes or failures; refresh the host-credential balance after removing the active account.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/deepseek-harness-wallet?label=npm&color=5965d8)](https://www.npmjs.com/package/deepseek-harness-wallet)
4
4
  [![GitHub release](https://img.shields.io/github/v/release/feibi-mochi/deepseek-harness-control-center?label=release&color=5965d8)](https://github.com/feibi-mochi/deepseek-harness-control-center/releases)
5
5
  [![CI](https://github.com/feibi-mochi/deepseek-harness-control-center/actions/workflows/validate.yml/badge.svg)](https://github.com/feibi-mochi/deepseek-harness-control-center/actions/workflows/validate.yml)
6
- [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek%20Harness-0.1.1--rc.2-4aa3ff)](https://github.com/deepseek-ai/DeepSeek-Harness)
6
+ [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek%20Harness-0.1.5--alpha.1-4aa3ff)](https://github.com/deepseek-ai/DeepSeek-Harness)
7
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-3b7a57)](./LICENSE)
8
8
 
9
9
  **DeepSeek Harness monitoring, alerts, recharge, and session control center.**
@@ -14,12 +14,14 @@
14
14
 
15
15
  > A local-first companion that keeps account status, per-conversation usage, completion reminders, official recharge, flexible layout, and host-gated session controls beside the DSH composer.
16
16
 
17
- > **Version:** v0.3.11.
17
+ > **Version:** v0.3.13 (unreleased).
18
18
 
19
19
  > If DeepSeek Harness Control Center helps you, please consider leaving a ⭐ Star. Thank you!
20
20
 
21
21
  ## What it does
22
22
 
23
+ The wallet UI is currently primarily Chinese and does not yet follow the host language setting (#32). DeepSeek balances come from the official API; cost accounting is a local estimate.
24
+
23
25
  ```
24
26
  余额 ¥5.89 · 本场 ¥0.72 · 官 18.8M | 三方 800K · ↗充
25
27
  ```
@@ -30,7 +32,7 @@
30
32
  - **Official pricing sync** — periodically checks the official DeepSeek pricing page and applies only a fully validated table. Network failures retain the last validated rule (or the built-in rule before the first successful sync); an unrecognized page structure is marked for review instead of silently changing billing.
31
33
  - **Z.ai Coding Plan quotas** — a generic official-plan adapter monitors configured Global and China plans without exposing credentials. It separates the 5-hour model-token window from monthly MCP-tool usage, leads with quota remaining from 100% down while keeping usage as secondary context, retains the last successful snapshot on failure, and never converts subscription quota into CNY balance.
32
34
  - **Provider-aware composer surfaces** — the chip and sidebar clock follow the session's selected provider/model. Z.ai—including transparent `vision-toolkit-` variants—replaces DeepSeek balance, recharge, and peak pricing with plan-window summaries; unrelated providers show only their own session tokens, and DeepSeek V4 restores the wallet and peak clock.
33
- - **365-day local usage ledger** — Wallet settings keeps the heatmap visible, while compact wallet panels keep it collapsible. Stable request identities are deduplicated, official cost is locked at usage time, official and third-party data stay separate, and prompts or responses are never stored. Collection begins after upgrading to v0.3.2; older aggregate counters have no trustworthy dates and are not backfilled.
35
+ - **Local usage ledger (up to 365 days / 20,000 events)** — Wallet settings keeps the heatmap visible, while compact wallet panels keep it collapsible. Stable request identities are deduplicated, official cost is locked at usage time, official and third-party data stay separate, and prompts or responses are never stored. Collection begins after upgrading to v0.3.2; older aggregate counters have no trustworthy dates and are not backfilled.
34
36
  - **Third-party total** — current-session tokens (input / cache read / output) remain available with zero configuration.
35
37
  - **Custom third-party pricing** — enter an exact Provider/model route, currency, and base per-million input/cache-read/cache-write/output rates, then optionally add multiple IANA-timezone, weekday, and cross-midnight pricing windows. Current-session and 365-day ledger costs are recalculated locally by occurrence time and clearly labeled as user-defined estimates, never as provider balances or invoices.
36
38
  - **Provider classification** — observed wrapper routes appear in the settings page; opted-in routes join the official token/cost bucket for subsequent calls and are priced with the official table. Existing history is not retroactively reclassified.
@@ -39,7 +41,6 @@
39
41
  - **Composer-label controls and skin compatibility** — independently show/hide the composer label or reduce it to the primary remaining value (DeepSeek balance, Z.ai five-hour quota) without disabling reminders, settings, plan monitoring, or history. The standard chip also resists broad skin button rules and aligns with maid-atelier's 38px navy-and-gold composer toolbar.
40
42
  - **Floating window mode** — detach the detail panel into a draggable window with a remembered position, or minimize it directly to a freely movable dot; the dot turns red below the threshold.
41
43
  - **Completion reminders** — optionally notify when a conversation finishes, with persistent or timed modes, queueing and deduplication for simultaneous completions, cross-tab coordination, and an in-page fallback when system notifications are unavailable.
42
- - **Optional permanent deletion** — when the DSH host advertises a real deletion capability, an opt-in setting enables a confirmed permanent-delete action in the session menu; unsupported hosts keep the control disabled.
43
44
  - **Low-balance alert** — below the threshold the chip turns red with a breathing animation and fires one desktop notification; it resets automatically once the balance recovers.
44
45
  - **Theme-native UI** — uses DSH `--dsw-alias-*` variables with safe fallback colors, so light and dark themes both render correctly; the panel closes when you click outside and flips open-direction near screen edges.
45
46
  - **Clear current-session wallet data** — one button clears only the open conversation's token/cost records; it does not delete the conversation, and every other conversation is untouched. Historical ledger clearing is a separate action.
@@ -47,30 +48,16 @@
47
48
  ## Multi-account
48
49
 
49
50
  - Open the wallet panel → **Account Management(账户管理)** to add accounts (name + API key), switch the active one, or remove them.
50
- - The first account added becomes the active account automatically and is synced into the credentials seam.
51
+ - Adding the first account attempts to synchronize its key with the host credential store. It activates only if that write succeeds; a refused write retains the saved account without marking it active for billing.
51
52
  - Switching prompts a confirmation because it changes **LLM billing** for subsequent requests: the switch writes the account key into the credentials seam (`credentials.set('DEEPSEEK_API_KEY', ...)`), and since the llm-deepseek provider route resolves that reference per request, the very next LLM call is billed with the new account — no restart needed.
52
53
  - Account keys are encrypted at rest in `$DSH_HOME/storages/accounts.json`: Windows uses the current user's DPAPI; other platforms use an owner-only AES-GCM key file. An encrypted `.bak` recovers a missing, corrupt, or undecryptable primary file; if neither copy can be read, writes are locked instead of overwriting account data. The UI only shows masked keys.
53
- - Session usage estimates follow the active account's currency: USD-settled accounts show `本约 $x`, converted from the CNY price table at the vendor's long-standing list ratio (not a live FX rate); CNY accounts show `本场 ¥x`. These are local estimates, not an official invoice.
54
+ - Session usage estimates follow the active account's currency: USD-settled accounts show `本约 $x`, converted from the CNY price table using a fixed estimate of 7.25 CNY per USD (neither a live exchange rate nor the official USD tariff); CNY accounts show `本场 ¥x`. These are local estimates, not an official invoice.
54
55
  - If `DEEPSEEK_API_KEY` is supplied by the launching environment, switching is refused with a clear error (the credentials provider rejects shadowed writes) — unset it in your shell to enable switching.
55
56
 
56
57
 
57
58
  ## Project overview
58
59
 
59
- ### One place for the signals that matter
60
-
61
- DeepSeek Harness can keep several conversations and model providers active at once, but balance, usage, background-task status, and session actions normally live in different places. Control Center brings the information worth checking repeatedly beside the composer, so the current workflow can answer three questions at a glance: **How much official balance remains? What has this conversation used? Does anything need attention?**
62
-
63
- ### Present when needed, quiet when not
64
-
65
- The project is designed around quick reading and in-context action rather than another full-page dashboard. Its compact surface expands only when needed, adapts to the available space, and leaves layout and reminder behavior under the user's control. Accounting remains separated by conversation and provider, while wallet-data cleanup and permanent session deletion remain intentionally different operations.
66
-
67
- ### Extensible without hiding the boundaries
68
-
69
- The npm package handles monitoring and interface behavior; optional host powers are enabled only when DSH actually provides them. That capability-based boundary keeps unsupported actions visibly unavailable and gives browsers or desktop wrappers a small, reviewable adaptation surface. Future providers and controls can therefore be added without changing the established `deepseek-harness-wallet` package identity or silently expanding what the plugin is trusted to do.
70
-
71
- > **Want permanent session deletion?** It cannot be enabled by configuring the plugin alone. Give the [integration guide](./integrations/dsh-session-delete/README.md) and [Agent adaptation prompt](./integrations/dsh-session-delete/AGENT_PROMPT.md) to an Agent with access to the buildable DSH source. The control-panel switch becomes available only after the host implementation is built, tested, and advertises the capability.
72
-
73
- Details: [compatibility](#browser-desktop-and-os-compatibility) · [data and trust](#data--trust) · [pricing](#pricing-timeline)
60
+ DeepSeek Harness Wallet is for users who want to check balances during a conversation, compare model costs, or manage multiple accounts. A chip beside the composer shows the selected model’s balance, remaining plan quota, or token usage; open it for details or detach it into a floating panel. Settings brings together encrypted accounts, low-balance and completion reminders, a usage heatmap, and fixed or time-of-use prices for third-party APIs. DeepSeek balances and Z.ai quotas come from their respective APIs. Costs are estimated locally from host-reported usage, helping you track consumption without replacing provider invoices.
74
61
 
75
62
  ## Install
76
63
 
@@ -112,12 +99,14 @@ dsh plugin --profile web remove deepseek-harness-wallet
112
99
 
113
100
  ## Browser, desktop, and OS compatibility
114
101
 
102
+ See [0.3.13 compatibility evidence](https://github.com/feibi-mochi/deepseek-harness-control-center/blob/main/docs/compatibility-0.3.13.md). The official 0.1.5-alpha.1 host does not provide this plugin’s permanent-delete capability, so that switch stays disabled; the old source integration patch is not a drop-in update.
103
+
115
104
  The client contains no operating-system-specific feature branch; it checks the Web and host capabilities it needs. That makes the same code portable, but **portable code is not the same as real-device verification**:
116
105
 
117
106
  | Verification level | Coverage |
118
107
  | --- | --- |
119
- | Real environment checked for this release | Windows + current Edge + DSH Web |
120
- | Verified Harness versions | `0.1.1-rc.2` and isolated `0.1.2-alpha.3` Web profiles; the alpha profile was built from its official tag and started with no real credentials |
108
+ | Current local verification | Windows + Node 24.18.1 + DSH 0.1.5-alpha.1; keyless Web UI and isolated lifecycle checks. No live paid-API acceptance |
109
+ | Exact host coverage | 0.1.5-alpha.1 checked for this update; earlier 0.1.2-alpha.3/alpha.4/alpha.5/rc.1 evidence belongs to previous wallet releases. Other releases remain unverified |
121
110
  | Automated compatibility checks | Browser notification failure, in-page fallback, cross-tab fallback, storage fallback, CSS-scale fallback, and synchronous/asynchronous desktop adapters |
122
111
  | Capability-compatible targets | Current Chrome, Edge, and Firefox on Windows/macOS/Linux; Safari on macOS; Electron/Tauri-style DSH wrappers that provide the requirements below |
123
112
 
@@ -139,10 +128,14 @@ window.__DSH_WALLET_ADAPTER__ = {
139
128
  }
140
129
  ```
141
130
 
142
- `notify()` may return a notification-like handle, a Promise for one, or nothing for fire-and-forget native APIs. The payload also includes `onClick` / `onClose` callbacks so Electron IPC, Tauri notification actions, and other desktop bridges can return events without copying wallet logic; returning `false` asks the wallet to use its browser fallback. `requestNotificationPermission()` is optional for hosts such as Tauri and macOS that require a native permission request. Returning `false` from `openExternal()` likewise asks the wallet to try the browser fallback. Declare `permanentDelete` only when the host actually implements the wallet preference and session-menu action; compatible hosts advertise it automatically, while unsupported hosts show a disabled control instead of a switch that has no effect. Platform adaptations are intentionally confined to `createCompatibilityAdapter()` in `lib/client.js`, so an Agent can add a new wrapper without editing wallet accounting or UI logic.
131
+ `notify()` may return a notification-like handle, a Promise for one, or nothing for fire-and-forget native APIs. The payload also includes `onClick` / `onClose` callbacks so Electron IPC, Tauri notification actions, and other desktop bridges can return events without copying wallet logic; returning `false` asks the wallet to use its browser fallback. `requestNotificationPermission()` is optional for hosts such as Tauri and macOS that require a native permission request. Returning `false` from `openExternal()` likewise asks the wallet to try the browser fallback. Declare `permanentDelete` only when the host actually implements the wallet preference and session-menu action; compatible hosts advertise it automatically, while unsupported hosts show a disabled control instead of a switch that has no effect. Platform adaptations are intentionally confined to `createCompatibilityAdapter()` in `src/client/core.js`, so an Agent can add a new wrapper without editing wallet accounting or UI logic.
143
132
 
144
133
  For buildable DSH hosts, the npm package and repository include a versioned [Agent-assisted permanent-delete integration kit](./integrations/dsh-session-delete/README.md) with a Chinese guide, complete Agent prompt, read-only preflight, compatibility manifest, upstream notice, and an exact-baseline reference patch. The patch is not a universal installer: a different DSH commit must be inspected and adapted by semantics, and closed or non-rebuildable desktop applications remain unsupported.
145
134
 
135
+ ## Optional host integration
136
+
137
+ Permanent session deletion is implemented by the host, not the wallet. Its switch remains disabled on the official 0.1.5-alpha.1 host. For a source integration, see the [guide](./integrations/dsh-session-delete/README.md) and [Agent adaptation prompt](./integrations/dsh-session-delete/AGENT_PROMPT.md); the old reference patch is not a drop-in update for newer hosts.
138
+
146
139
  ## Data & trust
147
140
 
148
141
  Client development now uses five readable files under `src/client/` and a committed `lib/client.js` artifact; run `npm ci`, `npm run build:client`, and `npm run check:client` after source edits. Installation runs no build scripts. Exact-version smoke checks are documented in [0.3.10 compatibility evidence](https://github.com/feibi-mochi/deepseek-harness-control-center/blob/main/docs/compatibility-0.3.10.md).
@@ -152,7 +145,7 @@ Client development now uses five readable files under `src/client/` and a commit
152
145
  | Token accounting | Listens to the `llm/stream` event and buckets per session and provider: `deepseek-official` plus explicitly opted-in wrapper routes use the official bucket; other providers stay third-party; each usage event also locks its contemporaneous official price, so multiple sessions and pricing windows never mix. |
153
146
  | Balance | The wallet plugin itself sends the active key directly only to the official `/user/balance` endpoint. When multi-account switching is enabled, the selected key is also written into the DSH credentials seam; DSH may then use it for subsequent model requests. |
154
147
  | Accounts | Keys live encrypted in `$DSH_HOME/storages/accounts.json`, with an encrypted `accounts.json.bak` fallback for a missing, corrupt, or undecryptable primary. Windows uses current-user DPAPI; other platforms use an owner-only AES-GCM key file, so move `accounts.json`, `.bak`, and `.key` together. If neither copy can be read, account writes fail closed. |
155
- | Usage ledger | Local events and custom third-party price rules live in `$DSH_HOME/storages/wallet.json` with a `wallet.json.bak` recovery copy. Missing/corrupt primaries recover automatically; if neither copy is readable, wallet writes fail closed. Up to 365 days of session/provider/model/token metadata and official locked cost are kept—never prompts, tool arguments, response bodies, or API keys. Third-party estimates are recalculated from the current custom rule and each retained event's occurrence time; aggregate usage without a retained timestamp safely falls back to the base rate. |
148
+ | Usage ledger | Local events and custom third-party price rules live in `$DSH_HOME/storages/wallet.json` with a `wallet.json.bak` recovery copy. Missing/corrupt primaries recover automatically; if neither copy is readable, wallet writes fail closed. Up to 365 days and 20,000 events of session/provider/model/token metadata and official locked cost are kept—never prompts, tool arguments, response bodies, or API keys. Third-party estimates are recalculated from the current custom rule and each retained event's occurrence time; aggregate usage without a retained timestamp safely falls back to the base rate. |
156
149
  | Local settings | Layout, scale, visibility, reminder, and panel settings stay in browser-compatible local storage. |
157
150
  | Permanent deletion | Opt-in and host-gated. The wallet never advertises the action unless the host implements the matching session deletion path. |
158
151
  | Model surface | No tools registered, no prompt injection, zero token cost. |
package/index.js CHANGED
@@ -34,11 +34,11 @@ const TRANSPARENT_PROVIDER_PREFIX = 'vision-toolkit-'
34
34
  // DeepSeek's official paid-API bucket by the wrapper-provider alias control.
35
35
  const PLAN_PROVIDER_IDS = new Set(PLAN_ADAPTERS.map((adapter) => adapter.provider))
36
36
  const RECHARGE_URL = 'https://platform.deepseek.com/top_up'
37
- const PLUGIN_VERSION = '0.3.11'
37
+ const PLUGIN_VERSION = '0.3.13'
38
38
  const PRICING_SOURCE_URL = 'https://api-docs.deepseek.com/zh-cn/quick_start/pricing/'
39
39
  const PRICING_SYNC_INTERVAL_MS = 6 * 60 * 60_000
40
40
  const PRICING_SYNC_TIMEOUT_MS = 8_000
41
- const MIN_HOST_VERSION = '0.1.0-rc.8'
41
+ const MIN_HOST_VERSION = '0.1.2-alpha.3'
42
42
  const DSH_HOME = process.env.DSH_HOME ?? join(homedir(), '.dsh')
43
43
  const STORE_PATH = join(DSH_HOME, 'storages', 'wallet.json')
44
44
  const STORE_BACKUP_PATH = STORE_PATH + '.bak'
@@ -414,6 +414,7 @@ function detectHostManifest() {
414
414
 
415
415
  function compareVersions(left, right) {
416
416
  const parse = (value) => {
417
+ if (typeof value !== 'string') return null
417
418
  const match = typeof value === 'string' && value.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/)
418
419
  if (match === null) return null
419
420
  return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]), pre: match[4] || '' }
@@ -431,15 +432,22 @@ function compareVersions(left, right) {
431
432
  }
432
433
 
433
434
  const HOST_MANIFEST = detectHostManifest()
435
+ const COMPATIBILITY_RELEASES = readPackageManifest(new URL('./package.json', import.meta.url))?.dsh?.compatibility?.dshReleases || {}
434
436
 
435
- export function hostHealthSnapshot() {
436
- const hostVersion = HOST_MANIFEST.version
437
+ export function hostCompatibility(hostVersion) {
437
438
  const comparison = compareVersions(hostVersion, MIN_HOST_VERSION)
438
- const compatibility = comparison === null
439
+ return comparison === null
439
440
  ? { status: 'unknown', minimumVersion: MIN_HOST_VERSION, message: '无法读取 Harness 版本' }
440
- : comparison >= 0
441
- ? { status: 'compatible', minimumVersion: MIN_HOST_VERSION, message: '满足插件最低版本要求' }
442
- : { status: 'upgrade-recommended', minimumVersion: MIN_HOST_VERSION, message: 'Harness 版本低于插件建议版本' }
441
+ : comparison < 0
442
+ ? { status: 'upgrade-recommended', minimumVersion: MIN_HOST_VERSION, message: 'Harness 版本低于插件建议版本' }
443
+ : Object.hasOwn(COMPATIBILITY_RELEASES, hostVersion) && COMPATIBILITY_RELEASES[hostVersion] === 'compatible'
444
+ ? { status: 'compatible', minimumVersion: MIN_HOST_VERSION, message: '该精确版本已声明兼容;验证范围见兼容文档' }
445
+ : { status: 'unknown', minimumVersion: MIN_HOST_VERSION, message: '该 Harness 版本尚未验证兼容性' }
446
+ }
447
+
448
+ export function hostHealthSnapshot() {
449
+ const hostVersion = HOST_MANIFEST.version
450
+ const compatibility = hostCompatibility(hostVersion)
443
451
  return {
444
452
  name: HOST_MANIFEST.name,
445
453
  version: hostVersion,