DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Puzzle Mode — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
P

dsh-puzzle-mode

Puzzle Mode

DSH 插件:拼图模式——把项目拆成主文档 + 若干模块文档,AI 主动提问把不确定项变成已定项,用五维算项目健康性。一个会话可同时绑多个项目;主文档第五节 ## 工作流 是标准化流水线,命中触发词自动注入——**首次给完整步骤,之后只给一行指路**,不刷屏。**自动更新**:可翻各版本更新日志(每版**最多三句摘要**,来自 Release 正文的 `## 摘要` 区块),一键更新装失败会**自动回退**。**主题开发与分享**:一键建脚手架、一键推送到主题仓库,也能导出单文件主题包;默认皮肤为**液态玻璃**。**文件观察守卫**:写被拒时提示「先 read 再重试」、文件久未读时提前提醒

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:liancha22/dsh-puzzle-mode#371af19fdeb357d306ec0aa2db84a1fb73d2b2fc
README兼容性版本

说明

DSH 插件:拼图模式——把项目拆成主文档 + 若干模块文档,AI 主动提问把不确定项变成已定项,用五维算项目健康性。一个会话可同时绑多个项目;主文档第五节 ## 工作流 是标准化流水线,命中触发词自动注入——**首次给完整步骤,之后只给一行指路**,不刷屏。**自动更新**:可翻各版本更新日志(每版**最多三句摘要**,来自 Release 正文的 `## 摘要` 区块),一键更新装失败会**自动回退**。**主题开发与分享**:一键建脚手架、一键推送到主题仓库,也能导出单文件主题包;默认皮肤为**液态玻璃**。**文件观察守卫**:写被拒时提示「先 read 再重试」、文件久未读时提前提醒、未查证就改时做行为纠正。所有注入(含**说话纠正** / **催促** / **重复思考熔断**)共用一道闸门,防叠成噪音;催促每 12 步一行、明确禁止写进度播报。**自动审查只找代码漏洞**。文档格式 v7;与 dsh-infinite-gen-5 同装时按契约共存。

兼容性与来源证明

Puzzle Mode 以 dsh-puzzle-mode 发布,当前版本为 1.1.3。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/9

版本

1.1.3stable
2026/10/9
1.1.2stable
2026/10/9
1.1.1stable
2026/10/9
查看其余 23 个版本收起版本
1.0.3stable
2026/10/8
1.0.1stable
2026/10/8
1.0.0stable
2026/10/8
0.30.0stable
2026/10/7
0.29.0stable
2026/10/7
0.28.2stable
2026/10/7
0.27.1stable
2026/10/5
0.27.0stable
2026/10/4
0.26.0stable
2026/10/4
0.24.2stable
2026/10/3
0.24.0stable
2026/10/3
0.23.3stable
2026/10/3
0.23.2stable
2026/10/3
0.23.0stable
2026/10/3
0.21.0stable
2026/10/3

相关插件

正在加载相关插件…

最新版
1.1.3
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 3
周下载
0
最近提交
2026/10/9
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
0.19.9stable
2026/10/2
0.19.8stable
2026/10/2
0.19.7stable
2026/10/2
0.19.6stable
2026/10/2
0.19.5stable
2026/10/2
0.19.1stable
2026/10/2
0.18.0stable
2026/10/2
0.17.0stable
2026/10/1

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundle为 Web 组合添加 Schedule、其任务页面和时间上下文的可选捆绑包Ab Ocrdsh-ab-ocr--- description: "外部 ocr 工具:逐页识别扫描的 PDF 或图像,仅在处理完最后一页后按顺序合并页面,并使用模型确定的标题级别保存为一个 Markdown 文档。" kind: "package-reference" ---Client Ui Task Board@linxin666/dsh-client-ui-task-board面向 DSH Web GUI 的主机权威任务面板,支持实际会话执行、主机 cron 调度以及可选的跨平台空闲睡眠保护;以挂载方式提供,无需修改 DSH 源代码。

README

dsh-puzzle-mode · 拼图模式

DSH(DeepSeek Harness)插件。把项目拆成一份主文档 + 若干模块文档, 让 AI 主动提问、把不确定项变成已定项,并在输入框的模型选择器左边 放一个显示项目健康性的小按钮。

面板速览

它解决什么:长会话里,项目的关键决定散落在聊天记录里——AI 会忘,你也没处查。 拼图模式把这些决定落到你随时能打开看的文件里:主文档当查找入口, 模块文档存细节,每条都带源码出处,随时能回查。

主文档的第五节 ## 工作流 是标准化流水线:为完成某个特定任务,把重复的步骤、工具、 规则按顺序串成一条可复用的路。一条工作流 = 一个 ### 名字 块,块内逐行是有序步骤。 随提示段注入,每一步都读得到;面板上图块式列出,点名字看步骤、可整条删除 / 恢复 / 永久删除。

