dsh-balance-plugin 0.2.0 → 0.2.1

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/PUBLISHING.md CHANGED
@@ -1,45 +1,53 @@
1
1
  # Publishing dsh-balance-plugin
2
2
 
3
- Step-by-step release manual for the two official distribution channels (both are supported and can coexist).
3
+ Release manual for the supported npm and GitHub Release tarball channels.
4
4
 
5
5
  ## Prerequisites
6
6
 
7
7
  - [npm](https://docs.npmjs.com/cli/) account, logged in: `npm whoami`
8
8
  - A GitHub account; the repository will be public.
9
9
 
10
- ## 1. Create the GitHub repository
10
+ ## 1. Build and verify
11
11
 
12
- 1. On GitHub, **New repository** → name `dsh-balance-plugin`, public.
13
- 2. **Do not** initialize with README/.gitignore (this repo already has them).
14
- 3. Add the local remote and push:
12
+ ```sh
13
+ # from plugins/dsh-balance-plugin
14
+ pnpm run build
15
+ pnpm test
16
+ pnpm pack --dry-run # must contain lib/, cordis.patch.yml, README files, and LICENSE
17
+ ```
18
+
19
+ In an isolated DSH `0.1.5-rc.1` or later profile, verify both installation and update behavior:
15
20
 
16
21
  ```sh
17
- cd ~/Documents/dsh-balance-plugin
18
- git remote add origin git@github.com:luokai-demo/dsh-plugins.git
19
- git push -u origin main
22
+ dsh plugin --profile demo add ./dsh-balance-plugin-<version>.tgz
23
+ dsh plugin --profile demo update dsh-balance-plugin
24
+ dsh --profile demo --dump-config # expect "# == dsh-balance-plugin"
20
25
  ```
21
26
 
22
- 4. On the repository page: **About → Topics → add `dsh-plugin`** (the official discovery topic from DeepSeek Harness's README). Also consider `deepseek-harness`.
27
+ Restart the Web profile and hard-refresh the browser to verify the authenticated balance readout.
23
28
 
24
29
  ## 2. Publish to npm
25
30
 
26
31
  ```sh
27
- # from ~/Documents/dsh-balance-plugin
28
32
  pnpm run build && pnpm test # gates
29
- npm version patch # bumps to 0.1.1, creates the git tag
33
+ npm version patch # creates the release version and git tag
30
34
  pnpm pack # inspect the tarball contents
31
35
  npm publish # publishes prebuilt lib/ — users install with zero friction
32
36
  git push && git push --tags
33
37
  ```
34
38
 
35
- npm is the **recommended** channel: users run `dsh plugin --profile <name> add dsh-balance-plugin` and get prebuilt code with no install-time build or permission prompt.
39
+ npm is the **recommended** channel: users run `dsh plugin --profile <name> add dsh-balance-plugin` and get prebuilt code with no install-time build or permission prompt. Existing npm users upgrade with `dsh plugin --profile <name> update dsh-balance-plugin`.
36
40
 
37
- ## 3. GitHub installs (optional, automatic once the repo exists)
41
+ ## 3. Publish a GitHub Release tarball
38
42
 
39
- Users can also install directly from GitHub. Two official caveats (from `docs/user/develop/basic/publish.md`):
43
+ The package is in this monorepo's `plugins/` subdirectory, so `github:` package specs cannot target it. Publish the prebuilt tarball instead:
44
+
45
+ ```sh
46
+ pnpm pack
47
+ gh release create v<version> dsh-balance-plugin-<version>.tgz --title "dsh-balance-plugin <version>" --notes-file <notes-file>
48
+ ```
40
49
 
41
- - Git installs fetch **source**, not build output the package ships a self-contained `prepare` script (`node scripts/build.mjs`, no project references), which pnpm runs after install;
42
- - pnpm ≥ 10 refuses to run git dependencies' `prepare` until the user opts in via `allowBuilds` in the profile's `pnpm-workspace.yaml`. Document this in your README (already present).
50
+ Users install or replace a tarball release with `dsh plugin --profile <name> add ./dsh-balance-plugin-<version>.tgz`, then run `dsh --profile <name> --dump-config` and restart DSH.
43
51
 
44
52
  ## 4. Versioning and release notes
45
53
 
@@ -47,16 +55,7 @@ Users can also install directly from GitHub. Two official caveats (from `docs/us
47
55
  - Create a GitHub Release per tag with the changelog; reference the npm version.
48
56
  - Semantic versioning: `patch` for fixes, `minor` for features, `major` for breaking changes.
49
57
 
50
- ## 5. Verification checklist (official inspection points)
51
-
52
- ```sh
53
- # fresh install from the tarball
54
- dsh plugin --profile demo add ./dsh-balance-plugin-0.1.0.tgz
55
- dsh --profile demo --dump-config # expect "# == dsh-balance-plugin" layer
56
- # then in the web profile with a real credential: the readout renders
57
- ```
58
-
59
- ## 6. Local development loop
58
+ ## 5. Local development loop
60
59
 
61
60
  ```sh
62
61
  pnpm install
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  DeepSeek wallet balance at the sidebar foot — a [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin.
4
4
 
5
+ > **DeepSeek-only**: this plugin targets the DeepSeek platform exclusively — the official DeepSeek balance endpoint and `DEEPSEEK_API_KEY`. No other platforms or providers are supported.
6
+
5
7
  English | [中文](README.zh.md)
6
8
 
7
9
  Shows your DeepSeek account balance as a **card icon + amount** in the sidebar footer (beside Settings), tinted by how much is left. Refreshes when a conversation turn ends, on click, and on mount — no polling. When the amount changes, a signed delta (`+¥3.14` / `-¥1.97`) floats up and fades next to it — every spend (or top-up) is visible at a glance.
@@ -22,7 +24,7 @@ Shows your DeepSeek account balance as a **card icon + amount** in the sidebar f
22
24
 
23
25
  ## Install
24
26
 
25
- Requires a DeepSeek account credential. The plugin resolves `DEEPSEEK_API_KEY` through the harness credential seam (`~/.dsh/.credentials.yaml` or the environment), exactly like the official DeepSeek adapter.
27
+ Requires DeepSeek Harness `0.1.5-rc.1` or later and a DeepSeek account credential. The plugin resolves `DEEPSEEK_API_KEY` through the optional harness credential service (`~/.dsh/.credentials.yaml`) or the environment.
26
28
 
27
29
  ### From npm (recommended)
28
30
 
@@ -40,6 +42,18 @@ dsh plugin --profile <name> add ./dsh-balance-plugin-<version>.tgz
40
42
 
41
43
  Note: the plugin lives in the `plugins/` subdirectory of the `dsh-plugins` monorepo, so `dsh plugin add github:...` cannot target it — use the tarball (or npm).
42
44
 
45
+ ### Update an existing install
46
+
47
+ For npm installs, update the package in the same profile, confirm that its bundle layer remains active, then restart the Web server:
48
+
49
+ ```sh
50
+ dsh plugin --profile <name> update dsh-balance-plugin
51
+ dsh --profile <name> --dump-config # expect a "# == dsh-balance-plugin" layer
52
+ # restart dsh web, then hard-refresh the browser
53
+ ```
54
+
55
+ `dsh plugin` forwards pnpm commands and reconciles the installed package's `dsh.bundle` declaration after a successful update. For a Release tarball, run `dsh plugin --profile <name> add ./dsh-balance-plugin-<version>.tgz` with the newer archive, then perform the same verification and restart.
56
+
43
57
  ## Configuration
44
58
 
45
59
  The plugin ships with sensible defaults; override via the bundle's plugin row:
@@ -59,7 +73,7 @@ The plugin ships with sensible defaults; override via the bundle's plugin row:
59
73
 
60
74
  | Half | What it does |
61
75
  |---|---|
62
- | **Host** (Node) | Registers `GET /dsh-balance` (the wallet readout as JSON) and `GET /dsh-balance/events` (an SSE stream). Listens on the harness's `session/event` broadcast and emits a `refresh` SSE event per `turn/end`. Resolves the credential **per request** through `ctx.credentials`, falling back to the environment — a changed key applies without a restart. |
76
+ | **Host** (Node) | Registers authenticated `GET /dsh-balance` (the wallet readout as JSON) and `GET /dsh-balance/events` (an SSE stream). Each route passes the Harness browser-auth and Origin fence before reading a credential. It listens on `session/event` and emits `refresh` per `turn/end`, resolving credentials **per request** through the optional service before falling back to the environment. |
63
77
  | **Client** (browser) | Registers the `sidebar.footer.action` slot entry (the shell's reserved seat beside Settings; on the collapsed rail it stacks above the settings icon). Fetches the readout on mount, on `refresh` SSE events, and on click, with an in-flight guard. The card icon is self-contained (no dependency on the shell's icon library). |
64
78
 
65
79
  Position and interaction follow the shell's own design: the `sidebar.footer.action` hole is the official extension point for "optional actions beside Settings".
@@ -92,7 +106,7 @@ tests/ # node:test unit tests for balance-core
92
106
  ```sh
93
107
  pnpm install
94
108
  pnpm run build # emits lib/index.js + lib/client.js
95
- pnpm test # balance-core unit tests
109
+ pnpm test # balance-core, float, and host-route unit tests
96
110
  ```
97
111
 
98
112
  Local install check (official verification points):
@@ -107,7 +121,7 @@ dsh --profile demo --dump-config # expect a "# == dsh-balance-plugin" layer
107
121
  Before publishing a new version:
108
122
 
109
123
  1. `pnpm run build` and `pnpm test` pass.
110
- 2. Local install check above passes (`--dump-config` shows the layer; the web profile renders the readout with a real credential).
124
+ 2. Local install and `dsh plugin --profile demo update dsh-balance-plugin` both keep the `--dump-config` layer; the web profile renders the readout with a real credential.
111
125
  3. Version bumped (`npm version patch/minor/major`); git tag matches.
112
126
  4. `pnpm pack` — inspect the tarball: it must contain `lib/`, `cordis.patch.yml`, `README.md` (and nothing else heavy).
113
127
  5. `npm publish` — publishes prebuilt code, so users install with zero friction.
package/README.zh.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  侧边栏底部的 DeepSeek 钱包余额——一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件。
4
4
 
5
+ > **纯 DeepSeek**:本插件只针对 DeepSeek 平台——官方 DeepSeek 余额端点与 `DEEPSEEK_API_KEY`,不支持任何其他平台或服务商。
6
+
5
7
  [English](README.md) | 中文
6
8
 
7
9
  在侧边栏底部(设置按钮旁)以**信用卡图标 + 金额**显示你的 DeepSeek 账户余额,并按剩余额度着色。在对话结束时、点击时与挂载时刷新——无轮询。金额变动时,带符号的差额(`+¥3.14` / `-¥1.97`)会从余额旁上飘淡出——每次花费(或充值)都一目了然。
@@ -22,7 +24,7 @@
22
24
 
23
25
  ## 安装
24
26
 
25
- 需要一个 DeepSeek 账户凭证。插件通过 harness 凭证接缝(`~/.dsh/.credentials.yaml` 或环境变量)解析 `DEEPSEEK_API_KEY`,与官方 DeepSeek 适配器一致。
27
+ 需要 DeepSeek Harness `0.1.5-rc.1` 或更高版本,以及一个 DeepSeek 账户凭证。插件通过可选的 harness 凭证服务(`~/.dsh/.credentials.yaml`)或环境变量解析 `DEEPSEEK_API_KEY`。
26
28
 
27
29
  ### 从 npm 安装(推荐)
28
30
 
@@ -40,6 +42,18 @@ dsh plugin --profile <名字> add ./dsh-balance-plugin-<版本>.tgz
40
42
 
41
43
  注意:插件位于 `dsh-plugins` monorepo 的 `plugins/` 子目录,`dsh plugin add github:...` 无法指向子目录——请使用 tarball(或 npm)。
42
44
 
45
+ ### 升级已有安装
46
+
47
+ 通过 npm 安装的版本,在同一个 profile 中升级包,确认 bundle 层仍处于启用状态,然后重启 Web 服务:
48
+
49
+ ```sh
50
+ dsh plugin --profile <名字> update dsh-balance-plugin
51
+ dsh --profile <名字> --dump-config # 应出现 "# == dsh-balance-plugin" 层
52
+ # 重启 dsh web,然后硬刷新浏览器
53
+ ```
54
+
55
+ `dsh plugin` 会转发 pnpm 命令,并在成功升级后重新核对已安装包的 `dsh.bundle` 声明。GitHub Release tarball 则执行 `dsh plugin --profile <名字> add ./dsh-balance-plugin-<版本>.tgz` 安装新归档,再进行相同的验证与重启。
56
+
43
57
  ## 配置
44
58
 
45
59
  插件带合理默认值;可通过 bundle 的插件行覆盖:
@@ -59,7 +73,7 @@ dsh plugin --profile <名字> add ./dsh-balance-plugin-<版本>.tgz
59
73
 
60
74
  | 半面 | 做什么 |
61
75
  |---|---|
62
- | **宿主**(Node) | 注册 `GET /dsh-balance`(钱包读数 JSON)与 `GET /dsh-balance/events`(SSE 流)。监听 harness `session/event` 广播,每个 `turn/end` 推送 `refresh` 事件。**每次请求**经 `ctx.credentials` 解析凭证并回退环境变量——改 key 无需重启。 |
76
+ | **宿主**(Node) | 注册经认证的 `GET /dsh-balance`(钱包读数 JSON)与 `GET /dsh-balance/events`(SSE 流)。每个路由都会先通过 Harness 的浏览器身份与 Origin 栅栏,再读取凭证。监听 `session/event`,每个 `turn/end` 推送 `refresh`;**每次请求**经可选服务解析凭证,再回退环境变量。 |
63
77
  | **客户端**(浏览器) | 注册 `sidebar.footer.action` 插槽条目(shell 预留的设置旁座位;收起 rail 时堆叠在设置图标上方)。在挂载时、`refresh` SSE 事件与点击时抓取读数,带 in-flight 守卫。信用卡图标自包含(不依赖 shell 的图标库)。 |
64
78
 
65
79
  位置与交互遵循 shell 自身设计:`sidebar.footer.action` 是"设置旁可选操作"的官方扩展点。
@@ -86,13 +100,13 @@ src/
86
100
  index.ts # 宿主插件:路由 + SSE + 轮次结束监听
87
101
  client.tsx # 浏览器插件:侧边栏底部操作
88
102
  scripts/build.mjs # esbuild:宿主 ESM + 浏览器 __ModuleLoader__ bundle
89
- tests/ # balance-core node:test 单元测试
103
+ tests/ # balance-core、float 与宿主路由的 node:test 单元测试
90
104
  ```
91
105
 
92
106
  ```sh
93
107
  pnpm install
94
108
  pnpm run build # 生成 lib/index.js + lib/client.js
95
- pnpm test # balance-core 单元测试
109
+ pnpm test # balance-core、float 与宿主路由单元测试
96
110
  ```
97
111
 
98
112
  本地安装检查(官方检验点):
@@ -107,7 +121,7 @@ dsh --profile demo --dump-config # 应出现 "# == dsh-balance-plugin" 层
107
121
  发布新版本前:
108
122
 
109
123
  1. `pnpm run build` 与 `pnpm test` 通过。
110
- 2. 上述本地安装检查通过(`--dump-config` 显示层;web profile 用真实凭证渲染读数)。
124
+ 2. 上述本地安装与 `dsh plugin --profile demo update dsh-balance-plugin` 都通过;`--dump-config` 保留该层,且 Web profile 在真实凭证下能渲染读数。
111
125
  3. 版本已提升(`npm version patch/minor/major`);git tag 对应。
112
126
  4. `pnpm pack`——检查 tarball:必须包含 `lib/`、`cordis.patch.yml`、`README.md`(别无其他大文件)。
113
127
  5. `npm publish`——发布预构建代码,用户零摩擦安装。
package/lib/index.js CHANGED
@@ -98,13 +98,27 @@ async function fetchBalance(credentials, env, config) {
98
98
 
99
99
  // src/index.ts
100
100
  var name = "dsh-balance-plugin";
101
- var inject = ["webServer"];
101
+ var inject = ["webServer", "connection"];
102
102
  var Config = Schema.object({
103
103
  apiKeyEnv: Schema.string().default("DEEPSEEK_API_KEY"),
104
104
  baseURL: Schema.string().default("https://api.deepseek.com"),
105
105
  timeoutMs: Schema.natural().min(1).max(12e4).default(12e3),
106
106
  lowBalanceThreshold: Schema.number().min(0).default(2)
107
107
  });
108
+ function rejectUntrustedRequest(ctx, req, res) {
109
+ const connection = Reflect.get(ctx, "connection");
110
+ const status = connection.requestRejection(req);
111
+ if (status === void 0) return false;
112
+ res.statusCode = status;
113
+ res.end();
114
+ return true;
115
+ }
116
+ function rejectNonGetRequest(req, res) {
117
+ if (req.method === "GET") return false;
118
+ res.writeHead(405, { allow: "GET" });
119
+ res.end();
120
+ return true;
121
+ }
108
122
  function apply(ctx, config) {
109
123
  const sseClients = /* @__PURE__ */ new Set();
110
124
  const broadcastRefresh = () => {
@@ -119,7 +133,8 @@ function apply(ctx, config) {
119
133
  const unregisterBalance = ctx.webServer.register({
120
134
  kind: "exact",
121
135
  path: "/dsh-balance",
122
- handler: async (_req, res) => {
136
+ handler: async (req, res) => {
137
+ if (rejectUntrustedRequest(ctx, req, res) || rejectNonGetRequest(req, res)) return;
123
138
  const credentials = ctx.get("credentials");
124
139
  const resolver = credentials === void 0 ? void 0 : { resolve: (ref) => credentials.resolve(ref) };
125
140
  const readout = await fetchBalance(resolver, process.env, config);
@@ -136,6 +151,7 @@ function apply(ctx, config) {
136
151
  kind: "exact",
137
152
  path: "/dsh-balance/events",
138
153
  handler: (req, res) => {
154
+ if (rejectUntrustedRequest(ctx, req, res) || rejectNonGetRequest(req, res)) return;
139
155
  res.writeHead(200, {
140
156
  "content-type": "text/event-stream",
141
157
  "cache-control": "no-cache",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-balance-plugin",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "DeepSeek wallet-balance readout at the sidebar foot: card icon + amount, status-tinted, refreshed on turn end and on click, with a floating delta animation on change",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -29,21 +29,14 @@
29
29
  ]
30
30
  }
31
31
  },
32
- "scripts": {
33
- "build": "node scripts/build.mjs",
34
- "prepare": "node scripts/build.mjs",
35
- "test": "node --test tests/*.test.mjs"
36
- },
37
32
  "peerDependencies": {
38
- "@deepseek-ai/cordis": "^4.0.1",
39
- "@deepseek-ai/dsh-credentials": "0.0.1-rc.5",
40
- "@deepseek-ai/schemastery": "^3.18.1",
33
+ "@deepseek-ai/cordis": "^4.0.2",
34
+ "@deepseek-ai/schemastery": "^3.18.2",
41
35
  "react": "^18.0.0"
42
36
  },
43
37
  "devDependencies": {
44
- "@deepseek-ai/cordis": "^4.0.1",
45
- "@deepseek-ai/dsh-credentials": "0.0.1-rc.5",
46
- "@deepseek-ai/schemastery": "^3.18.1",
38
+ "@deepseek-ai/cordis": "^4.0.2",
39
+ "@deepseek-ai/schemastery": "^3.18.2",
47
40
  "@types/react": "^18.0.0",
48
41
  "esbuild": "^0.25.0",
49
42
  "react": "^18.0.0",
@@ -60,5 +53,9 @@
60
53
  "dsh-plugin",
61
54
  "balance",
62
55
  "wallet"
63
- ]
64
- }
56
+ ],
57
+ "scripts": {
58
+ "build": "node scripts/build.mjs",
59
+ "test": "node --test tests/*.test.mjs"
60
+ }
61
+ }