@rayadesu/dsh-billing 0.3.18 → 1.0.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/AGENTS.md +43 -12
- package/README.i18n.yaml +2 -2
- package/README.md +8 -5
- package/README.zh.md +5 -4
- package/package.json +5 -5
package/AGENTS.md
CHANGED
|
@@ -28,7 +28,8 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Web 官方安装方式用同一个包名:侧栏 插件 → 添加插件 → 输入 `@rayadesu/dsh-billing`
|
|
31
|
-
|
|
31
|
+
(安装源可选默认源或中国大陆镜像源)。**对外只承诺这一种**:对话框虽然也收 GitHub 地址、
|
|
32
|
+
本地目录与 `.tgz` 路径,但多包下前两者装不全,见「约定」里的实测说明。
|
|
32
33
|
- **手动**:把 `cordis.patch.yml` 的 insert 合并进 `$DSH_HOME/profiles/<name>/cordis.patch.yml`,
|
|
33
34
|
并用 `dsh plugin --profile <name> add @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing`
|
|
34
35
|
安装两个包(行名解析同上)。
|
|
@@ -40,10 +41,38 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
|
|
|
40
41
|
`tsconfig.base*.json`,`@deepseek-ai/*` peer 包从 npm 解析。`pnpm run build`
|
|
41
42
|
依次跑 host/client 两个编译面:`tsc -b` 产出 `lib/types`,tsdown 产出
|
|
42
43
|
`lib/index.js`/`lib/invariant.js`,typert 生成器按 package.json 的 name 重新生成
|
|
43
|
-
`lib/typert.host.js` 与 `lib/typert.remote-client.*`,client 面重建 `lib/client.js
|
|
44
|
-
`lib
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
`lib/typert.host.js` 与 `lib/typert.remote-client.*`,client 面重建 `lib/client.js`,
|
|
45
|
+
末尾 `scripts/normalize-lib-paths.mjs` 把 client bundle 里 `\0dsh-css:` 区域注释的
|
|
46
|
+
绝对路径削成文件名(见下条)。
|
|
47
|
+
- **分发只有 npm;下面几条只解释 dev 验证为什么用 tarball(2026-09-29 实测)**:DSH 的执行模型是
|
|
48
|
+
`pnpm add <spec>` 之后按 `cordis.patch.yml` 里的**行名**去 profile 的 `node_modules`
|
|
49
|
+
解析包。pnpm 对 **`link:`(本地目录)与 git/GitHub 依赖不装其嵌套依赖**(最小复现:
|
|
50
|
+
一个只有 `is-odd` 一个注册表依赖的 bundle,链进消费方后 `is-odd` 同样没被装),
|
|
51
|
+
于是 bundle 声明的两个组件包永远不会落进 profile:
|
|
52
|
+
- **npm**:`pnpm add @rayadesu/dsh-billing` → 解出 tarball,pnpm 当**真实安装**处理,
|
|
53
|
+
组件包随依赖解析一起装 → ✅ 可用;
|
|
54
|
+
- **tarball**:`pnpm add <pkg.tgz>`(绝对路径)→ 同样是真实安装,解包后照常解析
|
|
55
|
+
`dependencies` → ✅ 可用,**但三个 tarball 必须一次 `add`**:根 bundle 的组件依赖是
|
|
56
|
+
registry 区间,单独重装根包会从 npm 取组件包,工作区代码静默不进 profile。
|
|
57
|
+
这是**阶段 A 的 dev 验证方式**(`node scripts/local-install.mjs all --check <marker>`),
|
|
58
|
+
不作为对外分发方式;
|
|
59
|
+
- **本地目录**:`pnpm add <绝对路径>` → `link:`,只有根软链进 `node_modules` → ❌;
|
|
60
|
+
- **GitHub**:`pnpm add git+…` → 实测同样只得到根包,组件包缺失 → ❌。
|
|
61
|
+
两种失败形态一致:启动报 `2 entries did not activate llm-billing … failed to import`。
|
|
62
|
+
本地目录仍可用 CLI 的**三目录一次给全**绕开(`dsh plugin --profile <name> add <仓库根>
|
|
63
|
+
<packages/llm-billing> <packages/ui-billing>`),但 GUI 只收一个 spec,做不到;
|
|
64
|
+
GitHub 目前无解(官方文档建议 git 安装靠 `prepare` 构建,但 pnpm 11.7.0 实测不执行
|
|
65
|
+
git 依赖的 `prepare`,故产物必须入库)。**要这些来源都通必须改 DSH**:让 bundle 能声明
|
|
66
|
+
「我由哪些包组成,一起装」,或安装后按 patch 的 `name` 逐个解析依赖包。
|
|
67
|
+
- **`lib/` 构建产物进仓库**:三个包的 `lib/` 由 `.gitignore` 白名单放行、随源码一起提交。
|
|
68
|
+
原因是 **git-Hosted 安装没有构建步骤**——pnpm 对 git-hosted 依赖**不执行 `prepare`**
|
|
69
|
+
(2026-09-29 实测:连显式在 `prepare` 里跑 pnpm install 也不触发),产物必须已经在
|
|
70
|
+
仓库里;本地目录安装(`link:`)也直通工作区的 `lib/`。代价是每轮改完源码**必须重跑
|
|
71
|
+
`pnpm run build` 并提交重新生成的 `lib/`**,否则拿到的是旧产物。
|
|
72
|
+
`build`/`verify` 末尾的 `scripts/normalize-lib-paths.mjs` 幂等,把构建机绝对路径
|
|
73
|
+
从产物里去掉,否则每台机器构建出的字节都不同。
|
|
74
|
+
- **发布前校验**:`pnpm run verify`(每个包 `prepublishOnly` 自动运行)先归一化产物路径,
|
|
75
|
+
再检查 `lib/typert.host.js` 的 `TYPERT.package` 必须等于导出它的包名,且 lib 中不得残留
|
|
47
76
|
其他包名的清单;失败即禁止发布。
|
|
48
77
|
- **依赖以发布形态声明**:`@deepseek-ai/dsh-*` 依赖写 `^0.2.0-rc.1`(对应官方 monorepo 当前发布基线,monorepo 内为
|
|
49
78
|
`workspace:^`);本插件的三个包发布到 npm 的
|
|
@@ -75,10 +104,11 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
|
|
|
75
104
|
- **密钥不进仓库**:`DEEPSEEK_API_KEY` 等一律由用户环境或凭据 seam 提供,仓库不含真实值。
|
|
76
105
|
- **README 双语**:每个 README 遵循 DSH 结构 `README.md`(EN) + `README.zh.md`(ZH) +
|
|
77
106
|
`README.i18n.yaml`(记录两文件 git blob hash,改动后需更新)。
|
|
78
|
-
- **版本对齐**:根 bundle 与两个包统一版本号(当前 0.
|
|
79
|
-
- **提交与发布流程**:见 `.agents/skills/dsh-release/SKILL.md` —— 阶段 A(改代码 →
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
- **版本对齐**:根 bundle 与两个包统一版本号(当前 1.0.0),`pnpm-lock.yaml` 随依赖变更更新。
|
|
108
|
+
- **提交与发布流程**:见 `.agents/skills/dsh-release/SKILL.md` —— 阶段 A(改代码 → 按档位校验 →
|
|
109
|
+
`node scripts/local-install.mjs all --check <marker>` 装进 profile → 交用户验证)**不提交**,
|
|
110
|
+
改动留在工作区;用户说「发布」进入阶段 B 才 bump 版本、**按类型分别提交**、推送、发 npm 与
|
|
111
|
+
GitHub Release。
|
|
82
112
|
- **浮动说明卡一律用 `HoverCard`,不要用 `Tooltip`**:两者形态不同 —— `Tooltip` 是「单行短标签」容器
|
|
83
113
|
(`padding: 3px 7px` 的 26px 条带、`pointer-events: none`、`label` 只收 `string`),官方自己那颗信息按钮
|
|
84
114
|
装的是 ~50 字 / 2–3 行;把 4 行说明硬塞进去会渲染成一整块贴边白字方块,版本号跟正文同权重,且球泡用的是
|
|
@@ -99,15 +129,16 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
|
|
|
99
129
|
|
|
100
130
|
```sh
|
|
101
131
|
pnpm install # 安装本仓库依赖(dsh-* 从 registry 解析)
|
|
102
|
-
pnpm run build # host + client 两个编译面(tsc + tsdown + typert
|
|
132
|
+
pnpm run build # host + client 两个编译面(tsc + tsdown + typert 产物 + 路径归一化;产物 lib/ 随后提交)
|
|
103
133
|
pnpm run test # vitest
|
|
104
134
|
pnpm run verify # 发布前校验
|
|
105
|
-
|
|
135
|
+
node scripts/local-install.mjs all --check <marker> # 阶段 A:build + 三包 pack + 三包一次 add + 核对
|
|
136
|
+
dsh plugin --profile web add @rayadesu/dsh-billing # 从 npm 装进 DSH(bundle 依赖带齐两个插件包)
|
|
106
137
|
```
|
|
107
138
|
|
|
108
139
|
**从零构建顺序是硬约束**:`ui-billing` 的浏览器半面(`tsconfig.client.json`)导入
|
|
109
140
|
`@rayadesu/dsh-llm-billing/remote`,其类型声明是 host 面 tsdown 生成的
|
|
110
|
-
`lib/typert.remote-client.d.ts
|
|
141
|
+
`lib/typert.remote-client.d.ts`(构建产物,已随 `lib/` 入库,但干净 checkout 仍要按序重建)。所以干净 checkout 必须先跑
|
|
111
142
|
`pnpm run build:host`(tsc + tsdown 生成 typert 产物)再跑
|
|
112
143
|
`pnpm run typecheck` / `pnpm run build:client`;`pnpm run build` 本身已按
|
|
113
144
|
host → client 顺序封装,CI 亦按此顺序执行。
|
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# last confirmed-consistent state. Both languages carry equal authority; after
|
|
3
3
|
# editing either side, bring the other along and re-record both hashes with:
|
|
4
4
|
# git hash-object README.md README.zh.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 4edc746be51848977b43a23da3dc33f98b0d6ad1
|
|
6
|
+
README.zh.md: f63930f0a3459ae60a61e2b43fcaab72ed26ebc7
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
|
|
|
12
12
|
- **Detail panel** — the remaining amount with today's consumption measured from the balance series after it (see *How session spend is computed*); today's billed token count next to today's all-session spend (`今日 Token` / `今日花费`, one row; the count is DSH's compact notation with its own unit — `12.2K tok`, followed by the day's cache-hit share as a bare, unparenthesized percentage, rendered by DSH's own hit-rate rule: an integer percent that grows decimals only as far as a partial hit needs to stay below 100, and none at all when the day billed no prompt-side input); directly under that row, today's two bucket detail lines — tokens on top, costs below, each on its own with its natural ` · ` spacing (no column alignment between them), in the per-model breakdown line's typography but on the third section's row spacing (the today session-spend ranking's tight 6px rhythm); every spend amount renders at **three significant digits** (`¥9.58`) but never finer than four decimals — an amount below ¥0.0001 reads `¥0` — while the balance line alone keeps four decimals; and a manual refresh action and a spend disclaimer on the `?` button (one line of estimate scope, then a line stating that a conversation's amount includes the subagent sessions it delegated, and the running plugin version as the last line, e.g. `v0.3.13`). The panel ends with a **today session-spend ranking**: sessions sorted by today's spend, highest first — one row per conversation, since each subagent session's spend is merged into the row of the session that delegated it (names come from the log's Chinese titles and follow renames automatically; at most the top 10 rows, with a "…N more sessions" hint).
|
|
13
13
|
- **Turn cost amount** — each completed turn's closing message shows a plain static `¥X` at the **end** of the actions row, after the clock: non-interactive (no icon, no "cost" word, no card), its typography replicates the clock text (13px secondary tier, tertiary tone, nowrap), and it is **always visible** (not hover-revealed like the clock text — the row's own hover reveal shows both together); turns without DeepSeek usage (zero cost) or failed loads stay hidden.
|
|
14
14
|
- **Composer spend pill** — the composer's own stat row (the one DSH's time/token pills sit in) carries one more entry: this plugin's ring-and-sparkle mark plus this conversation's billed spend, at the same three-significant-digit precision as the badge, opening a cost card whose three rows are the spend's three billing buckets (uncached input / cached input / output) under DSH's own token-card wording. Its amount is the **conversation's** — this session plus the subagent sessions it delegated, merged by the same rule the host's own sums use; it is the ONLY surface that shows the conversation's own spend (the badge's second line and its panel report the day), so a session that priced nothing anywhere shows no pill, while one that priced nothing itself but delegated a priced subagent still shows.
|
|
15
|
-
- **Failures and empty states** — a session or day without priced usage shows "no usage recorded" instead of a fabricated figure; a missing key, rejected credential, or transport error renders a muted "Balance unavailable" whose
|
|
15
|
+
- **Failures and empty states** — a session or day without priced usage shows "no usage recorded" instead of a fabricated figure; a missing key, rejected credential, or transport error renders a muted "Balance unavailable" chip, and an API key the API reports without any spendable balance renders the ordinary chip with a `—` amount. Both open the detail panel, whose first row explains the `—` in one short localized sentence (check the API key, or that the key holds no balance — the Remote's verbatim English message is not rendered) and which keeps the refresh action; today's spend is read from the session logs, so it stays on the chip and in the panel either way.
|
|
16
16
|
|
|
17
17
|
## Data update mechanics
|
|
18
18
|
|
|
@@ -67,10 +67,13 @@ name installs everything**: pnpm pulls the bundle's dependency closure into the
|
|
|
67
67
|
profile, where the hoisted `node_modules` makes the two row names resolvable.
|
|
68
68
|
|
|
69
69
|
1. In the sidebar open **Plugins** → **Add plugin**.
|
|
70
|
-
2. Enter `@rayadesu/dsh-billing`. The
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
2. Enter `@rayadesu/dsh-billing`. The npm registry is the supported install
|
|
71
|
+
source: the bundle arrives as a real package and pnpm resolves its two
|
|
72
|
+
`dependencies` alongside it. The dialog also accepts a GitHub repository
|
|
73
|
+
address or a local directory path, but a bundle installed that way does not
|
|
74
|
+
bring the two plugin packages — pnpm installs no dependencies of a linked or
|
|
75
|
+
git-hosted package, so the profile keeps the bundle alone and startup reports
|
|
76
|
+
`2 entries did not activate llm-billing … failed to import`.
|
|
74
77
|
3. Pick an install source (the default npm registry or the **Mainland China
|
|
75
78
|
mirror**), press **Install**, then **Enable now**.
|
|
76
79
|
|
package/README.zh.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- **详情面板** —— 剩余金额(后跟按余额序列算出的今日消费,见「会话花费是怎么算的」);今日计费 token 数与今日所有会话合计同一行(`今日 Token` / `今日花费`,token 数按 DSH 的紧凑记数法带自己的单位,如 `12.2K tok`,token 数值后紧跟当天的缓存命中率(裸数字、无括号)——按 DSH 官方命中率规则渲染:整数百分比,只有部分命中会被凑到 100% 时才逐位多留小数;当天没有 prompt 侧输入就不显示);紧跟该行下面是**今日两行桶明细**——token 在上、花费在下——两行各自成行、各自保持自然的 ` · ` 间距(两行之间不做列对齐),字体沿用模型分项行那一套,行距用第三部分(今日会话花费排行)那一套紧凑节奏(6px);**面板上所有花费金额都按三位有效数字渲染**(`¥9.58`),但**不细于四位小数**——低于 ¥0.0001 的金额显示 `¥0`;只有余额行保留四位小数;外加手动刷新按钮与「?」上的花费说明(一句估算口径,一行说明会话金额含它委派的子代理会话,最后一行顶格是当前插件版本号,如 `v0.3.13`);面板底部是**今日会话花费排行**:按今日花费从高到低排列的会话列表——一行就是一个对话,子代理会话的花费已并入委派它的那个会话行(会话名取日志中的中文标题,重命名后自动同步;最多显示前 10 条,其余以「…还有 N 个会话」提示)。
|
|
13
13
|
- **本轮花费金额** —— 每条已完成回合的收尾消息操作行**行尾**(时钟之后)显示纯静态的 `¥X`:不可点击、无图标、无「花费」字样、不弹卡片,字体样式逐项复刻时钟文本(13px 次级字号、tertiary 色、nowrap),并且**始终显示**(不随悬停隐藏,与时钟文本一致——整行的悬停显隐规则让两者同进退);回合没有 DeepSeek 用量(花费为 0)或加载失败时不显示。
|
|
14
14
|
- **输入框花费 pill** —— 输入框自己的统计行(官方 time/token pill 所在那条)多一枚:本插件的「环 + 四角星」标记 + 本会话的计费花费,精度与徽标同为三位有效数字;点击向上弹出花费卡片,三行就是花费的三个计费桶(未缓存输入 / 缓存读取 / 输出),文案沿用 DSH token 卡那一套。金额是**整段对话**的——本会话加上它委派的子代理会话,合并方式与主机自己的汇总一致;它是**唯一**显示会话自身花费的界面(徽标第二行与面板报的都是当日口径),所以任何地方都没计价的会话不显示 pill,而自身没计价、委派的子代理却烧了钱的会话照常显示。
|
|
15
|
-
- **失败与空态** —— 会话或今日没有可计价消耗时显示「暂无消耗记录」而不是编造数字;未配置 key
|
|
15
|
+
- **失败与空态** —— 会话或今日没有可计价消耗时显示「暂无消耗记录」而不是编造数字;未配置 key、凭据被拒或传输错误时显示弱化的「额度不可用」徽标,而 API 明确报告「该 key 没有可用余额」时显示普通的 `—` 徽标。两者点开都是同一个详情面板:第一行用一句本地化短句说明上面为什么是 `—`(「额度不可用,请检查 API key」,或「该 API key 当前没有可用余额」;Remote 的英文原文不在卡片里渲染),刷新按钮仍在面板里;今日花费来自会话日志,两种情况下都照常在徽标与面板里显示。
|
|
16
16
|
|
|
17
17
|
## 数据更新机制
|
|
18
18
|
|
|
@@ -66,9 +66,10 @@
|
|
|
66
66
|
profile,hoisted 的 `node_modules` 让两个组件行名可解析。
|
|
67
67
|
|
|
68
68
|
1. 侧栏进入 **插件** → **添加插件**。
|
|
69
|
-
2. 输入 `@rayadesu/dsh-billing
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
2. 输入 `@rayadesu/dsh-billing`。**支持的分发来源就是 npm**:bundle 以真实包解包,
|
|
70
|
+
pnpm 随之解析它的两个 `dependencies`。对话框也接受 GitHub 仓库地址或本地目录路径,
|
|
71
|
+
但那样装出来的 profile 里只有 bundle、没有那**两个插件包**——pnpm 不安装 `link:` 或 git
|
|
72
|
+
来源包的依赖,启动会报 `2 entries did not activate llm-billing … failed to import`。
|
|
72
73
|
3. 选安装源(默认 npm 源或**中国大陆镜像源**),点**安装**,完成后**立即启用**。
|
|
73
74
|
|
|
74
75
|
### 用命令行安装
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rayadesu/dsh-billing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "DeepSeek Harness billing plugin: account balance and this session's billed spend with a session-header badge.",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "pnpm run build:host && pnpm run build:client",
|
|
21
|
+
"build": "pnpm run build:host && pnpm run build:client && node scripts/normalize-lib-paths.mjs",
|
|
22
22
|
"build:host": "tsc -b tsconfig.host.json && tsdown --env.DSH_BUILD_FACE host && node scripts/typert-compat.mjs",
|
|
23
23
|
"build:client": "tsc -b tsconfig.client.json && tsdown --env.DSH_BUILD_FACE client",
|
|
24
24
|
"typecheck": "tsc -b tsconfig.host.json && tsc -b tsconfig.client.json",
|
|
25
25
|
"lint": "eslint .",
|
|
26
26
|
"test": "vitest run",
|
|
27
|
-
"verify": "node scripts/verify-packages.mjs"
|
|
27
|
+
"verify": "node scripts/normalize-lib-paths.mjs && node scripts/verify-packages.mjs"
|
|
28
28
|
},
|
|
29
29
|
"exports": {
|
|
30
30
|
"./package.json": "./package.json",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@rayadesu/dsh-client-ui-billing": "^0.
|
|
52
|
-
"@rayadesu/dsh-llm-billing": "^0.
|
|
51
|
+
"@rayadesu/dsh-client-ui-billing": "^1.0.0",
|
|
52
|
+
"@rayadesu/dsh-llm-billing": "^1.0.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@deepseek-ai/cordis": "^4.0.4",
|