# 面板 UI 说明 · 每个地方有什么用
> 对应 v1.1.3。面板是输入框左边那颗小按钮点开的浮层。
> 本文只讲 **UI 上有什么、点了会怎样**;安装、模式语义、文档规格见 [README](README.md)。
>
> 每节的图是**照着本文件渲染**出来的(`node tools/render-tutorial.mjs`),
> 与正文同源,改完正文重跑一次即可——不存在「图与文字对不上」的中间态。
> 整份一图流:[`.github/images/ui-tutorial.png`](.github/images/ui-tutorial.png)
> (约 8000px 高,适合存档或整份转发;逐节阅读请直接看各节自己的图)。
---
## 1. 入口按钮
**位置**:输入框里、模型选择器左边。
```
[🧩 拼图 62%]
```
| 元素 | 含义 |
| --- | --- |
| 🧩 拼图 | 图标,固定 |
| `62%` | **项目健康性**;未绑定项目时不显示 |
| 高亮 | 面板已打开 |
点一下开面板,再点(或按 `Esc`)关闭。打开时会自动拉取状态、项目列表与主文档。

---
## 2. 面板顶部(两种状态共用)
| 位置 | 内容 |
| --- | --- |
| 标题 | `拼图 · <当前项目名>`;未绑定时只有 `拼图` |
| 副标题 | 已绑定:`<模式> · 格式 v7 · <文档目录>`,旧格式会追加「(旧格式,建议迁移)」
未绑定:`本会话未绑定项目` |
| 右上角 | `健康性 62%`(**手机上隐藏**,省空间) |
| 主题图标 | **切换到主题管理页**(面板主界面的另一种视图,不是浮层)。见 [§7](#7-主题管理页) |
| `⟳` | 刷新:状态 + 项目列表 + 主文档 + 工作流**一起重拉** |
| `✕` | 关面板(`Esc` 同效;在主题页里 `Esc` 先返回项目面板) |
### 顶部可能出现的三条提示
| 样式 | 触发条件 | 你要做什么 |
| --- | --- | --- |
| 🔴 红字 | 读取失败 / 写入输入框失败 | 点 `⟳` 重试;持续失败再看红字内容 |
| 🔵 蓝字 | 中性提示(如「项目已存在,本次没有改动绑定」) | 通常只需知道,不必处理 |
| ⚠️ 样式自检 | 样式表没生效(`applied=false`) | 把那一行 `puzzle-style-diag …` 发回作者 |
> 样式自检那一行长这样:
> `puzzle-style-diag applied=<真值> rules=<条数|null> inset=… color-mix=… backdrop=… min()=… ua=…`
> 它是「面板能开但没样式」的唯一可靠线索 —— 老 WebView、CSP、别的插件清样式,
> 症状都一样,靠猜分不出来。
>
> ⚠️ **v0.16.5 之前这一行会误报**:`applied` 被写死成 `false`、四项特性因 `CSS` 被遮蔽
> 也恒为 `false`,**样式完全正常的面板照样显示这条警告**。见到它先升到 v0.16.5。
.png)
---
## 3. 空态(本会话未绑定项目)
三栏:**左=建项目 · 中=交给 AI · 右=绑定已有**。
### 左栏 · 直接建(不经过 AI)
**顺序**:先按会话开关,再是建项目表单。
| 控件 | 作用 |
| --- | --- |
| `关掉本会话的拼图模式` | 见下(空态在最上面) |
| 项目名 | **会成为工作区里的文件夹名** |
| 模块名,逗号分隔 | 每个模块一份文档;可留空 |
| 一句话目标 | 写进主文档;可留空 |
| `立刻建` | 直接落盘:文件夹 + 主文档 + N 份模块文档,并**绑定本会话** |
> 这条路**不经过模型** —— 建空壳是纯机械动作,走模型要多花一整轮对话。
### 左栏 · 开关(**空态与已绑定态都有**)
这里有两颗按钮,**作用范围不一样**,所以各自标了范围:
| 按钮 | 作用范围 | 作用 |
| --- | --- | --- |
| `关掉本会话的拼图模式` | **只本会话** | 下一轮起不再注入拼图规则、也不再拦工具 |
| `固定收尾问:开 · 点此关闭` | **全局** | 关掉后**所有会话**的提问都不再带「要不要先停下?」 |
- 「本会话」那颗:其他会话**照旧**;**下一轮立即生效**,不必等新会话;
再点一次(按钮变成 `本会话:已关拼图 · 点此恢复`)恢复。
- 「固定收尾问」那颗:写进 `$DSH_HOME/.dsh-puzzle-mode.json`,**跨会话跨项目一致**;
关掉后提示段会明说「已全局关闭、不要再问」,工具返回也不再下发收尾问文案与选项。
**默认是开**(老行为不变);设置文件里缺这个字段也算开。
- 两颗按钮下面有一行灰字说明当前状态与范围差异;
- 开关状态**读不到时不显示这些按钮**(宁可少一颗,也不显示错的状态)。
### 中栏 · 或交给 AI
| 按钮 | 走什么 | 用在什么时候 |
| --- | --- | --- |
| **照现有项目搭文档** | 读工作区真实代码 → `op:init` + `op:bind` + `op:source` | **项目已经在工作区里**(老会话、刚装插件),只缺文档 |
| `快速建空壳` | `op:init` | 从零建新项目,模块名已经想好 |
| `采访后再建` | 先问最多 10 问(每题最多 10 个选项),再 `op:init` | 从零建新项目,目标与模块划分还没定 |
> **三颗都只把提示词填进输入框**,不自动发送 —— 你补完槽位再按发送。
> 底部两行提示写清了这个分水岭:
> `「照现有项目搭文档」= 项目已在工作区里,只是还没文档;下面两条 = 从零建一个新项目。`
> 以及目标目录 `目录:/x/<项目名>/拼图/`。
### 右栏 · 绑定已有项目
顶部先选**绑定模式**(两颗分段按钮),再按模式选项目:
| 模式 | 行为 |
| --- | --- |
| `单绑定`(默认) | 列出工作区里的项目,每行一颗 `绑定`。绑过去之后**原先绑的项目自动解绑**——本会话就绑这一个 |
| `多绑定` | 每行变成勾选框,可多选,底部一颗 `绑定选中的 N 个`。**追加**绑定(不动已有的),最后一个成为**当前项目**;之后在左栏的切换条上换当前 |
- 绑定是**按会话**记的;
- 一个会话**可以同时绑多个**项目(多绑定模式);
- 绑了多个之后,左栏「项目」区出现**切换条**(见下节)。
.png)
---
## 4. 已绑定态
三栏:**左=我要做什么 · 中=现在什么状态 · 右=具体内容是什么**。
### 左栏 · 项目 / 模式 / 动作
**顺序就是渲染顺序**(从上到下):
| 区块 | 内容 |
| --- | --- |
| **项目** | **绑定切换条**:绑定 2–4 个时是一排**胶囊**(当前项高亮,带健康性百分比;悬停出 `×` 可只解这一个),≥5 个时换成**卡片列表**(多显示模式、模块数与健康性进度条)。末尾 `+` 展开工作区里**还没绑**的项目,点一个即追加绑定。下面显示当前项目的文档目录 |
| | ⚠️ 切换条只列**本会话绑定的那几个**项目——不是工作区全部项目。「换当前」走 `method:current`(**不动绑定集合**),与 `op:bind` 的「替换全部绑定」是两件事 |
| **执行模式** | 三颗分段按钮 `只拼不写` / `写后再拼` / `边拼边写`;点一下即切换并落盘。下面一行写清当前模式什么意思 |
| **看项目** | `主文档`(见下)。原先这里还有一颗「审查 / 真实值」——v0.23.0 按用户裁定删了(配套的「真实值」显示区一起删;审查能力本身没动,见「让 AI 动手」) |
| **让 AI 动手** | `新增模块文档` / `接续会话` / `审查(交给 AI)` / `工作流模板` |
| **改文档** | `迁移/重构` / `仅迁移格式` |
| (无标题) | 按会话开关 `关掉本会话的拼图模式`;拿不到会话工作目录时另有一条黄色警告 |
| (无标题) | `解绑本会话` —— **单独一块**,红色危险样式,与其他操作分开摆 |
> **黄色警告**:`拿不到会话工作目录,已退回 <路径>(文档可能写错地方)`。
> 出现它说明宿主没给出会话 cwd,文档可能写到了别处 —— 这时先确认目录再继续。
#### 执行模式三颗按钮
悬停能看到差别(名字在 v5 换过含义,所以 UI 里必须写清):
| 模式 | 悬停说明 |
| --- | --- |
| `只拼不写` | AI 只提问 + 更新文档,越权工具会被宿主拦下 |
| `写后再拼` | AI 先把这一轮改完,再一起汇报与提问(**旧名「边拼边写」**) |
| `边拼边写` | AI 每个写动作之前先问:说清改哪个文件、改成什么,你点头才动手 |
#### 看项目
| 按钮 | 作用 |
| --- | --- |
| `主文档` | **只读**查看主文档原文(含 front-matter 与五节);工作流条目与归档也在这块。再点一次收起,**每次展开都会重新拉**(文档可能已被 AI 改过) |
#### 让 AI 动手(都只填提示词,不自动发送)
| 按钮 | 填进去的提示词要 AI 做什么 |
| --- | --- |
| `新增模块文档` | 在**当前项目**里再加一份模块文档,并同步主文档的「模块索引」(**不会新建项目、不动已有文档**) |
| `接续会话` | 新会话按需读:先 `op:read` → 只读主文档 → 只读相关那一个模块,**不通读全部**;读到断点就接着干,**不自己翻代码推评估**(那交给审查) |
| `审查(交给 AI)` | 按五维审查这个项目,并出可执行修复清单 |
| `工作流模板` | 先问清**是哪条流程、依次哪些步骤**,再用 `op:main` 写成 `### 名字` + 有序步骤 |
#### 改文档
| 按钮 | 作用 |
| --- | --- |
| `迁移/重构` | 填提示词:按最新规格清理**全部**文档(形状 + 正文),不留手。旧格式时按钮带 ⚠ |
| `仅迁移格式` | **不经过 AI**,直接出重建预览(dry-run):收敛成五节、补小节、拆 悬而未决/已定,**正文一字不动** |
#### 解绑本会话(单独一块)
`解绑本会话` 摆在左栏**最下面、单独一块**,红色危险样式,与其它操作隔开。
本会话回到未绑定。**文档与文件夹都留着**,不会被删。解绑后面板回到空态。
### 中栏 · 读数
| 区块 | 内容 |
| --- | --- |
| **项目健康性** | 大圆环 + 一句话评语。评语分档:≥85 证据充分 / ≥70 基本可用 / ≥50 证据偏薄 / <50 证据很少 |
| | 下面写清分数的来源:`来自文档里写下的证据(要点 / 详细记录 / 悬而未决 / 已定 / 坑)——空文档就是 0,不是印象分` |
| **五维** | 五条横条(任务复杂度 / 可拓展性 / 维护系数 / 代码质量 / 可复用性),标注 `跨模块均值 · 声明值` |
| **规模** | 三颗按钮 `小` / `中` / `大`,当前档高亮;下面一行写清当前各节上限(悬而未决 / 已定 / 工作流 / 坑)。点一下**直接写**主文档 front-matter 的 `规模:`,条目上限随之变。中档是默认值,不写那一行 |
| **模块** | 图块墙。每块=一个模块,显示名字 + 健康性条 + 百分比 + `点 N / 悬 N / 定 N`。**点开读该模块详情**,再点收起。未建文档的模块标 `未建` |
| **审查 · 客观发现** | 按严重度排序的发现列表:左侧徽标 `堵` / `补` / `提`,正文是 `范围:事实` + `→ 修复建议`。末尾一行说明「事实由规则数出来,点评由 AI 写」 |
> **真实值这一块最该看**:模型自评的分几乎总是偏高,而真实值由插件算
> (文档证据 + 源码体检),**模型改不了它**。
### 右栏 · 文档与细节
| 区块 | 内容 |
| --- | --- |
| **模块详情** | 点了图块才出现。标题 `模块 · <名> · 健康性 N%`;下面是五维 + 逐条卡片 |
| **工作流** | 主文档 `## 工作流` 的**流水线**,标题标 `(N/5 · 每条 ≤12 步 · 点名字看步骤)` |
| | 每条是一颗**图块**:只显示「序号 + 名字 + 几步 + ▸」。**点名字才铺开有序步骤**(1. 2. 3.,与模块图块同一套交互);再点收起。右侧一颗 `✕ 删除`(整条删) |
| | 下方 `归档(N · 可恢复 / 可永久删除)`:被删的**整条**工作流在这里,只显示「名字 · 几步」,**不可展开**;每条两颗按钮:`恢复` / `永久删除`(后者危险色,不可恢复) |
| **主文档** | 只读原文,标题标 `只读 · 格式 v7`,旧格式会标出来 |
| **重建预览** | `仅迁移格式` 的 dry-run 结果:`重建预览 · 文档格式 v4 → v5(N 处改动)`,逐文件列出改什么 |
#### 重建预览(点了「仅迁移格式」才出现)
| 元素 | 内容 |
| --- | --- |
| 标题 | `重建预览 · 文档格式 v<当前> → v<目标>(N 处改动)` |
| 每行 | 左侧徽标 `主` / `模`,正文 `文件名 · v<版本>` + 这文件要改什么(多项用 `;` 连起来) |
| 没有改动时 | 显示「已经是当前格式,无需重建」 |
| `落盘` | **把预览里的改动真正写进文档**(正文不动,只改 front-matter 形状与缺失小节) |
| 旁边说明 | `本项目不自动备份,落盘前请确认` |
| 已落盘后 | 显示 `已落盘:<文件列表>`,`落盘` 按钮消失 |
> 这是面板里**少数几颗不经过模型、直接写文档**的按钮之一(另一颗是空态的 `立刻建`)。
> 只改形状是纯机械动作,出预览让你确认就够了。

