dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
English: README.en.md
一句话:给同一台机器上的多个 AI 会话(或多台引擎)一个"异步信箱" —— 信按文件落盘、默认不叫醒对方、不会丢、不会刷屏。
docs/FOR-AGENTS.md。npm install —— 就这四步)先起一个干净的临时邮局(不碰你机器上的任何东西),再让它跑起来:
# 0) 先备名单 —— 不备的话,下面 send 会报"未知收件人"
# (离线件不必握手 —— 它本来就在"落在信箱里等人来收";【在线】件要握手 )
# (另外:【组名】要名单里有定义,【人名】要已在名单里 —— 这条对离线件也管 )
mkdir whale-mail && cd whale-mail
printf '%s' '{"apiVersion":1,"members":[{"id":"alice"},{"id":"bob"}],"groups":{"all":["alice","bob"]}}' > roster.json
# 1) 握手(在线件没握过手会拒发;离线件不看握手 )
npx -y dsh-whale-post-cli@0.6.1 hello --as alice --root .
npx -y dsh-whale-post-cli@0.6.1 hello --as bob --root .
# 2) 发一封(默认离线 ⇒ 信落在对方信箱里,不叫醒任何人 )
npx -y dsh-whale-post-cli@0.6.1 send --as alice --to bob --subject 'hi' --body 'first letter' --root .
# 3) 收信(投出去/留下来,都由这一句决定 )
npx -y dsh-whale-post-cli@0.6.1 pump --as bob --root .
跑完你会看到(下面是真跑出来的输出):
已投递 …-alice-0001-… → bob(seq 1)【离线(落在对方信箱,不唤醒)】
投递策略:kept(留在信箱里等人来收)
配额(offline 桶):今日 1/80 条
OK …-alice-0001-….msg.json :: [离线] alice → bob:《hi》
| first letter
--root . 指的是信箱根=当前目录 —— inbox//seen//ack//hello/ 都在里面。
判据看退出码:0 过 / 2 拒发 / 1 没料到的错。
dsh plugin --profile <profile> add link:/abs/path/to/dsh-whale-post
npm install # 仓内要先装一次(把六个插件链进 node_modules;否则 CLI 找不到兄弟件)
node packages/cli/index.js selftest # 看退出码
# 其余命令与上面 npx 那几行完全一样,把 `npx -y dsh-whale-post-cli@0.6.1` 换成
# `node packages/cli/index.js` 即可(记得同样先备 roster.json )
装法、接线、接口表、配置项表、写插件规范 ⇒ 见 docs/INSTALL.md;
给 AI 体看的用法纪律 ⇒ 见 docs/FOR-AGENTS.md。
bus + roster + types + cli这四件合起来就是一个能用的邮局 —— 留信、收信、认人、认类型都齐:
| 件 | 它管什么 | 详细说明 |
|---|---|---|
dsh-whale-post-bus | 核心:信封/摘要+HMAC 签名/握手/幂等/落盘 | packages/bus/README.md |
dsh-whale-post-roster | 谁在名单里(含成员属性) | packages/roster/README.md |
dsh-whale-post-types | 信是什么类型 | packages/types/README.md |
dsh-whale-post-cli | 命令行(不是插件) | packages/cli/README.md |
它们各自的说明写在各自的 README 里 —— 主体这一页不重复讲:
| 插件 | 它加什么 | 详细说明 |
|---|---|---|
dsh-whale-post-deliver | 投递策略:离线留着等人/在线投出去;接真引擎的探针在这里 | packages/deliver/README.md |
dsh-whale-post-gate | 闸:配额与计费 + 回环闸 | packages/gate/README.md |
dsh-whale-post-verify | 安全校验:验签 + 白名单(默认禁用) | packages/verify/README.md |
在 DSH 插件商店里的状态 ⇒ docs/SHOP.md(在 —— 而且是自动的;只是缺 cli/verify 且停在 0.1.x)。
接手继续做 ⇒ docs/HANDOFF.md(现在什么状态 + 下一步做什么 + 先读哪几篇)。
怎么发一个新版本 ⇒ docs/RELEASE.md(步骤 + 为什么 —— 发布是不可逆的,宁慢勿错)。
怎么把它们接起来 ⇒ docs/INSTALL.md;组合示例 ⇒ example/。
node scripts/selftest-all.mjs —— 退出码 0 = 七件全过 + 跨包一致(条数由它自己打出来,不写死)。node scripts/racetest.mjs:12 路真子进程同时 send
⇒ 退出码全 0 + 每个 seq 全唯一;它还会重放"state 被写倒退"(把 nextSeq 写回 1 ⇒ 新信仍拿新号)。
它还测了并发记账(2026-10-10 加,而这条抓出过一个真 bug):
12 路真子进程各往同一个配额台账里记一笔 ⇒ 正好 12 条,一条不丢 ——
台账原来是"读 → 改 → 写回" ⇒ 12 路只活下来 8/9/10 条(而配额台账是钱,且它没有任何兜底);
现在每笔记一个增量文件("各写各的" —— 设计文档给 ack 用的就是这一手)⇒ 一条都不许丢。共 11 条判据。
那条"截断路径"已经补成判据了(2026-10-10):seen 状态数组会被 slice(-2000) 截断 ——
而判"读过没有"有两道保险:state.seen 数组(会被截)+ seen/<我>/<id>.msg.json 那个文件(永不被截)。
判据造的是最狠的现场:把状态数组截空、把同一封信放回信箱 ⇒ 必须仍判重复;
而负向证明:只去掉 existsSync 那一路 ⇒ 判据立刻红。node scripts/xcheck.mjs —— 六项(摘要/签名域/MAC/老字段/日界/"名字说真话");
它盯的是**"同一件事在两件里各算一份、结果还相等吗"**(我们在这形状上栽过两次)。docs/ACCEPTANCE.md)。0.6.1 已发上 npm(上面那几行 npx 装的就是它,已按
docs/RELEASE.md 第 2 步真装验收过)。
ⓘ npm 的 registry 有几分钟同步延迟 ⇒ 刚发完那一会儿可能还装不到 @0.6.1
—— 装不到就先用 @0.3.0(它也在 npm 上、也真能跑)。v0.6.1(0.1.x 装进真引擎会六个插件全部加载不上);
接口带 apiVersion,类型可以随时扩充(加类型不用动核心)。逐版改了什么、为什么 ⇒ 见 CHANGELOG.md。failed to apply(apply() 里读了 ctx.whale 属性,而真 Cordis 里读它要先 inject);
而 --dump-config 完全看不出来(它只组配置树、不跑 apply())。
⇒ 现在只 ctx.provide(...) + 运行时 ctx.get(...),并钉了一条静态判据。细节与坑 ⇒ docs/INSTALL.md §六。很多引擎已经能派子代理(或"团队功能")⇒ 常见一问是「那还要你这个干嘛」。答:
| 引擎自带的子代理/团队 | 本仓(邮局) | |
|---|---|---|
| 管什么 | 此刻的并行(同一进程树里派出去、同步等结果、用完即弃) | 此刻不在一起时的传递 |
| 范围 | 同一个引擎 | 跨引擎/跨设备/跨会话 |
| 身份 | 无(都是主会话的分身) | 有 —— 钥匙 + 名单;每设备一把,冒名验不过 |
| 留痕 | 不落盘(这一轮结束就没了) | 信落盘,seen/ 永久留档 |
| 同步性 | 同步等待 | 异步 —— "只会晚到,不会不到" |
| 代价 | 烧同一个账号的额度 | 配额制 + 默认离线 ⇒ 省粮;离线件不占别的桶 |
一句话:子代理是"你的手",邮局是"我们之间的路"。 判据一句:"我现在就要它做" ⇒ 用子代理;"它现在可能不在" ⇒ 用邮局。
同类的东西已经有不少。写这个仓库之前我们查过一圈(2026-10-10),最近的几个:
| 项目 | 它是什么 |
|---|---|
avivsinai/agent-message-queue | 文件式的本地 agent 间消息队列,Maildir 风格,Go 写的 |
@yuanchilin/dsh-mailbox | DSH 的跨会话文件信箱,走共享文件系统,带 seen 去重和 TTL 清理 |
polaris-smart/dsh-agent-mailbox | DSH 的跨 agent 信箱插件,桥接 agent-mailbox |
它们解决的是同一类问题:让几个 agent 能互相留话。我们多做了三件事:
另外两件是我们顺手做的:身份与验签(HMAC 签名 + 名册白名单,默认关,开了才验), 以及跨设备(投到远端信箱、取回来、回执也镜像回来)。
该说的短处也说清楚:agent-message-queue 的生态比我们大得多,也支持更多引擎;
@yuanchilin/dsh-mailbox 有一个 /mailbox 交互界面,我们只有命令行。
我们的星少、也没进任何官方目录(@deepseek-ai 那个 scope 下是官方组件,我们不在其中)。
如果你只想要"能发信",用哪个都行;如果你在意"别把对方的会话烧醒、别把额度刷爆、别丢信",
那这三件是我们和它们最大的差别。
| 取舍 | 为什么 |
|---|---|
| 默认离线 | 叫醒对方=让对方付一次满上下文推理;默认省下它 |
| 只投活体,不活就"不投也不消费" | 怕丢信 ⇒ 宁可信晚到(信留信箱,人来了再给) |
| 拒发就是拒发(不静默降级) | 悄悄降级=让人以为发出去了 ⇒ 最危险(我们踩过"急件写成 ONLINE 就永远叫不醒人") |
packages/bus/ packages/roster/ packages/types/
packages/deliver/ packages/gate/ packages/verify/ packages/cli/
example/ docs/ CHANGELOG.md
许可:MIT。本仓为独立实现(未使用任何无许可代码)。
讨论和修改都留在提交记录和 issue 里。
我们拿它做各种东西,whale-post 是其中做得最久的一个:一开始只是想让几个跑在同一台机器上的程序
能互相留个话,后来慢慢长成了一套完整的东西。有问题欢迎开 issue,我们看到会回。