# 变更记录

本文件记录对外可见的行为变化。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)，
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。

> **入仓说明**：本仓库于 **2026-10-11** 首次公开。1.0.0–1.0.4 是此前在一台开发机上连续迭代出的四个版本，
> 同一日一次入仓；下面的日期是各版本**当时的完成日**，不是公开日。

---

## [1.1.0] - 未发布

### 变更

- **设置面板并入「ANB 工具」栏目**：面板不再独占一个设置导航项，改为注册进
  `anb.tool.tab`（order 30）；栏目壳（`settings.section`，id `anb-toolbox`，order 16）
  由本插件**内置**——随插件自带，**不需要另外安装 `dsh-anb-toolbox`**。
- 壳是**运行时单例**：账本里已有壳时本插件让位、不重复登记；登记壳的插件被禁用后，
  由本插件接管（否则留在壳里的面板会全部变成孤儿）。
- 只装本插件时，栏目里只有它一个标签（选中态），不出现空壳；装更多 ANB 插件后在
  标签行里切换，只显示当前选中的工具。

### 新增

- **面板内「壳自检」**：说明区多出一行 `壳（设置 → ANB 工具）：…`，把壳的状态摊开——
  `本包登记（order 16）` / `由其它 ANB 插件登记 —— 本包让位（正常）` /
  `⚠️ 未登记 —— 设置里不会出现「ANB 工具」（异常）`。
  它读的是与壳同源同口径的账本（`entriesOfSlot('settings.section')`），
  不新增订阅、不发请求，随面板自身的 5 秒轮询刷新。
  为什么需要：壳出问题时症状是"静默的"——面板注册进一个没人声明的 slot，不报错、只是不显示；
  有了这一行，用户不必去猜是壳没了、还是自己装错了。
- 新增 `test/client.test.mjs`：用最小 `__ModuleLoader__` 桩真跑浏览器半侧，
  覆盖自检三态（self / other / none）与面板契约。

### 兼容

- 宿主侧（RPC、写回、工具）零改动；改动只在浏览器半侧的注册点。
- 升级后必须**重启宿主**（客户端插件在启动时装配，刷新页面不生效）。

---

## [1.0.4] - 2026-10-11

### 新增（文档与发布）

- **`CONTEXT.md`**（用词真源）：把易被误读的词逐条定死，并给出「**禁止这么说**」的反向表 ——
  最典型的是「已启用」**不等于**连上了、「状态列」**不是**健康检查。
- **`docs/adr/0001-两层文件与两条写回路径.md`**（架构决策记录）：记录"面板写哪个文件"这一决策，
  并留痕 **4 个被否决的替代方案**（直接改写 profile patch / 迁移手写行 / 只读展示 / 文本替换）。
- **`docs/实测/2026-10-10-面板实机验证记录.md`**：F1–F11 真机发现（含踩坑与**口径订正**）。
  其中 **F11** 是 2026-10-11 追加的**宿主侧**发现：宿主把 `versionNegotiation` 设为 `mode: 'auto'` 时，
  会先发 `server/discover` 探测；**某些服务端对该探测回 5xx**，而客户端库把 5xx 判为致命、**不回退旧版握手**
  ⇒ 该行永久连不上（面板上表现为「已启用 · 未发现工具」）。
- **首次发布 npm**：本版本起去掉 `private`、新增 `publishConfig.access: public`，
  安装方式 `dsh plugin --profile web add @yiyunet/dsh-mcp-client-manager` 成立。

### 修复

- **表格横向溢出**：根因是 1.0.3 给操作列加的 `min-width: 300`，把表格最小宽度顶过卡片容器 →
  尾部横线溢出卡片。改法四处：
  1. 去掉该强制宽度，列宽回归内容自适应（`修改｜禁用｜不可删`仍同排，因为行内 flex 仍是 `nowrap`）；
  2. 表格外套一层 `overflow-x: auto` 兜底——万一再超也只在本卡片内横向滚动；
  3. 服务名 / 行 id 加 `ellipsis` 截断（`max-width: 200`，悬停看全文）；
  4. 文案 `不可删（手写）` → **`不可删`**（悬停解释保留：手写行不能删、可改用禁用）。

