@virzz/dsh-plugin-deepseek-balance 1.0.0 → 1.1.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/README.md +95 -11
- package/lib/client.js +20 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ official account balance as a row in the sidebar footer, above **Settings**.
|
|
|
5
5
|
|
|
6
6
|
```
|
|
7
7
|
◆ Cordis Plugin 0 running
|
|
8
|
-
▤ DeepSeek 余额
|
|
8
|
+
▤ DeepSeek 余额 $1058.69
|
|
9
9
|
⚙ 设置
|
|
10
10
|
```
|
|
11
11
|
|
|
@@ -34,36 +34,120 @@ Design notes:
|
|
|
34
34
|
the browser. The read route returns only balance figures.
|
|
35
35
|
- **Two cadences.** The child collects every 60s; the row re-reads the host's cached
|
|
36
36
|
snapshot every 15s, so no polling happens from the browser.
|
|
37
|
+
- **Positive balances only.** A currency whose total is zero or negative says nothing useful
|
|
38
|
+
in a balance read-out, so it is left out of both the row and its tooltip. The tooltip
|
|
39
|
+
reports how many entries were hidden, and the row reads `0` when nothing is positive. The
|
|
40
|
+
host still returns every currency it receives — the rule is presentation, not data.
|
|
37
41
|
|
|
38
|
-
## Install
|
|
42
|
+
## Install into DSH
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
A DSH plugin is a package plus a row. The package has to be resolvable **from the profile
|
|
45
|
+
that mounts it**, and the row has to name it — the browser half only reaches the page as part
|
|
46
|
+
of that profile's client roster, which is composed at boot.
|
|
47
|
+
|
|
48
|
+
### 1. Add the package to the profile
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
dsh plugin --profile web add @virzz/dsh-plugin-deepseek-balance
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`dsh plugin` forwards everything after `--profile <name>` to pnpm **in the profile
|
|
55
|
+
directory**, so this is an ordinary `pnpm add` in `$DSH_HOME/profiles/web` — which is exactly
|
|
56
|
+
the `node_modules` tree the loader resolves row names from.
|
|
57
|
+
|
|
58
|
+
To leave the shipped `web` profile untouched, derive your own from it and install there:
|
|
41
59
|
|
|
42
60
|
```sh
|
|
43
|
-
|
|
61
|
+
dsh --profile balance --from-default-profile web
|
|
62
|
+
dsh plugin --profile balance add @virzz/dsh-plugin-deepseek-balance
|
|
44
63
|
```
|
|
45
64
|
|
|
46
|
-
|
|
65
|
+
The package is published to npmjs and to GitHub Packages. The command above resolves from
|
|
66
|
+
npmjs by default; to install from GitHub Packages, point the scope at it first:
|
|
47
67
|
|
|
48
68
|
```sh
|
|
49
69
|
npm config set @virzz:registry https://npm.pkg.github.com
|
|
50
|
-
npm install @virzz/dsh-plugin-deepseek-balance
|
|
51
70
|
```
|
|
52
71
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
72
|
+
<details>
|
|
73
|
+
<summary>Without pnpm</summary>
|
|
74
|
+
|
|
75
|
+
`dsh plugin add` does two things; both can be done by hand — put the package where the
|
|
76
|
+
profile can resolve it, and name it in the profile's own patch layer.
|
|
56
77
|
|
|
57
78
|
```sh
|
|
58
|
-
|
|
79
|
+
mkdir -p ~/.dsh/profiles/web/node_modules/@virzz
|
|
80
|
+
ln -s /path/to/dsh-plugin-deepseek-balance \
|
|
81
|
+
~/.dsh/profiles/web/node_modules/@virzz/dsh-plugin-deepseek-balance
|
|
59
82
|
```
|
|
60
83
|
|
|
61
84
|
```yaml
|
|
62
|
-
# ~/.dsh/profiles/web/cordis.patch.yml
|
|
85
|
+
# ~/.dsh/profiles/web/cordis.patch.yml — applied after every bundle layer
|
|
63
86
|
- insert:
|
|
64
87
|
- id: deepseek-balance
|
|
65
88
|
name: '@virzz/dsh-plugin-deepseek-balance'
|
|
66
89
|
```
|
|
90
|
+
</details>
|
|
91
|
+
|
|
92
|
+
### 2. Provide the DeepSeek API key
|
|
93
|
+
|
|
94
|
+
The host half re-resolves the credential reference `DEEPSEEK_API_KEY` on every collector
|
|
95
|
+
start. Either of these works:
|
|
96
|
+
|
|
97
|
+
- **Settings → Models**, on the DeepSeek provider card — stored in `$DSH_HOME/.credentials.yaml`; or
|
|
98
|
+
- export it where DSH boots: `export DEEPSEEK_API_KEY=sk-...`
|
|
99
|
+
|
|
100
|
+
Nothing else needs it. The key never reaches the browser and never appears on a command
|
|
101
|
+
line: the collector receives it in its environment, and the read route exposes balance
|
|
102
|
+
figures only.
|
|
103
|
+
|
|
104
|
+
### 3. Boot
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
dsh --profile web # or: dsh web
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The row appears in the sidebar footer, directly above **Settings**:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
◆ Cordis Plugin 0 running
|
|
114
|
+
▤ DeepSeek 余额 $1058.69
|
|
115
|
+
⚙ 设置
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Hover it for the per-currency breakdown (total, granted, topped up) and the collection time;
|
|
119
|
+
click it to re-read the host's cache immediately.
|
|
120
|
+
|
|
121
|
+
### 4. Verify without opening the UI
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
dsh --profile web --dump-config | grep -A2 deepseek-balance # is the row composed?
|
|
125
|
+
curl -s http://127.0.0.1:8021/deepseek-balance # does the host half answer?
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The launcher prints its URL on boot; adjust the port if yours differs. A healthy answer:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{"ok":true,"available":true,"balances":[{"currency":"USD","total":"1058.69","granted":"0.00","toppedUp":"1058.69"}],"fetchedAt":1789030816379}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Troubleshooting
|
|
135
|
+
|
|
136
|
+
| Symptom | What to check |
|
|
137
|
+
| --- | --- |
|
|
138
|
+
| Row reads `未配置密钥` | `DEEPSEEK_API_KEY` is not resolvable — set it in Settings → Models, or in the environment that boots DSH |
|
|
139
|
+
| Row reads `不可用` | Hover it: the tooltip carries the exact cause (`http-401`, `request-failed`, `poller-exited`, …) |
|
|
140
|
+
| Row reads `不可用`, tooltip says `subprocess 服务不可用` | The row activated before the subprocess service. It declares that as a hard dependency *and* retries every 5s, so it clears itself |
|
|
141
|
+
| No row at all | The client roster is composed at boot — restart the profile. `--dump-config` above shows whether the row is composed at all |
|
|
142
|
+
| Row only visible when the sidebar is expanded | Expected: in the 56px rail it collapses to a 36px circle showing the primary currency symbol |
|
|
143
|
+
|
|
144
|
+
### Uninstall
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
dsh plugin --profile web remove @virzz/dsh-plugin-deepseek-balance
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Or delete the row from `cordis.patch.yml` plus the `node_modules` entry, then restart.
|
|
67
151
|
|
|
68
152
|
`dsh.client` in `package.json` puts `lib/client.js` into the browser roster that
|
|
69
153
|
`@deepseek-ai/dsh-client-modules` composes into `window.__DSH_BOOT__`. The module id inside
|
package/lib/client.js
CHANGED
|
@@ -45,13 +45,18 @@ window.__ModuleLoader__.load({
|
|
|
45
45
|
return symbolOf(entry.currency) + entry.total;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/**
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The balances worth showing. A currency whose total is zero or negative carries no
|
|
50
|
+
* information for a balance read-out, so it is left out of both the row and its
|
|
51
|
+
* tooltip — and only counted, so the tooltip can say that something was hidden.
|
|
52
|
+
*/
|
|
53
|
+
function positiveOf(balances) {
|
|
54
|
+
const shown = [];
|
|
50
55
|
for (let index = 0; index < balances.length; index += 1) {
|
|
51
56
|
const value = Number(balances[index].total);
|
|
52
|
-
if (Number.isFinite(value) && value
|
|
57
|
+
if (Number.isFinite(value) && value > 0) shown.push(balances[index]);
|
|
53
58
|
}
|
|
54
|
-
return
|
|
59
|
+
return shown;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
function timeText(ms) {
|
|
@@ -131,6 +136,8 @@ window.__ModuleLoader__.load({
|
|
|
131
136
|
}, []);
|
|
132
137
|
|
|
133
138
|
const balances = state.balances;
|
|
139
|
+
const shown = positiveOf(balances);
|
|
140
|
+
const hidden = balances.length - shown.length;
|
|
134
141
|
let tone = "loading";
|
|
135
142
|
let label = "DeepSeek 余额";
|
|
136
143
|
let value = "…";
|
|
@@ -138,12 +145,14 @@ window.__ModuleLoader__.load({
|
|
|
138
145
|
|
|
139
146
|
if (state.phase === "ok") {
|
|
140
147
|
tone = state.available ? "ok" : "error";
|
|
141
|
-
value =
|
|
148
|
+
value = shown.length > 0 ? shown.slice(0, 2).map(amountOf).join(" · ") : "0";
|
|
142
149
|
const lines = ["DeepSeek 余额(常驻 node 采集)"];
|
|
143
|
-
for (let index = 0; index <
|
|
144
|
-
const entry =
|
|
150
|
+
for (let index = 0; index < shown.length; index += 1) {
|
|
151
|
+
const entry = shown[index];
|
|
145
152
|
lines.push(entry.currency + " " + entry.total + "(赠金 " + entry.granted + " · 充值 " + entry.toppedUp + ")");
|
|
146
153
|
}
|
|
154
|
+
if (shown.length === 0) lines.push("所有币种余额均不大于 0")
|
|
155
|
+
else if (hidden > 0) lines.push("已隐藏 " + hidden + " 项非正余额")
|
|
147
156
|
if (state.available !== true) lines.push("该账户当前不可调用");
|
|
148
157
|
const updated = timeText(state.fetchedAt);
|
|
149
158
|
if (updated !== "") lines.push("采集于 " + updated);
|
|
@@ -156,8 +165,10 @@ window.__ModuleLoader__.load({
|
|
|
156
165
|
}
|
|
157
166
|
|
|
158
167
|
if (wide !== true) {
|
|
159
|
-
const primary =
|
|
160
|
-
const glyph = state.phase === "ok"
|
|
168
|
+
const primary = shown.length > 0 ? shown[0] : undefined;
|
|
169
|
+
const glyph = state.phase === "ok"
|
|
170
|
+
? (primary === undefined ? "0" : symbolOf(primary.currency))
|
|
171
|
+
: state.phase === "error" ? "!" : "…";
|
|
161
172
|
return React.createElement("button", {
|
|
162
173
|
type: "button",
|
|
163
174
|
className: "dsb-row dsb-rail",
|
package/package.json
CHANGED