不是独立模式:装进宿主组合后,标准模式(或任何 preset)的会话都带上它。

  • 仓库:https://github.com/liancha22/dsh-puzzle-mode
  • 主题仓库:https://github.com/liancha22/dsh-puzzle-themes(主题不在插件包里,点一下从仓库下)
  • 最新版:v1.1.3 · 更新日志 · 所有版本
  • 适配:DSH 0.2.0-rc.2(peer 覆盖 0.1.5 / 0.1.6 / 0.1.7 全部预发布版,见下)
  • 面板 UI 逐块说明:UI.md —— 每颗按钮、每个区块点了会怎样

下载与安装

方式一 · 插件管理器(推荐)

python3 "$DSH_HOME/plugin-manager.py" github liancha22 dsh-puzzle-mode v1.1.3

App 的插件页「添加插件」用的就是它,也支持标签 / 分支 / 子目录:

python3 "$DSH_HOME/plugin-manager.py" github liancha22 dsh-puzzle-mode main/lib

方式二 · 直接下载附件

dsh-puzzle-mode-1.1.3.tgz (含全部源码)

方式三 · dsh CLI

dsh plugin --profile web add github:liancha22/dsh-puzzle-mode

⚠️ 装完必须重启该 profile(patchReload: startup),再刷新浏览器页面。

本插件没有任何 npm 依赖,不需要 npm install;除运行时提供的 @deepseek-ai/dsh-tools 外不消费任何外部包。


最新版本

v1.1.3 · 更新日志改成「简短三句」

面板的「各版本更新日志」不再取 Release 正文的前 3 行,改成只认正文里的 ## 摘要 区块,每版最多三句交代改了什么。

没写这个区块的版本会明说「这版没写摘要」,不再拿背景铺垫冒充摘要(v1.1.2 的正文头三行是用户原话,一句都没说改了什么)。

最近三版(v1.1.2 / v1.1.1 / v1.1.0)的 Release 正文已按新格式改短并补上摘要区块。

v1.1.2 · 治「复读机」:注入降频 + 催短 + 加那句

用户原话:「他现在还是一直跟个复读机一样说相似的话,很烦」,追问里点名 「两个都烦」 (插件注入的行 + 模型自己的播报)。

先量,再改。 一个 4 天的会话(8815 行日志)里,插件注入了 688 条,全部被 Web GUI 渲染成独立消息行:工作流触发 510(同一条流程被原样塞 159 次完整 11 步)、 催促 147、说话纠正 31。平均每 1.8 条助手消息就被插一条。

改哪改成什么为什么
工作流触发首次全文,之后一行指路重复的体积压到约 1/10;但不彻底闭嘴——压缩后模型看不到那 11 步
催促节拍 6 → 12 步,文案压成一行它是确定会重复的那条;条数减半 + 每条降到约 1/4
催促撤掉「一句话报进度」那句话被模型照做了,每到一个节拍就多一句播报——正是「复读机」的来源
催促加上**「你怎么这么慢,快点做啊」**用户指定原文,三档都带,一眼认得出
提示段工具调用之间不写「我刚发现了什么」逐字比对抓不到「同一种动作重复」,只能用行为规则治

解日志本身还有个坑:日志是多帧 zstd,zstdDecompressSync 只解第一帧—— 8964937 字节的文件解出来只有 195 字节,看起来像「日志是空的」。按魔数切帧(3996 帧)才对。

测试:npm test 15 组全绿 + 跨插件握手 18/0;变异验证 29 项全部按预期变红 (新增 5 项,其中一项第一版是假绿——断言写成 includes(NUDGE_PUSH), 常量改成空串后 includes('') 恒真,被变异验证抓出来,已改成比对字面量)。

v1.1.1 · 修「一键更新装不上」(本机 github.com 不通)

v1.1.0 发完当场真机自更新,失败了——但这次失败很有价值:回退机制干净地生效了 (三处全部还原、插件照旧可用),而日志把真原因写清楚了。

两次尝试、两次不同的死因:

规格报错
github:owner/repo#taggit+ssh:// → Host key verification failed
git+https://github.com/…#tagFailed to connect to github.com:443 after 21119 ms

根因:本机可达性实测(2026-10-09):

域名443
api.github.com通
codeload.github.com通
github.com不通

而 pnpm 装 git 依赖要两步:① 在 github.com 上 git ls-remote 解析 tag → SHA; ② 按 SHA 从 codeload 下 tarball。第一步就死了——所以任何要碰 github.com 的规格都装不上,换协议解决不了。

解法:把第一步挪进插件——插件走可达的 api.github.com 解析出 SHA, 再把 SHA 版的 codeload URL 交给 pnpm,那一步不必碰 github.com。

