npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-my-cost

v0.3.0

Published

DeepSeek Harness cost & balance plugin: hourly official-price polling (peak/off-peak ready), cache-aware per-session/per-message cost projection, and account balance via the DeepSeek API.

Downloads

172

Readme

dsh-my-cost

DeepSeek Harness 费用与余额插件:定时拉取官方定价、缓存感知的会话/消息级费用估算(峰谷定价兼容),以及账户余额查询。

  • 价格轮询:每小时抓取 DeepSeek 官方定价页(api-docs.deepseek.com/zh-cn/quick_start/pricing/),解析后写入 $DSH_HOME/prices/official-prices.json;失败时保留旧价格并记录错误。
  • 峰谷定价兼容:官方宣布 2026-08-17 起采用峰谷定价。插件解析出峰谷两档价格与生效日期,但 生效日之前一律按当前(平价)价格计费——峰谷机制已就位,目前处于休眠状态;生效日后自动按北京时间的峰谷时段计价(高峰 9:00–12:00、14:00–18:00)。可用 peakPricing: on/off 强制开启/关闭。
  • 缓存计费:输入(缓存未命中)、输出、缓存命中、缓存写入四类 token 各自按官方单价计价。
  • 余额查询:通过 GET https://api.deepseek.com/user/balance 查询账户余额,凭证复用 DSH 凭证服务里的 DEEPSEEK_API_KEY(web「设置 → 模型」页写入的那个),API key 只在 host 端使用,不会下发到浏览器。
  • 展示:会话头部估算费用、每条消息的估算费用、输入框底部信息栏的会话总花费(与 turns/steps/token 统计同一 conversation.composer.dock,悬停显示分模型明细)、设置页「费用与余额」面板(余额卡片 + 跨会话费用汇总 + 当前/峰谷价格表)。

安装

# 1. 安装到 web profile(已发布到 npm,直接用包名;本地开发可改用 link: 指向本地目录)
dsh plugin --profile web add dsh-my-cost

# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 追加:
# - insert:
#     - id: my-cost
#       name: 'dsh-my-cost'
#       config:
#         currency: CNY          # 显示币种
#         pollIntervalMs: 3600000   # 价格轮询周期(默认 1 小时)
#         balanceIntervalMs: 3600000 # 余额刷新周期
#         peakPricing: auto      # auto | on | off

# 3. 重启 dsh web,浏览器硬刷新

说明:也可以从 GitHub 源码安装:dsh plugin --profile web add github:hehe1111/dsh-my-cost。 lib/ 为构建产物(不入 git),git 安装会触发 prepare 构建脚本;pnpm ≥10 默认拦截 git 依赖的 prepare,需按 dsh 提示把 dsh-my-cost 加入 profile 的 pnpm-workspace.yaml allowBuilds(key 含冒号,写入时加引号)后重装。推荐直接用 npm 包安装(发布时已构建)。

开发与构建

lib/ 是纯构建产物(.gitignore 忽略、不入库):src/(host 端,Node)与 client/ (浏览器端,React 19 + JSX)经 Vite 8(编程式构建脚本)产出 lib/index.js 与 lib/client.js。prepare 脚本会在 npm install/npm publish 时自动构建:

npm install        # 安装 devDependencies(vite ^8、vitest ^4、@deepseek-ai/schemastery;react/react-dom 运行时由 dsh 的 seed 词表提供,不声明)
npm run build      # node scripts/build.mjs → 构建 host + client 两个目标到 lib/
npm test           # vitest:单测(定价核心/投影/格式化/组件渲染)+ 集成(apply 接线、/my-cost/status 路由)+ 构建产物契约
  • host 产物 lib/index.js(ESM):src/ 源码,zod/@deepseek-ai/schemastery/node:* 保持 external(由 profile pnpm 闭包注入)。
  • client 产物 lib/client.js(CJS):符合 DSH 官方 client 契约—— window.__ModuleLoader__.load({ id, factory }) 包装,react/react/jsx-runtime/ react-dom/react-dom/client 为平台 seed 词、不打进包(低余额 toast 用 createRoot 渲染在插槽之外的独立容器)。
  • 样式:client 全部使用 JS 内联样式对象(client/styles/,渲染为 style={{...}})。 为什么必须这样、官方怎么写、限制在哪,见下方「样式编写」小节。
  • 改 client/ 或 src/ 源码 → 重新 npm run build:client 改动重装 + 刷新页面即可; host(src/)改动需重启 web(ESM 缓存)。

样式编写(为什么全用内联)

