把生成的文件推到手机,也能引用手机发回的内容
29.5/100
综合分
3
GitHub 星标
169
npm 周下载
—/5
用户评分
数据截至 2026/9/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-swarmdropnpm 源 · dsh-swarmdrop 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-conversation@deepseek-ai/dsh-client-ui-input-trigger@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-ui-settings@deepseek-ai/dsh-client-ui-sidebar@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-client-ui-theme@deepseek-ai/dsh-commands给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 推送文件到手机
- 引用手机回传内容
- 端到端加密
把文件从 DeepSeek Harness 智能体直接发到你手机,还能引用手机回传的内容——不用账号、不用公网 IP,端到端加密。
最近更新
在 GitHub 查看全部 →v0.7.12026-08-24
· 已修复
· @ 引用在任何 0.1.1 系列的 harness 上都完全生成不出候选。ProjectionDefinition 在这个包编译时对应的版本和当前 dsh 运行的版本之间改了名:schema 变成 stateSchema,view 移进 wire.view,旁边还有 wire.viewSchema。
没有任何地方大声报错,因为 wire 是可选的——没有 wire 的单元是合法的仅服务端单元,只是永远不会推给客户端。于是 inbox 单元注册得干干净净、折叠得也对、在 checkpoint() 里也出现了,可 snapshot()——构建客户端收到内容的那次调用——却跳过了它。@ 菜单里没有 SwarmDrop 分组,任何日志也没说为什么。
现在定义里两种拼写都带着,所以两条线都能用。dev-notes/at-reference-broken.md 记下了排查路上排除了什么,因为在找到这个原因之前先排掉了八个看似合理的起因。
· peer 范围现在接纳 0.1.1 harness 线(^0.1.0-rc.8 || ^0.1.1-rc.1)。caret 范围跨一个预发布版不匹配另一组 major.minor.patch 上的预发布版,所以 ^0.1.0-rc.8 悄悄排除了 0.1.1-rc.2——正是这一点让插件能对着一个契约编译、却对着另一个契约运行。
· scripts/check-tokens.mjs 读取 @deepseek-ai/dsh-client-ui-theme,而它此前只是作为被提升的三级传递依赖才到达那里。现在它是声明的 devDependency,所以 dsh 自己的依赖树变动不会再让 typecheck 变红。
v0.7.02026-08-24内容较长已截断
· 变更
· 设置页现在由页头、标签栏和一列内容组成。它以前在 dsh 自己的导航旁边再放一套垂直导航,看起来像一套导航被拆成两半,还让七个短标签占掉内容区 128px 的宽度。
· 节点存活状态和启动/停止从「概览」移到页头,每个标签页都能看到。没有把更耗资源的项一起搬过去:页头在全部七个页面下都会挂载,而插件版本和命令行路径各自要起一个 swarmdrop 进程,所以它们留在「关于」页。
· 分组标题改成普通的 13px 标题。原来是 11px 大写加字距,七个分组各戴一个。
· 错误和回执渲染在标签栏下方而不是页头上方,关闭控件改成图标。长消息以前会把「dismiss」这个词挤得没有宽度,结果沿边缘一行折一个字符。
· 错误文本改成常规字重、中性底色加红色图标,不再是一整片红。命令行把补救办法放在消息末尾,而那正是读者得先读完诊断才能看到的部分。
· 侧边栏面板把节点 id 和公网地址各显示为一行省略文本,配一个复制按钮。完整显示时它们要占两行和四行,没法复制出来,光地址就占面板高度的四分之一。
· 展开面板的收件箱后,每条现在显示大小和到达时间,采用邮件客户端那种「发件人加时间在上、摘要在下」的版式。它原来只列设备名和一个计数,这就是展开不值得点一下的原因——PanelInboxEntry 本来就带着 totalSize、receivedAt 和 contentKind,三个都没画出来。
· 会话行说用户的语言。方向、文件数、结果词、进度行和暂停/继续/取消按钮全是硬编码英文。nodes.tsx 曾辩称这些行「渲染设备名和字节数,所以这里没什么可翻译的」——写的时候属实,现在不属实了——还自己点出了修法:用本插件自己的 locale 命名空间,而不是借 conversation 的。注册现在传的就是这个。
· 正在到达的传输现在会在到达过程中在会话里长出一行。以前只有本插件发起的传输才会归属到会话,所以设备往这台机器推文件时,整个传输期间什么都不会出现——记录全程沉默,看起来就像什么都没发生。到达事件广播给每个根会话,理由和 swarmdrop/inbox-received 已有的一样:发送属于发起它的会话,到达不属于任何特定会话。这一行带着和发送行一样的进度条、速率、剩余时间和暂停/继续/取消控件,开头用 ← 而不是 →。
· 收件箱行只说只有它能说的话——该项现在可以用 @ 寻址。它重复了上面传输行刚显示过的设备、计数和大小,还换成了结构化布局,取代原来的一行文本。
· 设置里的传输行说明接收策略做了什么决定(policyAction),标题属性后面是命令行自己的措辞。在这台主机上这值得露出来:新配对的设备默认是 Collaborator,会请求确认,而常驻节点替用户应答,因为没有终端能挂住提示。一行写着「已接收」的记录,桌面版可能会停下来先问一句。
· 页头把可达性说成结果,而不是形容词:「其他网络上的设备能连到你」,而不是「良好」或「受限」。六级阶梯抄自 SwarmDrop 的共享视图包,本仓库无法导入它(private: true 且未发布),所以 node-health.ts 是它的第三份实现,测试钉住的是层级顺序和三段宽限规则,而不是措辞。
· 页头显示已配对和在线数量,即结论层的第三个槽位。
· 网络披露列出每条 bootstrap/relay 链接及其状态词、归属(scope · sources · roles),中继失败时还在复制按钮后面给出内核原样的 lastError。契约禁止翻译它:那是用户要贴进 issue 的内容。
· 概览上的网络信息收进一个默认折叠的披露块,折叠行仍说明中继就绪状态。SwarmDrop 的 Node Status Contract 定下这个拆分:一层始终可见的结论,一个折叠的诊断披露。展开后,这台机器列出 17 个监听地址。
· 已配对设备在两个界面里都用圆点旁的一个词说明在线状态。Device Card Contract 的第三个槽位明确说「一个光秃秃的彩色圆点不满足要求」;状态原来只靠颜色编码,屏幕阅读器根本读不出来。
· 面板分组标题改成 12px 次级色,不再是 11px 三级色大写。text-transform 对它们读的中文毫无作用,所以它换来的只是面板上对比度最低的文字,而这些元素本该便于扫读。
· 修复
· 字典原来注册在面板的 ['connection', 'locale'] fiber 里,把本插件的文案绑到一个与文案无关的服务上:有 locale 但没有 connection 的部署会得到会话行,却没有对应的词。现在只注册在 locale 下。
· 只打开设置的人,网络区永远是空的。network 由 PanelPort.setOpen 启
v0.6.02026-08-22
· 变更
· 破坏性变更:swarmdrop 最低版本从 0.5.0 升到 0.9.0——邀请二维码是 0.9.0 才有的,配对对话框里的二维码就来自它。这个下限并不统一,关于页面也写明了:低于 0.5.0 插件不起作用,而 0.8.x 装上去还能用、也还能配对——对话框会说明它画不出二维码,只留下链接。
· 配对从侧边栏浮层挪进了两个对话框。发起邀请现在显示可扫描的二维码,不再是几百个字符的链接,旁边有复制和打开按钮;链接文本本身没了。
· 收到配对请求现在会弹出对话框,不管面板开没开。以前它渲染在浮层里,关掉面板就没人能应答,对面只能超时。
· 关掉邀请对话框不再结束配对,只有「取消配对」才会。配对区保留一行提示,说明有个桌面已开启,并留了回去的入口——你每次去别处粘贴链接都会关掉那个对话框。
· 新增
· 设置控制台也能从「邀请」里配对设备。它驱动的是和面板同一个桌面:一台机器一个桌面,开不出第二个。
· 内置的 swarmdrop 可选依赖升到 ^0.9.0,与上面的下限一致——什么都没装的人最终跑的那份副本,也得能画出二维码才行。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-swarmdrop
为你的 DeepSeek Harness agent 提供一条通往你自己设备的通道。它可以把刚生成的内容直接推送到你的手机,你也可以用 @ 引用手机发回的内容——无需账号、无需公网 IP、端到端加密。
传输层是 SwarmDrop,通过其 CLI 驱动。
状态:开发者预览版。 dsh 本身声明会有破坏性变更,而本插件依附于其扩展接缝。请固定版本。
也要固定 dsh 版本线。 对等依赖范围针对 0.1.0-rc.x;@deepseek-ai/ 包在 npm 上的 latest 标签仍指向较旧的 0.0.1-rc.x 版本线,因此不固定版本的安装会解析到本插件并不针对的包。
你能得到什么
| 在 dsh 中 | 会发生什么 |
| “把报告发到我的手机” | agent 调用 swarmdrop_send_files;对话中出现一行传输记录,并跟踪其直至完成。 |
| /swarmdrop send ./report.pdf phone | 同上,无需模型往返。 |
| 在输入框中输入 @ | 你的收件箱——你的设备发送到本机的所有内容——作为引用候选。 |
| 你的手机发送一个文件 | 对话中出现一行记录,该项变为可引用。
展开完整文档(README 剩余 1 节)
dsh-swarmdrop
为你的 DeepSeek Harness agent 提供一条通往你自己设备的通道。它可以把刚生成的内容直接推送到你的手机,你也可以用 @ 引用手机发回的内容——无需账号、无需公网 IP、端到端加密。
传输层是 SwarmDrop,通过其 CLI 驱动。
状态:开发者预览版。 dsh 本身声明会有破坏性变更,而本插件依附于其扩展接缝。请固定版本。
也要固定 dsh 版本线。 对等依赖范围针对 0.1.0-rc.x;@deepseek-ai/ 包在 npm 上的 latest 标签仍指向较旧的 0.0.1-rc.x 版本线,因此不固定版本的安装会解析到本插件并不针对的包。
你能得到什么
| 在 dsh 中 | 会发生什么 |
| “把报告发到我的手机” | agent 调用 swarmdrop_send_files;对话中出现一行传输记录,并跟踪其直至完成。 |
| /swarmdrop send ./report.pdf phone | 同上,无需模型往返。 |
| 在输入框中输入 @ | 你的收件箱——你的设备发送到本机的所有内容——作为引用候选。 |
| 你的手机发送一个文件 | 对话中出现一行记录,该项变为可引用。 |
| 侧边栏底部的 SwarmDrop 按钮 | 节点状态和网络态势、启动/停止、已配对设备,以及配对新设备——无需离开 dsh 去终端操作。 |
| 设置 → SwarmDrop | 所有需要空间的内容:邀请及其撤销、完整收件箱、传输历史及其控制项、本机名称和接收目录、引导节点。 |
面板
设置旁边的圆点表示节点是否正在运行:绿色表示运行中,琥珀色表示已停止,灰色表示第一个响应仍在途中。打开它会给你
- 节点——运行中或已停止、其节点 ID,以及一个用于切换的按钮。
- 网络——NAT 类型、中继预留、引导、已连接对等节点、监听地址。仅在节点运行时显示,因为否则每个字段都会显示“unknown”,不会提供节点行之外的信息。
- 设备——已配对的内容以及是否在线。unknown 是它自己的状态,不是离线的同义词。
- 配对——“添加设备”会签发一个邀请并值守岗位,然后打开一个对话框,将其显示为二维码供你的手机扫描,链接则放在复制按钮后面,以备无法扫描时使用。当设备出现时,第二个对话框会在你决定之前给出其名称、系统、链接类型和完整节点 ID——无论面板是否显示,它都会打开,因为无人应答的请求只会让设备超时。
配对仍然需要有人查看对端的身份——这一点并未放宽,只是转移了位置。邀请是一次性能力,以链接形式传递,谁先出示谁就消耗它,因此除非有人在岗位值守,SwarmDrop 的节点会拒绝所有入站请求。
只要你没有按下“取消配对”,服务台就会一直有人值守,而不是直到你关闭对话框为止——复制链接正是为了把它粘贴到别处,所以对话框总是在配对进行到一半时被关闭,而关闭它绝不能终止对端已经进行到一半的事情。Pairing 区域会保留一行“配对进行中”,并提供一个返回入口,同时侧边栏圆点会变成琥珀灰色,这样即使不打开任何东西,也能看到有服务台仍在值守。
二维码由 swarmdrop 本身渲染,而不是由浏览器渲染。SwarmDrop 通过一个模块对其所有界面进行编码,而该模块还决定二维码上能容纳多少个可拨号地址,并丢弃其余地址——这项工作需要展开邀请的结构。浏览器中的第二个编码器会悄悄生成摄像头无法读取的二维码。
设置页面
面板是一盏状态灯;页面才是偶尔进行工作的地方。七个部分,每个部分在你打开时读取一次,并在你要求时重新读取——绝不按定时器读取,因为它们每一个都要消耗一个 swarmdrop 进程。
- Overview — 面板的事实,未经删减:每个监听地址、完整的节点 ID、每台已配对设备及其身份。
- Invites — 这台机器已发出的邀请,以及一个将其收回的按钮。邀请有效期为 24 小时,重启后仍然有效,并且持有它的人可以配对,所以这是阻止已泄露邀请的唯一方法。
- Inbox — 所有已到达的内容、它们落在哪里,以及将副本导出到别处。
- Transfers — 历史记录,仅在 CLI 会接受的地方提供暂停 / 继续 / 取消。
- Settings — 这台机器的设备名称和接收目录。每个值都会说明它来自哪里,当环境变量优先时,它会说明什么被压制了——否则你会编辑一个不起作用的字段。
- Bootstrap — 这台机器使用的中继和引导节点、它们的连接状态,以及当某个节点无法启动时内核自己的说法。你的添加和删除会叠加在内置列表之上,而不是替换它,因此更改内置地址的版本仍能到达你这里。
- About — 插件和 swarmdrop 版本,以及检查是否有更新版本。
最后两项需要 swarmdrop 0.6.0 或更新版本;使用较旧版本时,它们会说明这一点,而不是向你显示参数解析错误。
面板无法打开此页面。 dsh 仅将 openSection 交给 settings.onboarding 条目,因此插件无法自行打开其所在部分的 Settings。面板会展开它已经就位的部分,并把打开 Settings 留给你——这就是为什么页面作为唯一归属的任何内容都必须只能从 Settings 中找到。
安装
dsh plugin --profile add dsh-swarmdrop
这就是全部——该包声明了一个 dsh.bundle,因此 dsh 会将其追加到配置文件的 bundle 列表中,其配置层会在下次启动时激活。启动前使用 dsh --profile --dump-config 验证,它应显示一个 == dsh-swarmdrop 层。
dsh plugin 会在 profile 目录内转发给 pnpm,因此它接受任何 pnpm 目标——无需 npm publish:
dsh plugin --profile add /path/to/dsh-swarmdrop # 本地检出
dsh plugin --profile add ./dsh-swarmdrop-0.1.0.tgz # 来自 npm pack
用 dsh plugin --profile remove dsh-swarmdrop 移除它,这会同时移除依赖和该层。
SwarmDrop 二进制文件
你自己的安装优先。 如果 swarmdrop 在 PATH 上——Homebrew、安装脚本、npm i -g——那就是插件运行的版本。同时也会附带一份作为可选依赖,仅在你没有自己的版本时使用,因此 dsh plugin add 仍能给你一个可用的插件,无需安装其他东西。SWARMDROP_BIN 会覆盖以上两者。
顺序比看起来更重要。SwarmDrop 的数据目录是按用户划分的,最多只有一个进程为它持有节点;其他所有进程都会通过本地通道成为该节点的客户端,且没有版本协商。因此,无论哪个二进制文件启动了节点,就决定了什么能正常工作,而运行一个与你终端不同的二进制文件,正是你最终得到一个自己的 swarmdrop 无法与之通信的守护进程的原因。遵从 PATH 能让两者使用同一个二进制文件。
About 部分会说明正在使用哪个二进制文件、它来自哪里,以及运行中节点的版本——当两者不一致时会给出警告。即使没有两个安装,这种情况也会发生:swarmdrop update 会替换可执行文件,并让守护进程继续运行旧代码,直到它被重启。
你会在安装过程中看到 pnpm 提示 Ignored build scripts: swarmdrop。这没关系:npm 包通过 postinstall 钩子获取其平台二进制文件,pnpm 默认会阻止这些钩子,而 shim 会改为在首次使用时回退到获取。唯一可见的影响是安装后第一次调用 SwarmDrop 会比其余调用多花几秒钟——而且只有在使用捆绑副本的情况下才会如此。
需要 swarmdrop 0.9.0 或更新版本。 0.4.0 添加了 swarmdrop watch,本插件会订阅它;0.5.0 添加了 invite create --decide-from-stdin,正是它让面板能够运行配对台;0.9.0 添加了 invite qr,配对对话框中的代码就来自它。下限并不统一:低于 0.5.0 时插件不起作用,而在 0.5.0 到 0.9.0 之间,一切都能工作,配对也能工作——只是对话框会说它无法绘制代码,并留给你链接。
从面板配对设备——否则插件没有可通信的对象。如果你更喜欢,终端方式仍然可用:
swarmdrop invite create # 打印链接;打开它以获取可扫描的代码
这里的一切都不要求 SwarmDrop 节点正在运行:在你尚未启动节点的机器上,插件也能正常加载,工具会说明这一点,而不是神秘地失败,并且面板会提供启动一个节点的选项。
工具
| 工具 | 作用 |
| swarmdrop_send_files | 将文件或目录发送到你的某一台设备。 |
| swarmdrop_send_text | 向某台设备的收件箱发送一条短消息。 |
| swarmdrop_list_devices | 你已配对的设备,以及它们是否在线。 |
| swarmdrop_node_status | 本地节点是否正在运行,以及如何访问它。 |
| swarmdrop_list_inbox | 你的设备向这台机器发送了什么,以及它们落在了哪里。 |
| swarmdrop_search_inbox | 按关键词查找条目——标题、发送者、消息正文、文件名。 |
| swarmdrop_inbox_item | 完整查看一个条目:每个文件的真实路径,或消息正文。 |
| swarmdrop_inbox_files | 只查看某个条目的文件,当你只需要这些时。 |
| swarmdrop_list_transfers | 传输会话,进行中的和最近的。 |
| swarmdrop_transfer_status | 单个传输:阶段、进度、速率。 |
| swarmdrop_pause_transfer | 暂停正在传输字节的传输。 |
| swarmdrop_resume_transfer | 从检查点恢复。 |
| swarmdrop_cancel_transfer | 永久停止一个传输,并告知另一端。 |
这里没有任何东西可以配对设备。 接受入站请求是你在面板上做出的决定——一个能够配对的工具,就是一个能够把进入这台机器的通道交给陌生人的工具。
有两个值不是布尔值而是三值,而且这两个区别都很重要:
- presence 是 online / offline / unknown。unknown 意味着没有正在运行的 SwarmDrop 节点可供探测——这就是“你的手机在休眠”和“启动 SwarmDrop”之间的区别。
- 传输的 speed 是一个数字或 null,绝不是 0。核心对于“滑动窗口内没有新字节”会报告为零,而这正是保存已完成文件时的样子;把它当作测量到的零传递出去,会让 agent 告诉你一个健康的传输已经停滞。
swarmdrop_search_inbox 需要 swarmdrop 0.7.0;较旧的版本会用一句话说明这一点,而不是像你输错了什么一样失败。
每次调用都会在其卡片上说明它正在做什么——Send 3 files to 光印-华为410,而不是在参数转储之上显示 swarmdrop_send_files。实时进度和暂停 / 取消控件不在卡片上:dsh 的工具卡片是一组封闭的静态形状词汇,它们的呈现器是纯函数,会在数月后被重放,因此卡片无法诚实地表示“此刻”。这些内容存在于对话行和面板中,而这两者都可以做到。
它是如何组合起来的
src/
cli.ts swarmdrop 二进制文件:一次性调用、订阅、配对 machine.ts 这台机器看起来是什么样,由订阅折叠而来 pairing.ts 配对工作台:一个窗口,以及谁站在它前面 revision.ts 面板所依赖的共享“有东西变了”计数器 bridge.ts 机器范围内的事件 → 按会话划分的事件 panel.ts 面板的 RPC 通道(状态、设备、配对) panel-wire.ts 面板的通信契约,由两半共同编译 console.ts 设置页面的两条路由:读取一个区段,运行一个操作 console-wire.ts 页面的通信契约,由两半共同编译 projection.ts 收件箱列表,作为 Session 投影(@ 读取的内容) tools/ 模型可以调用的内容 index.ts 注册表:每个工具,只注册一次 shape.ts CLI 输出 → 本插件的契约 explain.ts CLI 失败 → 模型的下一步动作 send.ts 写入对话的那两个 inbox.ts 收到了什么,以及在哪里 transfer.ts 观察一个,并操控一个 device.ts 谁可达,以及这个节点是否在线 present.ts 一次调用运行期间及之后,其卡片显示什么 command.ts 你可以输入的内容 types.ts 本插件拥有的 Session 事件族 client/ 浏览器那一半:面板、对话行、@ 数据源
在改动任何东西之前,有四个值得了解的决定:
两类数据,两种载体。 对话行和 @ 候选项通过会话日志传递:它们必须在刷新、翻到历史页、或几个月后重放时都能以相同方式重建,因此 @ 菜单读取的是会话投影——Node 那一半注册一个纯折叠,框架按日志顺序在已提交事件上驱动它,浏览器收到的是一个最终值。
面板的数据不走那里。节点存活状态、设备和网络态势是关于当下的事实;一个声称“节点在线”的会话事件会成为一个关于某一时刻的断言,被永久持久化,并在读回时仿佛仍然为真。因此面板有自己的通道——Host 上的 ctx.connection.rpc.handle('/swarmdrop', …),浏览器中的 rpc.call。两者在所有 dsh 载体下都能工作,包括从你的手机访问家里的 dsh。
本文件较早的一个版本说 dsh 不给第三方插件提供 Client→Node RPC。那是错的。真正成立且关键的是上面的拆分:转录从日志重建,任何东西都不得绕过这一点。
面板进行长轮询,因为无法向它推送。 dsh 从一份固定的允许列表将 Host 事件转发到浏览器,第三方插件无法扩展该列表。因此面板在 Host 上停放一个请求,直到有东西发生变化——这并非推送的降级:当变化发生时,请求已经在等待,所以答案会立即发出,而不是等到计时器的下一个 tick。
事件记录发生了什么,而不是现在是什么。 swarmdrop/sent、swarmdrop/inbox-received 和 swarmdrop/transfer 是在某一时间点发生的事,因此几个月后重放一段对话仍然能解释它。唯一一个整值事件 swarmdrop/inbox-baseline 回答的是“这件事开始时你手头有什么”——这正是读者需要的上下文。
面板进行长轮询;页面完全不轮询。 面板可以承受一个停放的请求,因为 Host 会保持它打开。设置页面上的任何东西都做不到:每个 section 都是一个 swarmdrop 进程,所以 section 在你打开它时才会被读取而当你询问时,实时的那一半(节点存活状态、设备、配对)根本不会被重新读取——它已经通过面板的订阅到达,页面读取的是同一个存储。
每个负载都携带一个 version。 这些会进入你的会话日志,而会话日志的生命周期长于进程,并且会被重放。一种仍然能解析但含义不同的格式变更,是可能发生的最糟糕的失败。
一个你应该知道的限制
dsh 拒绝读取包含它不认识的事件类型的会话日志,除非该事件被标记为 ignorable。这两种规避方式对第三方插件都不可用:已知类型集合是根据 dsh 仓库内部声明的类型生成的,而 Session.append() 没有提供任何设置该标记的方法。dsh 知道这一点——它自己的源码说,面向仓库外事件的注册接口“被推迟到此类消费者出现时”。
这个插件就是那个消费者,所以它在加载时会向正在运行的 harness 宣告它的四种事件类型。这使得它们在这里可读。它不会在事件上设置 ignorable,所以:
请禁用这个插件,而不是卸载它,如果使用过它的对话对你仍然重要的话。一个没有该插件的 harness 会拒绝打开包含其事件的会话日志——你会看到“unknown to this harness”,并且整个对话,而不仅仅是 SwarmDrop 行,都会变得不可读。
该宣告还依赖于插件和 dsh 解析到同一个 @deepseek-ai/dsh-session 模块实例。这在普通安装中成立;当 dsh 在 tsx 下从源码检出运行时则不成立,此时两半会得到独立的模块图,宣告会落在一个没人读取的副本上。
开发 bash
npm install
npm run typecheck # both halves
npm run build # tsc for the Node half, tsdown for the browser one
这两半会作为独立的 TypeScript 程序编译,而这不是可选的。 dsh 在两侧对 Context.sessions 的增强方式不同(Node:SessionStore;浏览器:ISessions),所以把两者放进同一个程序会让浏览器那一半针对 Node 服务接口进行编译,并失败于指向完全偏离原因的错误。同样的规则也适用于源码内部:客户端文件绝不能导入包根——只能导入 /types 和 /client 子路径,它们不携带 Context 增强。
浏览器 bundle 不是普通的 ESM 构建。 dsh 的加载器期望 ./client 入口通过 window.__ModuleLoader__.load({ id, factory }) 注册自身,并通过注入的 require 解析外部依赖——没有 import map,也没有全局变量。dsh 用一个未发布的共享 tsdown 预设来构建它自己的版本,所以 tsdown.config.ts 以 banner/footer 对的形式重新实现了这个包装器。id 必须等于包名,因为那是宿主组合进 window.__DSH_BOOT__ 的入口名。
关于那个配置,有两点是承重性的,而非风格性的。tsdown 在 tsc 之前运行,而不是之后,正是这个顺序让它能够 clean: lib 同时容纳两半,且没有其他东西会清空它,所以在关闭清理的情况下,三个提交前删除的源文件所产生的输出仍会留在那里,而 files 会把它打包进去。如果第二个运行 tsdown,同样的 clean 反而会删除 Node 那一半。而 banner 以对象形式
({ js: … })给出,是因为普通字符串会被前置到每一个* chunk:声明文件也会被加上
包装,从而不再能作为 TypeScript 解析。
两半的声明来自不同的工具,这就是它们落在不同位置的原因:lib/types/* 逐文件镜像 Node 源码,而浏览器那一半是单个打包后的 lib/client.d.ts。两者都是 exports 指向的目标;两者都不是手写的。
有三件事,否则读者会以艰难的方式重新发现:
- 对话节点 cookbook 的代码片段按原样无法编译。
ChatNodeViewProps 捆绑了 t: TranslateNS,但只有当注册传入 locale 时,插槽才会注入 t,而第一方代码传入的命名空间值并未导出。参见 src/client/nodes.tsx。
- exec.agent 是可选的。 嵌套的 Code-Mode 派发没有 agent,因此发送仍会发生,但没有可归属的对话。
- npm 的 latest 标签滞后于真实版本线。 npm view @deepseek-ai/…
报告的是 0.0.1-rc.1,其客户端包依赖 @deepseek-ai/dsh-compact —— 一个未发布的包,使该版本线无法解析。实际在用的版本线是 0.1.0-rc.x,它可以干净地解析。请检查 npm view versions,而不是裸的 version。
发布
changelog 是发布的输入,而不是发布之后写的记录。先写章节,再打标签: bash
1. 在 CHANGELOG.md 中,在新的 ## [x.y.z] - YYYY-MM-DD 标题下描述变更,并在文件末尾添加其 compare 链接。提交它。
2. 让 npm 设置版本,提交并打标签。
npm version minor
git push --follow-tags
用 npm version 设置版本,绝不要通过编辑 package.json。 它也会写入 package-lock.json,而手工编辑的 manifest 会把 lockfile 落在后面 —— 这会一直不可见,直到之后的某次 npm ci 拒绝安装,并把发布任务一起拖垮。发布任务正是因此会检查两者是否一致。
推送标签会运行 release.yml,它会类型检查两半、运行测试、拒绝与 package.json 不一致的标签或与任一方不一致的 lockfile、从 CHANGELOG.md 中读取说明 —— 如果该版本没有章节则失败* —— 以 provenance 发布到 npm,并用同样的说明创建 GitHub Release。
npm 会在 Release 创建之前发布,因为 npm 是无法撤回的那一半。因此,唯一值得知道如何
修复的失败,是在发布之后才死掉的运行:不要重新运行该任务,那会尝试发布一个已经存在的版本。改为手动创建 Release: bash
node scripts/changelog-section.mjs x.y.z > /tmp/notes.md
gh release create vx.y.z --title vx.y.z --notes-file /tmp/notes.md --verify-tag
普通推送和拉取请求会运行 ci.yml——相同的类型检查和测试,外加一次真实的 npm run build,因此浏览器打包的包装器会在
npm publish 之外的地方得到实际检验。
许可证
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
swarm-apps/dsh-swarmdrop
把生成的文件推到手机,也能引用手机发回的内容
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,362已汉化DSH
71.4
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,076已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,814已汉化DSH
71.1
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。