## [1.0.3] - 2026-10-10

### 变更

- **操作列强制单行**（1.0.4 已取消其中的强制宽度）。
- **端点 / 命令不在列表显示**（会撑宽首列）——只保留在「修改」表单的 url 提示与悬停 title；
  首列小字恢复为仅「原手写行」。

### 修复

- 修正 1.0.2 挪位编辑引入的**括号配平错误**。

## [1.0.2] - 2026-10-10

### 安全

- **回传浏览器的路径一律符号化**（`$DSH_HOME\…`）：不再出现含用户名的绝对路径，
  `list` / `state` 均适用；单测新增断言「回传载荷不得含绝对主目录路径」。

### 变更

- **表格规整**：删除「端点 / 命令」整列，单元格禁折行。
- 手写行的「不可删」提示移到「禁用/启用」按钮**之后**
  （受管行：`修改 ｜ 禁用 ｜ [撤销覆盖] ｜ 删除`；手写行：`修改 ｜ 禁用 ｜ 不可删 ｜ [撤销覆盖]`）。

## [1.0.1] - 2026-10-10

### 修复

- **状态列误读官方字段**：应读 `fiberPhase`，且 cordis 的 `FiberState` 是**数字枚举** ——
  早先按字符串匹配全部落空，把正常行误报成"挂载 / 重连中"。

### 变更

- 状态口径改大白话：`已启用` / `已启用 · 未发现工具` / `已禁用` / `加载失败` / `未加载` / `配置冲突`；
  工具数收进悬停提示。
- 顶部备注重写为普通用户可读，并**动态显示受管行的写入路径**（`list` 回传 `paths.homePatch`）。

## [1.0.0] - 2026-10-10

### 新增

- **设置 → 侧栏「MCP 客户端」面板**：列出挂在 `@deepseek-ai/dsh-mcp-client` 下的服务器行，
  支持新增 / 改写 / 启停 / 删除。
- **两条互不越界的写回路径**：
  - 受管行（行 id 前缀 `mcpx-`）写**自有层** `$DSH_HOME/cordis.patch.yml`（全量重写、确定性渲染、原子写）；
  - 手写行走**官方通道**（`ctx.configEditor.edit()` / `ctx.pluginManager.setPluginEnabled()`），
    只改凭据族字段与启停，**不改标识与协议、不删除**。
- **三级 id 冲突检测**（活动行 / 受管清单 / 手写层文本弱扫）与 **serverName 保存前查重**。
- **漂移检测与两个逃生口**：自有层被外部改动 → 面板转只读，可「以清单为准重建」或「以文件为准清空清单」。
- **「撤销覆盖」**：把被面板改过的 profile patch 覆盖行还原为 `insert` 行的原值（官方语义：`next === inherited` 时移除覆盖行）。
- 零构建、零运行依赖（宿主半侧只用 `node:*` 与 ctx 服务；浏览器半侧用官方 module-loader 工厂格式）。

### 安全

- **url 永不回传浏览器**：只给 `协议//主机/…`，不含路径、查询串或任何 key 片段，也不透露长度。
- **stdio 的 env 取值永不回传**：只回传键名与"已设置"。
- **凭据族字段留空 = 保留原值**（未改不重写）；要改必须整段重填。
- 清单文件 `servers.json` 与生成物 `cordis.patch.yml` 均按 `0600` 写入。

### 已知限制（明示，不掩饰）

- **状态列不是健康检查**：状态 = 行阶段 + 工具数（`mcp__<serverName>__*` 计数）。
  断线重连期间工具仍会列出、调用才失败（`mcp-client` 的既定行为），因此本面板**不做协议层探活**。
- **手写行不能删、不能改标识与协议**（官方编辑服务的能力边界）；要改请手工编辑 profile patch。
- **手写行的改写落点是 profile patch**：首次追加一条顶层覆盖行、之后原地更新；
  已被覆盖的行再改 `insert` **不生效**，需先点「撤销覆盖」。
- **只覆盖 `streamable-http` / `stdio` 两种传输**；`headers`、`reconnect`、`toolCallTimeoutMs`、
  `maxInstructionBytes` 等字段仍以文件为准。
