dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 插件:把「汇报」做成代理之间的一等交互原语 —— 可追溯的传递路径账本、回执/结案/修正,以及一个会话时间线标签页。
一个 DSH 插件:把「汇报」做成代理之间的一等交互原语,并为长期协作留下可追溯的账本。
DSH 原本的代理间通信是相邻 Agent 的 steer 投递:只能投给直接子代理或直接父代理,没有持久 mailbox(父代理不在线时消息被拒绝),也没有抄送、回执、线程与传递路径记录。本插件补上的是这一块地基,而且不改会话格式:账本是 $DSH_HOME/report-ledger/ 下的纯文本文件,模型只读 front matter 缩略,正文按需打开。
dsh plugin --profile web add dsh-report-ledger这条命令把包装进该 profile 的 node_modules;因为包声明了 dsh.bundle.patch,dsh plugin 会自动把它追加进 profile 的 dsh.profile.bundles,不需要手改任何配置文件。装完重启 profile(dsh web)生效。不启动也能验证:
dsh --profile web --dump-config # 配置树里应出现 report-ledger 这一行卸载走同一条通道,依赖与该配置层一起移除:
dsh plugin --profile web remove dsh-report-ledger要求与边界
$DSH_HOME/report-ledger/(可用 DSH_REPORT_LEDGER_ROOT 覆盖),不上传任何地方。peer_start 是唯一会新增活代理的能力,受 maxPeersPerAgent(默认 8)约束,每次创建都记进名册日志。report_lease 与各工具的 worktree 参数。源码与发行版同步在 gitee.com/stone_zhan/dsh-report-ledger,不经过 GitHub 也能装:
# 预构建产物,不需要构建工具链
dsh plugin --profile web add https://gitee.com/stone_zhan/dsh-report-ledger/releases/download/v0.2.4/dsh-report-ledger-0.2.4.tgz
# 或直接从 Gitee 安装(预构建产物,安装时不构建)
dsh plugin --profile web add git+https://gitee.com/stone_zhan/dsh-report-ledger.gitGitHub 每次推送后由 .github/workflows/mirror-to-gitee.yml 自动镜像所有分支与 tags。
注意:npm 安装走的是 npm 镜像站而不是 GitHub,所以 npm publish 之后上面那条一行命令才是国内用户最省事的路;Gitee 镜像解决的是「拿不到 GitHub」时的源码与产物可达性。
dsh plugin --profile web add dsh-report-ledger # install + register the bundle layer
dsh --profile web --dump-config # verify: a `report-ledger` row appears
dsh web # restart the profile to load itReports are first-class agent-to-agent messages with a persisted ledger: front matter is the digest that enters the model's context, the body stays on disk and is opened on demand, and every hop is appended to an auditable transfer path. The ledger lives in $DSH_HOME/report-ledger/ and nothing leaves the machine. The host half works in any profile; the web profile additionally gets a Reports tab and a topological canvas in the right sidebar. Aligned with DSH 0.2.0-rc.2.
开一份汇报(把活交给下级,或向上回报):
report_author(subject="重构读路径缓存", body="...", to=["<session-id>"], task="read-path")收件方立刻被唤醒(steer)。对方不在线不是错误:投递留在账本里,等它重新驻留时自动送达。
回执 → 共写 → 结案:
report_ack(report="R-0007", note="收到,开始做") # 我收到了(事情仍在推进)
report_contribute(report="R-0007", body="结论:...") # 以共写者身份追加一节,互不覆盖
report_send(report="R-0007", to=["<other-session>"]) # 主送更多代理(唤醒)
report_cc(report="R-0007", cc=["<watcher-session>"]) # 抄送,进入上下文但不唤醒
report_close(report="R-0007", note="已合并") # 这件事结束了改错了用修正,不要重开一份:report_amend 改主题/任务标签/正文,改动会被逐字记进传递路径(重开会丢掉原有的收件人与路径)。收件人永远不能在这里改——它们由跳流派生,唯一途径是再追加一跳。
需要纵览时用 report_list({ task: "read-path" }) 把一次协作跨会话拉到一起;需要知道"还有谁在线、跟我什么关系"用 peer_list。
汇报是两层结构。
report_read 按需打开(超长时只返回头部与文件定位,模型用 read 分页取余下部分)。传递路径是权威的。 每次操作都追加一跳(append-only JSONL):
to / cc / authors / hops / last 都是从跳流派生的缓存,任何下一条跳都会重新校正它——账本不可能显示历史里没有的收件人;report_list / peer_list 找到最后落下的跳、谁已交付、谁还在线,不要从头重做;重试前先确认动作是否已经落地。账本布局($DSH_HOME/report-ledger/):
reports/R-0001.md front matter 缩略 + 正文
reports/R-0001.route.jsonl append-only 传递路径,一行一跳选文件而不是私有数据库,是因为账本是一段协作的长期记忆:它必须可被人直接检查、手工修正,而 front matter 让"只读缩略"不必打开正文。设计动机、取舍与被否掉的替代方案见 设计。
工具 · 作用 report_author · 开一份汇报,可同时主送 to 与抄送 cc,可用 parent 关联上溯汇报 report_contribute · 以共同作者身份追加自己的一节(互不覆盖,各自记为独立跳) report_send · 主送给更多代理(唤醒):向上回报、向下派发 report_cc · 抄送给更多代理(不唤醒):让需要知情者持有副本 report_forward · 转呈下去,或 mode:"copy" 作为参考副本分发 report_read · 读缩略 + 完整传递路径 + 正文(读取本身也记一跳;读取不推进 `updated`、不改变列表顺序) report_list · 只列缩略,可按 session、status、task、worktree 过滤,用于纵览长期协作 report_ack · 回执,让发送方看到闭环 report_amend · 修正:改缩略字段或更正正文,仅发起者/共写者可改,改动会被记录 report_close · 结案:事情的终结,仅发起者/共写者可关;同时交还它持有的工作区 report_lease · 认领一个已存在的检出(仅工作区功能开启时暴露) report_release · 交还检出占用,检出留在磁盘上原封不动(工作区关闭时调用会说明"本部署未启用工作区") report_transfer · 把一笔尚未送达的投递从欠它的会话转给另一个会话——义务仍然存在,只是换了人欠;不记为送达 report_handover · 退役/接管:枚举一个会话名下的一切,能搬的搬、能关的关,并落一份 task: handover 记录
另有 peer_list / peer_start 两个同伴工具(见 同伴),以及只在 devMode 下出现的 dev_* 三个(见 开发者模式)。工具背后完整的语义——投递怎么落、修正与结案为什么这样设计、退役怎么转移资产——在 设计 里。
三个状态:open → acked → closed。
动作 · 谁能做 · 效果 report_ack · 任何收件人(to/cc/共写者/发起者);非收件人会被拒绝并列出可回执的人 · open → acked。回执 = "我收到了",事情仍在推进 report_close · 仅发起者或共写者;被拒绝时会点名该找谁关 · → closed。结案 = "这件事结束了" 贡献 / 主送 / 抄送 / 转呈 / 修正 · 任何有权限者 · 自动重开:先记 reopened 跳,再落下活动本身那一跳
修正必须被记录,而不是抹掉:缩略字段(subject / task / artifacts)是当前状态,直接替换并把改前改后逐字写进跳里;正文是人说过的话,默认追加一段 ### amendment,replace_body: true 才真替换(跳里注明被重写过)。所以一个写错的标题被改正后,落盘是"缩略给当前真相、路径留历史"。
`closed` 是状态,不是锁:结案后又有人贡献/主送/抄送/转呈,说明这件事又活了,于是自动重开并记录——否则一份被过早关闭的汇报会静默吞掉后续工作。同理,不需要单独的"重开"工具:活动本身就是重开。
一个会话退场时,它名下的未结汇报、待送达的投递与占用的检出可以整体交给继任者(report_handover),退役因此是账本里的一个事实,而不是一段缺席。
- insert:
- id: report-ledger
name: 'dsh-report-ledger'
config:
announceToAgent: true # 默认 true;false 则不向任何 agent 注入提示词段
maxPeersPerAgent: 8 # 一个会话终身的同伴名额
devMode: false # 必须是字面量 true;只在克隆的仓库里可用
worktree:
enabled: false # 总开关;关闭时相关工具与参数都不出现键 · 默认 · 说明 announceToAgent · true · 是否注入两段 systemPrompt(账本协议 + 伙伴契约,见 设计) maxPeersPerAgent · 8 · peer_start 的终身额度;超限是明确的工具错误,不是静默拒绝 devMode · false · 严格:只有字面量 true 才算打开,其余值全部关闭 worktree.enabled · false · 开启后一份汇报可拥有自己的 git 检出,见 工作区 worktree.root · 仓库同级 .dsh-worktrees// · 检出根目录 worktree.onClose · keep · 结案处置:keep \ · remove-if-clean worktree.maxActive / maxRetained · 4 / 4 · 同时占用上限 / 结案后留在磁盘上的上限 worktree.reclaim · never · never \ · oldest-closed:超预算时清一个最老的、干净的、账本自建的 worktree.relativePaths · false · 启用 extensions.relativeWorktrees,会把仓库格式版本抬到 1(旧版 git 直接拒绝访问)
开启工作区之后,每份汇报可以有自己的 git 检出,但独立的只有工作目录与索引:config、hooks、对象库以及检出之外的一切仍然共享——装一个 hook,会影响所有检出的每一次提交。占用与回收的完整规则见 工作区。
web profile 里多两处:
report_contribute 用追加,规避了常见路径)。maxPeersPerAgent(默认 8)数的是名册日志里的行,不区分同伴是否还在、是否首轮就死;没有退役工具。回收是人工动作:备份后从 $DSH_HOME/report-ledger/peers.jsonl 删掉已结束同伴的行。conversation.view 的契约没有 composer 可见性维度,外壳在视图下方无条件渲染输入区,所以汇报页底部始终有输入框。视图侧唯一能整块替换它的是 conversation.composer 链(审批/提问面板用的同一机制),拿它隐藏属于偏用:该页会同时失去输入、发送、停止、模型/权限控件与队列/待办 dock。等上游给 view 定义提供正式开关后再做。工作区相关的限制(默认关闭,未开启时都不适用)见 工作区。
正文按读者分开。只想用起来,上面这些就够了;下面这些是「要改它」或「想知道为什么」时才需要的。
文档 · 什么时候读 设计 · 账本布局、读路径的性能模型、修正与生命周期的理由、退役交接、提示词协议 工作区 · 要用 git 检出隔离,或想知道"独立"到底独立了什么 界面 · 时间线标签页的交互规则、数据通路、HTTP 守卫与信任假设 画布 · 卡片图的几何、为什么一个图库都不引、每项决定的实测数字 同伴 · peer_start 开出来的到底是什么、它落在哪个工作区分组 工程约定 · 改这个仓库之前:20 条踩过的坑,每一条都对应一次真实故障 开发、构建与验证 · 构建、测试分层、HMR 开发回路、隔离 profile 开发者模式 · 开发期陪跑代理:名单、增减、退役、归档 发布 · 维护者:产物清单、可信发布、CI 分工、Gitee 镜像
pnpm build # 产出 lib/index.js(宿主半)与 lib/client.js(浏览器半)
pnpm test # 十六套确定性检查,1133 项断言(不需要 DSH,不碰真实账本)
pnpm check # 完整本地门禁:typecheck + test + test:tools开发与测试需要 Node ≥ 22.6(脚本直接跑 .ts,依赖 type stripping)。lib/ 随源码提交,所以 clone 下来不用构建也能跑。开发回路、测试为什么分成 test 与 test:tools、CI 为什么只跑前者,都在 开发、构建与验证。
MIT。第三方声明见 THIRD-PARTY-NOTICES.md。