这不是权宜之计:pnpm 自己写进 pnpm-lock.yaml 的就是这个形式 (实测本机锁文件:version: https://codeload.github.com/…/tar.gz/<sha>), 所以装完 package.json / 锁文件的形状与原来一致,回退与后续升级都不受影响。 用 SHA 而不是 tag 还有个额外好处:tag 可以被移动(本仓发版时确实 git tag -f 过),SHA 不能——这才是「装的东西可复现」的前提。

顺带修掉三个由此暴露的缺陷

  1. 自检把成功判成失败:判据一是「依赖声明里含 tag」,而 SHA 版 URL 里没有 tag → 一次已经装成功的安装被拦下并回退(实测)。判据的本意是「指向这次要装的那一版」, 而 SHA 更精确地表达了这件事,所以改成「有 SHA 就认 SHA,没给才退回认 tag」。
  2. 失败信息没有信息量:第一版只写「pnpm add 退出码 1」,而真正的死因 (Host key verification failed)躺在 4000 字符的日志里。现在会把关键行 摘出来放进 error——失败信息的第一职责是让人知道下一步该干什么。
  3. main() 是 async 却没有 .catch:未处理的 rejection 会让 Node 打一行警告后以退出码 0 结束,于是面板看到的「进程结束」是成功, 而结果文件什么都没写 → 面板永远转圈。现在兜底写结果并退出码 1。

新增一个机械检查

tools/check-install-spec.mjs(11 项):面板显示的命令与安装器实际执行的 spec 分处两个文件(后者不能 import 前者),靠人记着同步必然漂移。 它剥掉注释再查代码——第一版直接查全文,把「解释为什么不用它」的注释也判成违规, 而那种检查会逼着人删掉解释,下一个人就会把旧写法加回来。

npm test 全绿:60 + 47 + 7 + 51 + 17 + 36 + 12 + 9 + 21 + 23 + 21 + 32 + 22 + 12 + 22; 跨插件握手 18 / 0。变异验证 25 项全部按预期变红。

更早的版本(v1.1.0 及以前)见 CHANGELOG.md。

功能

用户一次点了三件事:「模型在几度陈述时会复读类似的意思,而且陈述用英语」「读文件老是 分段读,不如直接一次读全部要的地方」「干活都磨磨唧唧的,加一个自动注入语音犀利的催促的功能」。

前两条是提示段规则(模型每轮都读得到),第三条是新注入。

① 说话方式(新增 ### 说话与干活 一节):

  • 一律用中文:正文、结论、工具参数说明、代码注释都写中文;英文只留给标识符、 路径、命令与报错原文,不许用英文整段陈述。
  • 同一件事只说一遍:结论写完就往下走;每轮开头不复述上一轮,直接给这一轮的 新结论或新动作。反复重述同一个意思(尤其连续几轮都在讲「我准备要做什么」)是纯成本。

② 读文件一次读全:read 把 limit 给足,不要一段一段读同一个文件; 要看好几个文件就同一步里并行发多个 read,别串着等。

③ 催促(新功能):只看不动时,宿主注入一条语气犀利的催促。判据是 连续只读调用(read / grep / glob)没有产出,以及同一个文件被读第二次 (正是用户说的「分段读」):

触发阈值文案
只读连击连续 6 次无产出「停止检索,先产出一步」;每 4 次升级一档
分段读同一文件读第 2 次「一次读全,limit 给足」,并点名是哪个文件

档位加码方式是撤出口(与熔断同一手法):第 1 档还允许「说清你在找什么」, 第 2 档禁掉只读工具,第 3 档只留「写结论 + 执行下一步」。到顶后仍按间隔继续催—— 沉默比重复更贵。

误报防线(宁可漏催,不可误催):只读白名单只有 read / grep / glob, 其余一切(write / edit / pwsh / bash…)都算产出并清空连击;阈值取 6, 连着读 5 个文件是正常调研;工具失败(block)时不插话——失败重试是正当行为。

测试:新增 test/100-nudge.test.mjs(21 项),纯函数层 + 真钩子接线层, 含 4 条「守卫自证」(持续产出不被催 / 读一次改一次不被催 / 工具失败不插话 / 分段读只催一次)。变异验证三处均红:只读白名单混入 write → 红; 催过就永久闭嘴(退回「只报一次」)→ 红;关掉分段读判定 → 红。

顺带修掉一个既有红:test/40-pre-execute.test.mjs 没有隔离 DSH_HOME, 于是它会去读用户真实的设置——用户在面板上关掉固定收尾问之后,那条 「拒绝理由里必须复述固定收尾问」立刻变红,而代码一行没错(本机实测踩到)。 已给 4 个漏掉隔离的测试文件补上 helpers/isolate-home.mjs(该文件早就写着这条纪律)。

npm test 全绿:60 + 47 + 7 + 51 + 17 + 36 + 12 + 5 + 21;跨插件握手 18 / 0。

功能

1. AI 主动提问,把不确定项变成已定项

插件会往会话里注入一段规则,规定 AI 怎么问:

  • 主动提问,一轮最多 10 问、每题最多 10 个选项,能用选项就用选项;
  • 每题给 3–6 个真岔路,每个配一句取舍(options[].description)。只说「① 改 ② 不改」 等于没问——你看不到代价就没法选;推荐项放第一并加「(推荐)」;
  • 找岔路从五个维度问:做法(走哪条路)/ 范围(改多大)/ 时机(现在做还是先记下)/ 代价(出问题怎么退、多花什么)/ 取舍(快 vs 稳、通用 vs 专用);
  • 同一件事只有一种做法时别硬凑选项——那不是岔路,写进正文说明即可;
  • 必须调用提问工具——在正文里写「① ② ③」不算提问,你点不到选项;
  • 每次提问的最后固定问「要不要先停下?」,两个选项: ① 停下 → 只回写文档 + 一句话说明,本轮立即结束,不做任何动作; ② 继续 → 按当前模式继续。

这样你能随时喊停,而不用担心中途被改了代码。

2. 一个会话可以同时绑多个项目

绑定信息写在主文档里,不是插件的状态文件:

---
puzzle: 7
项目: 我的项目
模式: 写后再拼
计划模块: ["登录流程","数据存储"]
会话: ["<sessionId>"]        # 绑了哪些会话(一个会话可出现在多个项目里);没绑定时整行不写
当前会话: ["<sessionId>"]    # 这些会话里,「当前项目是这里」;不变量:当前会话 ⊆ 会话
更新时间: 2026-10-03 12:00:00
---

一个会话可以同时操作几个项目(v0.20.0 起)。分工是:

动作走哪条语义
绑一个新项目、保留已有的面板「+ 绑定项目」/ 空态的多绑定模式追加,并设为当前
换掉全部绑定op:bind「本会话就绑这一个」,会解绑别处
在已绑的之间换当前面板胶囊 / op:current只切,不动绑定集合
看全部绑定op:bindings每个项目的模式 + 健康性 + 哪个是当前
解绑一个面板胶囊上的 × / op:unbind 带 project只解那一个
全解op:unbind 不带 project回到未绑定

「当前项目」是落盘的状态:工具不给 project 时落在它上面。不落盘的话, 重启进程 / 换一条调用路径就会漂回列表里的第一个——那种漂移没有可见起因, 用户只会觉得插件不听话。切换走 method:current,不动绑定集合。

多绑定联动:只要有一个绑定的项目是「只拼不写」,写动作就被拦(不是只看当前项目) ——多绑定时模型随时可能在几个项目间跳着改文件,「当前项目」只是默认落点,不是「只许动它」。 工作流触发同理:按命中的项目各自注入,并在注入时点名属于哪个项目。 绑定超过 8 个只在面板上提醒,不阻断。

作用于全部绑定的三个动作(v0.21.0 起)——它们的共同点是「与当前在看哪个无关」:

动作全局语义
迁移 / 仅迁移格式把每个绑定项目升到当前格式,逐项目预览改动数;只迁当前那个会留下格式不一致的文档
接续会话提示词列出全部绑定项目,逐个接上,别只接当前那个(不自己翻代码推评估——那交给审查)
一次建多个空态「扫工作区 · 一次建多个」:扫出还没有文档的顶层目录,勾选后一次建齐并全部追加绑定

一次建多个的判据宽(纯数据目录、脚本集合也算项目——漏掉比多列糟), 但 node_modules / .git / .cache / 隐藏目录这类噪音会挡掉;每条候选带上 目录里的文件名当证据,用户勾选后才建(不是扫到就自动全建)。

归属跟着文档走:复制项目、换 profile、拷到别的机器,绑定都还在。

解析顺序只有三步:显式指定 > 本会话绑定的 > 空。没绑定就是空—— 不会自动占用别的会话的项目(早先「回退到最新项目」正是文档混成一团的根因)。

新建项目时一次同时创建工作区文件夹 + 主文档 + 每个模块一份文档。

3. 工作流 = 标准化流水线

第五节 ## 工作流 不是待办清单,也不是「别做某事」的禁令——它是为完成某个特定任务, 把重复的步骤、工具、规则按顺序串成的一条可复用的路。一条工作流写成:

## 工作流

### 发布新版本
触发: package.json, release.sh
1. 先改 `package.json` 的 version 与 `.github/release-vX.Y.Z.md`
2. 跑 `node --check lib/*.js` 确认语法
3. `git commit` 并打 tag、推送
4. 建 Release 并**单独上传** tgz 附件

### 接入新模块
1. `op:module` 建模块文档
2. `op:main section:'index'` 补主文档的模块索引行

可选的 触发: 关键词(v0.19.9):写了这一行的块,会在命中该动作时自动注入—— 比如上面那条写了 触发: package.json,你用 write 改到 package.json 时, 整条工作流会作为上下文送到模型面前,不拦工具、不弹窗。 没写 触发: 的块照旧只在提示段常驻。

为什么加它:PUBLISH.md 里早就写着「description 别堆版本历史」,但改 package.json 时 撞不见它,照样违反。规则躺在文档里,不如在动作发生的那一刻出现。

四条硬规则:

  • 一条 = 一个 ### 名字 块,块内逐行是有序步骤(序号由文档自动重排成 1. 2. 3.);
  • 每条是并列的一条独立的路,两条之间不应有依赖——若两条其实是一条就合并,若要分叉就是两条;
  • 要改一条就改那一块,不要新加一条;
  • 最多 5 条(超了删最旧、整条进归档),每条最多 12 步—— 超步数是报错而不是删步骤(一条有序的路少一步就断了,静默删比拒绝写入危险得多)。

面板上图块式列出:只显示「名字 + 几步」,点名字才铺开有序步骤(与模块图块同一套交互); 每条可整条删除,删掉的进归档(显示名字与步数、不可展开),归档里可恢复或永久删除。

4. 三种执行模式

模式提问改文档执行(跑命令 / 改代码)
只拼不写可以可以禁止,越权调用会被拒绝
写后再拼一轮做完才问可以允许
边拼边写每个写动作之前先问可以允许

模式名在格式 v5 换过含义:v4 及更早的 边拼边写 表示「一轮做完才问」, 那个含义现在叫 写后再拼;新 边拼边写 才是「每个写动作前先问」。 旧文档一律按旧含义读(= 写后再拼),跑一次「迁移/重构」会把名字改写落盘。 这样才不会出现「升级插件那一刻,所有旧项目静默变成每次写文件都要问」。

模式是项目级设置,写在主文档里,面板上随时切换。

5. 拼图面板

模型选择器左边一个小按钮(拼图图标 + 当前项目健康性百分比),点开是面板:

  • 五维条:任务复杂度 / 可拓展性 / 维护系数 / 代码质量 / 可复用性(跨模块均值);
  • 模块图块:点开读该模块文档——要点 / 悬而未决 / 已定 / 详细记录逐条成卡片, 每条带序号与出处,不合规的当场标出来(超N字 / 缺出处,边框转警告色);
  • 客观发现直接列在面板里:三档(堵 / 补 / 提)+ 事实 + 下一步, 不必先问 AI 才看得到;
  • 真实值:点一下看「声明 → 实测」逐维对照与虚高标记;
  • 按钮:新增模块文档 / 接续会话 / 审查 / 工作流模板 / 迁移重构 / 仅迁移格式 / 解绑; 模板只填进输入框,不自动发送;

    「新增模块文档」只在项目已有文档时用:走 op:module,不新建项目, 只在当前已绑定的项目里再加一份模块文档,并同步主文档的「模块索引」 (不写那一行,这份文档在主文档里就查不到)。

  • 按会话开关:「关掉本会话的拼图模式」——按下之后这个会话下一轮起 不再注入拼图规则、也不再拦工具,其他会话照旧;再点一次恢复本会话。

新会话默认空,面板显示空态,给四条路:

空态入口走什么用在什么时候
①照现有项目搭文档读工作区真实代码 → op:init + op:bind + op:source项目已经在工作区里(老会话、新装插件),只缺文档
②表单直建面板直接落盘从零建新项目,不想经过模型
③快速建空壳op:init从零建新项目,模块名已经想好
④采访后再建先问最多 10 问(每题最多 10 个选项)再 op:init从零建新项目,目标与模块划分还没定

①和②③④的分水岭:①是「已有项目,补文档」,②③④是「建一个新项目」。 ①不采访(项目已经在那了,该让模型去读而不是让人从零起名),并且必须补一次 op:bind——op:init 在项目已存在时返回 rebound:false、不动绑定, 不补绑定面板就会停在空态,看起来像建失败了;还要显式 op:source 记源码根, 否则源码索引与源码体检全是空的。

6. 不想用的时候:关掉某个会话的拼图模式

总有场景你只想安安静静改个代码,不想被提问规则牵着走,但又不想卸载插件。 面板顶部的开关(或 op:settings disabled:true)就是那条退路:

  • 它按会话 ID 记名单,只影响被点名的那个会话——其余会话互不干扰;
  • 关掉立即生效:宿主每个 step 都重新拼装提示段, 所以本会话下一轮就不再注入拼图规则、也不再拦工具,不必等新会话;
  • disabled:false 恢复本会话;其他会话的禁用状态不受影响;
  • 名单存在 $DSH_HOME/.dsh-puzzle-mode.json,跨项目、跨 profile 一致。

写文件坏掉 / 读不出来时一律当作「没禁用」:宁可少拦,也不要因为一个坏文件 让所有会话都用不了拼图。

7. 审查:给事实,也给你真实分数

审查是执行方,产出是一份可执行修复清单(fixPlan):每条 文件:行 + 现状事实(带数字)+ 具体改法 + 预期效果 + 一个复测用的 key。

清单类别谁产出说明
structure / doc / health插件(规则)巨函数、文件少而长、目录不分层、条目超长/无出处、虚高分
vulnerability(漏洞)/ redundancy(冗余)模型插件读不到函数体语义,测不出来;模型读代码后补,用 additions 回传,插件校验后合并进清单

插件能测什么 / 不能测什么(prompt 里明写,不再暗示):

  • 能测:文件行数与函数形状、文件数与目录分层、导出符号的文本计数;
  • 不能测:真实漏洞、竞态、空值兜底、语义级冗余——这些完全靠模型读代码补。 所以「清单里没有漏洞类条目」不等于没有漏洞。

回传有校验:additions 每条必须 kind 是 vulnerability/redundancy、 target 带行号、fact/fix/expect 四段齐全——缺一整条退回(additions.rejected 里给原因), 而不是静默丢弃。复测也做实:重跑时把上一轮各条的 key 用 previousKeys 传回, 返回 recheck.resolved / recheck.remaining。

resolved 只表示「清单里不再有这一条」,不等于代码改对了——改错方向或把发现藏起来也会消失。

发现分三档:blocker(数字与文档对不上,挡路)、warn(该补)、info(提示,不扣分)。

条目级问题会逐条验:v3 的字数上限与源码出处只在写入时拦, 已经躺在文档里的长条目、无出处条目不会被追溯。审查会告诉你 「某一节有几条超长、几条没出处」——否则「要点 15 条很充实」可能 实际是 15 条全超长、全没出处,数字漂亮,规格全破。


文档长什么样

<会话工作区>/<项目名>/拼图/
├── 主文档.md                 # 只有五节:模块索引 / 源码索引 / 工具索引 / 坑 / 工作流
└── 模块/
    ├── 登录流程.md
    └── 数据存储.md

主文档固定五节,除这五节外不写任何内容——它是查找入口, 细节一律下沉到模块文档。其中第五节 ## 工作流 与其余四节不同: 那四节是查回来的事实,工作流是写给 AI 的行为流程(标准化流水线)。

条目格式固定为「一句话(源码: 文件:行)」,查找方向是 主文档 → 源码, 所以每条都能回查。字数上限只算「(源码…」之前那句话,出处不占额度:

位置上限条数上限
模块索引 / 源码索引 / 工具索引50 字—
坑20 字—
主文档 ## 工作流名字 20 字 / 步骤 80 字5 条,超了删最旧(整条进归档,可恢复);每条 ≤12 步,超步数报错不删
模块 ## 要点20 字—
模块 ## 可复用20 字—
模块 ## 详细记录50 字—
模块 ## 悬而未决20 字4 条,超了删最旧
模块 ## 已定20 字10 条,超了删最旧

超长是报错,不是截断——半句话落进文档比让你重写一遍更糟。 超条数是自动删最旧,不论旧项有没有澄清。

规范之外的小节会被清掉

主文档只允许那五节、模块文档只允许上表里的小节。其它小节一律算「非规范」: 它们既读不进任何 op、也不会被写入覆盖,只能靠迁移清掉。 所以 op:rebuild 会删除它们(预览里逐条列明「删了哪个、含几条」), op:audit 也会报 unknown_section 提醒你——内容若有用,先搬进规范小节。

标题允许带说明后缀:## 源码索引(src/,共 110 文件) 仍算「源码索引」, 写回时会归一化成规范标题。但 ## 坑与决策 不算 ## 坑。

文档锁

write / edit 只要目标是 拼图/ 下的文件就会被拒绝,所有模式都一样。 原因:文档形状由插件统一维护(条目限长、条数上限、路径守卫), 一次覆盖就能把这些规则全跳过。只读不受影响。


项目健康性怎么算

五个维度,每一维 0-100、越高越好(含「维护系数」——高分表示维护负担轻):

维度含义
任务复杂度模块实际承担的任务量;记下的要点与细节越多越完整
可拓展性还能往哪里长:悬而未决与已定越多,扩展空间越清晰
维护系数维护负担轻的程度(高分 = 好维护):要点写清了才敢改
代码质量坑与决策的沉淀程度:踩过的坑记下来了,质量才站得住
可复用性有多少可被别处复用的东西(共享模块、公共接口、抽象)

两条取值路径,显式优先:

  1. 显式写:模块文档的 ## 健康性 里一行一维,如 任务复杂度: 80。 写 维护成本: 30(成本型)会被自动翻成 维护系数: 70。
  2. 由文档证据推导(没写时):
任务复杂度 = 要点×12 + 详细记录×10
可拓展性   = (悬而未决 + 已定)×20
维护系数   = 要点×18 + 详细记录×8
代码质量   = 坑×25 + 已定×15
可复用性   = 共享条目×30 + 要点×10

模块健康性 = 五维均值
项目健康性 = 各模块健康性的均值

这是设计意图,不是缺陷:健康性反映「已经写在文档里的证据」, 不是模型凭感觉打的印象分。空模块五维全 0,不是「看起来还行给 60」。 想让数字涨,就真的把内容写进去。

真实值:不让分数自己封自己

光有自评不够——模型刚写完代码,天然觉得自己写得好。所以审查会额外算出真实值:

真实值 = min(文档证据推导, 源码体检)

源码体检只看可测量的东西:

规则警戒硬限扣分吗
单函数行数60150✅ 扣(warn 10 / fail 25)
文件少而总行数大—≤3 个文件且 ≥400 行 → 「一个文件装下整个项目」✅ 扣
目录分层6 个以上文件全在同一层—✅ 扣
单文件行数8002000❌ 不扣,只出 info
导出符号零引用文本计数 ≤1—❌ 不扣,只出 info

为什么「文件大」不扣分:工程化是一棵树,树干粗不是病。核心调度、状态机、 协议编解码天然内聚,硬拆只会让调用链横跨十个文件。健康的标准是「每个部分的职责清晰」, 不是「所有部分一样细」——一个 1200 行、30 个平均 28 行小函数的文件是健康的树干; 一个 300 行、塞了一个 260 行函数的文件才有病。行数与健康度之间没有单调关系。

所以 source_big_file 只负责提示去看:大但函数都小 → 「承重模块,函数粒度健康, 不必拆文件」;大且有超长函数 → 「问题不是行数,是第 N 行那个函数」, 真问题由 source_long_function 承担(不重复扣分)。该拆的是函数,不是文件。

阈值是经验值不是真理:超了只报事实 + 怎么拆的下一步,由你决定。 插件只给事实,不代改——改分数与拆代码由 AI 按提示执行,且不许反过来改文档凑证据。

源码在哪:源码根

文档目录与源码目录常常不是同一处。本插件自己就是:文档在工作区, 源码在插件目录。所以有个 front-matter 字段 + op:source:

{ "op": "source" }                                        // 看现在记的是哪
{ "op": "source", "path": "/root/.dsh/plugin-src/xxx" }    // 记下来(会校验目录存在且有源码)

三级回退:显式参数 > front-matter 的 源码根: > 拼图目录的上一级。 查不到源码时如实说「没查到」,而不是把 0 个文件当成「代码很干净」。


工具 op 一览

op作用
list列出现有项目(名字 / 模式 / 健康性 / 模块数 / 更新时间)
read读状态;带 brief:true 出精简档
show读某个模块文档的详情
init新建项目:文件夹 + 主文档 + N 份模块文档,一次建齐并绑定本会话
bind把本会话绑到已有项目(旧项目自动解绑)
unbind解绑本会话;文档与文件夹都留着
rebuild迁移文档格式:默认只出预览,apply:true 才落盘;正文一字不动
main写主文档五节之一:index / source / tools / pit / workflow
module写模块文档小节:health / progress / points / pending / decided / reuse / detail
health写五维健康性(必须带 name)
audit审查:可执行修复清单(fixPlan)+ 真实值 + 虚高清单 + 最弱维度;可传 additions 回传漏洞/冗余、previousKeys 复测
source记 / 查源码根
workflowremove 删整条工作流(进归档)/ restore 整条恢复 / drop 从归档永久删除
mode切换执行模式:只拼不写 / 写后再拼 / 边拼边写
settings按会话开关:disabled:true 让当前这个会话不带拼图模式(下一轮立即生效,其他会话不受影响),false 恢复本会话;不给参数只查询

每次返回都带 projectSource(explicit / bound / none)与 cwdSource, 「用的是哪个项目、项目根从哪来」始终可见,不会静默选错。


迁移旧文档

文档格式有版本号(当前 5)。旧文档被读到不会报错——只会分数偏低、 问题静默存在。所以 op:read 会返回 outdated: true 提醒你。

v4 → v5 会改写模式名:模式: 边拼边写(旧含义 = 一轮做完才问) 被改写成 模式: 写后再拼。预览里会明确列出这一条,落盘前能看清。

{ "op": "rebuild" }                 // 预览:逐文件列出将要改什么,不写盘
{ "op": "rebuild", "apply": true }  // 落盘

面板上有两颗按钮,分工不同:

按钮做什么
仅迁移格式只做机械动作:补小节、拆悬而未决/已定、删已取消的小节。先出预览,正文一字不动
迁移/重构交给 AI:先迁移格式,再按规格逐节重写正文(压长度、补出处、删超限旧项)

为什么分两颗:格式迁移是确定性的,面板自己就能做完;而正文重写必须 AI 来做 (旧条目超长、没出处,迁移刻意不追溯)。前者快,后者狠,别混在一起。

重建刻意不做的事:不改你写的正文、不自动绑定会话、不校验旧条目字数。 另外不自动备份——预览就是唯一的刹车,所以默认 dry-run。


卸载

dsh plugin --profile web remove dsh-puzzle-mode

或从 profile 的 dsh.profile.bundles 与 dependencies 里删掉那两行,重启。 工作区里的拼图文档不受影响,它们只是普通 markdown 文件。


常见问题

Q:会不会占满我的上下文? 主文档就是查找入口,配合 brief:true 与「接续会话」按钮,新会话先读入口、 按需读一个模块即可,不必通读。

Q:AI 会不会偷偷改我的代码? 在只拼不写模式下,所有执行类工具都会被宿主拒绝,理由是明确的; 在边拼边写模式下,每个写动作之前它必须先问过你(一次点头只管一个动作); 在写后再拼模式下,它先把这一轮改完,再一起汇报与提问。 另外任何模式下 write / edit 都改不了拼图文档本身。

Q:健康性分数是 AI 随便打的吗? 不是。显式写的分数与推导分数都会保留来源标记;审查还会给出真实值与虚高清单。

Q:我的文档会被锁死吗? 不会。文档就是普通 markdown,你随时能读、能复制、能带走; 只是写入要走插件(为了维持条目规格与路径守卫)。

Q:我只是想安静改个代码,不想被拼图模式管着,怎么办? 面板顶部的「关掉本会话的拼图模式」,或 op:settings disabled:true。 它只影响当前这个会话,下一轮立即生效,其他会话照旧——想恢复就再点一次。 不用卸载插件。

Q:我刚装插件,老会话里一个拼图文档都没有,要一个个手建吗? 不用。打开面板,空态第一颗按钮就是 「照现有项目搭文档」(v0.16.4 起): 它让模型先读你这个会话工作区里的真实代码,据此推导项目名与模块划分, 再 op:init 建出整套文档,并把主文档的「模块索引 / 源码索引 / 坑」 按真实的 文件:行 填好。不采访——项目已经在那了,不该让你从零起名。

Q:面板能打开,但缩在左上角 / 文字重叠 / 全透明,怎么办? 这是样式没生效,不是功能坏了。先升级到 v0.16.2 以上(修了 inset:0 简写 与 color-mix 两个坑)。若仍然如此,面板顶部会显示一行自检:

puzzle-style-diag applied=<真值> rules=<条数|null> inset=… color-mix=… backdrop=… min()=… ua=…

把这一行发回来即可定位(applied=false 且 rules=null 说明样式表根本没进文档, 多半是 CSP 或别的插件清了样式)。

⚠️ 若你看到的是 applied=false 加四项全 false,先别急着排障 —— 那多半是 v0.16.5 之前的自检 bug(applied 写死、CSS 被遮蔽), 与你的浏览器无关。升到 v0.16.5 再看这行。

Q:装上了但提示不兼容 / 根本没生效? 看 peerDependencies 覆盖不覆盖你的 DSH 版本。v0.16.1 修过一次声明了但等于没声明的 范围:^0.1.6-rc.1 指向一个从未发布的版本,按 semver 预发布规则把 整个 0.1.6-alpha 与 0.1.7-alpha 系列都排除在外了(13 个已发布版本里 9 个不满足)。 现在按每个 minor 锚到最早存在的预发布版,13 个全覆盖。


致谢

按时间倒序,记下具体做了什么——名字后面不是客套,是可回查的改动。

  • @SunsetRNE · PR #2(已合并,v0.19.8 一并发布): 发现 npm test 在 v0.19.7 上三红一绿(文档格式 v4 → v6 改造后断言整片脱节), 把 test/10-puzzle test/20-client test/30-rpc 三个文件对齐到现行实现 (+201 / −180),并给出三条建议——本版的「断言引常量 / 格式契约测试 / 发版门禁」 正是接着这三条做的。他还指出 v0.19.7 的 tag 是在测试全红下打出来的。

发现 bug、提 PR、纠正文档都算。这个项目没有 CONTRIBUTORS 文件——名单就在这里, git log 是第二份(提交作者身份原样保留,git log --author=SunsetRNE 查得到)。


MIT License · 作者 liancha22