# 变更日志

本文件记录本项目的所有重要变更。

格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)，版本号遵循[语义化版本](https://semver.org/lang/zh-CN/)。

- 只想看「大致改了什么」→ [版本更新概要](docs/update.md)
- 功能说明与用法 → [README](README.md) / [README_EN](README_EN.md)
- 工程细节（根因分析、实测数据、设计取舍）在 git 历史里，不在这里。

---

## [0.12.0] - 2026-09-20

### 新增

- **兼容页「功能总览」**：一行一个功能点（十几项，第一行是「插件是否完整挂载」），状态由三层合成 —— 装配层（listener / provider / 适配是否真的挂上）＋宿主能力层（探测结果）＋你自己的配置（开关 / 令牌 / 场景锁定）。取值：正常 / 降级（附原因）/ 未启用 / 受令牌限制 / 部分生效 / 不可用。点一行跳到该功能所在的页签；数据全部来自已有缓存，不新增宿主探测。
- **停用的 MCP 工具真的从模型可见的工具表里消失了**：`tools.restrict` 之前是在插件级上下文上调的，官方要求 agent scope、必抛 —— 异常被当成"registry race"吞掉，所以「停用」一直只有执行时拦截这一半。现在按 agent 逐个应用（跟随 agent 上线/下线），重新启用后工具会恢复可见。
- **补丁写入前先做一次解析校验**：复刻官方解析补丁用的 YAML 方言（js-yaml + `!!js` 标签 + 官方那两条断言），写入前判一次产物。判据是**非对称**的 —— 只有"改前能解析、改后不能解析"（＝我们的改动把产物弄坏了）才拒绝写入并保留原文件与备份；改前本来就解析不过（说明复刻过期）照写 + 上报；依赖不在也照写 + 上报。校验结论会出现在兼容页，写入回执也带一条 warning。
- **doctor 新增三项检查**：① 插件运行时按裸模块名要的那几个宿主包（MCP 客户端 / 人设 / AGENTS.md 注入 / 技能目录）是否仍被宿主暴露；② 插件挂载心跳（`tool-management/mount.json`，含 12 个 inject 服务名）—— 官方改名任何一个 inject 服务名时插件根本不会 apply，且官方既不抛错也不打日志，这份心跳是那种情形下唯一的线索；③ 宿主版本与本插件验证过的版本不一致时显式提示。
- **发行物的 `!!js` 表达式自带兜底**：双挂载判定那段表达式在**每次启动**被宿主求值，而那条调用链没有任何保护；现在表达式自己包了 try/catch，出错返回 false（＝不参与判定、保持挂载），绝不把启动流程拖垮。

### 变更

- **宿主补上原生删除入口时，先不切换**：单删与批删两条都改为"上报「宿主已提供原生入口」+ 继续走本插件自有完整序列（级联子会话 + spill + 记账 + 缓存行）"。切过去的代码今天不可达，写成即等于它会在官方补上入口的那次升级上首次运行、且无从事前验证。
- **会话删除的前置检查补齐**：转录清理还要 `readSessionHeader` 与持久化后端的 `locate()`，而它们排在「装写屏障 → flush → detach → 清缓存行」之后 —— 缺任何一个，失败点都会落在中段（转录还在、记账已清）。现在这两项与已有检查一样，在任何破坏性步骤之前先确认。
- **`@deepseek-ai/cordis` 的 peer 下界提到 `^4.0.2`**（对齐宿主实装）；两个子智能体 spawn provider 进 devDependencies（运行时硬 require、此前在本仓库解析不到）；移除没有引用的 devDependency `@deepseek-ai/dsh-user-approval`。
- **依赖投递链写进文档**：`npm run build` 的镜像清单**不含 `node_modules`**，新增的运行时依赖（js-yaml）需要在 profile 侧安装；装不上时校验自动降级为「跳过 + 上报」。

### 修复

- **关掉技能 / 提示词域后，官方那条注入真的停了**：此前拦不拦得住取决于启动时的注册先后 —— 没拦住的那次，官方内容照旧进上下文，界面上也看不出异常。现在位置固定，不再看运气。
- **投影缓存删除屏障的三处缺陷**：① 第三方也包装同一份缓存时，旧屏障退役后仍留在登记表里、被下一次删除复用 → 墓碑拦截静默失效（缓存行可能复活）；现在退役即摘出登记表，且复用前先验证包装器确实在岗。② 首次使用抛 `TypeError`（宿主形状变了）时不再把宿主留在"半个包装器"状态下 —— 恢复原方法并上报。③ 安装期（`requireTable()`）抛错时上报，不再只抛一句裸错。
- **兼容页的删除动作可用性判定与服务端对齐**：此前客户端要求一个可选槽位（`projection.delete-native`），把本机可用的删除显示成不可用；同时服务端运行时真正要求的那条硬前提（投影缓存存储可删行）提升为能力表的正式条目 —— 界面说的和服务端做的从此同一份依据。
- **兼容页的宿主身份锚点与 doctor 同一套策略**：此前运行时只按"插件自己解析到的包"上溯，dev 布局下会比出假的「同一份模块」，出现"界面说 ok、doctor 说 SEPARATE COPY"。
- **工作区实体快照写不进去时不再静默**：写入后立刻读回，没写进去就上报（界面上的会话计数可能不刷新）。
- **几处"只落 console"的装配失败现在出现在兼容页**：技能 provider 装配失败、上下文注入通道装配失败 —— 此前界面看起来一切正常。
- **关域拦截有了顺序自检**：关域生效期间连续多轮一条都没拦到时会提示"可能没拦到（也可能是官方那几轮本来没内容）"。

---

## [0.11.0] - 2026-09-20

### 新增

- **访问令牌可以设置、关闭、修改、删除了**：以前只有「设置」一条路，关掉就等于把配置里的令牌删掉、想再开只能重新输一遍。现在关闭只是"暂时不生效"（令牌留着，随时开回来），新增「修改令牌」与「删除令牌」，状态收成一枚四态胶囊 + 一句实况。
- **批量启停可以撤销了**：MCP / 技能 / 记忆三处批量开关做完后出现一条不会自动消失的提示，点「撤销」按操作前的状态逐条写回。
- **兼容页可以清理旧备份了**（页头「刷新」旁边）：每份备份都是整份配置的副本、凭据在里面是明文，而自动剪枝只保证每层最多 5 份。逐层级选删除份数，弹窗内二次确认，只删备份、不碰当前配置。
- **提示词页与子智能体页可以搜了**：按名称 / 描述过滤，无命中说「没有匹配的…」而不是「还没有…」。
- **兼容体检改为真调一次**：归档 / 解档 / 批量 / 永久删除四个原生入口与会话的 detach / announce，以前只查方法名在不在就判可用；现在各用一个不可能命中的哨兵 id 真调一次，能调通才算数。
- **令牌开启、本次启动还没解锁时，输入框会锁住**：对话走的是 DSH 自己的会话通路，不经过插件的 HTTP 门禁 —— 此前令牌配了没填照样能聊、五个域的注入照样进上下文。现在这种情况输入框直接锁住并说明去哪填，解锁后立刻恢复。

### 变更

- **关闭 / 修改 / 删除令牌都要当场重输一次当前令牌**：解锁过**不算** —— 请求头里那份已验过的凭证对这三个销毁方向一律不作数，否则"能打开界面就能关掉保护 / 换掉凭证"。
- **令牌面板拆成「访问令牌」与「令牌管理」两块，表单全部搬进弹窗**：前者只管本次启动 —— 一枚状态胶囊 + 解锁框，解锁错误直接顶替状态句显示；后者只管配置文件 —— 设置/修改、保护开关、删除、清除令牌四行静态清单，行名/说明/按钮同形同位。页面上不再有会展开收起的东西；成功 = 弹窗收起 + 状态行更新，失败 = 弹窗不关、错误显示在弹窗内；红色只出现在确认按钮上。
- **「保护开关」的方向改按"令牌在不在生效"判断**：用环境变量提供令牌的用户以前会把"开着"显示成"开启保护"、找不到关闭入口；配置文件里没有令牌值时「删除令牌」也不再显示（点了是空操作）。「loader 行读不到」的提示也贴到操作区旁 —— 这一态下写配置必被宿主拒绝。
- **同一类名字的判定口径统一了**：Windows 保留设备名与控制字符一律拒绝；场景名不再接受尾随空格或点（界面与宿主此前各有一套校验、已经分叉）。
- **目录链接不再被跟随**：链接进来的记忆以前列得出来、开关也能开，却永远注入不进去。
- **「打开源文件」限定在技能来源与人设目录内**：这个操作把路径交给系统编辑器，以前只校验后缀。
- **六页搜索改为停手约 200ms 才过滤，列表只在数据或搜索词真变了才重算**：此前每敲一个字就把整份列表过滤排序一遍，而页面上任何一次重渲染（勾一次选、开个弹窗、MCP 每 5 秒轮询）都会再算一遍。
- **会话批量删除不再逐条重扫全部会话**（原先 O(N × 全部会话)，现在这批共用开头取的一次快照）；注入通道与记忆列表也不再反复重读同一份索引（按文件 `mtime+size` 指纹缓存，外部改了下一轮照常生效）。
- **导出加了病态上限**：单文件 32 MB / 合计 256 MB，超了明确报错（不再把"全部正文 + 一份 zip"同时堆在内存里）；注定超限的上传在开始读之前就拒掉。
- **没配访问令牌时，查看明文密钥不再要求令牌**：原先一律拒绝，而那时用户根本没有可填的令牌 —— 点「显示密钥」只有一句"缺少访问令牌"，是条死路。有令牌（含"关掉保护"）时照旧要带对的。
- **「注入」设置块不再因为没填令牌而整块消失**：`inject-settings` / `mcpm-settings` 这两个"读改写"op 的**读**不再按写操作门禁（写仍然要令牌）。

### 修复

- **打码的密钥不再被「保存」写坏**：编辑弹窗预填的是打码值，以前保存会把它当真值写回补丁文件，真密钥永久丢失。现在保存时用原值顶替、没有原值就跳过并提示。
- **宿主没配令牌但浏览器里残留旧令牌时，现在有「清除令牌」入口**：以前那一态整行不渲染，残留令牌没有任何出口。
- **别处触发"去填令牌"时，先收起弹窗再聚焦解锁框**：解锁框在弹窗展开期间是禁用的，直接聚焦会被浏览器吞掉。
- **「令牌未验证」横幅不再盖住宿主的设置窗口**：层级降到插件弹窗之下，并加了关闭键；关掉后本次锁态期间不再出现，解锁后再锁照常回来。
- **堵上「清除令牌后仍可对话」的漏洞**：解锁一次后「清除令牌 + 强刷新」，浏览器里已无令牌、对话却畅通 —— pre-step 门禁读的那颗"本次启动已验过"的闩只置位不清零。现在清除令牌会让宿主把闩重新挂上（`token-unaccept`，不进 handlers、模型碰不到；不要求凭证 —— 它只会收紧），必须重新验令牌才能对话；其它标签页内存里的旧令牌同步作废。
- **编辑 MCP 服务器不再把 URL 里的凭据写成占位串**：URL 查询串是另一种打码形态（`?<redacted>`），现在与 env / headers 同一条规则 —— 没有原值可顶替时拒绝整次保存并提示重填。
- **「设置宿主令牌」不再可能把 DSH 写坏到起不来**：`config:` 形状识别不了时会插入重复键，而官方解析器对重复键是抛错；现在识别不了就拒绝改写并说明。
- **记忆索引损坏不再静默清空配置**：以前解析失败被当成"没有索引"，下一次写入就把空索引落盘，一次损坏丢掉全部启用集合与排序。现在坏文件留存、拒绝写入并说明怎么办。
- **开关状态不再莫名回弹或陈旧**：两个开关同时写同一份状态文件会互相抹掉；现在写操作串行执行，并跟随文件的实际改动。
- **锁定场景正在生效时，不再能通过清空启用集合绕开模型侧的写门禁**。
- **MCP「重启」中断后不再把服务器留在停用态**（恢复写在 `finally` 里）。
- **导入文件不再让设置面板变空白**：渲染期抛错把整棵组件树卸载了。
- **详情弹窗不再被"晚到的响应"搅乱**：连点两条时先发的响应后到会覆盖详情，关窗后晚到的响应还会把它重新打开。
- **「显示密钥」真的能显示明文了**：以前客户端又打了一次码，解锁后看到的仍是 `sk-1****`。
- **「令牌没过」的提示统一成一句话**，不再几秒后自己消失，且在任何弹窗里都看得见（此前弹窗里有的什么都不显示、有的没有跳转按钮）。
- **子代理工具注册失败不再静默**：子智能体页顶部会出黄条说清是哪几个工具、为什么。
- **读不到的记忆不再"人间蒸发"**：文件被删 / 权限不足 / 被锁时会连名字与原因出现在记忆页的告警条里。
- **导出会话不再静默覆盖同名文件**（文件名带短哈希区分，撞名如实报 skipped）。
- **命令行体检（`node scripts/doctor.mjs`）补齐 6 项能力**：删除 / 归档 / 列表路由真正依赖的那些以前不在体检范围，现在 15 项全列。
- **键盘可达**：导入拖拽区以前是 `div` + `onClick`（Tab 到不了、回车也打不开），现在是真的按钮；工具页签补上页签语义与 ←/→/Home/End 切换。
- **开了系统的「减少动态效果」后**，开关、拖拽区、注入预算条不再有过渡动画。
- **批量归档部分失败会在结果里说明**；**人设改名改为原子写入**；**新建 / 导入记忆改为先落索引、再落文件**。
- **技能 / 子智能体 / 记忆三页现在会显示场景与锁定横幅了**：服务端标了、界面读不到（技能页的字段被响应信封挡掉、子智能体页刷新时漏搬、记忆页压根没渲染）。记忆页的写控件在场景锁定时也因此**从未被禁用**过，一并修好。
- **场景锁定期间不再显示「改动会同步写进场景档案」那条长提示**：开关都是灰的，那句话没有落点，与锁定横幅并排还互相矛盾。
- **批量启停的撤销条改成琥珀色**（边框 + 提示句 + 淡底）：它是这次批量操作唯一的补救通道，此前与旁边的普通回执长得一样，扫一眼不会注意到。

### 文档

- **README 补上此前缺失的边界告知**：场景锁定的具体冻结范围、会话永久删除不进回收站、导出是可读转录不是完整备份、白名单会并回全部 MCP 工具、密钥在磁盘上始终是明文。

---

## [0.10.0] - 2026-09-18

### 新增

- **「注入实况」显示每个域的采纳统计**：「注入 N 次 · 调用 M 次 · 采纳 K 次」，勾了开关但模型从没伸手一眼可见；节头并标注本进程观测到的工具调用数，区分「模型没用」与「统计没接上」。
- **人设可配「目录注入」（`catalogDepth`）**：控制常驻人设目录注入到哪一层会话（默认只在顶层），不限制子代理继续嵌套。
- **人设子代理支持 `inherit`**：继承本次会话**已完成**的轮次（本轮内委派仍要写全任务）；贴合人设的任务从此一律走 `subagent_manager_run`，官方 `subagent` / `subagent_fork` 只在没人设贴合或需要后台任务时用。
- **人设新增「输出要求」字段（`output:`）**：一行一条硬要求，单独成节写进子代理系统提示词，并约束父代理的 `task` 只给目标与上下文、不规定做法。

### 变更

- **注入框架重排为 markdown 四级结构**：`##` 标题 + 加粗动作句前置 + 补充动作行 + 取代声明，五域同一副骨架；场景记忆与子智能体引导语同步重写（给判据、给优先级、补触发条件），正文重复标题与「已清空」通知的插件前缀一并去掉。
- **提示词注入不再「裸送」**：与其余四域同款框架且整条包进 `<system-reminder>`（正文里的闭合标记会转义），界面显示来源文件与载入状态，模型侧正文带「来源：」行。
- **关掉「技能」或「提示词」的勾选，官方那条注入一起停**（此前只停本插件自己）；其余三域勾选完全生效。
- **子代理会话不再注入场景记忆**（只在顶层注入），子代理上下文收敛为「角色 + 任务」，需要时用 `memory_manager_*` 自取。
- **人设进子代理系统提示词时带角色框**：`# 角色：名` 标题 + 授权/边界一行 + `## 角色定义` 围栏，不含 `description`，人设文件本身不用改。
- **MCP 列表改为全局在前、同级按名排序**，页面、场景档案勾选器与模型侧清单三处同序。
- **人设目录的注入判据定为「深度 < `catalogDepth`」**；「注入实况」两档状态改称「已注入 / 不在本会话注入」，无正文行不再画展开箭头。
- **五个管理工具的描述回指上下文里的注入块**，目录与工具互相指路。
- **全部服务端错误码补齐双语词条**（此前 15 码无词条，英文界面回退中文原文）；目录选择器与技能详情 frontmatter 标签同样改走词典。
- **README 安全段补充**：栅栏降级面、`dir-list` 暴露面、HTTP 状态码以 `body.ok` 为准、裸 API 退出场景不清启用集。
- **文档更正**：人设「默认停用」（此前写成自动启用）、场景接管期间「应用 = 改绑该场景」（此前写会被拒绝）、「四域开关同步档案」更正为三域（并更正 0.9.1 条目同句）、密钥打码字形改为与实现一致。
- **六个管理页的启用项排到列表前面**：MCP / 技能 / 子智能体 / 提示词 / 记忆 / 场景，开着的浮在上面、停用后落回原位（两半内部保持原顺序，不是按名重排；提示词页没有开关，按「生效中」排）。拨开关引起的换位有 180ms 过渡，搜索 / 筛选 / 折叠与轮询刷新引起的位移不做动画，「减少动态效果」下直接落位。

### 修复

- **兼容页的「访问令牌」块重排**（用户裁定 2026-09-18）：块挪到「注入」**上面**（令牌不过时写操作全被拒，是"先解决才能用别的"的一件事）；状态胶囊只放**短状态**（未配置 / 未填写 / 已匹配 / 不匹配）——上一版把整句"与宿主配置的令牌不一致……"塞进胶囊，一行里两种字号交错，是这块"很杂乱很丑"的主因；次要操作改成一行 quiet 文本按钮（与 MCP 页那排「详情 / 编辑 / 重启」同款，三个带边框的按钮挤在一起边框互相打断是另一半原因）；说明从一整段散文改成**三条短句**（用户原话：写简单简洁一点，用户大致了解就行），版式与「工具能用 ≠ 模型知道」那份清单一致。
- **「令牌没过」的提示统一成一套文案，并带跳转按钮**（用户裁定 2026-09-18）：此前同一件事有四种说法（宿主写门禁、明文门禁两条分支、界面错误码词典各写一套，截图里能同时看到三种），用户无法判断是不是同一件事。现在宿主侧只有 `http-fence.ts` 里的 `TOKEN_MSG_NO_HOST` / `TOKEN_MSG_BAD` 两句（`TOKEN_PANEL_HINT` 拼进去，保证每个出口都指路），界面词典与它们逐字相同；识别按**文本相等**而不是猜关键词（"缺少/未配置"这类词出现在别的提示里会误挂按钮）。按钮挂在共享的 `Notice` 组件里一处实现，于是**任意页面**的令牌提示右侧都会出现「填写令牌」——点了切到兼容页并把光标放进输入框（`ToolsSection` 注册切页签、兼容页消费聚焦请求，两条通路都覆盖：已在兼容页 / 刚切过去）。`apply` **之外**的 CompatPage 用不了 `Notice`，按本页写法手工拼同一套。另加一条契约测试钉住"宿主常量与界面词典逐字相同"——不同则按钮静默消失、同一件事又变两种说法。
- **MCP 详情弹窗里也能看到「显示密钥」被拒的提示**（用户指出）：用户是在弹窗里点的按钮，而提示此前只长在弹窗背后 —— 弹窗盖着它，等于没有提示。现在同一份提示面板在页面与弹窗里各渲染一份（`tokenGatePanel()`），弹窗里就贴在「显示密钥」那一节下面。
- **作用域护栏补上"暂时性死区"这一类**（`test/client-scope.test.mjs`）：`detailNode` 里调了写在它下方的 `const tokenGatePanel` —— 首屏不打开弹窗时那条引用不求值，测试全绿，一点「详情」就白屏（本次差点翻车）。判据扩成两条：跨 `apply` 作用域的**组件引用**、以及同函数内**先用后声明 const**（两种引用形态：组件首参与被调函数）。已用真实代码回退验证过判据抓得到（`L2408 用了 tokenGatePanel，但它的声明在 L2430`）。
- **访问令牌的控制面挪进面板，且只对本次运行有效**（用户裁定 2026-09-18 的三条）：① 宿主没配令牌时，「设为宿主密钥」把 `config.token` 写进 profile 的 `cordis.patch.yml`（新增 `mcp/loader-token.ts` 做行级改写：只动 `config:` / `token:` 两行，注释与 `!!js` 守卫一个字不碰；改前照旧自动备份；空 `config:` 会连块一起删）；② 已配令牌时，填入该令牌点「关闭令牌功能」即把配置里的令牌删掉，重启后不再需要令牌 —— 不需要「先保存再关闭」两步（宿主接受输入框里那个值作为凭证），填错一律拒绝，否则"能开 GUI 就能关掉保护"；③ 填写的令牌与宿主**本次进程的标识**（`token-status` 回 `bootId` = pid + 进程启动时刻）绑定存储，DSH 退出后再启动必须重填，同一次运行内刷新页面不必重填（旧的无归属裸令牌键按过期处理并清除）。两个新 op（`token-status` / `token-configure`）都**不进 `handlers` 表**：前者只需请求头与进程状态，后者如此才能保证**没有任何模型工具能关掉访问令牌**。配置改动需要重启 DSH 才生效，界面用「本次填写 = 已匹配」与「待重启」两处状态如实说清，而不是让人以为点了没反应。
- **新增静态护栏：`apply` 外面的组件不许引用 `apply` 里面的组件**（`test/client-scope.test.mjs`）：这类引用只在 state 有值时才求值 —— 首屏正常、一交互就白屏，且不留任何日志（客户端错误不进宿主日志）。本次「兼容页访问令牌」的第一版正是这么翻的（`CompatPage` 声明在 `apply` 之外，却用了 `apply` 内的 `Notice`，填完令牌点保存即白屏）。判据只查 `createElement(名)` / `h(名)` 的首参，所以不误报：一般化的跨作用域检查会被同名局部变量与参数遮蔽，实测在本文件上能报出 30+ 条假阳性。护栏附一条自检用例，拿一段必然违规的代码喂给同一个判据，避免"没报错"其实等于"没在跑"。
- **访问令牌有了与页面无关的固定入口**（兼容页「访问令牌」块，用户裁定）：此前输入框只长在 MCP 页的服务详情弹窗里，而「缺少或错误的访问令牌」这条错误会出现在**任意**页面 —— 在场景页被拒的用户找不到任何地方能填（实测死路）。现在兼容页显示两枚状态（宿主配置有没有 / 本机浏览器这串对不对）、能填能清，错误文案也直接指向那里；宿主侧新增只读的 `token-status`（只回答"配没配 / 这次带的对不对"，**不回令牌本身**），写操作被拒时回 `code: error.token.required`。
- **打码密钥不再被写回补丁文件**（真实事故）：编辑弹窗的密钥框预填的是**打码值**（列表本来就把它打码了），而写入路径原样接受表单内容 —— 于是「打开编辑 → 改个别的字段 → 保存」就把真密钥覆盖成了 `••••••`，且无法找回（本机 `TAVILY_API_KEY` 即如此丢失）。现在保存前按 `src/mcp/secret-guard.ts` 收敛：有原值就用原值顶替（= 这一项没改），没有原值或原值本身已是打码值时**跳过该键**并回一条提示；新增与 JSON 导入走同一套。出口另加结构性断言（`buildInsertBlock`），任何漏过守卫的调用点直接拒绝写入，而不是写一个假值进去。
- **补丁文件里已存在的打码密钥会被主动报出来**：MCP 列表把它列进告警（`服务器名.键名`），说明真值已丢失、要重新填写 —— 此前这种状态完全隐形，用户只会在下次保存时再撞一次同一个结果。
- **「显示密钥」解锁后能看到明文了**：客户端此前在详情面板又打了一次码（保留前 4 个字符 + `****`），导致配好访问令牌、`mcpm-reveal` 返回真值之后，界面上显示的仍是 `sk-1****`；同时打码字形与宿主不一致，详情里会出现 `••••****` 这种双重打码。现在打码的**唯一出处是宿主**，客户端不再加工。
- **编辑弹窗会说明密钥框里是打码值**：明确「直接保存不会改动它们」「要看原文需要点『显示密钥』并填对访问令牌」，避免用户以为真密钥长这样、或者以为保存会改掉它。
- **场景锁定补齐模型侧**：`mcp_manager_add` / `skill_manager_create` / `memory_manager_write` / `prompt_manager_apply` 四个工具此前绕过守卫，锁定期间仍可调用。
- **记忆怎么删都进回收站**：形态转换与改名此前直接删旧文件（bundle 连附件一起），现在先入回收站再删。
- **`mcpm-tools-refresh` 要求令牌**：它会临时启停服务器并写两次补丁，此前漏在写操作门清单外。
- **子代理结果不再混入思考块**；「没有正文」按收尾原因分档说明，不再一律报「无输出」。
- **人设正文与名字里的 `{{…}}` 不再让子代理启动失败**。
- **子会话里调委派工具不再被本插件拦下**（不再向官方传 `maxDepth`，人设列表也不再按深度过滤）。
- **MCP 状态不再把「连不上」报成「可用」**：可用性只认当前真实注册的工具数；曾连上、当前不可用的如实标注。
- **场景里手动关掉的技能目录 / MCP 服务器，退出场景后正常还原**（快照全量记录进场景前状态）。
- **覆盖导入失败自动回滚**；编辑 MCP 服务器保留手写的 `toolCallTimeoutMs`；整台停用时「上次运行时」工具行不再标「已启用」。
- **场景进行中改 MCP serverName 或人设名，退出场景恢复正常还原**；重启等待窗口内的并发启用不再被快照覆盖。
- **记忆描述含独立 `---` 行不再截断**（此类多行描述改用引号标量序列化）。
- **提示词页「应用」失败现在会显示错误**；手工编辑 memories-index.json 的场景描述会触发注入重算。
- **兼容页「注入实况」的说明不再截断、节头不再错位**；技能页页头按钮窄栏自动收档，「全选」不再折行。
- **访问令牌比较改为常量时间**（双侧 sha256 + timingSafeEqual）。
- **测试与开发工具**：补 parseModeState 透传契约断言；client-render 夹具对齐现行响应形状；check-i18n 修复行首键漏对账；`preview-memory-note` / `preview-compat` 修到可跑。

### 移除

- `./projcache` 子路径导出与 `lib/history/projcache.js`（archive-manager 时代的投影缓存替换实现，与现行「不插入竞争 provider」的架构冲突，仓库与文档均无引用）。若某个 profile 曾用 `dsh-plugin-tool-management/projcache` 挂载过它，删掉那一行。

---

## [0.9.1] - 2026-09-17

### 新增

- **兼容页「注入实况」**：显示最近活跃会话里模型**实际看到**的五域文本，并如实分清「在上下文中 / 未投递 / 官方注入 / 已关闭」——勾了开关却没送到时一眼可见。
- **「全选」统一成「全选 ↔ 取消全选」二合一**（不再并列两个按钮），并给技能管理页、记忆管理页、记忆的每个场景卡片补上缺的批量开关。
- **场景未锁定时页面开关照常可用**，改动会同步写进当前场景的档案（MCP / 技能 / 子智能体 / 提示词**三域**的开关同步进档案 —— 记忆域的开关是单一真相源，不经过档案；锁定才冻结）。
- **人设也严格「退出即还原」**：快照记下进场景时全部人设的开与关，退出逐个恢复。
- **技能管理页每个来源（目录）卡片也能批量开关**，点它或点来源开关会顺带把卡片展开。
- **bundle 记忆在列表里显示附件数量**：多一颗「N 个附件」标签（0 个也显示，灰色），悬停给出总量与文件名，点它打开编辑弹窗并跳到附件区。

### 变更

- MCP 页的「全部启用 / 全部停用」移到页头动作栏，会话页的「全选」移到「导出会话」旁。
- 场景横幅与提示词接管提示改口：从「开关已停用、请到档案编辑器里改」改成「改动会同步写进该场景的档案」。
- 技能目录卡片的「移除来源」改为纯图标按钮（悬停说明后果，点击仍弹确认框）。

### 修复

- **退出模式失败、卡在场景里**：项目级技能来源在恢复时解析不到就中断整个退出，现在按 key 前缀解析，且逐行容错、不再因为一行把人困住。
- **场景内打开技能，档案不跟着变**：同步逻辑读错了开关字段，「打开」被当成「关闭」而跳过写盘；现在按操作名判方向，档案没写成时页面也不再只报「已更新」。
- **被同名技能覆盖的副本、结构不完整的技能不再进场景档案**：前者档案与运行时各说各话，后者曾让整个场景进不去。
- **场景档案的 MCP / 技能 / 子智能体段全勾满仍显示「全选」**（没有「取消全选」态）；并列的「全选 + 清空」收敛成一个按钮。
- **按钮文案一变就把整行挤走**：「全选 / 取消全选」与「刷新 / 刷新中…」的宽度改为按较宽的那份固定，八个管理页一致。
- **点刷新没有「刷新中…」**：MCP / 提示词 / 会话三页的刷新从不立起加载标记，现在手动刷新会真的切过去（后台轮询不算），会话页并补上缺失的失败分支。
- **MCP 工具描述的「展开」按钮**：改为按真实溢出显示，真被裁到两行才给按钮。
- **flat 记忆的描述与「已启用」之间空出一段**：窄布局下空标签行不再占位置。

---

## [0.9.0] - 2026-09-16

### 新增

- **五个域各有自己的上下文注入**（用户裁定）：场景和记忆 / MCP / 技能 / 子智能体 / 提示词各发一条消息、轨迹里各占一行；只改一个域只重发那一条，域被关掉或清空时单独发一条「已清空」。
- **提示词与技能目录两个新域**：官方那两条行挂得到就让官方送（标准等），挂不到（极简）才由插件兜底，不会出现两份；场景提示词与 `~/.dsh/AGENTS.md` 在官方语义里是同一件事，合并为一个「提示词」域。
- **兼容页「注入」块**：总开关「极简模式也注入」+ 五个域勾选，设置存 `tool-management/inject-settings.json`。
- **模型侧信息补全**：技能同名标出 `shadowed by <root>`（被覆盖）与 `preferred`（首选），启用被覆盖的副本不再回 OK 而无效；`skill_manager_list` / `prompt_manager_list` 给出源文件路径；MCP 备注进 `mcp_manager_list` 输出（字段 `user-hint`）；未运行的服务器也显示工具描述（按「上次运行时」缓存），超两行默认折叠。
- **AGENTS.md 预设库记住「最近一次应用」**：手改过全局文件也能答出「来自预设 X（此后文件有变）」，不再退化成全列。
- **`npm run sync:profile`**：把构建产物镜像进 DSH profile——profile 里是硬链接拷贝，构建新增的文件不会自动过去。

### 变更

- **注入不再依赖系统提示词段**（用户裁定）：四个域从 `systemPrompt.section()` 改走官方自己用的那条通道（`agent/pre-step` 合成消息）——persona `complete` 的预设（极简）再也压不掉；内容没变不重发，引导语压成一句。
- **域名与顺序**：`记忆` → **场景和记忆**、`全局提示词` → **提示词**；从左到右 **场景和记忆 → MCP → 技能 → 子智能体 → 提示词**（注入块、可达矩阵、注入消息三处一致）。
- **兼容页「预设注入边界」与页脚重写**：页脚区分「可调用 ≠ 已知晓」——工具任何预设下都可调用，但呈现由预设决定（`ptc` 会把工具编成生成 SDK，要在 `run_code` 里调）。
- **破坏性**：四个工具族改名——`agentsmd_*` → `prompt_manager_*`、`rule_manager_*` → `memory_manager_*`、`skill_mcp_manager_*` → `mcp_manager_*`、`subagent_list/run` → `subagent_manager_list/run`；提示词或工作流里点名过旧名的一起改。
- **插件文件全部收进 `tool-management/` 并按域改名**（`agents-md/` → `prompts/`、`agents/` → `subagents/`、`rules-index.json` → `memories-index.json`、`state.json` → `skills-state.json` 等），启动时自动迁移（只搬不删、绝不覆盖）。
- **四个列表工具默认只列生效条目**（各带 `all=true` 看全量，表头给出全量口径）；工具描述精简 37%。
- **MCP 详情页运行状态改成标题右侧的彩色标签**；备注的模型侧前缀统一为「用户提示：」。
- **场景记忆段排版重做**：场景上提到 `##`、条目挂在各自场景下；名称恒为标题、显式描述进括号；bundle 补一行附件目录与文件名；正文文件 `SKILL.md` → `<名>.md`（旧名只读兼容，不迁移）。

### 修复

- **子智能体人设弹窗三个毛病一起修**：候选不自动拉、已启用模式的名单进不去、「关闭」后再「启动」清空勾选；现在自动展开也拉候选，**点行首即可展开 / 收起名单**，右侧按钮只管启用 / 停用，停用后再启用记得勾选。
- **「预设注入边界」三处口径纠正**：子智能体列答「人设目录到不到得了模型」；技能 / 提示词列以官方为准（官方那条行挂着就是绿的）；MCP 列按提示词平面作答（被压制即红框）。
- **每个场景块恒有一行加粗的「场景说明：」**（未填描述给默认句）。
- **场景内的开关统一收归档案**（四域同口径，模型工具同样拒绝）；改档案立即生效、失败如实回报。
- **人设域与 MCP / 技能进场景按档案勾选集全量对齐**（整段未定义 = 全部停用），退出按快照双向还原。
- **场景接管提示词时四条状态共用一套事实**：只有场景绑定的那份可「重新应用」；删除保护扩成引用清单；文件被手改时两页都标出「文件里不是它」。
- **场景退出后 MCP 行「开关已关、进程已停、却仍显示已运行」**：补丁说停用即不可能在运行，显示跟着控制面走。
- **「N 个工具」不再把停用工具算进去**（有停用时显示 `可用/总数`）；工具全被停用的服务器不进段。
- **场景名与记忆名相同会「吃掉」整个场景**：统一为「根下的一级目录恒为场景」（发现 / 定位 / 导入三处）。
- **进场景被关掉的人设，退出没开回来**：快照名单落盘读回时被剥掉，现在原样透传。
- **未启用的场景不再整片标红**：记忆页里「场景未启用」此前与真问题（游离记忆、被同名覆盖）共用同一个错误色，整块红读起来像出了错；现在未启用 = 灰色置灰（标签同色），红色只留给真问题——场景页与档案编辑器里的「未启用」标签同步改灰。
- **小项**：注入边界提示不再点名工具（此前让模型去用刚用过的工具）；`skill_manager_list` 修影子技能误报停用；删 `subagent_manager_list` 空参数 `scene`、修 `create_skill` 老文案。

---

## [0.8.5] - 2026-09-16

### 新增

- 场景级 MCP 服务器备注：场景档案的 MCP 段可为每台勾选的服务器写专属备注，进入该场景时覆盖全局备注（写入 notes.json），退出场景时按快照恢复改动前的备注；未配场景备注的服务器照常使用全局备注。
- 未运行服务器的工具可见性：新增「已知工具」侧车（`dsh-plugin-tool-management-mcp-tools.json`），枚举到 live 工具时按服务器记下名单——未运行的服务器不再永远显示 0 工具，工具勾选框也能列出最后一次见过的工具。从未运行过的服务器可在编辑弹窗点「启动服务器读取工具」：临时启用、轮询等工具注册（≤30s）、记入名单后恢复原启停状态。

### 变更

- 新增技能 / 子智能体 / MCP 一律默认不启动（用户裁定，三域同口径）：新建与导入的技能显式写入停用名单；新建/导入/回收站恢复的人设默认停用；新增 MCP 服务器创建即停用（显式传 `enabled: true` 才创建即启动）。启动与否由用户手动开启。
- 场景档案 MCP「编辑」弹窗重做：行内备注输入框移除，「选工具」改为「编辑」，点击打开固定尺寸次级弹窗——第一栏备注、第二栏工具勾选（含全选/清空），有备注的服务器行显示「有备注」标签。
- 系统提示词注入段文案优化：子智能体人设段措辞改为「可从下面的人设中选用」（此前读起来像"只能调用这几个"），并补充委派机制说明；场景记忆段标题下加固定引导语，让模型明确这是当前场景的常驻参考知识；MCP 备注前缀由「用户备注：」统一为「备注：」。
- peer 依赖去掉 semver 上界（`>=0.1.5-rc.2 <0.2.0-0` → `>=0.1.5-rc.2`）：宿主跨 minor 升级不再被 pnpm peer 校验挡住安装，兼容性改由运行时能力探测兜底。

### 修复

- 历史页「已移除」标签红灰两色统一为灰色：此前红色 = 从未登记、灰色 = 曾登记被移除，颜色区分无实际意义。
- 目录真实存在但没有「重新登记」按钮：`canRegister` 判定从「宿主会话索引命中」放宽为「磁盘目录真实存在」（带 stat 缓存，同一目录只探一次盘），与 `registerWorkspace` 的 realpath 目录校验一致——目录在即可一键重新登记；目录已删除的组显示「⚠ 目录已不存在」提示。
- MCP 状态段缓存不刷新：MCP 工具加载完成（`tools/change`）与进/退/切换场景后均主动重算状态段——此前段停留在「空/旧集合」的缓存值，出现「切换 MCP 后系统提示词没有 MCP 段」「退出场景后备注看似没恢复」的现象。
- 退出场景备注永不回退：rules-index.json 读盘时的快照规范化按白名单解析，漏掉了 `snapshot.mcpNotes`——进入时拍下的恢复名单一读回来就被剥掉，退出模式拿不到名单、备注永远停在场景值。现已透传该字段（并补进入覆盖/退出恢复/未勾选不触碰三条直证回归测试；未勾选服务器的场景备注不再在进入时覆盖其全局备注）。

### 说明

- 人设"文件缺失 = 全部启用"的老数据兼容语义保留：只有首次新建/导入/恢复时物化现状并排除新名；已有技能与人设的启用状态不动。

---

## [0.8.0] - 2026-09-15

### 新增

- 场景锁定：锁定后 MCP / 技能 / 子智能体 / 记忆 / 提示词五个域整体只读；未启动不能上锁，锁定中不能关闭或切换，先解锁再改。
- 子智能体开关：停用的人设不注入上下文、模型不可见（文件不动）；新建 / 导入 / 回收站恢复的人设自动启用，首次升级全部启用。
- 场景联动：启动场景时档案勾选的子智能体自动启用，退出按快照精确停回。
- 子智能体人设目录进入系统提示词：只列名字 + 描述，正文仅在委派时传给子代理。
- MCP 服务器状态与用户备注进入系统提示词：只列当前真正可用的 server，备注作为决策提示带给模型。
- 四个管理域补上导出（技能 / 子智能体 / 提示词 / 记忆）：勾选条目打包 zip 写到指定目录，只读源文件。
- 提示词预设支持描述：只显示在插件界面，不写进 AGENTS.md。

### 变更

- 导出弹窗重做：固定宽高、默认不勾选、条目分组折叠（技能按来源文件夹、记忆按场景、会话按工作区目录），组内同名条目全部展示。
- 导入入口统一：提示词补上与技能页同源的导入弹窗；四个导入弹窗一律用「文件要求」清单。
- 删除场景不再要求先清空：连它下面的全部记忆一起进同一条回收站条目，恢复按原路径整条放回；使用中的场景仍拒绝删除。
- 场景名与人设名可以改了：改名连带目录与档案绑定同步；保留场景、重名、正在使用的场景明确拒绝。
- 场景开关成为唯一入口：打开 = 进入场景（应用档案 + 启用），关闭 = 恢复全局默认；「退出模式」与开关走同一条路径。
- 记忆改为单一真相源 `enabled`：档案弹窗的勾选就是记忆自身的开关；新建与导入的记忆默认不开启。
- 提示词「应用」生效时机口径修正：下一轮对话即生效（宿主每轮重读 AGENTS.md），不再说「新会话生效」。
- 技能回收站弹窗重做：上下两块（目录 / 技能）各占一半、各自滚动，两组的后果差异写进界面；入口移到工具栏。
- MCP 新增默认级别改为全局；「Profile 级」更名「应用级」，级别下拉全局在上。
- 界面统一化：按钮四级语义、列表类弹窗固定尺寸且只允许列表层滚动、工具栏顺序固定、命名统一「新增 / 导入 / 导出 + 页名」；提示词 / 子智能体页补统计行。
- 备注输入框加 200 字上限，备注标签如实说明（会随请求发送给模型）。

### 修复

- 进 / 退模式报 EPERM 且开关要点两次：索引与技能管理状态的原子写遇文件占用（EPERM/EACCES/EBUSY）自动重试。
- 退出场景模式后 MCP 服务器级与技能目录不回滚：快照的服务器级 / 来源级名单在读盘时被剥掉，现在原样保留。
- 列表类弹窗条目多时看不到滚动条：列表组被 flex 收缩后条目直接被裁掉；现在列表层正常滚动并带常驻细滚动条。
- 顶部「当前模式」横幅永远不显示：开关与按钮各写一个状态、互不同步，现在两者恒等。
- 长文本排版错位与截断丢失：标题截断补齐并加 `title` 提示。
- 历史页两个工作区分组标签区分无实际意义，统一为「已移除」。
- 兼容页把 semver 上界当受支持版本展示。
- 清理 CSS 死规则、未定义类名与 i18n 死键；滚动容器改为向上查找。

### 移除

- 「切入此模式」按钮（开关承担）。
- 场景档案的 `memories` 段：老档案里的该字段被忽略，不做自动迁移。
- `memoryAllowed` / `computeMemoriesPlan`（单一真相源后不再需要）。

### 说明

- 新建记忆默认不开启是行为变更：已有记忆的 `enabled` 原样保留，不受影响。
- 老数据里 `mode.scene` 与 `active` 可能不一致：不做一次性迁移，下次拨动任一场景开关时自然对齐。

## [0.7.0] - 2026-09-15

### 新增

- 回收站扩到子智能体 / 场景 / 提示词预设三处：删除都进回收站，可恢复或永久删除（恢复绝不覆盖）。
- 子智能体工具限制改为按 Agent 预设：每个预设一份白/黑名单（互相排斥），运行期按当前预设生效。
- 兼容页「预设注入边界」改版：五列标签（记忆 / 提示词 / 技能 / MCP / 子智能体），绿/红/灰框一眼看出哪个域被预设关掉。

### 变更

- 已移除的来源并入回收站（分目录/技能两部分，目录支持永久删除）。
- 五处回收站排版统一（固定高度容器、行内边距收紧）。
- MCP「整理补丁」重新上线：删多余启停覆盖块（生效状态不变），界面只留一个按钮。

### 修复

- 技能页「移除来源 / 恢复读取」死按钮：补客户端 op 映射 + 补进 writeOps 门禁清单。
- `rules-toggle` 不传 `enabled` 时静默 no-op 却返回成功：改为缺参明确拒绝、不写盘。
- 场景档案「技能集」把来源 key 当技能名显示：改为技能名与来源名分开回传，不再显示 `custom-<hash>`。

### 安全

- 明文密钥改为一律要令牌：「显示密钥」与配置导出没配 `token` 时一律拒绝，不再只靠宿主栅栏。

---

## [0.6.0] - 2026-09-14

### 新增

- 「工具 → 兼容」页（第 8 个页签，只读）：宿主版本、能力可用数、每个动作走原生/适配/不可用、降级项与原因。
- `node scripts/doctor.mjs`：命令行版兼容体检。
- `node scripts/host-deps.mjs --fix/--restore`：把插件依赖 junction 到宿主安装。
- 归档分组可重建：工作区登记被删后按会话目录自动重建，可一键重新登记。
- 恢复归档顺带挂回工作区归属（此前会掉进「未分组」）。
- 场景可绑定提示词预设；切换场景直接改写 `~/.dsh/AGENTS.md`（关掉自动恢复基线）。
- 提示词预设库：新建即可写正文、编辑可改 id（= 目录改名，场景绑定自动跟着改）。
- 正在生效的提示词预设不能删除。
- 场景启用改单选（同时只启用一个，新场景默认不启动）。

### 变更

- 兼容判定换底座：源码文本比对 → 模块实体 + 能力探测；拒绝永远在写入之前。
- 技能来源权限语义修正：默认来源必须读取但技能可删；外部目录可停用/移除但技能只读。
- 用户数据搬出插件目录（归档账本等移入 hub）。
- 归档服务改为独立门面：`cordis.patch.yml` 只插入本插件。
- 弹窗按钮统一（取消/关闭只在右上角）。
- 面板语言跟随宿主；会话页与 AGENTS.md 页接入中英词典。
- AGENTS.md 应用保留 5 代备份。
- 提示词预设 id 口径放宽（中文、空格等可用）。
- `history-retention-set` 拒绝小数；`rules-set-active` 必须显式传参；`mcpm-set-enabled` 停用幂等。
- 写操作门禁：先过宿主栅栏，`token` 作为脚本/局域网逃生门。

### 修复

- 进出场景模式会静默改写技能策略（数据污染）：快照只取生效项，已处于目标状态的不再写。
- 导入技能删进回收站拿不回来：按作用域分岔，用户级来源按 key 重新解析路径。
- 技能回收站显示字面量 `undefined`。
- 面板不随宿主语言切换、两页硬编码中文、词条键写错导致界面露原始键名。
- `subagent_manager_run` 确认门早于参数校验：人设不存在时不再先弹卡。
- 删除链路前置实现检查：在任何破坏性步骤之前校验所需方法。
- 英文界面下兼容页结论条仍是中文：改为客户端按当前语言拼。
- 两处过时文案（AGENTS.md 应用说明、创建技能确认卡落点）。

### 安全

- `mcpm-reveal` / `mcpm-export` 额外要求带 `Origin` 头。
- `history-workspace-register` 补入 WRITE_OPS（此前漏了 token 门禁）。

---

## [0.5.1] - 2026-09-13

### 新增

- 场景档案弹窗新加段默认一项都不勾：记忆段只预勾本场景已启用的，其余三段是空集。

### 变更

- 档案弹窗「记忆」段只列被编辑场景自己的记忆。
- 场景页排版重做：卡片只留名字+描述+动作，数量收进页首「当前模式」条。
- 保留场景「全局」不再出现在场景页与档案弹窗。

---

## [0.5.0] - 2026-09-13

### 新增

- 插件自有技能来源「导入技能」（新建/导入落点，优先级高于 `~/.dsh/skills/`）。
- 「移除来源」= 连目录都不再扫描（文件零改动，可恢复）。
- 场景档案编辑器新增第 4 段「记忆」。
- 人设模型与工具限制收进「高级选项」折叠区。

### 变更

- **破坏性**：插件产生的文件全部收进 `~/.dsh/tool-management/`（旧位置自动搬入）。
- 场景升级为显式记录（带描述与顺序）；空场景合法；根层裸 `.md` 不再注入。
- 斜杠命令全部下线。

### 修复

- 工具页整页白屏（`sceneLabel` 闭包作用域错）。
- 导出静默丢失（导出写在 `apply` 体内）。
- Skills 页被锁死（状态文件缺键被判非法 → 改为缺键自愈）。

---

## [0.2.0] - 2026-09-12

### 新增

- 五个域合并进一个「工具」设置面板：MCP / Skills / AGENTS.md 预设 / History。
- MCP：工具级独立启停、重启只重连不改启停、密钥默认打码、改写补丁前自动 `.bak`（保留 5 份）。
- Skills：接入 `~/.agents` / `~/.codex` / `~/.claude` 与自定义目录；创建 / ZIP 导入 / 回收站；目录后台监听自动刷新。
- AGENTS.md 预设库：多套全局基线，一键应用。
- History：归档会话按项目分组、批量恢复 / 删除、保留期清理；从 Claude Code / Cursor / Codex / 任意文本导入；导出 Markdown / JSONL。

> 0.1.1 / 0.1.2 / 0.1.3 没有独立记录（只有 git tag），此处不拆分它们的差异。
