🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

省钱时段 zhu168/dsh-save-money

DeepSeek Harnessv1.4.4
zhu16872 天前有提交已提供中文文档扫描:含敏感能力

省钱插件,用于 DSHDeepSeek Harness——自己定义「暂停 /…

44.3/100
综合分
35
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add zhu168/dsh-save-money
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · other
装得上吗
npm 包存在但缺 main/exports/bin 入口声明,源码安装也可能起不来
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 72 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-save-money @ 1.4.4
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 15:46:43

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 36 处,展示前 32 条)
  • 读取本地文件
    scripts/build.js:43
    const source = readFileSync(join(srcDir, file), 'utf8')
  • 写入本地文件
    scripts/build.js:75
    mkdirSync(distDir, { recursive: true })
  • 读取本地文件
    scripts/build.js:80
    const rootPkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
  • 写入本地文件
    scripts/build.js:92
    writeFileSync(join(distDir, 'core.js'), core, 'utf8')
  • 写入本地文件
    scripts/build.js:93
    writeFileSync(join(distDir, 'balance-history.js'), balanceHistory, 'utf8')
  • 写入本地文件
    scripts/build.js:94
    writeFileSync(join(distDir, 'balance-bars.js'), balanceBars, 'utf8')
  • 写入本地文件
    scripts/build.js:95
    writeFileSync(join(distDir, 'balance-host.js'), balanceHost, 'utf8')
  • 写入本地文件
    scripts/build.js:96
    writeFileSync(join(distDir, 'balance-client.js'), balanceClient, 'utf8')
  • 读取本地文件
    scripts/make-plugin.js:38
    const src = readFileSync(join(root, 'dist', 'host.js'), 'utf8')
  • 写入本地文件
    scripts/make-plugin.js:72
    writeFileSync(join(root, 'plugin', 'index.js'), hostOut)
  • 读取本地文件
    scripts/make-plugin.js:76
    const clientSrc = readFileSync(join(root, 'dist', 'client.js'), 'utf8')
  • 写入本地文件
    scripts/make-plugin.js:112
    writeFileSync(join(root, 'plugin', 'client.js'), clientOut)
  • 读取本地文件
    scripts/make-plugin.js:117
    const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
  • 写入本地文件
    scripts/make-plugin.js:130
    writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
  • 发起网络请求
    plugin/client.js:1986
    const res = await fetch('/' + method, {
  • 发起网络请求
    plugin/index.js:644
    const res = await fetch(url, {
  • 执行外部命令来自配置/变量
    scripts/release.js:83
    execSync(cmd, { stdio: 'inherit', cwd: opts.cwd || root, env })
  • 执行外部命令固定命令
    scripts/release.js:100
    const dirty = execSync('git status --porcelain', { encoding: 'utf8', cwd: root }).trim()
  • 读取本地文件
    scripts/release.js:108
    const readJson = (p) => JSON.parse(readFileSync(p, 'utf8'))
  • 写入本地文件
    scripts/release.js:109
    const writeJson = (p, obj) => writeFileSync(p, JSON.stringify(obj, null, 2) + '\n', 'utf8')
  • 读取本地文件
    scripts/release.js:121
    const testSrc = readFileSync(testPath, 'utf8')
  • 写入本地文件
    scripts/release.js:124
    writeFileSync(testPath, nextTest, 'utf8')
  • 读取本地文件
    scripts/release.js:135
    const text = readFileSync(p, 'utf8')
  • 写入本地文件
    scripts/release.js:138
    writeFileSync(p, next, 'utf8')
  • 执行外部命令固定命令
    scripts/release.js:166
    const configured = execSync('git remote', { encoding: 'utf8', cwd: root })
  • 写入本地文件
    scripts/release.js:188
    copyFileSync(join(root, 'README.md'), readmeTmp)
  • 删除本地文件
    scripts/release.js:196
    try { unlinkSync(readmeTmp) } catch (e) { }
  • 读取本地文件
    scripts/typecheck.js:55
    const src = readFileSync(join(root, 'src', name + '.ts'), 'utf8')
  • 写入本地文件
    scripts/typecheck.js:69
    mkdirSync(tmpDir, { recursive: true })
  • 写入本地文件
    scripts/typecheck.js:70
    writeFileSync(tmpFile, wrapped, 'utf8')
  • 发起网络请求
    src/balance-host.ts:115
    const res = await fetch(url, {
  • 发起网络请求
    src/client.ts:101
    const res = await fetch('/' + method, {
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

2 张 · 点击查看大图

功能亮点

  • 自定义暂停恢复时间窗
  • 长任务到点自动暂停
  • 窗口结束自动恢复

README

由 DeepSeek 最新模型翻译生成
dsh-save-money 省钱插件,用于 DSH(DeepSeek Harness)——自己定义「暂停 / 恢复」时间窗;到暂停时间,正在跑的长任务会自动暂停(不是停止),窗口结束后自动恢复。专为 LLM API 的峰谷定价设计(比如 DeepSeek 的高峰时段是北京时间 9:00–12:00、14:00–18:00,低谷半价;从 2026-08-23 起周末全天低谷——插件的按星期开关默认跳过周六周日),同样适用于分时电价、带宽错峰、或者任何「这段时间我不想让机器干活」的场景。 状态:✅ 已实现,持续维护。中文版 界面 省钱插件截图 会话标题栏右上角的彩色状态文字(Save · ⚪/🟢/🟡/🔴,颜色跟随状态)是唯一的常驻入口——点它打开设置浮层。即将暂停或正在暂停时,页面顶部会出现提醒横幅(带 End this save mode 按钮)。 开启「Show balance」后,官方 DeepSeek 账户余额会显示在状态文字旁边;点击余额打开最近 8 小时的消费柱状图: 余额与消费柱状图截图 每根柱子是一个 10 分钟窗口:X 轴显示整点刻度,Y 轴显示关键金额刻度(≤5,带网格线),悬停可看每个窗口的精确时间范围和金额。余额下降但本地没有任何活动的窗口,会用警示色标出(变动可能来自另一台设备)。
展开完整文档(README 剩余 1 节)
dsh-save-money

省钱插件,用于 DSH(DeepSeek Harness)——自己定义「暂停 / 恢复」时间窗;到暂停时间,正在跑的长任务会自动暂停(不是停止),窗口结束后自动恢复。专为 LLM API 的峰谷定价设计(比如 DeepSeek 的高峰时段是北京时间 9:00–12:00、14:00–18:00,低谷半价;从 2026-08-23 起周末全天低谷——插件的按星期开关默认跳过周六周日),同样适用于分时电价、带宽错峰、或者任何「这段时间我不想让机器干活」的场景。

状态:✅ 已实现,持续维护。中文版

界面

省钱插件截图

会话标题栏右上角的彩色状态文字(Save · ⚪/🟢/🟡/🔴,颜色跟随状态)是唯一的常驻入口——点它打开设置浮层。即将暂停或正在暂停时,页面顶部会出现提醒横幅(带 End this save mode 按钮)。

开启「Show balance」后,官方 DeepSeek 账户余额会显示在状态文字旁边;点击余额打开最近 8 小时的消费柱状图:

余额与消费柱状图截图

每根柱子是一个 10 分钟窗口:X 轴显示整点刻度,Y 轴显示关键金额刻度(≤5,带网格线),悬停可看每个窗口的精确时间范围和金额。余额下降但本地没有任何活动的窗口,会用警示色标出(变动可能来自另一台设备)。

功能

- 多个时间窗:自由添加 / 删除暂停-恢复时间窗;支持跨午夜窗口(23:00–08:00)和按星期过滤;
- 到点自动暂停:暂停时间一到,正在跑的任务会被安全「冻结」(进度原样保留——不打断、不丢失),窗口结束后自动恢复;没有任务在跑就不暂停;
- 窗口内不发请求(省钱核心):暂停窗口内 AI 不向模型服务发新请求,因此不产生费用;窗口结束(或关闭 / 结束本窗口)后一切恢复,对话上下文和进行中的任务不受影响。窗口内 AI 不回复(包括新对话)是预期行为——想立刻恢复,点 End this save mode 按钮(直接生效,不经过 AI);
- 按模型档位分别设置省钱模式:按模型档位决定哪些在时间窗内暂停。设置面板显示两行紧凑选项——官方 API(DeepSeek 官方 API)和其他 API(所有非官方服务商:opencode go/zen、中转、SiliconFlow……)——每行都有 flash / pro / vision 开关(vision = deepseek-v4-flash-vision-exp),共六个开关。勾选 = 暂停(省钱);不勾选 = 豁免(即使处于时间窗内,请求也照常放行)。默认值:官方三个档位勾选,所有「其他」档位豁免;你的修改会持久保存,永不重置。模型名里不带 flash/pro/vision 标记的(旧版 chat/reasoner、未知模型、其他任何情况)始终豁免——它永远不会拦住你的请求;
- 全局星期开关:时间窗列表上方一行——一 ☑️ 二 ☑️ 三 ☑️ 四 ☑️ 五 ☑️ 六 ⬜ 日 ⬜。保存只在勾选的日期生效(默认 周一至周五——按 2026-08-23 高峰/低谷规则,周末全天都是低谷,所以周六周日不会暂停)。与每个时间窗自己的按星期过滤组合:两者都匹配,时间窗才生效;
- 结束本次省钱模式(一次性,仅当前时间窗):横幅和设置弹层里的按钮只结束当前正在生效的暂停时间窗——如果已暂停,任务立即恢复,闸门打开;如果暂停即将开始,则取消。该时间窗会一直跳过,直到它的恢复时间,然后状态自动清除。下一个时间窗(今天或之后)仍然生效,持久的 Enable 标志也从不改动,所以你不会不小心把功能关掉;
- 界面提醒:顶部浮动横幅(即将暂停为浅黄色 / 已暂停为浅红色,带 End this save mode 按钮)+ 会话头部唯一常驻入口(在 Session log 旁边,「Save · 🟢 Working」彩色状态文字;点击展开设置),颜色实时跟随状态变化;
- 时区支持:IANA 时区下拉框,浏览器自动检测,回退到北京时间(+8);UTC 投影已校验(北京时间 09:00 == UTC 01:00);
- 一键 DeepSeek 预设:去重追加高峰时间窗(08:58–12:02、13:58–18:02,带 2 分钟边界余量——提前 2 分钟暂停,延后 2 分钟恢复);它不会自动启用——由你决定;旧版无余量的时间窗在一键操作时自动升级;
- 持久配置:所有设置自动保存到工作区文件 save-money.config.json(已 gitignore);配置在浏览器刷新、插件停用/重新启用后依然保留,启动时加载,并可选对暂停的目标做一次对账;
- 账户余额显示(可选):在设置里勾选「Show balance」,官方 DeepSeek 账户余额就会出现在顶栏状态文字旁边(自动带货币符号,颜色跟随主题)。默认关闭。配置了多个模型来源时(官方 DeepSeek + SiliconFlow、中转等),余额会跟随实际在用的模型:最近一次真实请求跑在官方服务商上就显示,否则隐藏(采样得到的消费历史会保留,切回 DeepSeek 立刻重新显示余额);
- 消费统计:开启余额显示后,后端每 5 分钟采样一次余额(288 个点,覆盖最近 24 小时)。把鼠标悬停在余额上,可以看到最近 1 小时 / 10 分钟 / 24 小时花了多少(充值或退款带来的余额上涨显示为「+金额」);
- 消费柱状图(最近 8 小时,每 10 分钟一格):点击余额,打开最近 48 个十分钟窗口的图表。外部消费归因——某个窗口余额下降,但本地没有任何模型活动,就标成警告色(悬停提示:「no local activity in this window; change may come from elsewhere」),而不是记成本地消耗,这样在另一台机器上用同一个 API key 也不会看起来像一秒内消费爆炸。余额充值(充值 / 退款)永远不画成柱子,也不会撑开 Y 轴——坐标轴只表示消费;被隐藏的充值窗口悬停时会显示「balance recovered (recharge / refund), not counted in spend analysis」;
- 余额历史持久化:采样历史保存到 ~/.dsh/dsh-save-money-balance.json(账户级,跨项目共享),插件更新或重启都不会丢。文件以 API key 的指纹为键——换 key 会自动丢弃旧历史;
- 设计上不打扰:不锁屏、不弹遮挡层、不阻止任何用户操作——只暂停目标的自动续跑;手动交互始终畅通。

工作原理

stateDiagram-v2
direction TB
[] --> Disabled

Disabled : Disabled ⚪ — nothing pauses, no money saved Working : Working 🟢 — normal use, requests flow Pausing : Pausing soon 🟡 — yellow banner reminder Paused : Paused 🔴 — requests suspended, no cost

Disabled --> Working : check "Enable"
Working --> Pausing : a window starts within 5 minutes
Pausing --> Paused : pause time reached
Paused --> Working : window ends, auto-resumes
Paused --> Working : "End this save mode" — resume now
Pausing --> Working : "End this save mode" — cancel this pause
Working --> Disabled : uncheck "Enable"
Pausing --> Disabled : uncheck "Enable"
Paused --> Disabled : uncheck "Enable"
- 暂停窗口一启动,正在跑的任务会冻结(进度保留),AI 也停止回复——这是正常的:机器在帮你省钱。窗口结束后一切自动恢复;
- 看到黄色的「pause in X min」横幅,但你现在不想暂停?点 End this save mode,只取消当前这个窗口;
- 已经暂停,想立刻继续?点 End this save mode(红色按钮)——马上恢复,只跳过当前窗口,绝不会关掉 Enable:下一个窗口(今天或以后)照常省钱。如果哪天你想让每个窗口都重新生效,把 Enable 取消勾选再重新勾选即可。

安装

DSH 插件的官方形态是导出 apply 的模块 + cordis.yml 挂载(见 DSH 官方教程)。你可以从 npm 安装(一条命令,推荐),也可以从本仓库构建(下面三种方式:--patch 快速试用、可分发打包、或 link + HMR 开发工作流)。每种官方形态都带完整插件:Host 逻辑(调度、gate、目标冻结、工具、HTTP 端点)和浏览器 UI(状态文字、横幅、设置页),UI 会自动加载——不需要 AI 辅助配置。

从 npm 安装(推荐)

插件已发布到 npm——一条命令装进你的 Web 配置档:

首次安装

npx @deepseek-ai/dsh plugin --profile web add dsh-save-money

卸载

npx @deepseek-ai/dsh plugin --profile web remove dsh-save-money

安装后,完整重启 DSH(Ctrl+C,再启动),并强制刷新浏览器(Ctrl+Shift+R)——会话头部右上角会出现「Save」状态文字。

源码安装(从本仓库构建)

以 ~/app/ 为例目录(每一步都假设上一步已成功):

cd ~/app/

git clone https://github.com/zhu168/dsh-save-money.git

cd dsh-save-money
npm install

cd plugin
npm pack # runs the build automatically; produces the plugin tarball

ls # check the tarball name, e.g. dsh-save-money-1.4.4.tgz

cd ~/app/deepseek-harness # change to your harness directory (clone it first if missing — see "0." below)

pnpm dsh plugin --profile web remove dsh-save-money # only if you installed it before; skip if you haven't

pnpm dsh plugin --profile web add ../dsh-save-money/plugin/dsh-save-money-1.4.4.tgz # use the name from ls above

pnpm dsh --profile web # starts DeepSeek Harness — the plugin appears top-right in the session header

两点说明:① add 那行的 tarball 名字必须和 ls 打印的一致(1.4.0 只是示例);② 如果你的 harness 用 npx 运行,把上面所有 pnpm dsh 换成 npx @deepseek-ai/dsh(安装命令也一样)。

0. 先让 DSH 本身跑起来

插件运行在 DSH 里,所以下面任何操作之前,DSH 必须先跑起来。两种方式: A. 已安装的命令行(最省事,需要 Node.js):

npx @deepseek-ai/dsh web # starts the Web UI at http://127.0.0.1:3080

B. 从源码运行(比如在树莓派上;dsh 不是全局命令 —— 你必须在检出的 deepseek-harness 目录里面运行 pnpm dsh):

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web # inside this directory only

源码模式下,千万别直接敲 dsh ... —— 它不在 PATH 里(command not found: dsh)。要在 deepseek-harness 目录里用 pnpm dsh ...,或者用 ./node_modules/.bin/dsh ...。

路线 1:--patch 快速试用(官方方式,加载本地源码)

适合在存放这个仓库的同一台机器上试用插件。

1. (可选)重新构建最新的插件模块 —— 刚克隆下来要先装构建依赖:

npm install # first clone: installs typescript and friends
npm run prepare # one step: src/.ts -> dist/.js -> plugin/index.js + plugin/client.js

2. 编辑 cordis.patch.yml,把 <REPO_ROOT> 换成仓库的绝对路径(这是文件里唯一的占位符 —— 用编辑器的「全部替换」):

- insert:
- id: save-money
name: '<REPO_ROOT>/plugin/index.js'

示例 —— Windows:name: 'D:/git/github/dsh-save-money/plugin/index.js';Linux / macOS / Pi:name: '/home/pi/dsh-save-money/plugin/index.js'。

如果你的配置档里已经通过 bundle / link 装过这个插件,跳过路线 1(再叠加 --patch 会把插件注册两次)。

3. 带上 overlay 启动:

dsh web --patch ./cordis.patch.yml # globally installed dsh
npx @deepseek-ai/dsh web --patch ./cordis.patch.yml # npx-launched (Step 0, option A)
from source: pnpm dsh web --patch ./cordis.patch.yml

4. 用浏览器打开打印出来的 URL(默认 http://127.0.0.1:3080)—— 会话头部右上角会出现「Save」状态文字。不需要额外操作。

路线 2:bundle + dsh plugin add(官方方式,可分发 —— 推荐换机器 / 上树莓派时用)

bundle 是个很小的 .tgz,构建一次就能到处安装。目标机器上不用克隆这个仓库 —— DSH 会把插件装进自己的配置档(~/.dsh/profiles/web/node_modules/)。

第 1 步 —— 构建并打包 bundle(在任何有本仓库的机器上):

cd dsh-save-money
npm install # first clone only (typescript dev dependency)
cd plugin
npm pack # runs the prepare build automatically; produces dsh-save-money-1.4.4.tgz

plugin/ 是标准的 bundle 布局:package.json 声明 dsh.bundle.patch + dsh.client,cordis.patch.yml 插入插件那一行,index.js 是 Host 模块,client.js 是浏览器 UI bundle。
第 2 步 — 把 tgz 复制到目标机器(scp / U 盘 / 你平时怎么传文件都行;在构建机器上运行,位于仓库的上一级目录,路径按你的实际情况调整):

scp dsh-save-money/plugin/dsh-save-money-1.4.4.tgz pi@<pi-ip>:~/

第 3 步 — 安装到配置档(在目标机器上执行;首次运行会用 @deepseek-ai/dsh-base 初始化配置档):

DSH run from source (inside the deepseek-harness directory):
pnpm dsh plugin --profile web add ~/dsh-save-money-1.4.4.tgz
npx-launched (Step 0, option A) or globally installed dsh: works from any directory
npx @deepseek-ai/dsh plugin --profile web add ~/dsh-save-money-1.4.4.tgz

两条命令做的事一样:把 tgz 安装到 ~/.dsh/profiles/web/node_modules/。按你启动 DSH 的方式选一条就行。

用 git 安装也可以:dsh plugin --profile web add github:you/dsh-save-money#<sha>(git 安装需要 prepare 构建和 allowBuilds,见 DSH 发布教程)。

第 4 步 — 确认层已挂载,然后启动(完整重启 DSH,别只刷新页面):

pnpm dsh --profile web --dump-config # the output should show a dsh-save-money layer (its plugin rows)
pnpm dsh --profile web # Ctrl+C to stop an already-running instance first

第 5 步 — 打开浏览器访问 http://127.0.0.1:3080,然后强制刷新(Ctrl+Shift+R)。「Save」状态文字会出现在会话头部;点它就能打开设置。你也可以在对话里确认插件已生效(save_money_status)。

升级到新版本(比如 1.3.0 → 1.4.0):

下面的命令用的是 pnpm dsh;如果你通过 npx 启动 DSH,把 pnpm dsh 换成 npx @deepseek-ai/dsh。

on the build machine:
cd dsh-save-money && git pull && cd plugin && npm pack # fresh dsh-save-money-<new>.tgz
scp dsh-save-money/plugin/dsh-save-money-1.4.4.tgz pi@<pi-ip>:~/

on the target:
pnpm dsh plugin --profile web remove dsh-save-money
pnpm dsh plugin --profile web add ~/dsh-save-money-1.4.4.tgz
pnpm dsh --profile web # restart, then hard-refresh the browser

你的设置升级后依然保留(它们存在 save-money.config.json 里,remove/re-add 不会动它)。

卸载:

pnpm dsh plugin --profile web remove dsh-save-money

路径 3:开发工作流(这个仓库实际用的方式:link 安装 + HMR 热重载)

改动立即生效——不用重启 DSH,也不需要 tgz。开发插件时用的就是这种形式:dsh plugin add link: 把 plugin/ 目录直接链接进配置档,再由 cordis-plugin-hmr 热重载插件监听构建产物。保存源码 → npm run prepare → 运行中的 DSH 就会热替换成新插件;强制刷新浏览器就能看到客户端 UI。

一次性设置(在开发机器上):

1. 构建并 link 安装:
cd dsh-save-money
npm run prepare # src/.ts -> plugin/index.js + plugin/client.js
pnpm dsh plugin --profile web add link:D:/git/github/dsh-save-money/plugin # use your repository's absolute path

2. 配置热重载:编辑 ~/.dsh/profiles/web/cordis.patch.yml(文件不存在就新建),把 root 换成你仓库里 plugin 目录的绝对路径:

- insert:
- id: save-money-hmr
name: '@deepseek-ai/cordis-plugin-hmr'
config:
root: ['D:/git/github/dsh-save-money/plugin']
ignored: ['/node_modules', '/.']
debounce: 100

3. 启动 DSH(pnpm dsh web / npx @deepseek-ai/dsh web),打开浏览器(默认 http://127.0.0.1:3080)。

日常开发循环:

after editing src/.ts, run once:
npm run prepare # rebuild -> writes plugin/index.js + plugin/client.js

DSH 会在约 0.1s 内热替换插件(终端里找 [hmr] 日志)——不用重启;强制刷新浏览器(Ctrl+Shift+R)才能看到客户端改动。

注意:link: 和 Path 2 的 bundle 安装互斥——如果你之前装过 bundle,先跑 pnpm dsh plugin --profile web remove dsh-save-money,再 add link:。

配置持久化(所有安装形式)

插件把设置写入 save-money.config.json(已被 .gitignore 排除,绝不提交):启动时自动加载,每次改动立即落盘。配置文件位置在运行时按候选列表逐个查找——第一个真正存在配置文件的目录胜出:

1. 指针文件 ~/.dsh/save-money-config-path.json 记录的目录(最后一次的真实位置,这样即使没有会话匹配,重启后也能解析到同一个文件);
2. 当前会话的工作区目录;
3. 所有路径以 dsh-save-money 结尾的会话工作区(有多个时取最新的一个);
4. DSH 启动目录本身(process.cwd(),官方安装形式);
5. 与 DSH 启动目录同级的 dsh-save-money 目录(README 快速安装布局:~/app/deepseek-harness 旁边就是 ~/app/dsh-save-money);
6. 最后兜底:sandboxPolicy.workspaceRoot(DSH 安装目录)。

全新安装时(哪里都没有配置),插件优先把配置写进仓库目录(第 4/5 步匹配到的 dsh-save-money 目录),而不是污染 DSH 安装目录,并在 ~/.dsh/ 里记录指针,之后每次重启都加载同一个文件。删掉配置文件即重置所有设置。

故障排查

| 现象 | 原因与修复 |
| zsh: command not found: dsh / dsh: command not found | 你在从源码运行 DSH——dsh 只在 deepseek-harness 目录内以 pnpm dsh ...(或 ./node_modules/.bin/dsh)的形式可用。绝不要在目录外直接敲 dsh。 |
| 插件加载失败,报 ReferenceError: harness is not defined | 你运行的构建版本低于 v1.2.2 —— 官方表单在 v1.2.2 中已修复。重新构建(npm run prepare)、重新打包、重新安装,然后重启。 |
| 已安装,但没有状态文字 / 横幅 / 设置页 | 完全重启 DSH(Ctrl+C,再启动),并强制刷新浏览器(Ctrl+Shift+R)—— Client 那一半在启动时才会被发现。如果还是不出现,说明你运行的构建版本低于 v1.2.4 —— 请升级。 |
| UI 显示了,但启用复选框(以及其他设置)没有反应 | 你运行的构建版本低于 v1.2.5 —— 以前插件会在 Web 服务器就绪之前启动,所以 UI 请求到不了它那里。升级到 ≥ v1.2.5 并重启。 |
| 我的配置文件在哪? | 按上面的 6 步候选列表自动解析(优先会话工作区 / 仓库目录;~/.dsh/save-money-config-path.json 记录上次的位置)。删掉它会重置所有设置。 |

快速开始

下面的步骤适用于所有安装形式 —— Path 1 / Path 2 / Path 3 都带同一套设置 UI。你也可以在对话里通过工具配置(save_money_configure、save_money_status)。

1. 安装并激活后,点击会话头部右上角(Session log 旁边)的 「Save · 🟢 Working」 状态文字,打开设置(唯一的常驻入口);或者用系统设置页(侧边栏 → Settings → Save-money);
2. 点击一键 DeepSeek 峰谷省钱 → 自动加入高峰时段(北京时间 08:58–12:02、13:58–18:02,带 2 分钟边界余量);
3. 勾选「启用」(一键操作不会自动启用);
4. 保存时段设置 —— 插件开始监视:任务在时段开始时自动暂停,时段结束时恢复。

入口

| 入口 | 位置 |
| 状态文字(唯一常驻入口) | 会话头部右上角(Session log 旁边)「Save · 🟢 Working」,点击打开设置浮层 |
| 系统设置页 | 侧边栏 → Settings → Save-money |
| 浮动横幅 | 暂停即将开始 / 正在进行时顶部的胶囊条 + 结束本次省钱模式按钮(一次性:只结束当前时段,不影响后续时段) |

动态工具(Host)

| 工具 | 用途 |
| save_money_status | 查询状态 / 门控状态(gate: open\|closed) / 时段 / 暂停记录 / UTC 投影 |
| save_money_configure | 配置(enabled / timezone / warnMinutes / windows) |
| save_money_end_window | 只结束当前活动时段的省钱模式(一次性,存于内存):立即恢复 / 取消即将开始的暂停;后续时段仍然生效 |
| save_money_debug_tick | 开发工具:手动推进状态机 |

文档与许可

- 仓库结构:src/ 存放 TypeScript 插件源码(唯一数据源,每个文件 ≤ 400 行):core.ts / state.ts / config.ts(纯逻辑:时间辅助函数、状态机、配置控制器),balance-history.ts / balance-bars.ts / balance-host.ts / balance-client.ts(余额历史、模型分类 + 消费条形图、余额传输、余额 UI 辅助函数),host-goals.ts / gate.ts / balance-tracker.ts / host-http.ts / host-tools.ts(宿主子模块,由 host.ts 串联),i18n/(10 种语言词典 + 聚合器),ui/(客户端组件,由 client.ts 串联)。tests/(单元测试,npm test),scripts/build.js(TS → JS 插件主体),scripts/typecheck.js(类型检查),scripts/make-plugin.js(官方打包生成器),plugin/(打包产物:package.json + cordis.patch.yml + index.js + client.js),cordis.patch.yml(快速试用覆盖层),package.json / tsconfig.json(构建与类型配置),dist/(构建输出,已 gitignore),save-money.config.json(运行时配置,已 gitignore)
- i18n:UI 文案放在 src/i18n/* —— 每种语言一个词典(zh.ts、zh-TW.ts、en.ts、de.ts、fr.ts、es.ts、it.ts、pt.ts、ja.ts、ko.ts);语言从浏览器区域设置自动检测,也可手动选择(Auto + 10 种),选择结果会持久化到配置里
- 许可证:MIT(见 LICENSE)
预览分享卡片长什么样 ↓zhu168/dsh-save-money
分享 · DeepSeek Harness Hub
zhu168/dsh-save-money

省钱插件,用于 DSHDeepSeek Harness——自己定义「暂停 /…

回到顶部