---
## 5. 哪些按钮会直接写、哪些只填提示词
面板上的按钮分三类,**别混**:
| 类型 | 按钮 | 会怎样 |
| --- | --- | --- |
| **只填提示词**(不发送) | 空态:`照现有项目搭文档` / `快速建空壳` / `采访后再建`
已绑定:`新增模块文档` / `接续会话` / `审查(交给 AI)` / `工作流模板` / `迁移/重构` | 文字进输入框,**你自己按发送**才动 |
| **直接写**(不经过模型) | 空态 `立刻建`;`仅迁移格式` → `落盘`;执行模式三颗;**规模三颗**;`关掉本会话的拼图模式`;`解绑本会话` | 点下去**立即生效** |
| **只读** | `主文档`、模块图块 | 只取数据,不改任何东西 |
> 执行模式按钮写的是主文档 front-matter 里的 `模式:`,所以它也算「直接写」——
> 点错会立刻改掉项目模式,注意看下面的说明行。
#### 模块详情的逐条卡片
每条是一张卡片,**一行排开**(不是两行):
```
① <条目正文> lib/client.js:181 [超3字 · 缺出处]
↑ ↑ ↑
序号 出处(等宽小字, 不合规时才出现的胶囊标签
已去掉「(源码: )」外壳)
```
- 分组:**要点 / 悬而未决 / 已定 / 可复用 / 详细记录 · 轮汇报**;
- 分组标题带 `(N 条,每条 ≤20 字 + 出处)`(详细记录是 ≤50 字);
- 分组**没有条目时整组不渲染**(不会出现空标题);
- **超字或缺出处会当场标出来**:标签转警告色,卡片左边框也转警告色;
- 出处是等宽字体,只显示 `文件:行`(`(源码: )`那层外壳被剥掉了)。

