dsh-prompt-customizer 0.12.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +7 -6
  3. package/README.i18n.yaml +2 -2
  4. package/README.md +7 -6
  5. package/build.mjs +236 -236
  6. package/client/client.js +2226 -1395
  7. package/client/client.js.map +4 -4
  8. package/cordis.patch.yml +11 -11
  9. package/docs/adr/0001-remove-catalog-pool.md +27 -0
  10. package/docs/adr/0002-hide-identity-name-source.md +23 -0
  11. package/docs/adr/0003-destructive-updates-allowed.md +18 -0
  12. package/docs/adr/0004-generalized-filter-model.md +17 -0
  13. package/docs/adr/0005-universal-prompt-takeover.md +109 -0
  14. package/docs/design/prompt-control-consensus.md +103 -0
  15. package/docs/guide.md +25 -11
  16. package/docs/testing/feature-matrix.md +142 -0
  17. package/docs/upgrades/1.0.0-sqlite-breaking.md +26 -0
  18. package/docs/upgrades/1.4.0-generalized-model.md +23 -0
  19. package/docs/upgrades/1.4.1-web-preview-fixes.md +15 -0
  20. package/docs/upgrades/2.0.0-remove-workspace-level.md +16 -0
  21. package/docs/upgrades/2.0.1-context-fixes.md +6 -0
  22. package/docs/upgrades/2.0.10-import-and-skill.md +6 -0
  23. package/docs/upgrades/2.0.11-regression-fixes.md +7 -0
  24. package/docs/upgrades/2.0.12-generative-tool-tests.md +5 -0
  25. package/docs/upgrades/2.0.13-runtime-contract.md +8 -0
  26. package/docs/upgrades/2.0.14-tool-execution-guard.md +5 -0
  27. package/docs/upgrades/2.0.15-mask-pool-regression.md +5 -0
  28. package/docs/upgrades/2.0.16-regression-cleanup.md +6 -0
  29. package/docs/upgrades/2.0.17-unhide-source.md +5 -0
  30. package/docs/upgrades/2.0.18-unhide-cleanup.md +4 -0
  31. package/docs/upgrades/2.0.19-mcp-json-edit.md +4 -0
  32. package/docs/upgrades/2.0.2-generic-context-filter.md +6 -0
  33. package/docs/upgrades/2.0.20-preset-isolation.md +4 -0
  34. package/docs/upgrades/2.0.21-isolation-restore-test.md +4 -0
  35. package/docs/upgrades/2.0.22-source-immutability.md +3 -0
  36. package/docs/upgrades/2.0.3-skill-summary.md +6 -0
  37. package/docs/upgrades/2.0.4-tool-draft.md +5 -0
  38. package/docs/upgrades/2.0.5-tool-catalog-robustness.md +13 -0
  39. package/docs/upgrades/2.0.6-tool-restrict.md +6 -0
  40. package/docs/upgrades/2.0.7-tool-stability.md +5 -0
  41. package/docs/upgrades/2.0.8-catalog-row-stability.md +4 -0
  42. package/docs/upgrades/2.0.9-tool-and-write.md +8 -0
  43. package/docs/upgrades/2.1.0-universal-prompt-takeover.md +41 -0
  44. package/docs/upgrades/2.1.1-tool-shadow-detection.md +48 -0
  45. package/docs/upgrades/2.1.2-tool-catalog-scope.md +55 -0
  46. package/docs/upgrades/README.md +145 -1
  47. package/docs/upgrades/rc2-migration.md +70 -70
  48. package/lib/index.js +5474 -3041
  49. package/lib/index.js.map +4 -4
  50. package/package.json +97 -97
  51. package/scripts/e2e-report.json +221 -0
  52. package/scripts/e2e-terminal.mjs +210 -0
  53. package/scripts/fixtures/rc2-mode.mjs +12 -12
  54. package/scripts/fixtures/rc2-preview.snapshot.json +35 -35
  55. package/scripts/fixtures/rc2-runtime.mjs +85 -85
  56. package/scripts/fixtures/rc2.cordis.yml +31 -31
  57. package/scripts/fixtures/rc2.overlay.yml +9 -9
  58. package/scripts/simulate-rescan.mjs +184 -180
  59. package/scripts/smoke-client.mjs +382 -382
  60. package/scripts/smoke-host.mjs +130 -130
  61. package/scripts/test-skill-manager.mjs +170 -170
  62. package/scripts/verify-apply-all.mjs +64 -0
  63. package/scripts/verify-effect.mjs +153 -0
  64. package/scripts/verify-mcp-edit-ext.mjs +48 -0
  65. package/scripts/verify-mcp-edit.mjs +45 -0
  66. package/scripts/verify-workspace-mcp.mjs +62 -0
