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

消息暂存 TetraSsky/dsh-hold

DeepSeek Harness
TetraSsky34 天前有提交已提供中文文档扫描:含敏感能力

把草稿消息留到会话真正结束后再发送

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add TetraSsky/dsh-hold
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · other
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件
查看扫描证据(共 4 处,展示前 4 条)
  • 写入本地文件
    src/queue.js:82
    mkdirSync(dirname(filePath), { recursive: true })
  • 写入本地文件
    src/queue.js:84
    writeFileSync(temporary, JSON.stringify({ version: QUEUE_VERSION, records }, null, 2))
  • 写入本地文件
    src/queue.js:85
    renameSync(temporary, filePath)
  • 读取本地文件
    src/queue.js:93
    const parsed = JSON.parse(readFileSync(filePath, 'utf8'))
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-home-paths@deepseek-ai/dsh-llm
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 暂存草稿消息
  • 会话结束后发送

把草拟的消息压住,等会话真正结束再发出去。

README

由 DeepSeek 最新模型翻译生成
dsh-hold 将草拟的消息保留到会话真正结束后再发送。 harness 已经会把你发送的消息在 agent 工作时排队,并在主 agent 停止说话后立即释放该队列。但这并不等同于完成:子 agent 和后台任务对编辑器不可见,因此队列会在实际工作仍在进行时就把你的消息交出去。dsh-hold 补上了缺失的选项——等到完全没有任何任务在运行时再发送——并且它把消息保留在主机上,因此关闭标签页也不会丢失。 这是一个独立插件。它只读写自己的文件,不依赖任何其他插件。 要求 - 带有 web profile 的 DeepSeek Harness。 - 无需其他东西。没有 job 或 subagent 服务时,相应的检查只会报告没有任务在运行。 安装 dsh plugin --profile web add github:TetraSsky/dsh-hold 然后将 dsh-hold 添加到 $DSH_HOME/profiles/web/package.json 中的 dsh.profile.bundles,并重启。该包的 cordis.patch.yml 会插入自己的行。 按钮 一个 Hold 按钮位于编辑器工具栏中,紧挨着发送操作。它使用 harness 自带的 Button 和队列图标,因此看起来与周围的控件一致。
展开完整文档(README 剩余 1 节)
dsh-hold

将草拟的消息保留到会话真正结束后再发送。

harness 已经会把你发送的消息在 agent 工作时排队,并在主 agent 停止说话后立即释放该队列。但这并不等同于完成:子 agent 和后台任务对编辑器不可见,因此队列会在实际工作仍在进行时就把你的消息交出去。dsh-hold 补上了缺失的选项——等到完全没有任何任务在运行时再发送——并且它把消息保留在主机上,因此关闭标签页也不会丢失。

这是一个独立插件。它只读写自己的文件,不依赖任何其他插件。

要求

- 带有 web profile 的 DeepSeek Harness。
- 无需其他东西。没有 job 或 subagent 服务时,相应的检查只会报告没有任务在运行。

安装

dsh plugin --profile web add github:TetraSsky/dsh-hold

然后将 dsh-hold 添加到 $DSH_HOME/profiles/web/package.json 中的 dsh.profile.bundles,并重启。该包的 cordis.patch.yml 会插入自己的行。

按钮

一个 Hold 按钮位于编辑器工具栏中,紧挨着发送操作。它使用 harness 自带的 Button 和队列图标,因此看起来与周围的控件一致。

输入一条消息,点击 Hold,编辑器上方会打开一个窗口,其中有两个独立的选项:

| 维度 | 控件 |
| 发送时间 | 一个开关。关闭(默认)表示没有最早时间,因此消息会尽快发送。开启后会显示一个日历和两个时间下拉菜单。 |
| 如果 AI 仍在工作 | 一个下拉菜单:Queue (Default) · Wait idle · Send now (Steer) |

日期从日历中选择而非手动输入,小时和分钟从两个下拉菜单中选取,因此拼写错误不会产生无意义的时间点。今天之前的日期被禁用,这是一道防护栏。确认时还有第二道:已过去的时间会在窗口中拒绝,绝不会被发送。

两个时间列表是有上限的,而不是交给随附的 Menu 自身的边界(即视口):在那个高度下,24 小时或 60 分钟会变成整页的列,而不是选择器。这个上限是 bundle 安装的一小段样式表,绑定到窗口仅在打开时携带的标记,因此页面上的其他内容不受影响。行使用 compact 变体,这能在有上限的列表中容纳最多的值。