---
## 6. 三条常驻提醒
面板底部常驻两行字,加上一条规格:
1. **拼图文档只能由 AI 通过 `puzzle_mode` 改**;`write` / `edit` 会被文档锁拒绝(所有模式)。
2. **每次提问的最后都会问「要不要先停下?」**,两个选项。
3. 面板上所有「让 AI 动手」按钮**都只填提示词**,不自动发送(例外见第 5 节)。
底部还常驻一行提问规格:**一轮最多 10 问、每题最多 10 个选项**。这两个数只在
`lib/constants.js` 的 `ASK_MAX_QUESTIONS` / `ASK_MAX_OPTIONS` 里定义一次,
提示段、首轮注入与面板模板都引用它(浏览器半 `lib/client.js` 拿不到 ESM 导出,
另存一份同值常量,改上限要两处一起改)。
除了上限,提示段还规定了**选项长什么样**:每题 3–6 个真岔路、每个配一句取舍
(`options[].description`),并给了反例(「① 改 ② 不改」)与正例(一条四个选项的
改法题);找岔路的五个维度是**做法 / 范围 / 时机 / 代价 / 取舍**。
所以点选项时你会看到**每个选项下面那行小字说明代价**——那是这一节要求的。

---
## 7. 主题管理页
面板右上角那颗**主题图标**点开的**主界面切换**——它替换面板的三栏主体,不是压在上面的
第二层浮层(v0.27.1 起;此前是一层全屏覆盖层,会同时出现两套玻璃框与两个关闭按钮)。
点「← 返回」或按 `Esc` 回到项目面板。**面板本身从头到尾只有一层。**
主题**不在插件包里**——包里只有代码,皮肤点一下从
[dsh-puzzle-themes](https://github.com/liancha22/dsh-puzzle-themes) 现取。
| 位置 | 内容 |
| --- | --- |
| 顶栏 · 左 | 标题 `主题` + 当前主题(默认皮肤时写「当前:液态玻璃(内置默认 · 随宿主明暗)」) |
| 顶栏 · **恢复默认** | 常驻一颗(不跟列表滚)。回到内置的液态玻璃,**不卸载**已下载的主题 |
| 顶栏 · 刷新列表 | 重新从主题仓库拉清单 |
| 顶栏 · `← 返回` | 回到项目面板(`Esc` 同效)。**不是**第二个 `✕`——关整个面板用右上角那颗 |
| 卡片墙 | 每张卡:主题主色块 + 名字 + 作者/版本 + 一句话说明 |
| 卡片 · 未装 | 一颗 **「下载并应用」**——下载、校验、落盘、应用,一步到位 |
| 卡片 · 已装 | **「应用」**(不联网)+ **「卸载」** |
| **开发区** | 主题 id 输入框 + **「建脚手架 + 填提示词」**;有仓库检出时另有**「重算清单」**与**「上传(推送到主题仓库)」** |
| **分享区** | 每套已装/仓库里的主题一颗**「导出」**(生成单文件主题包);下方**粘贴框** + **「导入并应用」** |
| 底部 | 主题源(仓库)+ 缓存目录 + 一句安全说明 |
### 默认皮肤叫「液态玻璃」
内置默认不是无名皮肤:它是一层**液态玻璃**——背景模糊 `blur(24px) saturate(1.35)`,
顶边一道白色高光,没有网格也没有扫描线。它**随宿主明暗自动跟随**
(基底令牌收口宿主的 `--dsw-alias-*`),所以不用为浅色/深色各挑一套。
### 开发与分享(v1.0.0)
**一键开发**:填一个主题 id(小写字母数字,中文名会被规范化;规范化不出来的会明确报错),
点「建脚手架 + 填提示词」——它在工作区建出 `themes//{manifest.json,theme.css}`,
并把一份**开发提示词**填进输入框(含该主题的目录、全部可用令牌、禁止项、验收命令)。
**已存在的文件不会被覆盖**:作者可能已经改了一半,覆盖等于把他的工作删了。
**一键上传**:`重算清单` → `上传`。上传只做 `git add / commit / push`,
**插件代码里没有任何令牌路径**——凭据由 git 自己的凭据链取。每一步的成败都逐行显示
(`✓ index — 清单已重算(5 套主题,有变化)` 这种),推送失败时把 stderr 也原样贴出来。
**分享给别人**有两条路:推到仓库(别人刷新列表就能看到、一键安装),或
**导出单文件主题包**(`.dshpz-theme.json`,发给对方粘贴导入,不依赖 git 与网络源)。
包里带 `sha256`,导入端验伪;本机已装同 id 时会**先问一句**「替换 / 保留本机」,不替用户决定。
**状态标记**:`使用中` 徽标 = 当前生效;`仅本机` = 已装但远端清单里没有(换过源或被作者
下架),仍然可以卸载。**清单缺 hash(不可安装)** 的主题按钮是禁用的——没有 `sha256`
就没有信任锚,装上等于不校验。
**离线时**:清单拉不到就用上次成功的缓存,页面顶部明说「⚠ 当前离线(原因),下面这份列表
是上次成功拉到的缓存(时间)」。三个镜像分别报了什么也会原样列出来
(`jsdelivr → HTTP 404` 这种),因为「下载失败」四个字排不了故障。
**主题只能是 CSS**:不允许 JS、不允许外部请求。下载的 CSS 会逐条过白名单
(`@import` / 外部 `url()` / `javascript:` / `expression(` / `` / 花括号不配平 /
越界选择器 / `html.dark{…}` 一律拒绝),并按清单里的 `sha256` 校验,不符就拒绝安装。
**小按钮也跟着换皮**:那颗小按钮与面板分属两个 Slot,所以主题令牌声明在 `:root` 上,
作用域靠 `--dshpz-` 前缀与 `.dshpz-*` 选择器收窄。
**主题作者**:往主题仓库加 `themes//{manifest.json,theme.css}`,跑
`node tools/build-index.mjs` 重算清单。可覆盖的 31 个令牌与全部硬约束见该仓库 README。

---
## 8. 更新页
面板右上角那颗**下载箭头图标**点开的主界面切换(与主题页同一套机制:替换三栏主体,
不是第二层浮层)。点「← 返回」或按 `Esc` 回到项目面板。
**有新版时那颗图标会亮一个小圆点**——用户不会没事点进来看版本号,这是「有新版本」
这件事唯一会被注意到的入口。点进去才联网检查(不在打开面板时自动查:断网时那会把
面板拖住几秒)。
| 位置 | 内容 |
| --- | --- |
| 顶栏 · 左 | 标题 `更新` + 当前版本 · 线上版本 · 状态(有新版本 / 已是最新 / 本机比线上新) |
| 顶栏 · 重新检查 | 重新对比线上版本并拉更新日志 |
| 顶栏 · `← 返回` | 回到项目面板(`Esc` 同效) |
| 发现新版本 | **「一键更新到 vX.Y.Z」** + **「只下载到暂存区」**(想先验一遍的人用) |
| 各版本更新日志 | 每个版本一块:版本号 + 标题 + 日期 + **正文里「## 摘要」区块最多 3 句**;当前那版打「当前」标记 |
| 备份与暂存 | 最近几次安装前的备份(从哪版到哪个 tag)+ 暂存目录里已下好的版本 |
### 更新日志为什么是「简短三句」
用户原话:「更新日志的信息改为**简短三句交代更新了什么**就行」。
v1.0.1 起摘要取的是**正文前 3 行**,到 v1.1.2 上就露馅了——那一版正文的头三行是用户原话
与「先量,再改」的铺垫,面板上的「摘要」里没有一句说这版改了什么。
**位置(前 3 行)跟内容(改了什么)不是一回事**,所以 v1.1.3 改成显式区块:
- Release 正文里写一个 `## 摘要`,块内**最多三句**(一句也行)交代这版改了什么;
- 宿主只认这个区块(`summarySectionOf`),区块**之前**的铺垫与**之后**的验收判据都不进摘要;
- **没写这个区块就明说「(这版没写摘要)」**——不拿正文开头冒充摘要,也不含糊成
「这一版没有单独的说明」(那会让人以为这版真没改什么)。
摘要仍在**宿主半**压好(`summarizeNotes`):丢掉标题行、图片行、分隔线、空行;
剥掉 `**粗体**` 与 `` `代码` `` 记号;列表符号统一成 `·`。
**表格行压平保留**(`| a | b |` → `a · b`)——发版正文的关键信息常在表里,整行丢掉会漏掉「改了什么」。
超出行数时**明说**「…还有 N 行」,静默截断会让人以为这版就这么点内容。
### 一键更新:失败会**自动回退**
点「一键更新」之后,插件把安装交给一个**独立进程**(`tools/dsh-puzzle-update.mjs`),
它先被复制到 `$DSH_HOME/puzzle-mode-updates/` 下再执行——那个位置不属于任何包,
所以 `node_modules` 被装坏也不影响它跑完回退。**这是整套设计能成立的原因**。
它做的事:备份三处(`node_modules` / `package.json` / 锁文件)→ `pnpm add` →
自检(依赖声明 · 版本号 · 入口文件能否解析)→ **任何一步不过就整体回退三处**。
界面上的表现:
- 安装期间显示「**正在安装…(独立进程 pid …)**」——这个状态由安装器自己写出来,
所以换页面、刷新都还在(面板分不清「在装」与「没起来」是实测踩过的坑);
- 成功 → 「已装好 vX.Y.Z。**重启 profile** 才会生效。」
- 失败 → 「更新失败,**已自动回退**到 vX.Y.Z:<原因>」,下面逐行列出三处的恢复结果;
你原来那版还在,插件照旧能用。
**为什么轮询上限是 5 分钟**:pnpm 解析 git tag 要联网问 GitHub,实测要几秒到一两分钟。
上限太短会把「其实在正常装」判成卡住——那比不提示更糟。
### 校验到什么程度,界面就说什么
- Release 正文里写了 `sha256` → 下载后逐字节比对,**「sha256 比对通过」**;
- 正文里没有(老版本没写)→ 退化成结构校验(gzip 解得开、包里是 `dsh-puzzle-mode`、
版本对得上),并**如实标成「结构校验,正文里没有哈希锚点」**。
假装验过了比不验更糟,所以这两档在界面上是**分开写的**。
**拉不到时**:走 GitHub API 失败会退到 jsDelivr 读仓库里的 `package.json` 与
`CHANGELOG.md`——够回答「有没有新版、改了啥」,但**拿不到附件地址**,
所以这时只给「打开 Release 页」,不给一个点了必然失败的「下载」按钮。
---
## 9. 手机端
窄屏(<900px)自动变成**单栏 + 面板内滚动**:
- 三栏纵向堆叠,栏间改横线分隔;
- 面板高度上限放宽到 `92vh`;
- 顶部那颗 `健康性 N%` 隐藏(标题副标题里仍有模式与目录)。

---
## 附:按钮总览(一屏速查)
**空态**
```
左:关掉本会话的拼图模式
项目名 / 模块名 / 目标 → 立刻建
中:照现有项目搭文档 · **扫工作区 · 一次建多个** · 快速建空壳 · 采访后再建
右:绑定(已有项目列表)
↓ 点「扫工作区」后在中栏下方出现勾选器:
列出还没有拼图文档的顶层目录(带目录内文件名当证据)
→ 勾选 → 「建这 N 个」= 每个建一份主文档 + **全部追加绑定**(最后一个是当前)
```
**已绑定**
```
左:绑定切换条(只列绑定的项目)· 执行模式×3
审查/真实值 · 主文档
新增模块文档 · 接续会话 · 审查(交给 AI) · 工作流模板
迁移/重构 · 仅迁移格式 ← 多绑定时**作用于全部绑定**(逐项目预览 + 一起落盘)
关掉本会话的拼图模式
解绑本会话 ← 单独一块,红色
中:健康性圆环 · 五维 · 规模 · 模块图块 · 客观发现
右:模块详情 · 工作流图块(+归档) · 主文档 · 重建预览(+落盘)
顶:主题图标 → 主题管理页(卡片墙 · 下载并应用 · 卸载 · 恢复默认 · 开发区 · 分享区)
更新图标 → 更新页(版本对比 · 更新日志 · 下载到暂存区 · 复制安装命令)
更新图标**有新版时亮一个小圆点**
```
.png)