限制(硬约束,实测确认)

  1. client 通道没有 CSS 资源路由。dsh 的 client-modules 只服务 /plugins/<id>/client.js (+ .map),浏览器加载不到任何独立 .css 文件。Vite lib 模式遇到 CSS 导入必然提取成 独立 .css(cssCodeSplit: false 也不内联)——所以 Less/CSS Modules/Tailwind/UnoCSS 的 默认产物在这里会静默丢失样式。
  2. 宿主 CSS 可覆盖插件 class。官方坑清单(make-dsh-plugin skill 的 references/gotchas.md 第 4 条):宿主全局 CSS 可能覆盖插件注入的 <style> 规则或命中同名 class;关键样式必须 用 JS 内联 style 属性(内联优先级最高,宿主无法覆盖),不要依赖 CSS class 注入。

原因

  • 单文件通道 + 无 CSS 路由 → 样式要么进 JS bundle,要么不存在;
  • class 体系(含工具类框架)样式可被宿主更高优先级规则覆盖;内联 style 属性无法被覆盖;
  • Tailwind/UnoCSS 的 preflight(全局 reset)注入会冲掉宿主 UI,必须关闭。

官方写法

  • 官方 client 包把 CSS 作为字符串内联进 bundle,运行时注入 <style> 标签,例如 const css$9 = ".lXshSW_root{...}" + document.createElement("style") + data-plugin-css 去重标记;client-modules 的 claimStyles() 跟踪这些标签,插件卸载时自动清理。
  • 对"关键样式",官方建议直接 JS 内联(见限制 2)。