两个维度可以组合。下个月 15 日 09:30 加上 Wait idle 意味着:到那个时间,如果会话仍在进行,就继续等待直到完成,然后发送。不设置时间加上 Wait idle 是核心场景,也是 harness 自身队列无法表达的那个。

窗口的控件是 harness 原语(Button、Switch、Menu),日历也是由这些相同的按钮构建的。消息字段是一个普通的多行 textarea,因为随附的 Input 是单行的。没有原生 或日期 picker 在任何地方使用时,都会使用操作系统的主题而不是 shell 的主题来绘制其弹出窗口。

暂存列表和窗口采用 composer 自身的宽度,与已发布的目标栏和队列条所用的相同方案,因此它们与聊天内容一样宽,并且在对话的拖拽手柄被移动时跟随它。该宽度位于调整大小手柄的内侧而不是横跨它们,因此窗口打开时无需隐藏任何手柄。

确认后会将消息从 composer 移入暂存列表。这三种行为是 harness 自身的术语:

- Queue(默认) 是普通的后续回合,也就是 composer 的队列所做的。
- Wait idle 是相同的投递,但仅在会话完成后进行。
- Send now (Steer) 会在最近的步骤边界被采用。对于空闲的 agent,这与排队相同,这是 harness 自身的规则,因此它永远不会 steer 一个休眠的 agent。

“已完成”的含义

必须同时满足三件事,全部在评估时刻从内存注册表中读取:

| 检查 | 来源 |
| 没有主 agent 在运行 | agent.status。running 跨越整个回合,包括每一次工具调用,因此 idle 确实意味着 agent 停止了说话 |
| 没有活跃的子 agent | 由此会话拥有、状态仍为 running 的活跃 agent |
| 没有后台作业 | ctx.jobs.list(agent),排除 completed / killed / failed |

可继续的子 agent 是故意根据其 agent 的 status 来判断的,而不是根据它是否驻留:一个已结束的子 agent 在其回合结束后仍会驻留,因此驻留会导致消息永远被挂起。

任何等待你处理的事情都已被涵盖。 待处理的审批、问题或计划审查都会使回合保持打开。dsh-user-approval 文档说明“该请求需要一个打开的回合”,而 ask_user_question 和 exit_plan_mode 是普通的工具调用,driver 仍在等待它们的结果。因此主 agent 在被你阻塞的整个期间都读取为 running,无需单独检查。

没有活跃 agent 的会话永远不会被视为已完成:消息会被保留,而不是丢弃,并在该会话再次运行时投递。

暂存列表

当前会话的暂存消息显示在 composer 上方。你暂存多少条都没有限制,因此该列表使用已发布的队列条自身的防护栏:一条暂存显示为其自身,两条或更多会折叠为一个 {n} held messages 标题,带有队列图标和一个 chevron。打开它会列出每一条暂存,并且该打开的列表上限为 180px,会滚动而不是增长,因此二十条暂存是一个标题加一个滚动框,而绝不是二十行堆叠。

每一行都提供:

- Edit 会重新打开窗口,显示该消息的文本、其附件和两个轴,并保存。
- Send now 立即投递,忽略它原本在等待什么。
- Delete 将其丢弃而不发送。

每一行还会说明它在等待什么(“Waiting on the main agent, a background 作业”)或已就绪,并在有时间时倒计时。

顺序。 几个同时到期的保持会一个接一个发出,最旧的优先。一个刚刚投递的 Wait idle 保持会让会话重新开始工作,因此下一个会等待下一次完成,而不是
叠在它上面。Queue (Default) 或 Send now (Steer) 保持不受任何条件限制,
因此它们都会在同一轮中发出,仍然是最旧的优先。两个设为同一时刻的保持行为相同:时间轴决定一个保持何时就绪,而不是一次发出多少个。

语言

窗口跟随界面语言,英文或中文,它显示的每一条拒绝也是如此。宿主用英文回答,因此浏览器有对应句子的代码会被替换为该句子,只有它不认识的代码才会按宿主的措辞显示。

附件

一个保持携带撰写器中已暂存的内容,图片和文件皆然。窗口将它们列在时间轴上方,其中任何一个都可以在保持前被移除。