@@ -0,0 +1,26 @@
1
+ # 1.0.0 —— 破坏式:自有存储迁移到 SQLite
2
+
3
+ > 破坏式更新:**不再兼容旧版 JSON / YAML 存储**。旧文件原样保留但**不读取、不迁移**。
4
+
5
+ ## 变更
6
+
7
+ - 插件自有存储从多份 `config.yaml` / `catalog.yaml`(以及后续账本)统一为**单文件
8
+ SQLite**:`~/.dsh/prompt-customizer/prompt-customizer.db`(WAL)。
9
+ 使用 Node 内建 `node:sqlite`,**无新增依赖**。
10
+ - 表结构见 `vendor/prompt-customizer/db.js`:
11
+ - `doc(key, json)`:小型整份文档(`config`、工作区 overrides、各 MCP / 技能账本)。
12
+ - `catalog_section` / `catalog_tool`:跨预设「全部提示词 / 全部工具」池,按行规范化存储。
13
+
14
+ > 注:这两张表已在 1.4.1 删除(ADR-0001),当前 DB 只有 `doc(key, json)` 与账本,不存在目录池表。
15
+ - `ledger(domain, scope, name, value)`:按条目读写的名单(预留)。
16
+ - 迁移范围:`config`、`catalog`、新增的**工作区级 override**、MCP `preset-masks` / `tool-disable` / `workspace-close`、技能 `preset-toggles` / `hidden-toggles` **全部进 DB**。宿主配置文件(`cordis.patch.yml` / `.mcp.json`)与技能根下的 `.bundles.json` 仍保持文件(不属于本插件账本)。
17
+ - **两级自定义**:预设级(`overrides[preset]`,只覆盖该预设作用域可见项)→ 工作区级(`workspaceOverrides[cwd]`,作用于该工作区所有会话、可覆盖会话里全部段/工具,且**覆盖预设级**)。面板顶部一个「预设级 / 工作区级」切换,SKILL / MCP / 提示词三 tab 共用。SKILL 工作区级为按 cwd 的技能/技能包开关(`skills/workspace-toggles`,优先级 工作区>预设>全局);MCP 工作区级可整台 server 关闭(`mcp/workspace-close`)与逐工具启停(`mcp/workspace-tool-disable`)。
18
+ - 配置 API 不变(`createConfigStore` 的 `raw / readResolved / writeSection / setField`),
19
+ 但底层由文件换成 DB 的 `doc('config')`。
20
+ - 旧版 `~/.dsh/settings.yaml` 的历史段**不再一次性迁移**;`config.yaml` / `catalog.yaml`
21
+ 不再读写。
22
+
23
+ ## 升级须知
24
+
25
+ - 首次启动会新建空的 `prompt-customizer.db`;用户需**重新配置**(旧定制不迁移)。
26
+ - 想回退:装回 0.x 版本即可(旧文件仍在原位、未被删除)。
@@ -0,0 +1,23 @@
1
+ # 1.4.0 — 通用过滤模型(破坏式)
2
+
3
+ 对齐 DSH `0.2.2-rc.1`。旧配置/快照**不迁移**。
4
+
5
+ > 本文记录 1.4.0 当时的行为,保留作历史材料。其中「工作区级」「预设级只叠通用会话项」已被后续版本修订:工作区级在 2.0.0 移除;会话级段的并入口径在 2.1.0 改为「同预设活动 agent 的真实装配」([ADR-0005](../adr/0005-universal-prompt-takeover.md))。
6
+
7
+ ## 变更
8
+ - 三阶段由唯一 `PHASES` 描述表驱动,字段名/状态映射/工具目录不再三处手抄。
9
+ - 段、工具、运行时上下文身份统一为 `{name, source}`;`source` 为注册层
10
+ `global` / `preset(id)` / `agent(session)` / `executor` / `workspace`。
11
+ - 名单(sections/contexts/tools exclude/add)存结构化 EntryRef;旧 name-only 名单忽略。
12
+ - `replace` 改为阶段化 `replacements: [{name, source?, phase, text}]`,只替换已存在段。
13
+ - 工作区级 = 预设候选超集 + 工作区 override:可隐藏但不可消失。
14
+ - 预设级只叠“通用会话项”(不属于任何已声明预设的 agent 条目),不叠具体会话的专属项。
15
+ - 运行时上下文按阶段独立显隐。
16
+ - `envBlocklist` 可配置、默认空;date/time/weekday 用 Intl 按宿主 locale/TZ。
17
+ - MCP:全局行读 `configEditor.entries()`;热重载用 `ctx.mcpManager.watch()` /
18
+ `mcp-manager/status`;工作区 `.mcp.json` 按 cwd 匹配的 agent scope 挂载;
19
+ 删除第三方探活与自动改写。
20
+ - 中文提示词整功能、SectionView、sectionOps、旧 rescan 文案等死代码全部删除。
21
+
22
+ ## 不再支持
23
+ - 旧 `replace` 字典、旧字符串名单、旧 catalog/目录池、旧中文提示词翻译、旧快照阶段键。
@@ -0,0 +1,15 @@
1
+ # 1.4.1 — Web 预览/编辑运行时修复
2
+
3
+ > **2.1.0 修订([ADR-0005](../adr/0005-universal-prompt-takeover.md))**:本页记录 1.4.1 当时的修复,保留作历史材料。第 1 条「预设预览不再读取当前会话的 agent 作用域条目」已被取代 —— 有同预设活动 agent 时 `/preview` 会并入其真实装配;`sessionOverlay` 字段仍不产生。`catalog_section` / `catalog_tool` 表(第 2 条)已随 ADR-0001 删除,当前 DB 不存在这两张表。
4
+
5
+ ## 修复
6
+ - 预设预览不再读取当前会话的 agent 作用域条目:`/preview` 返回纯预设 `baseSections` / `baseTools` / `baseContexts`,不再产生 `sessionOverlay`。
7
+ - 删除旧 `catalog_section` / `catalog_tool` DDL 与所有旧目录查询,避免旧 SQLite 文件触发 `no such table: catalog_section`。
8
+ - 运行时上下文只返回 `baseContexts`,上下文显隐写回配置时只保留 `{name, source}`,不再混入 `text` / `blocked`。
9
+ - 删除“左栏已并入当前会话”“会话变量尚未绑定”等过期提示。
10
+ - 保留工具阶段名单、提示词屏蔽/替换/注入和三态同步的保存路径。
11
+
12
+ ## 验证
13
+ - `npm run build`、`npm test`(141/141)、host/client smoke 全绿。
14
+ - 真实 web 预设矩阵:standard 24段/54工具/7上下文,ptc 25段/53工具/7上下文,minimal 9段/24工具/1上下文,cordis 24段/56工具/7上下文;三阶段一致。
15
+ - 浏览器实测:预设级引导期屏蔽段、工具可见性、上下文显隐保存后刷新仍保持;工作区级 ptc 的 `tools:ptc-only` 出现在 base 列表。
@@ -0,0 +1,16 @@
1
+ # 2.0.0 — 移除工作区级提示词/工具层
2
+
3
+ ## 破坏式变更
4
+ - 只保留**单预设编辑**:提示词 / 工具定制按 `overrides[presetId]` 保存和生效。
5
+ - 删除工作区级提示词/工具的 UI、查询参数、运行时装配与备份内容。
6
+ - `workspaceOverrides` 字段休眠:保留在 DB 中,不读、不写、不显示、不进备份;恢复备份也不删除既有休眠数据。
7
+ - 单预设编辑器提供导入 / 导出;设置页提供全部预设备份包与手动空 overrides 清理。
8
+ - 工作区概念继续用于 MCP、技能扫描和 cwd,不受影响。
9
+
10
+ ## 代码归档
11
+ - 工作区级相关源码保留在原目录,但不再被入口、路由或构建装配接线;恢复时手动接线。
12
+ - 对应的旧测试移到 `test/archive/`,不进入测试门禁。
13
+
14
+ ## 验证
15
+ - `npm run build`、`npm test`、host/client smoke 全绿。
16
+ - web 面板无“预设级 / 工作区级”切换与工作区选择器;单预设编辑、导入导出、清理按钮可见。
@@ -0,0 +1,6 @@
1
+ # 2.0.1 — 运行时上下文修复
2
+
3
+ - `tool:<name>:depth` 这类工具拥有的运行时上下文:工具不在当前候选目录或当前文本为空时不再显示,消除 `tool:subagent:depth` / `tool:subagent_fork:depth` 的残留项。
4
+ - 运行时上下文显隐改为编辑草稿:勾选只更新“预览含未保存草稿”,点「保存」一次写入;不再点一下立即刷新。
5
+ - `PromptContext` 的 `name/order/text/interpolate/required` 是宿主全部公开字段;插件不伪造 provider 元数据。
6
+ - 三阶段(引导期 / 常驻期 / 压缩受控期)使用同一套宿主 `assemble` 上下文;默认三阶段都返回,只有宿主显式 `suppressRuntimeContext()` 或 persona `includeRuntimeContext:false` 时才抑制可选上下文。
@@ -0,0 +1,6 @@
1
+ # 2.0.10 — 导入原子与技能摘要/健康补齐
2
+
3
+ - 新增 `/api/prompt-customizer/config/batch`:导入预设时 `envBlocklist` 与 `presets` 一次写入,第二次校验失败不会留下半套修改。
4
+ - `kernel-skills` 将已获取的真实技能摘要按 `scope + cwd + name` 持久化,重启后禁用 bundled/virtual 技能仍能回填原摘要。
5
+ - `skill-health` 将 kernel 中不在文件系统根内的 bundled/office/plugin 技能计入 healthy。
6
+ - 2.0.9 起的工作区技能状态与保存写队列继续保留。
@@ -0,0 +1,7 @@
1
+ # 2.0.11 — 回归修复
2
+
3
+ - `/presets` 只返回全局基底状态,不再把 workspace override 混入 preset 级 `skills`;workspace 状态由 `/workspaces` 单独提供。
4
+ - 技能摘要缓存键改为 `preset + cwd + name`(预设不可得时回落会话 id),跨会话恢复 office/plugin 禁用技能摘要。
5
+ - 完整目录保留同名 agent `locked-agent` 遮蔽行,同时不重复 `masked-plugin` 预设行。
6
+ - `skill-health` 路由捕获异常并返回 500,不再出现 unhandled rejection/悬挂响应;mask stub 不再当作真实 bundle 成员。
7
+ - 刷新时 `/config` 失败不再被 preview 成功覆盖。
@@ -0,0 +1,5 @@
1
+ # 2.0.12 — 工具泛例测试
2
+
3
+ - 工具目录测试不再列举具体工具名:运行时生成 15 个 agent 工具,验证全部进入完整目录。
4
+ - 工具可见性测试生成 24 个工具、混合 preset/agent/global 来源,验证全部进入 restrict;并模拟 restrict 后 schemas 缩小,确认 deny 不被撤销。
5
+ - 运行时实现不按工具名分支;`apply_patch` 只是历史上的一个观测样本,已不再作为测试或逻辑依赖。
@@ -0,0 +1,8 @@
1
+ # 2.0.13 — DSH 运行时契约对齐
2
+
3
+ - 工具目录按 `ctx.tools.definitions(scope)` 的注册定义识别来源,`locked-agent` 与 `masked-plugin` 行保留 `keySuffix`,同名遮蔽在 inventory/session 两条路径一致。
4
+ - `latestRootAgent` 改为复用按 `session.header.createdAt` 降序的 `listRootAgents`,不再假设 `agents.roots()[0]` 是最新会话。
5
+ - agent 来源匹配按 `source.kind='agent'` 跨会话匹配,预设配置不再绑定某个 session id。
6
+ - 工具可见性测试按宿主 `restrict` 契约拒绝 agent-local/未知名字;生成式 24 工具用例覆盖任意数量工具。
7
+
8
+ > 2.1.0 沿用:本页第 3 条「agent 来源按 `source.kind` 跨会话匹配」是 [ADR-0005](../adr/0005-universal-prompt-takeover.md) D4(清单身份稳定化)的前提。
@@ -0,0 +1,5 @@
1
+ # 2.0.14 — 工具执行前门禁
2
+
3
+ - 按 DSH `tools/pre-execute` waterfall 增加运行时工具门禁:配置中 exclude 的任意工具在执行前返回 `deny`,覆盖 `restrict` 无法触及的 agent 作用域私有工具。
4
+ - 门禁只按当前 agent 的预设/阶段配置计算,不改变未配置工具;与 `tools.restrict` 的目录遮蔽互补。
5
+ - 测试使用任意工具名和真实 waterfall 决策形状,不依赖 `apply_patch` 等具体名字。
@@ -0,0 +1,5 @@
1
+ # 2.0.15 — 工具屏蔽池恢复
2
+
3
+ - 修复 `catalogTools` 因 base 同名过滤丢掉 `masked-plugin` / `masked-own` 行,导致工具面板「已遮蔽」池为空的问题。
4
+ - 保留 base 的 `hidden/controllable` 行用于阶段反选,同时保留 masked 行供只读池解释;两者按 `state` / `keySuffix` 区分。
5
+ - 新增回归:预设 base 有 `masked-tool`、agent 视图缺失时,inventory 必须返回 `masked-plugin` 行。
@@ -0,0 +1,6 @@
1
+ # 2.0.16 — 回归清理
2
+
3
+ - 屏蔽池逻辑抽成 `src/client/prompt/tool-pool.ts` 的纯函数,新增任意同名 base + masked 状态测试;同名 base 不再吞掉 `masked-plugin` / `masked-own`。
4
+ - `/presets?workspace=` 返回独立的 `workspaceSkills`/`workspaceBundles`,workspace 级视图可显示 workspace 独有技能,不污染 preset 级状态。
5
+ - 技能摘要缓存增加跨 cwd 的宽 key 回退;DSH tool source 用 definition 对象身份识别同名遮蔽。
6
+ - 恢复/重置/导入/清理等配置写入口统一走 `enqueueWrite`;`silentSync` 加序号,旧 workspace 响应不再覆盖新状态。
@@ -0,0 +1,5 @@
1
+ # 2.0.17 — 解除屏蔽来源修复
2
+
3
+ - `sameEntry` 对 `source.kind='agent'` 按 name 匹配,不再要求旧 session id;解除屏蔽时能删除上一次会话写入的 exclude 条目。
4
+ - `tools/pre-execute` 与 `restrict` 使用同一份当前配置;解除后不会再被旧 agent 来源条目继续拒绝。
5
+ - 回归测试覆盖跨 session 的 agent source 解除匹配,以及 `restrict` disposer 释放。
@@ -0,0 +1,4 @@
1
+ # 2.0.18 — 解除屏蔽清理旧条目
2
+
3
+ - `ToolsPane.addToPhase` 在解除隐藏时,先按精确身份删除;若没有精确命中,再按工具名清掉该阶段旧 source 条目。
4
+ - 解决旧 session source id / 旧来源写法导致 UI 已取消勾选、`exclude` 仍残留,`tools/pre-execute` 继续拒绝的问题。
@@ -0,0 +1,4 @@
1
+ # 2.0.19 — MCP JSON 编辑恢复
2
+
3
+ - 恢复 MCP 编辑弹窗的 JSON 入口:全局 profile patch 编辑默认显示 YAML,但 `formatOptions` 不再收窄为仅 YAML;JSON/YAML 都可通过 `/api/triad/mcp-format` 互转后应用。
4
+ - 新增 `mcpEditFormatOptions` 纯函数与回归:global 编辑 `['yaml','json']`,preset/workspace 的 `.mcp.json` 保持 `['json']`,新增模式 `['json','yaml']`。
@@ -0,0 +1,6 @@
1
+ # 2.0.2 — 通用运行时上下文过滤
2
+
3
+ - 不按 `tool:<name>:depth` 或任何插件名做特判。
4
+ - 读取宿主 `PromptContext.required`:`required: true` 的空上下文保留(例如 `working-directory:current`);其它空的可选上下文不进入面板。
5
+ - 读不到宿主 `layers`(测试 / 旧宿主)时不过滤,保持原始上下文。
6
+ - 运行时上下文显隐仍为编辑草稿,点「保存」才落盘。
@@ -0,0 +1,4 @@
1
+ # 2.0.20 — 预设隔离修复
2
+
3
+ - `presetIdOfAgent` 优先读取 DSH 0.2.2 的 `agentPresets.composedPreset(agent.ctx)`,再回落到 `presetForSession` / `presetOfSession`。避免投影尚未刷新时多个活动会话被解析到同一默认预设,导致改一个预设串到其它预设。
4
+ - 新增 `test/preset-prompt-isolation.test.mjs`:两个 agent 的 `presetForSession` 故意返回同一个值,仍必须按 `composedPreset` 装配出各自的提示词。
@@ -0,0 +1,4 @@
1
+ # 2.0.21 — 预设隔离与卸载恢复回归
2
+
3
+ - 新增 `test/preset-isolation-restore.test.mjs`:两个 agent 预设各自屏蔽不同提示词段与工具,验证 A 的段/工具屏蔽不会作用于 B。
4
+ - 同一测试验证插件卸载:释放 assemble 包装、所有 `tools.restrict` 和 `tools/pre-execute` 监听后,A/B 都恢复原始提示词,工具不再被屏蔽。
@@ -0,0 +1,3 @@
1
+ # 2.0.22 — 原文不可变回归
2
+
3
+ - `preset-isolation-restore.test.mjs` 增加断言:插件装配 A/B 后,宿主原始 `sections` 数组及条目必须保持不变,证明插件只返回新的包装结果,不原地修改宿主提示词。
@@ -0,0 +1,6 @@
1
+ # 2.0.3 — 禁用技能卡片保留原摘要
2
+
3
+ - 预设层 / 全局层禁用技能时,闸门 provider 的 `disabled by ...` 桩不再作为 UI 摘要。
4
+ - `kernelSkillViews` 优先用文件系统扫描的真实技能元数据回填;扫描不到的 bundled/virtual 技能从全局层真实 summary 回填。
5
+ - 全局 mask 场景下用进程内真实摘要缓存保留启用时的描述;卡片状态仍是「已停用」,摘要与启用时一致。
6
+ - 运行时上下文过滤/草稿显隐沿用 2.0.2。
@@ -0,0 +1,5 @@
1
+ # 2.0.4 — 工具 Tab 草稿实时反映
2
+
3
+ - `buildPreview` 对 `/preview` POST 的草稿 `patch` 应用与 `/config/apply` 相同的 `overlayPatch`,再计算 `previewCfg`。
4
+ - 勾选工具后,不用保存即可看到左侧行状态、已启用/已停用计数、右侧工具预览变化;点「保存」才落盘。
5
+ - 修复工具 Tab 只有顶部“预览含未保存草稿”变化、列表不更新的问题。
@@ -0,0 +1,13 @@
1
+ # 2.0.5 — 工具目录补扫与健壮性修复
2
+
3
+ > 本文记录 2.0.5 当时的行为。「纯预设装配仍不混入会话提示词」已在 2.1.0 修订:提示词清单与预览并入同预设活动 agent 的真实装配([ADR-0005](../adr/0005-universal-prompt-takeover.md));工具目录仍按纯预设装配计算,本条对工具侧的描述不变。
4
+
5
+ - 预设工具目录新增 `catalogTools`:纯预设装配仍不混入会话提示词,但工具完整目录会扫描当前 agent 作用域,`apply_patch` 等客户端/agent 工具不再显示为消失。
6
+ - `/import`、`/restore`、`/config/set` 写入前按 Config schema 校验;非法 customization 返回 400,不再静默写坏数据。
7
+ - Skills 面板的静默轮询/焦点同步始终使用当前选择的工作区;`/presets?workspace=` 与 `/status?workspace=` 按工作区返回开关口径。
8
+ - 预设应用/删除/导入的多个配置写入由客户端串行队列执行,patch 失败不再继续写 `activePreset`。
9
+ - 上下文三态同步先预检全部阶段,再一次性写 draft,避免部分生效。
10
+ - 技能摘要缓存按 `scope + cwd + name` 隔离,并按宿主 rank 让内核 summary 覆盖同名文件扫描结果。
11
+ - `skill-health` 的 bundle 引用检查纳入 bundled / office / plugin 技能。
12
+ - 面板“刷新”同时重读 `/config`,避免旧编辑基线覆盖外部修改。
13
+ - 完整记录见本文件。
@@ -0,0 +1,6 @@
1
+ # 2.0.6 — 预设工具屏蔽在新会话生效
2
+
3
+ - `tool-visibility` 不再只查 root/global 工具名,也不再排除 `source.kind === 'preset'`。
4
+ - 工具名从 `ctx.tools.schemas(agent)` 读取;restrict 使用 `agent.ctx.tools`。
5
+ - 新会话创建后,预设级 `tools.exclude` 会通过 agent 作用域 restrict 生效;已验证 `pwsh` 在会话工具列表中消失。
6
+ - 同时保留 2.0.5 的工具目录补扫、导入校验、工作区轮询、写入串行化、技能健康与上下文预检修复。
@@ -0,0 +1,5 @@
1
+ # 2.0.7 — 工具屏蔽稳定性与预设隔离
2
+
3
+ - 修复工具屏蔽的“第一次生效、下一次会话事件又撤销”问题:每个 agent 缓存首次可见工具名,后续 sync 不再因 restrict 后的 schemas 缩小而清空 deny。
4
+ - 工具完整目录只读取当前编辑预设对应的活动会话,不再把其它预设会话的 agent 工具混入。
5
+ - 工具名来源改用 `ctx.tools.schemas(agent)`;restrict 使用 `agent.ctx.tools`。
@@ -0,0 +1,4 @@
1
+ # 2.0.8 — 完整目录保留预设隐藏行
2
+
3
+ - `catalogTools` 只追加 agent 独有的工具;同名预设工具保留 `baseTools` 的 `hidden` / `controllable` 行。
4
+ - 避免本插件 restrict 后的隐藏工具在完整目录被误标为 `masked-plugin`,从而导致用户无法在工具 Tab 反选恢复。
@@ -0,0 +1,8 @@
1
+ # 2.0.9 — 工具泛例与写入补齐
2
+
3
+ - 工具目录测试改为多个 agent 工具(apply_patch 只是示例),验证任意 agent 作用域工具都会进入完整目录。
4
+ - `tool-visibility` 增加 preset / agent / global 多来源回归用例。
5
+ - `/status`、`/presets` 按指定 workspace 读取技能视图,修复工作区独有技能在开关表中缺项。
6
+ - 保存按钮也走统一写队列,避免与预设应用/删除/导入并发覆盖。
7
+
8
+ > 2.1.0 说明:本版工具目录 / restrict 口径不变;2.1.0 的会话级合入**只作用于系统提示词段**,工具目录仍按纯预设装配计算([ADR-0005](../adr/0005-universal-prompt-takeover.md) D6)。
@@ -0,0 +1,41 @@
1
+ # 2.1.0 — 全域系统提示词接管
2
+
3
+ 决策见 [ADR-0005](../adr/0005-universal-prompt-takeover.md)。版本 2.1.0,宿主契约不变(`engines.dsh: ^0.2.2-rc.1`)。
4
+
5
+ ## 变更
6
+
7
+ 1. **发现面**:`vendor/prompt-customizer/index.js` 新增 `collectLivePromptView` —— `buildPreview` 在「编辑目标 == 同预设活动 agent」时,复用同一份 `hint`(含草稿 patch、名义阶段)只覆盖 `scope` / `agent`,额外跑一次该 agent 自己 scope 的真实装配。一次 `promptCustomizerBase: true` 装配同时给出预过滤清单(`promptCustomizerBaseView`)与过滤后的正文(`sections`)。
8
+ 2. **清单**:新增 `mergePromptEntries`,把「预设 base ∪ agent base」的 `sections` / `contexts` 按 `{name, source}` 去重(agent 视图优先、同名不同源分列);`sectionOrderMap` 改取「预设链 ∪ agent 链」,否则 agent 段的规范 order 取不到会被排到尾部。
9
+ 3. **预览**:有 live 视图时 `sections` / `text` / `contexts` / `emitted` / `takenOverBy` 都取自 agent 真实装配(过滤后),右栏显示模型此刻真正看到的系统提示词;无活动会话 / 装配抛错时 `warnOnce` 并退回纯预设装配。
10
+ 4. **身份稳定化**:新增 `stableSourceOf`,把清单与预览里的 agent 来源统一收敛成 `{kind:'agent'}`(不带 session id)。`model.js:entryMatches` 已对 `agent ↔ agent` 按 kind 匹配(2.0.13),因此 UI 写入的屏蔽名单、草稿 `entryKey`、运行时候选三者身份一致且跨会话稳定。`buildSessionPreview` 也同步稳定化。
11
+ 5. **隔离**:只用 `liveAgentForPreset(ctx, 编辑预设 id)`;`latestRootAgent` 仍只用于工具 catalog 与无会话兜底,切到别的预设不混入别会话的会话级段。
12
+ 6. **工具侧不动**:`finalTools` / `buildToolUnion` / `catalogTools` 仍按纯预设装配计算,避免推翻 2.0.5–2.0.18 的工具目录回归约束。
13
+ 7. 客户端零逻辑改动(`SectionsPane` 的「会话级」徽标、`phase-ops.ts:phaseRows` 已能渲染这些行);只更新 `locales.ts` 的 `agentScopedHint` 文案。
14
+
15
+ ## 动机(可观察的缺陷)
16
+
17
+ `dsh-hashline-edit@0.2.0` 在 `agent/created` 里用 `agent.ctx.systemPrompt.section()` 注册三段动态 `text` provider:`tool:read` / `tool:apply_patch` / `tool:undo_last_edit`。2.0.22 的 `/inventory` / `/preview` 只跑纯预设装配(live 段恒传空数组),导致:
18
+
19
+ - `tool:undo_last_edit` 在可编辑清单里根本不存在;另两段显示的是宿主同名段的原文;
20
+ - 即使勾了屏蔽,UI 写的 `{name, source:{kind:'global'|'preset'}}` 与运行时候选的 `{kind:'agent'}` 命不中(`entryMatches` 要求 `sourceKey` 相等),模型照样收到插件指引。
21
+
22
+ 运行时过滤链(`applySectionPolicy` + `forceSections` 包装)本已支持 agent 来源,缺的只是「UI 发现 / 枚举」这一环。
23
+
24
+ ## 行为变化(用户可见)
25
+
26
+ - 提示词页左栏新增带「会话级」徽标的行(插件在 agent 作用域注册的段),可独立屏蔽 / 替换 / 排序;同名不同源分两行。
27
+ - 右栏预览从「纯预设装配」变为「同预设活动 agent 的真实系统提示词」,与 `/session` 一致;无活动会话时保持原行为。
28
+ - 屏蔽一个会话级段后,最终系统提示词正文与 `/session.sections` 都不再含它;撤销即恢复。
29
+ - 工具页、三阶段名单、预设隔离、`/config/apply` 写盘格式、配置 schema 全部不变。
30
+
31
+ ## 明确不纳入
32
+
33
+ - 工具 schema 的 `description` / 参数 JSON Schema:走 `GenerateOptions.tools`,不是系统提示词 token(宿主 "tool declarations remain provider-owned")。本插件仍只做工具显隐,不做签名编辑。
34
+ - 不并入系统提示词的 user-role 消息、工具结果、LLM 请求体里另加的文本。
35
+ - 无活动会话时枚举 agent 作用域段:宿主 `systemPrompt.layers` 没有「列出所有作用域」的 API,属于契约边界。
36
+
37
+ ## 验证与反例
38
+
39
+ - 反例:把 `buildPreview` 里 `liveBase.sections` 换回空数组,或让 `stableSourceOf` 返回带 session id 的原始 source,新增用例必须失败。
40
+ - 组合用例:会话级段进入 `/inventory` 且 `source.kind==='agent'` / `scope==='agent'`;同名不同源分两行;写入 `{kind:'agent'}` 屏蔽名单后 `/preview.text` 与 `/session.sections` 都不含该段、撤销恢复;换一个不同段名的插件段同样可枚举(非样例特判);切到别的预设不串台;无活 agent 不抛错;工具目录行数 / 状态与变更前一致。
41
+ - `npm run check`(构建 + 全量单测 + 宿主 / 客户端 smoke)为交付门禁;`docs/testing/feature-matrix.md` 的 H 节 13/13 是 1.x 历史结果,不作为 2.1.0 的当前验证结论。
@@ -0,0 +1,48 @@
1
+ # 2.1.1 — 同名遮蔽探测
2
+
3
+ 版本 2.1.1,宿主契约不变(`engines.dsh: ^0.2.2-rc.1`)。本次只改**工具遮蔽池的探测**,不改 2.1.0 的提示词接管链路(ADR-0005 D6 保持)。
4
+
5
+ ## 缺陷(2.1.0 现状)
6
+
7
+ `buildToolUnion` 用单点判定识别同名遮蔽:
8
+
9
+ ```js
10
+ const shadowed = hasLive && inPreset && inLive && presetDefs !== null && liveDefs !== null
11
+ && presetDefs.get(name) !== liveDefs.get(name)
12
+ ```
13
+
14
+ 它会把以下场景漏掉,导致被插件同名工具顶掉的原生工具不进只读遮蔽池:
15
+
16
+ 1. **`ctx.tools.definitions` 缺席 / 抛错 / 返回的数组里没有该 name**:`presetDefs`/`liveDefs` 为 `null` 或 `get(name)` 为 `undefined`,源码注释也承认「没有 definitions 时无法判定,退化为同名即同一工具」。
17
+ 2. **`inPreset = false`**:宿主 `apply_patch` 是条件注册(`applyPatch: true` 才挂);当前 profile 没挂载原生 `apply_patch` 时,插件 agent 作用域注册的那一份被判成 `agentOnly → locked-agent`(启用列表),不是遮蔽。
18
+ 3. **0.2.1 的 `tools.restrict`**:宿主契约 `ToolRestriction` 只作用于继承层,「scope's OWN registrations stay exempt」(`docs/subsystems/tools.md:165`);插件自己的 `apply_patch` 仍在 agent 视图 → `inLive=true` → `restricted` 不成立,只能靠 `shadowed`,而 `shadowed` 有 1/2 的退化。
19
+ 4. **来源标错**:`emit` 的 `masked-plugin` 行 source 走 `sourceForTool(..., role:'agent')`,同名遮蔽时被判成 `agentSourceOf(agent)` → 被顶掉的明明是继承层原生工具,却落到「会话」分组。
20
+
21
+ ## 决策
22
+
23
+ - **多证据判定**(`buildToolUnion`):只要继承层(global ∪ preset)查得到同名定义 / schema,且 agent 视图里的同名工具与它「不是同一注册」,就判同名遮蔽。证据三条取一:① `definitions` 引用不同(精确,保留);② `definitions` 缺席/缺项时 `description` 不同(宿主 `schemas()` 只暴露 name/description/parameters);③ 只有继承层定义、agent 层另有注册(`inPreset=false`)。**继承层查不到同名定义时绝不误判**——纯 agent 新增(如 `undo_last_edit`)仍是 `locked-agent`。
24
+ - **新状态 `masked-shadow`**(区别于 `masked-plugin` = 被别的插件 restrict):`source` 用 `sourceOverride` 标继承层(`global` / `preset:<id>`),`description` 取被顶掉的原定义,`shadowedBy = { name, source: agentSourceOf(liveAgent) }` 指向顶掉它的插件工具,`keySuffix = 'shadowed'` 保证与 `locked-agent` 行的 `entryKey` 不冲突。
25
+ - **客户端**:`ToolState` / `toolStateOf` / `buildMaskedPool` 纳入 `masked-shadow`;徽标「同名遮蔽」与提示说明「只读、不能反开」;分组按继承层 source 落到「预设 / 全局」而不是「会话」。
26
+ - **口径(推荐)**:继承层查不到同名定义时**不凭空造行**,插件工具只显示「会话级」的 `locked-agent` 行。0.2.0 的 `apply_patch` 在没挂载原生 `apply_patch` 的 profile 上仍不会出现在遮蔽池——这是诚实的语义,不是缺陷。
27
+
28
+ ## 行为变化(用户可见)
29
+
30
+ - 同名遮蔽(如 0.2.0 hashline 的 `read`、0.2.1 的 `apply_patch`)在 `definitions` 退化、profile 未挂载原生、restrict 场景下都会出现在「完整目录 / 已遮蔽(只读)」,徽标「同名遮蔽」,来源落在正确的继承层分组,并带 `shadowedBy`。
31
+ - `masked-plugin`(被别的插件 restrict)、`masked-own`(本插件 MCP 遮蔽)、工具目录可开关项与阶段过滤全部不变。
32
+
33
+ ## 明确不纳入
34
+
35
+ - 不改 `finalTools` / 工具目录数据源(ADR-0005 D6)、不改 `tools.restrict` / 阶段过滤 / `tools/pre-execute`、不改 `buildPreview` 的 `editPresetId` 与 live 提示词视图;不接管工具 schema 的 `description`。
36
+ - 不新增 ADR:本次是探测逻辑增强,决策与边界记在本升级记录即可(ADR-0005 仍是提示词接管的唯一决策文档)。
37
+
38
+ ## 影响模块
39
+
40
+ - `vendor/prompt-customizer/index.js`:`buildToolUnion`(判定 / `emit` 第 6 参 `shadowedBy` / `rankOf`)、`catalogTools` 保留条件、`buildInventory` 透传 `maskedByShadow` / `shadowedBy`。
41
+ - `src/client/prompt/`:`types.ts`(`ToolState` / `BaseTool` / `Inventory.tools`)、`tool-pool.ts`、`locales.ts`(中英徽标与提示)、`ToolsPane.tsx`(`stateBadge`)。
42
+ - 测试:`test/tool-shadow.test.mjs` 断言改为 `masked-shadow`;新增 `test/tool-shadow-universal.test.mjs`(6 组 / 8 场景)。
43
+
44
+ ## 验证与反例
45
+
46
+ - 本机 `npm run check`:全量单测 **170/170 通过**、构建产物重建、宿主 / 客户端 smoke 全绿。
47
+ - 反例:把判定换回单点 `presetDefs.get(name) !== liveDefs.get(name)`,`test/tool-shadow-universal.test.mjs` 的 ①②③ 必须失败;为 `read` 写死特判,用例 ⑤(换名字)必须失败。
48
+ - 组合用例:① `definitions` 缺席;② agent `definitions` 缺该 name;③ `schemas` 未挂载原生但 `definitions` 有(`inPreset=false`);④ 0.2.1 restrict 场景;⑤ 任意工具名(`apply_patch` / `edit` / `plugin:custom`);⑥ 不误判 agent 新增 / 同一注册不拆行 / 跨预设不串台 / 无活动 agent 不抛错 / 工具目录状态不变。
@@ -0,0 +1,55 @@
1
+ # 2.1.2 — 工具目录与真实会话同源
2
+
3
+ 版本 2.1.2,宿主契约不变(`engines.dsh: ^0.2.2-rc.1`)。本次修两个由**实读宿主源码**定位的可观测缺陷,不再靠名字猜。
4
+
5
+ ## 缺陷 1:右栏只显示 38 个工具(真实注入 50)
6
+
7
+ 2.1.0/2.1.1 的 `/preview` 把**提示词段**改成了同预设活动 agent 的真实装配(`ADR-0005 D3`),但**工具目录**仍取 `assembled.tools`——`assembled = ctx.systemPrompt.assemble(hint)`,`hint.scope = presetScopeKey`(预设 scope key)。
8
+
9
+ 宿主源码证据:
10
+ - `packages/core/agent/src/dispatch.ts:174-175`:`assembleContextFor(agent, signal)` 返回 `{ agent, scope: agent }`——**真实会话装配的 scope 是 live Agent 对象自身,不是 preset scope key**。
11
+ - `packages/core/agent-loop/src/agent.ts:292-294`:`toolSet = await ctx.tools.resolve({agent, modelSelection, signal})`,`assembly = await ctx.systemPrompt.assemble({ ...assembleContextFor(this, signal), modelSelection: selection, toolSet })`。
12
+ - `assembly.tools` → `buildRequest(...)` → `GenerateOptions.tools`(`agent.ts:479`、`:656`、`:731-736`;`docs/subsystems/llm-streaming.md:678/722`)。
13
+ - `packages/core/system-prompt/src/index.ts:621` `const scope = context.scope`;`:640-644` providers = global + `scopeLayers`(`chainLayers(scope)`);`:674` `orderTools(...)`;`:687` `return { ...transformed, tools }`。**scope 决定 provider 集合**,所以 agent scope 的可见集 ⊇ preset scope。
14
+
15
+ `ctx.tools.schemas(agent)`(`packages/core/tools/src/index.ts:305-317`)返回该 agent 的注册视图全集(global + 祖先/preset + agent own,shadow 与 restrictions 已生效),**不带 toolSet 时含条件注册工具**,是「不区分 step 的可见工具目录」的正确入口(`docs/subsystems/tools.md:695/708`);`schemas(undefined)` 只是 global view,不能用来代表会话。
16
+
17
+ ⚠️ 不能用 `assemble({scope: agent}).tools` 当主源:PTC 模式下 executor 的 `describe()` 忽略传入定义、只返回 `run_code`(`packages/core/tools/src/tool-executor-ptc/src/index.ts:47-49`),会塌缩;`ctx.tools.schemas(agent)` 不经 executor,不受影响。插件也拿不到 `modelSelection`/`signal`,无法调 `resolve()` 复刻 step 准入,故用不带 toolSet 的注册视图(与 `/session` 的 `visibleTools` 同源)。
18
+
19
+ **改动**:`buildPreview` 新增 `visibleFinalTools`,主源 `toolSchemasOf(ctx, livePromptAgent, true)`,回落 `previewSource.tools` / `finalTools`;右栏 `tools`、`registryTools`、`registryTotal` 全部改用这份。`finalTools`(预设装配)仍保留给 `buildToolUnion` 的 `extraTools` 与排序,遮蔽池结构不变。无活动 agent 时回落纯预设装配。
20
+
21
+ ## 缺陷 2:`apply_patch` 不出现在只读池
22
+
23
+ 用户前提「插件遮蔽了原生 `apply_patch`」不成立,根因在宿主配置:
24
+
25
+ - `packages/fs/tool-fs/src/index.ts:53` `applyPatch: z.boolean().default(false)`;`:101` `if (resolved.applyPatch) applyApplyPatchTool(ctx, sandbox)`——**只有 true 才注册原生定义**。
26
+ - 出厂组合行 `packages/bundle/web-app/presets/standard.patch.yml:27-31`(以及 `ptc/cordis`、`bundle/base/cordis.patch.yml:300`)全是 **`applyPatch: false`**;运行时 `~/.dsh/profiles/web/cordis.patch.yml` 三处 tool-fs 行同样 false。`packages/bundle/web-app/cordis.patch.yml:517-518` 把 host 的 tool-fs 行 `disabled: true`,工具由 preset 层重挂。
27
+ - `docs/tool-catalog.md:33/1178` 与 `docs/upgrade-guide/v0.2.2-alpha.2/fs-observation-policy-default-off/guide.md:14` 声称 Web standard `applyPatch: true`,**与实际产物矛盾**(该目录自己也注明「the catalog sets it so the schema is documented」)。以实装 YAML/运行时 profile 为准。
28
+ - `dsh-hashline-edit@0.2.0` 的 `dsh/index.ts` 明确只把 `read` 当遮蔽对象(「shadow the preset's built-in `read`」);`apply_patch` 由 `registerApplyPatchTool` 在 agent 作用域**首次注册**,`cordis.patch.yml` 不覆盖 tool-fs 行。
29
+
30
+ ⇒ 继承层(global/preset)**不存在**名为 `apply_patch` 的原生定义;插件注册的是**纯新增**(`agentOnly → locked-agent`),不是同名遮蔽,没有「被顶掉的原定义」可取(`definitions(presetScopeKey)` 里也没有,teammate 实读 `agent-preset-registry` 确认 `lease.key` 与 tool-fs 注册 scope 是同一个)。2.1.1 的「不凭空造行」口径因此不显示它——语义上正确,但用户无法在只读池看到这个被插件接管的工具。
31
+
32
+ **改动(口径)**:客户端 `buildMaskedPool` 纳入 `locked-agent`,把这类工具在「完整目录 / 已遮蔽(只读)」里按**「会话级」**如实列出(徽标「会话级」而非「同名遮蔽」,不伪造遮蔽)。`completeCatalogHint` 本来就宣称该池包含「agent 作用域注册」,这次让实现与文案一致。同时修正 `toolAgentScopedHint` 的误导文案:这些工具**可以**按阶段隐藏(`isToggleable` 含 `locked-agent`,靠装配后过滤 `tools` 实现),不是「只能查看」。
33
+
34
+ `read` 这类**真·同名遮蔽**仍是 `masked-shadow`(继承层有 `read` 原定义),与纯新增区分;`test/tool-catalog-scope.test.mjs` ⑤ 钉住这条边界。
35
+
36
+ ## 明确不纳入
37
+
38
+ - 不改 `buildToolUnion` 的判定、`tools.restrict` / 阶段过滤 / `tools/pre-execute`、`editPresetId` 与 live 提示词视图;不接管工具 schema 的 `description`;不新增 ADR(探测/数据源修正记在升级记录即可)。
39
+ - 不按 `docs/tool-catalog.md` 的静态描述硬编码工具列表——宿主配置可覆盖,以运行时 `schemas(agent)` 为准。
40
+
41
+ ## 影响模块
42
+
43
+ - `vendor/prompt-customizer/index.js`:`buildPreview` 的 `visibleFinalTools` / `registryTools` / `registryTotal` / `tools` 字段与注释。
44
+ - `src/client/prompt/`:`tool-pool.ts`(`buildMaskedPool` 纳入 `locked-agent`)、`ToolsPane.tsx`(`stateBadge` 四态)、`locales.ts`(`toolAgentScopedHint` 中英、`completeCatalogHint` 不变)。
45
+ - 测试:反转 5 个旧断言(`rc2-preview` / `session-preview` / `tool-mask-pool` / `universal-prompt-takeover`),新增 `test/tool-catalog-scope.test.mjs`(5 用例)。
46
+
47
+ ## 验证与反例
48
+
49
+ - 本机 `npm run check`:全量单测 **175/175 通过**、构建产物重建、宿主 / 客户端 smoke 全绿。
50
+ - **反例实测**:把主源 `toolSchemasOf(ctx, livePromptAgent, true)` 换回 `toolSchemasOf(ctx, scopeKey, true)`(presetScopeKey),`test/tool-catalog-scope.test.mjs` 的 **①③④ 全红、②⑤ 仍绿**;还原后 175/175。
51
+ - 覆盖:① 右栏 = agent scope 注册视图(含 `apply_patch`/`undo_last_edit`);② 无 live agent 回落纯预设;③ 与 `/session` 同源;④ PTC 塌缩防护(`assemble().tools` 只剩 `run_code` 时仍用 `schemas(agent)`);⑤ 纯新增不伪造 `masked-shadow`、`read` 仍是真同名遮蔽。
52
+
53
+ ## 附:文档与产物矛盾(供后续排查)
54
+
55
+ `docs/tool-catalog.md` 与 `v0.2.2-alpha.2` 升级指南称 Web standard 启用 `applyPatch: true`,但 `0.2.2-rc.1` 的 shipped YAML 与运行时 profile 全是 `false`。若用户在 Agent presets 设置页或 `standard.patch.yml` 把它改成 `true`,继承层就会注册原生 `apply_patch`,插件的注册变为真同名遮蔽(`masked-shadow`)——这与本版逻辑兼容,届时遮蔽池会出现「同名遮蔽」行而不是「会话级」行。
@@ -4,12 +4,156 @@
4
4
 
5
5
  ## 当前兼容版本
6
6
 
7
- - 插件 **0.12.0** 对齐 **DSH 0.2.2-rc.1**(`peerDependencies` / `engines.dsh` 为 `^0.2.2-rc.1`)。
7
+ - 插件 **2.1.2** 对齐 **DSH 0.2.2-rc.1**(`peerDependencies` / `engines.dsh` 为 `^0.2.2-rc.1`);只扩展本插件自己的提示词枚举与工具探测,未改动宿主 API 依赖。
8
+ - 历史起点:**2.0.0** 起对齐该宿主版本。
8
9
  - 0.2.2-rc.1 的完整适配记录见 [dsh-0.2.2-rc1.md](dsh-0.2.2-rc1.md)。
9
10
  - 更早的 0.2.1-rc.2 适配记录见 [rc2-migration.md](rc2-migration.md)。
10
11
 
11
12
  ## 版本历史
12
13
 
14
+ ## 2.1.2:工具目录与真实会话同源
15
+
16
+ - 右栏「模型实际可见的工具目录」改用 `ctx.tools.schemas(agent)`(agent scope 注册视图),与 `/session` 同源;修掉只显示预设层工具(38 vs 50)与 `38 / 39 注册表` 错配。
17
+ - 只读「完整目录 / 已遮蔽」池如实列出插件在 agent 作用域**纯新增**的工具(会话级),不伪造「同名遮蔽」;同时修正「会话级工具只能查看」的误导文案(可按阶段隐藏)。
18
+ - 工具提示词段(`tool:*`)按工具组映射(`jobs` / `pty` / `goal` / `schedule` / `subagent`):工具页显示提示词段入口与只读 description,提示词页显示关联工具与空段;`forceSections` 仅在有实际段策略时覆盖,无定制时保留宿主 `complete` 原样。
19
+ - 完整记录见 [2.1.2-tool-catalog-scope.md](2.1.2-tool-catalog-scope.md)。
20
+
21
+ ## 2.1.1:同名遮蔽探测
22
+
23
+ - 工具遮蔽池不再只靠 `definitions` 对象引用相等来识别同名遮蔽;`definitions` 缺席 / 缺项、profile 未把原生工具挂进 `presetTools` 时都能识别,被顶掉的继承层工具进入只读遮蔽池(`masked-shadow`)。
24
+ - 遮蔽行来源标继承层(global / preset)而不是 agent,并携带 `shadowedBy`;工具目录数据源、阶段过滤与 2.1.0 的提示词接管链路全部不变。
25
+ - 完整记录见 [2.1.1-tool-shadow-detection.md](2.1.1-tool-shadow-detection.md)。
26
+
27
+ ## 2.1.0:全域系统提示词接管
28
+
29
+ - 清单与预览并入「同预设活动 agent」的真实装配,插件在 agent 作用域动态注册的段可被枚举、屏蔽 / 替换 / 注入 / 排序;同名不同源分列,agent 来源按 `{kind:'agent'}` 跨会话稳定匹配。
30
+ - 工具目录仍按纯预设装配计算(两条数据源分离),2.0.x 的工具目录 / restrict / 遮蔽池行为不变。
31
+ - 决策与边界见 [ADR-0005](../adr/0005-universal-prompt-takeover.md),完整记录见 [2.1.0-universal-prompt-takeover.md](2.1.0-universal-prompt-takeover.md)。
32
+
33
+ ## 2.0.22:原文不可变回归
34
+
35
+ - 增加插件不得原地修改宿主 `sections` 的回归断言。
36
+ - 完整记录见 [2.0.22-source-immutability.md](2.0.22-source-immutability.md)。
37
+
38
+ ## 2.0.21:预设隔离与卸载恢复回归
39
+
40
+ - 增加 A/B 预设提示词与工具隔离、卸载后提示词和工具恢复的端到端回归。
41
+ - 完整记录见 [2.0.21-isolation-restore-test.md](2.0.21-isolation-restore-test.md)。
42
+
43
+ ## 2.0.20:预设隔离修复
44
+
45
+ - 活跃 Agent 预设优先按 `composedPreset` 解析,修复预设投影未刷新时的跨预设串台。
46
+ - 完整记录见 [2.0.20-preset-isolation.md](2.0.20-preset-isolation.md)。
47
+
48
+ ## 2.0.19:MCP JSON 编辑恢复
49
+
50
+ - 恢复全局 MCP 编辑的 JSON/YAML 双格式入口,宿主扫描和应用仍支持两种格式。
51
+ - 完整记录见 [2.0.19-mcp-json-edit.md](2.0.19-mcp-json-edit.md)。
52
+
53
+ ## 2.0.18:解除屏蔽清理旧条目
54
+
55
+ - 解除隐藏时兼容旧 source id,按工具名兜底清理阶段 exclude。
56
+ - 完整记录见 [2.0.18-unhide-cleanup.md](2.0.18-unhide-cleanup.md)。
57
+
58
+ ## 2.0.17:解除屏蔽来源修复
59
+
60
+ - 修复解除工具屏蔽后旧 agent source 条目仍命中导致的持续隐藏。
61
+ - 完整记录见 [2.0.17-unhide-source.md](2.0.17-unhide-source.md)。
62
+
63
+ ## 2.0.16:回归清理
64
+
65
+ - 屏蔽池、workspace 技能状态、provider 摘要、同名 tool source、配置写队列和静默轮询竞态补齐。
66
+ - 完整记录见 [2.0.16-regression-cleanup.md](2.0.16-regression-cleanup.md)。
67
+
68
+ ## 2.0.15:工具屏蔽池恢复
69
+
70
+ - 修复完整目录过滤把 `masked-plugin`/`masked-own` 行一并吞掉导致屏蔽池消失。
71
+ - 完整记录见 [2.0.15-mask-pool-regression.md](2.0.15-mask-pool-regression.md)。
72
+
73
+ ## 2.0.14:工具执行前门禁
74
+
75
+ - 通过 `tools/pre-execute` 对 restrict 无法触及的 agent 作用域工具执行运行时拒绝。
76
+ - 完整记录见 [2.0.14-tool-execution-guard.md](2.0.14-tool-execution-guard.md)。
77
+
78
+ ## 2.0.13:DSH 运行时契约对齐
79
+
80
+ - 工具目录/来源/restrict 按 DSH 运行时契约泛化,不绑定具体工具名;同名遮蔽保留 keySuffix。
81
+ - 完整记录见 [2.0.13-runtime-contract.md](2.0.13-runtime-contract.md)。
82
+
83
+ ## 2.0.12:工具泛例测试
84
+
85
+ - 工具目录与 restrict 改为生成式 N 工具测试,不依赖具体工具名。
86
+ - 完整记录见 [2.0.12-generative-tool-tests.md](2.0.12-generative-tool-tests.md)。
87
+
88
+ ## 2.0.11:回归修复
89
+
90
+ - 修复预设工作区状态污染、技能摘要跨会话丢失、同名 agent 遮蔽行、health 路由悬挂与刷新错误覆盖。
91
+ - 完整记录见 [2.0.11-regression-fixes.md](2.0.11-regression-fixes.md)。
92
+
93
+ ## 2.0.10:导入原子与技能摘要/健康补齐
94
+
95
+ - 预设导入改为批量全局写入;技能摘要持久化;健康计数纳入 bundled/office/plugin。
96
+ - 完整记录见 [2.0.10-import-and-skill.md](2.0.10-import-and-skill.md)。
97
+
98
+ ## 2.0.9:工具泛例与写入补齐
99
+
100
+ - 工具目录按所有 agent 作用域工具泛化,不再只覆盖 apply_patch 示例;工作区状态与保存队列补齐。
101
+ - 完整记录见 [2.0.9-tool-and-write.md](2.0.9-tool-and-write.md)。
102
+
103
+ ## 2.0.8:完整目录保留预设隐藏行
104
+
105
+ - 完整目录补扫 agent 工具时不覆盖同名预设工具状态,隐藏工具仍可反选。
106
+ - 完整记录见 [2.0.8-catalog-row-stability.md](2.0.8-catalog-row-stability.md)。
107
+
108
+ ## 2.0.7:工具屏蔽稳定性与预设隔离
109
+
110
+ - 修复 restrict 后下一次 sync 撤销 deny 的回归;工具目录限定同预设活动会话。
111
+ - 完整记录见 [2.0.7-tool-stability.md](2.0.7-tool-stability.md)。
112
+
113
+ ## 2.0.6:预设工具屏蔽在新会话生效
114
+
115
+ - 修复预设工具屏蔽只对部分来源生效/新会话仍注入的问题;完整目录仍包含 agent 作用域工具。
116
+ - 完整记录见 [2.0.6-tool-restrict.md](2.0.6-tool-restrict.md)。
117
+
118
+ ## 2.0.5:工具目录补扫与健壮性修复
119
+
120
+ - 预设工具目录补扫 agent 作用域工具(apply_patch 等);导入/恢复校验、工作区轮询、写入串行化、上下文预检等修复。
121
+ - 完整记录见 [2.0.5-tool-catalog-robustness.md](2.0.5-tool-catalog-robustness.md)。
122
+
123
+ ## 2.0.4:工具 Tab 草稿实时反映
124
+
125
+ - 工具草稿预览与保存共用 `overlayPatch` 语义,未保存勾选即时反映到列表/计数/右侧预览。
126
+ - 完整记录见 [2.0.4-tool-draft.md](2.0.4-tool-draft.md)。
127
+
128
+ ## 2.0.3:禁用技能卡片保留原摘要
129
+
130
+ - 禁用技能只改变状态徽标,摘要/元数据保持启用时内容。
131
+ - 完整记录见 [2.0.3-skill-summary.md](2.0.3-skill-summary.md)。
132
+
133
+ ## 2.0.2:通用运行时上下文过滤
134
+
135
+ - 按宿主 `PromptContext.required` 通用过滤空的可选上下文,不做名字特判。
136
+ - 完整记录见 [2.0.2-generic-context-filter.md](2.0.2-generic-context-filter.md)。
137
+
138
+ ## 2.0.1:运行时上下文残留过滤与草稿显隐
139
+
140
+ - 过滤工具拥有的空 `tool:<name>:depth` 上下文;上下文显隐改为保存时落盘。
141
+ - 完整记录见 [2.0.1-context-fixes.md](2.0.1-context-fixes.md)。
142
+
143
+ ## 2.0.0:破坏式 —— 移除工作区级提示词/工具层
144
+
145
+ - 只保留单预设编辑;工作区级提示词/工具的 UI、路由、运行时装配与备份全部移除。
146
+ - `workspaceOverrides` 字段休眠:数据保留但不读、不写、不显示、不进备份。
147
+ - 单预设导入/导出、全部预设备份包与手动清理空 overrides 留在设置页。
148
+ - 完整记录见 [2.0.0-remove-workspace-level.md](2.0.0-remove-workspace-level.md)。
149
+
150
+ ## 1.0.0:破坏式 —— 存储迁移 SQLite + 预设/工作区两级自定义
151
+
152
+ - **存储统一到单文件 SQLite**(`~/.dsh/prompt-customizer/prompt-customizer.db`,WAL,`node:sqlite`,无外部依赖):`config`、`catalog`、工作区 override、MCP `preset-masks` / `tool-disable` / `workspace-close`、技能 `preset-toggles` / `hidden-toggles` 全部入 DB;宿主配置(`cordis.patch.yml` / `.mcp.json`)与技能根 `.bundles.json` 保持文件。
153
+ - **破坏式**:旧 `config.yaml` / `catalog.yaml` 与各 JSON 账本不再读取、不迁移(文件原样保留),升级后需重新配置。详见 [1.0.0-sqlite-breaking.md](1.0.0-sqlite-breaking.md)。
154
+ - **两级自定义**:新增工作区级 override(`workspaceOverrides[cwd]`),运行时按同名覆盖预设级;`/config/apply` 增 `level=workspace`;面板顶部加「预设级 / 工作区级」切换,工作区级可控制会话里全部段/工具。
155
+ - 段与工具按宿主规范顺序排列;同名工具拆分显示(插件提供=启用锁定、原生=遮蔽池);`assemble` 后按阶段过滤 `assembly.tools`,作用域内注册的工具也能真正隐藏。
156
+
13
157
  ## 0.12.0:适配 DSH 0.2.2-rc.1
14
158
 
15
159
  - `system-prompt/assemble` 不再携带 `tools`:提示词阶段化工具目录、工作区级 MCP 关闭都迁到 agent 作用域 `tools.restrict`;预览 / 清单工具目录改读 `ctx.tools.schemas()`。