本插件写法

  • 全部使用 JS 内联样式对象:client/styles/*.js 定义样式对象,组件以 style={{...}} 渲染;不注入任何 <style> 标签、零 CSS 工具链、零额外依赖。
  • 曾引入 UnoCSS(构建时扫描生成 CSS 字符串内联进 bundle + 运行时注入 <style>), 因"class 可被宿主覆盖 + 额外工具链 + preflight 风险"最终回归纯内联。
  • 动态样式(如随状态切换的颜色)用 { ...baseStyle, color: xxx } 在组件内合并。

结论:除非未来出现官方的 CSS 资源通道,否则新样式一律写成 client/styles/ 里的样式对象 并用 style={{...}} 内联,不要引入 CSS 文件、class 体系或工具类框架。

配置

| 字段 | 默认 | 说明 | |---|---|---| | currency | CNY | 显示币种 | | pricesDir | $DSH_HOME/prices | 价格文件目录 | | pricesUrl | 官方定价页 | 轮询源 | | balanceUrl | https://api.deepseek.com/user/balance | 余额 API | | apiKeyRef | DEEPSEEK_API_KEY | 凭证引用(走 ctx.credentials) | | pollIntervalMs | 3600000 | 价格轮询周期(最小 60s) | | balanceIntervalMs | 3600000 | 余额自动刷新周期 | | balanceCacheMs | 300000 | 余额缓存时长(?refreshBalance=1 可强制) | | peakPricing | auto | auto:生效日之后自动启用峰谷;on/off 强制 |

价格覆盖:$DSH_HOME/prices/local-prices.json(可选)可覆盖官方价,格式:

{ "prices": { "deepseek-v4-flash": { "inputPerM": 1.5, "outputPerM": 3, "cacheReadPerM": 0.03 } } }

HTTP 接口

GET /my-cost/status[?refreshBalance=1]:返回当前合并价格、峰谷时段/生效状态、以及(缓存的)账户余额。仅绑定在本机 dsh web 服务上。

代码结构

dsh-my-cost/
├── package.json            # 包元数据:入口/exports、dsh.client 声明、构建脚本、peerDependencies
├── README.md               # 本文档
├── LICENSE                 # MIT 许可
├── .gitignore              # 忽略 node_modules/、.temp/ 等
│
├── scripts/
│   └── build.mjs           # Vite 构建脚本:src/ → lib/index.js(Node ESM),client/ → lib/client.js
│
├── src/                    # 【host 端】Node 侧源码(纯 ESM,无中间产物)
│   ├── index.js            # host 插件入口:注册 myCost 会话费用统计、每小时价格轮询、
│   │                       #   GET /my-cost/status 路由、余额查询(凭证走 ctx.credentials,key 不下发)
│   └── pricing-core.js     # 定价纯函数核心:官方定价页解析、峰谷计价、costOf 费用计算、默认价表
│
├── client/                 # 【浏览器端】React 19 + JSX 源码
│   ├── index.jsx           # 浏览器插件入口:apply(ctx) 注册字典、3 个插槽、低余额轮询
│   ├── toast.jsx           # 低余额 toast:React 组件 + createRoot 挂载(渲染在插槽之外)
│   ├── status.js           # useStatus 钩子(拉 /my-cost/status)+ 低余额轮询逻辑
│   ├── format.js           # 金额/token/时间/价格格式化纯函数
│   ├── locales.js          # myCost 命名空间的中英文案
│   ├── components/         # 三个插槽组件
│   │   ├── MessageCost.jsx       # 每条消息的估算费用 chip(conversation.chat.assistant-actions)
│   │   ├── SessionCostLine.jsx   # 输入框底部信息栏:会话总花费 + 跨会话总计 + 余额(composer.dock)
│   │   └── MyCostSection.jsx     # 设置页「费用与余额」面板(settings.section)
│   └── styles/             # 内联样式对象(无 .css 文件,见「样式编写」小节)
│       ├── section.js      # MyCostSection 的样式对象
│       ├── dock.js         # SessionCostLine 的样式对象
│       ├── message.js      # MessageCost 的样式对象
│       └── toast.js        # 低余额 toast 的样式对象
│
└── lib/                    # 【构建产物】Vite 输出(.gitignore,不入 git;npm 发布时由 prepare 构建)
    ├── index.js            # host bundle(Node ESM;zod/官方包/node:* 为 external)
    └── client.js           # 浏览器 bundle(CJS + window.__ModuleLoader__.load 包装)

补充说明("会话投影"是什么):dsh 有个叫 session projection(会话投影) 的机制——框架把 每个会话的 token 用量事件依次回放给插件的统计逻辑,插件累计后产出费用数据,界面再用 useProjection("myCost") 读取。插件本身不用存数据,投影值会随会话持久化。

架构图(Archify)

交互式架构图(由 Archify 生成):

flowchart LR
  subgraph ext["外网"]
    pp["DeepSeek 定价页<br/>api-docs.deepseek.com"]
    ba["DeepSeek 余额 API<br/>api.deepseek.com/user/balance"]
  end

  subgraph host["Host(Node)"]
    runtime["DSH 框架运行时<br/>webServer · credentials · timer · 投影重放"]
    plugin["myCost Host 插件<br/>src/index.js"]
    core["定价核心<br/>src/pricing-core.js"]
    prices["$DSH_HOME/prices<br/>official/local JSON"]
    sessions["DSH 会话存储<br/>事件日志 + 投影值"]
  end

  subgraph browser["Browser(Web)"]
    shell["dsh Web Shell<br/>seed 词表 · __ModuleLoader__"]
    client["myCost Client 插件<br/>client/ · 3 插槽 + toast"]
  end

  plugin -->|"每小时抓取"| pp
  plugin -->|"GET /user/balance · Bearer key"| ba
  plugin -->|"解析 / 计价"| core
  plugin -->|"写 JSON"| prices
  plugin -.->|"注册投影"| runtime
  runtime -->|"回放用量事件"| plugin
  runtime -->|"持久化"| sessions
  client -->|"通道 A · GET /my-cost/status(价格 + 余额)"| plugin
  client -->|"通道 B · useProjection(费用)"| shell
  client -.->|"__ModuleLoader__.load 注册"| shell

核心设计是两条互不重叠的数据通道:

  • 通道 A(HTTP):GET /my-cost/status —— 价格表、峰谷状态、账户余额。API key 只在 host 侧解析(ctx.credentials),绝不下发浏览器。
  • 通道 B(会话投影):useProjection("myCost") / projectionValues.myCost —— 费用数据。 框架回放每次请求的 token 用量事件,插件纯函数累计计价,结果随会话持久化。

在线打开 https://hehe1111.github.io/dsh-my-cost/architecture.html(或本地 docs/architecture.html)可交互查看:聚焦节点、追踪路径、切换主题/预设。 重新生成:安装 Archify 的 DSH 集成(dsh plugin --profile web add @tt-a1i/[email protected]) 后用 archify skill 按 docs/architecture.json 规格 validate + deliver。

说明

  • 费用是怎么算出来的(为什么插件能算花费):依赖上面的会话投影机制,相当于给每个会话装了 一个"自动记账器"——框架负责把账本事件送过来(每次请求的输入/输出/缓存命中/缓存写入 token 用量),插件只负责"怎么算"(按当前官方单价实时计价,且按事件发生时刻计费,支持未来的 峰谷时段),记账结果跟着会话自动保存、界面随时读取。插件不需要自己监听事件、不需要自己 存数据——这就是它能在 host 端无侵入地算出每会话/每消息花费的原因。
  • 所有费用均为估算,以官方账单为准。
  • 价格轮询失败不影响运行:继续使用上次成功拉取的价格(或内置默认价)。
  • 源码在 src/(host 端:index.js + pricing-core.js)与 client/(浏览器端,React 19); lib/ 为 Vite 构建产物。

License

MIT