- 图片以其自身的字节被保持。这正是让该行在消息尚不存在时就能显示其缩略图的原因,因为 harness 不会提供会话尚未引用的图片。它在投递时通过与其自身 prompt 端点相同的 admitPromptContent 调用被接纳进 harness 的持久附件存储。
- 文件以其上传已被解析到的持久引用被保持。暂存文件以其上传生成的凭据传递,而该凭据不会比草稿存活更久,因此宿主在保持创建的那一刻就将其解析为引用。如果它不再能被解析,该保持会被拒绝,而不是在没有其文件的情况下被存储。

一旦一个保持拥有某个附件,它就会从撰写器的轨道中移除,因此它无法随从那里发送的下一条消息一起带上。编辑一个保持会保留其附件,并允许你移除其中一个。
添加新的附件意味着在撰写器中暂存它们并再次保持。

当文件仍在上传中或上传失败后,保持会被拒绝并附上原因,这与撰写器自身不会发送的状态相同。

@ 引用无需特殊处理,从来都不需要:@file 是系统提示所解释的字面文本, @session 由宿主预处理钩子在任何直接用户消息上解析,而引用编解码器是恒等的,因此保持所捕获的草稿正是发送本会使用的确切文本。

持久化

队列是 $DSH_HOME/hold-queue.json 中的一个 JSON 文件,以临时文件加重命名方式写入。它存储发送什么、发往何处、何时发送以及如何发送,从不存储投递状态。
重启时队列会被恢复。卸载插件会清除内存中的视图,并保留持久记录不动:卸载不是取消。

无设置

没有任何可配置项,插件也不注册任何设置命名空间。它始终等待全部三项检查,每一个选择都在窗口内按消息做出。

已知限制
- 宿主进程必须正在运行。 保留会在宿主上触发。已停止的 dsh 进程不会发送任何内容,队列会在下次启动后投递。
- 释放的消息是普通用户消息。 它通过与真实发送相同的路径投递(agent.followup,或在运行中使用 agent.steer),因此它会渲染为你自己的气泡,并且不携带任何表明它曾被保留的标记。
- 附件有预算限制。 测试框架允许一条消息携带 200 MB 的图片,但保留是一个 JSON 文件,宿主会在每次更改时重写它,因此每张图片占用 20 MB,整个保留占用 32 MB,超出后会以相应原因拒绝。带附件的保留需要测试框架的附件和上传服务。没有它们,文件会被拒绝,而不是在没有它们的情况下存储。
- 一次性。 保留只触发一次。重复提醒是 @deepseek-ai/dsh-schedule 的职责。
- 子代理检查会降级。 没有代理所有权 API 时,实时代理遍历不可用,也不会报告任何子代理,因此保留可能会在子代理仍在运行时释放。
主代理和作业检查不受影响。
- 没有跨会话视图。 保留列表显示当前会话。其他会话中的保留会正常投递,但不会在任何地方列出。

开发

npm test # 203 tests
npm run build # regenerate client.js after editing src/client.js

测试套件包含 tests/integration.test.mjs,它通过 JSON 序列化的 RPC,以 Connection 承载它的方式,驱动真实生成的浏览器包针对真实宿主门禁:组合一个保留,观察它等待正在运行的代理和后台作业,然后释放它并看到它作为普通用户消息到达。

tests/harness.mjs 保存共享的测试脚手架:一个 React 替身、已发布原语的替身,以及树遍历器。

浏览器包是生成的:scripts/build-client.mjs 将共享模块内联到 client.js,这正是让浏览器无需导入图即可加载单个文件的原因。
如果已提交的包与 src/ 发生偏离,tests/bundle.test.mjs 会失败。

布局:

| 路径 | 角色 |
| index.js | 宿主入口:队列、门禁和 RPC 路由 |
| src/hold.js | 纯模型:验证、忙碌原因、释放决策 |
| src/world.js | 会话实时工作的一个同步快照 |
| src/gate.js | 保留引擎:tick、投递、编辑、取消、恢复 |
| src/queue.js | 持久队列,临时文件加重命名 |
| src/deliver.js | 消息构造和队列/引导动词 |
| src/rpc.js | Connection 请求围栏后的 /dsh-hold 路由 |
| src/client.js | 浏览器部分:按钮、窗口、保留列表 |
| src/i18n.js | 英文和中文字符串 |

许可证

MIT
预览分享卡片长什么样 ↓TetraSsky/dsh-hold
分享 · DeepSeek Harness Hub
TetraSsky/dsh-hold

把草稿消息留到会话真正结束后再发送

回到顶部