dsh-plugin-tool-management 0.19.0 → 0.20.0

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 (47) hide show
  1. package/CHANGELOG.md +868 -798
  2. package/README.md +71 -59
  3. package/README_EN.md +91 -80
  4. package/docs/images/1-EN.png +0 -0
  5. package/docs/images/1.png +0 -0
  6. package/docs/images/2-EN.png +0 -0
  7. package/docs/images/2.png +0 -0
  8. package/docs/images/3-EN.png +0 -0
  9. package/docs/images/3.png +0 -0
  10. package/docs/images/4-EN.png +0 -0
  11. package/docs/images/4.png +0 -0
  12. package/docs/images/5-EN.png +0 -0
  13. package/docs/images/5.png +0 -0
  14. package/docs/images/6-EN.png +0 -0
  15. package/docs/images/6.png +0 -0
  16. package/docs/images/7-EN.png +0 -0
  17. package/docs/images/7.png +0 -0
  18. package/docs/images/8-EN.png +0 -0
  19. package/docs/images/8.png +0 -0
  20. package/docs/images/logo.png +0 -0
  21. package/docs/images/promo-cover-EN.png +0 -0
  22. package/docs/images/promo-cover.png +0 -0
  23. package/docs/update.md +31 -520
  24. package/lib/client.js +8308 -6307
  25. package/lib/hub.js +96 -6
  26. package/lib/index.js +54 -2
  27. package/lib/mcp/manager.js +24 -13
  28. package/lib/mcp/secret-guard.js +2 -2
  29. package/lib/memories/constants.js +9 -2
  30. package/lib/memories/service.js +6 -1
  31. package/lib/op-registry.js +22 -7
  32. package/lib/ops/prompts.js +64 -7
  33. package/lib/ops/sessions.js +62 -7
  34. package/lib/ops/trash-retention.js +55 -0
  35. package/lib/ops/trash.js +62 -3
  36. package/lib/prompts/service.js +191 -25
  37. package/lib/scene-prompt-sync.js +1 -1
  38. package/lib/sessions/history.js +32 -22
  39. package/lib/skills/core.js +68 -2
  40. package/lib/skills/manager-state.js +32 -1
  41. package/lib/skills/service.js +7 -1
  42. package/lib/tools/mcp.js +6 -0
  43. package/lib/tools/prompt.js +14 -2
  44. package/lib/tools/scene.js +146 -25
  45. package/lib/trash-retention.js +256 -0
  46. package/package.json +1 -1
  47. package/lib/mcp/inspect-probe.js +0 -199
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="docs/images/logo.png" width="120" height="120" alt="dsh-plugin-tool-management">
3
+ </p>
4
+
1
5
  # dsh-plugin-tool-management
2
6
 
3
7
  [![npm version](https://img.shields.io/npm/v/dsh-plugin-tool-management?logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-plugin-tool-management)
@@ -15,10 +19,21 @@
15
19
  DeepSeek Harness 的 **MCP、技能、场景、记忆、子智能体、提示词与归档会话**管理插件。八个页签:场景 / MCP / 技能 / 子智能体 / 提示词 / 记忆 / 会话 / 兼容。
16
20
 
17
21
  ```sh
18
- dsh plugin --profile web add dsh-plugin-tool-management@latest
22
+ dsh plugin --profile web add dsh-plugin-tool-management@latest # web 版
23
+ dsh plugin --profile desktop add dsh-plugin-tool-management@latest # 桌面版
19
24
  ```
20
25
 
21
- 装完硬刷新浏览器(Cmd/Ctrl+Shift+R),设置 → **工具**。插件只写自己的文件,不改技能源文件;重启与升级后配置都在。
26
+ 装完 web 版硬刷新浏览器(Cmd/Ctrl+Shift+R),桌面版重启应用,设置 → **工具**。插件只写自己的文件,不改技能源文件;重启与升级后配置都在。
27
+
28
+ ---
29
+
30
+ ## 演示视频
31
+
32
+ <video controls src="https://github.com/user-attachments/assets/3bed27b0-2d73-4e89-b1dd-f2b1cbd6eaca"></video>
33
+
34
+ 画面里每一个界面都是真机截图,没有重画的 UI,也没有伪造控件。
35
+
36
+ 背景音乐:Kevin MacLeod「Limit 70」,[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)。
22
37
 
23
38
  ---
24
39
 
@@ -39,32 +54,34 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
39
54
 
40
55
  一句话:**把「工作 / 写作 / 编程」各配成一套场景,点一下整套切换;插件管的东西,模型都看得见。**
41
56
 
42
- | 亮点 | 说明 |
43
- | --------------------------- | ----------------------------------------------------------------------------------------- |
44
- | 一键换场景 | 每个场景各配一套 MCP / 技能 / 人设 / 记忆,进入时整套切换、退出时还原;模型也能按你说的切 |
45
- | 不离开对话就能管 | 对话里打 `/` 出「工具」段,启停各域条目,点一下就生效 |
46
- | 记忆自动送到模型眼前 | 每个场景下写几段 `.md` 就是它的资料库,正文自动进上下文 |
47
- | 给 MCP 服务器写备注 | 写进备注的话模型每轮都看得到,会照做 |
48
- | 单个工具也能关 | 一台服务器里可以只停某个工具,模型看不见也调不到 |
49
- | 技能状况一眼看穿 | 哪份在生效标「首选」,被同名覆盖的标出来源 |
50
- | 子智能体 = 一个文件一个角色 | 写一份角色说明就能派活;跑完只回结果、不占你的会话记录 |
51
- | 提示词备好几套 | `AGENTS.md` 可以存多份、一键切换;场景可以各自绑一份 |
52
- | 会话不再丢 | 归档按项目分组、能搜、能批量恢复;Claude Code / Cursor / Codex 的记录能导进来 |
53
- | 模型一定看得见 | 六个域各注入一条上下文,内容没变不重发 |
54
- | 锁住就不怕手滑 | 场景可以上锁:五个域的增删改整体只读 |
55
- | 删了能找回 | 技能 / 记忆 / 人设 / 提示词 / 场景的删除都进回收站(会话永久删除除外) |
56
- | 安全、不添乱 | 只写自己的文件;密钥默认打码、看明文要令牌 |
57
+ | 亮点 | 说明 |
58
+ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
59
+ | 一键换场景 | 每个场景各配一套 MCP / 技能 / 人设 / 记忆,进入时整套切换、退出时还原;模型也能按你说的切 |
60
+ | 不离开对话就能管 | 对话里打 `/` 出「工具」段,启停各域条目,点一下就生效 |
61
+ | 记忆自动送到模型眼前 | 每个场景下写几段 `.md` 就是它的资料库,正文自动进上下文 |
62
+ | 给 MCP 服务器写备注 | 写进备注的话模型每轮都看得到,会照做 |
63
+ | 单个工具也能关 | 一台服务器里可以只停某个工具,模型看不见也调不到 |
64
+ | 技能状况一眼看穿 | 哪份在生效标「首选」,被同名覆盖的标出来源 |
65
+ | 子智能体 = 一个文件一个角色 | 写一份角色说明就能派活;跑完只回结果、不占你的会话记录 |
66
+ | 提示词备好几套 | `AGENTS.md` 可以存多份、一键切换;场景可以各自绑一份,也可以选「无」(不绑) |
67
+ | 会话不再丢 | 归档按项目分组、能搜、能批量恢复;Claude Code / Cursor / Codex 的记录能导进来 |
68
+ | 模型一定看得见 | 六个域各注入一条上下文,内容没变不重发 |
69
+ | 锁住就不怕手滑 | 场景可以上锁:五个域的增删改整体只读 |
70
+ | 删了能找回 | 技能 / 记忆 / 人设 / 提示词 / 场景的删除都进回收站(会话永久删除除外);可勾选批量永久删除,也可设保留期让它自动清(默认永久保留) |
71
+ | 安全、不添乱 | 只写自己的文件;密钥默认打码、看明文要令牌 |
57
72
 
58
73
  ## 快速开始
59
74
 
60
- 前置:DSH 已安装(`dsh web` 可运行),Node.js ≥ 18。
75
+ 前置:DSH 已安装(`dsh web` 可运行),Node.js ≥ 18。命令按端选:`--profile web` 装 web 版,`--profile desktop` 装桌面版。桌面版的 profile 由 DSH Desktop 自己初始化 —— 先打开过一次应用,执行命令前把它完全退出。
61
76
 
62
77
  ```sh
63
- dsh plugin --profile web add dsh-plugin-tool-management@latest # 安装 / 更新
64
- dsh plugin --profile web remove dsh-plugin-tool-management # 卸载
78
+ dsh plugin --profile web add dsh-plugin-tool-management@latest # web 版 · 安装 / 更新
79
+ dsh plugin --profile web remove dsh-plugin-tool-management # web 版 · 卸载
80
+ dsh plugin --profile desktop add dsh-plugin-tool-management@latest # 桌面版 · 安装 / 更新
81
+ dsh plugin --profile desktop remove dsh-plugin-tool-management # 桌面版 · 卸载
65
82
  ```
66
83
 
67
- 装完硬刷新浏览器,设置 → **工具** 出现八栏即成功。界面改动即时生效,宿主侧改动需重启 `dsh web`。
84
+ 装完 web 版硬刷新浏览器、桌面版重启应用,设置 → **工具** 出现八栏即成功。界面改动即时生效,宿主侧改动需重启(web 重启 `dsh web`,桌面重启桌面应用)。
68
85
 
69
86
  也可以让模型代劳:
70
87
 
@@ -74,47 +91,43 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
74
91
  装完提醒我硬刷新浏览器。
75
92
  ```
76
93
 
94
+ 桌面版把 `web` 换成 `desktop`,最后一句改成「装完提醒我重启桌面应用」。
95
+
77
96
  ## 功能
78
97
 
79
98
  ### 斜杠命令(在对话里直接管)
80
99
 
81
100
  - **打 `/` 出「工具」段**:六行 —— 场景 / 技能 / MCP 服务器 / 子智能体 / 提示词 / 记忆。点一行进这一域,再点一条直接生效;点完菜单不关。
82
101
  - **状态看得见**:启用项绿勾、停用项空框,右侧灰字是条目备注,域行右侧给当前态摘要。
83
- - **条目多也不挡路**:每域全量列出、面板自己滚;技能按来源目录分组、记忆按场景分组,已启用的排前面。每个外部技能目录另给一行,点它就是启停整个来源。
102
+ - **条目多也不挡路**:每域全量列出、面板自己滚;技能按来源目录分组、记忆按场景分组,已启用的排前面。
103
+ - **提示词两类都在**:全局那组选哪一份写进 `AGENTS.md`(单选),快捷那组是启停,点一行把存好的话贴进输入框、不自动发送。
84
104
  - **只放可逆动作**:进场景与各类启停;增删改、导入导出、改配置仍各归各页。
85
- - **走宿主官方通道**:用 DSH 的输入触发器接口注册,不 patch 官方包;「兼容 → 注入」里两段各一颗开关。
86
- - **「工具 › 提示词」两类都在**:全局那组选哪一份写进 `AGENTS.md`(单选),快捷那组是启停。
87
- - **「快捷提示词」另起一段**:只列开着的,点一行把存好的话贴进输入框,不自动发送。
105
+ - **走宿主官方通道**:用 DSH 的输入触发器接口注册,不 patch 官方包。
88
106
 
89
107
  ### 场景与记忆
90
108
 
91
109
  - **场景 = 分组,记忆 = `.md` 文件**:`memories/<场景>/<名>.md`,整篇正文自动注入上下文,文件名支持中文。
92
110
  - **「启用」与「进入」是两件事**:启用决定注入按哪个场景走(单选,全关 = 只注入「全局」与 `_shared`);进入才按档案整套切换 MCP / 技能 / 人设,并把绑定的提示词写进 `AGENTS.md`。
93
- - **场景档案**:每个场景搭配 MCP 工具集 / 技能集 / 子智能体 / 记忆;勾的启用、没勾的停用,整段没建 = 该域全部停用,退出时按进场景前的快照还原。
111
+ - **场景档案**:每个场景搭配 MCP 工具集与场景级备注 / 技能集 / 子智能体 / 快捷提示词 / 模型工具表方案,外加一份绑定的全局提示词预设;段内勾的启用、没勾的停用,整段没建 = 该域全部停用(快捷提示词例外:没绑 = 进入时不碰),退出时按进场景前的快照还原。
112
+ - **每格另给一档「无」**:这一域本场景不碰(提示词那格 = 进出都保持原样,快捷提示词 = 一条都不启用)。它区别于「保持现状」——那一档才是真的不动。
94
113
  - **场景锁定**:锁定后 MCP / 技能 / 子智能体 / 记忆 / 提示词五域的增删改整体只读。
95
114
  - **删除场景 = 连记忆一起删**:场景记录、档案与全部记忆进同一条回收站条目,恢复时整条放回;使用中的场景拒绝删除。
96
- - **导入导出**:`.md` / `.zip`(目录名 = 场景,bundle 带附件),同名跳过绝不覆盖。
97
- - **注入预算**:默认 128 KiB,放不下的跳过并列出清单。
98
- - **子代理会话不另设开关**:注入哪几个域由同一张表决定,但场景与记忆只在顶层注入。
115
+ - **导入导出**:`.md` / `.zip`(目录名 = 场景,bundle 带附件),同名跳过绝不覆盖;注入预算默认 128 KiB,放不下的跳过并列出清单。
99
116
 
100
117
  ### 子智能体
101
118
 
102
- - **一个文件一个人设**:`subagents/<人设>.md`,frontmatter 全可选;`output:` 一行一条写"产出必须长什么样"。
103
- - **人设正文带一层角色框架**:正文原样用在 `# Persona: <名字>` 标题下,附授权与边界各一行;人设文件本身不用改。
119
+ - **一个文件一个人设**:`subagents/<人设>.md`,frontmatter 全可选;`output:` 一行一条写"产出必须长什么样"。正文原样用在 `# Persona: <名字>` 标题下,人设文件本身不用改。
104
120
  - **委派**:`subagent_manager_run` 带人设运行、只回最终结果、不进 History;默认新起独立会话,`inherit: true` 继承本次会话已完成的轮次。
105
121
  - **启停与目录**:停用的人设不注入、模型不可见(文件不动);新建 / 导入 / 恢复默认停用。人设目录只列名字 + 描述。
106
- - **目录注入深度(`catalogDepth`)**:默认 `1` = 只在顶层会话注入目录,`99` = 任何深度都注入;不限制嵌套深度。
107
- - **工具限制按 Agent 预设**:每个预设一份白 / 黑名单(互斥),候选只列该预设自己的工具,分「插件工具 / 官方工具 / 其他工具」三段;白名单会并回当前所有 `mcp__*` 工具(只勾 `read` 拦不住 MCP 里的 shell),保留名 `run_code` 会被剔除并注明。
108
- - **模型与来源**:都从宿主 LLM 目录里选(选定来源后模型只列该来源的);留空 = 继承主会话。
109
- - **思考强度**:档位由所选模型声明;指定了模型时留空 = 用该模型的默认档位。
122
+ - **工具限制按 Agent 预设**:每个预设一份白 / 黑名单(互斥),候选只列该预设自己的工具,分「插件工具 / 官方工具 / 其他工具」三段。
123
+ - **模型与来源**:都从宿主 LLM 目录里选(选定来源后模型只列该来源的);留空 = 继承主会话;思考强度档位由所选模型声明。
110
124
 
111
125
  ### MCP 服务
112
126
 
113
127
  - **增删改查、即改即生效**:写入 `cordis.patch.yml`,改前自动备份。级别分「全局 / 应用级」,新增默认全局。
114
128
  - **工具级开关**:单个工具可独立停用(模型看不见也调不到),整台支持批量。
115
129
  - **停着也能看清单**:没在跑的服务器仍显示上次见过的工具名与描述(标「上次运行时」);从没跑过的可以一键启动读取。
116
- - **备注**:每台服务器可写一句给模型的提示,随状态段一起注入;曾经连上过、现在连不上的会列出来并标注。
117
- - **密钥打码**:默认把凭据整值打码(`$VAR`、`!!js` 这类间接引用不动),看明文要令牌;打码值不会被写回配置。
130
+ - **备注与密钥**:每台服务器可写一句给模型的提示,随状态段一起注入;凭据默认整值打码(`$VAR`、`!!js` 这类间接引用不动),看明文要令牌。
118
131
  - **迁移与备份**:跨项目级 / 全局迁移失败自动回滚;支持 JSON 导出导入。
119
132
 
120
133
  ### 技能
@@ -127,20 +140,17 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
127
140
 
128
141
  ### 提示词预设
129
142
 
130
- - 多套 `~/.dsh/AGENTS.md` 基线一键应用(下一轮对话生效),保留 5 代备份。
131
- - **记得「最近一次应用的是哪份」**:就算你手改过 `AGENTS.md`,也答得出来源。
132
- - 每条预设可写一句"这份是干什么的",只存在插件侧、不进 `AGENTS.md`。
133
- - **被引用的不能删**(场景绑定 / 当前内容 / 退出场景要恢复的那一份),删除进回收站。
134
- - **生效与否就是卡片左边那颗开关**:点亮 = 把这一份写进 `AGENTS.md`;基线是单选,所以关不掉 —— 想换一份就点亮另一份。
135
- - 场景接管期间点亮另一份 = 把该场景改绑到那一份;锁定时拒绝。
136
- - **快捷提示词**(同页第二段):存一段常用的话,`/` 里点一下就原样贴进输入框;它不注入上下文,卡片上那颗开关只管这条在 `/` 里出不出现。
137
- - **场景可以绑定一组快捷提示词**:进入本场景只启用勾的那几条、其余停用,退出按进场景前的开关还原。
138
- - **两组各自是一张可折叠卡片**(点卡片头收起 / 展开);快捷那组卡片头有「全选 / 取消全选」,全局那组没有 —— 那一档是单选。
143
+ - 多套 `~/.dsh/AGENTS.md` 基线一键应用(下一轮对话生效),保留 5 代备份;每条预设可写一句"这份是干什么的",只存在插件侧、不进 `AGENTS.md`;「最近一次应用的是哪份」也答得出来(手改过也认得出源)。
144
+ - **生效与否就是卡片左边那颗开关**:点亮 = 把这一份写进 `AGENTS.md`;再点一下 = **取消应用**。点之前弹窗会说清是哪种(删文件时按钮变红),点完还给一条回执。
145
+ - **「取消应用」一步回到链起点**,不是只退一步:这一串应用 / 取消往复开始之前是什么样就恢复成什么样(起点没有 `AGENTS.md` 就把文件删掉);中途每一份内容都留在 `__last-applied__/AGENTS.md.bak-*`(保留 5 代),随时能再应用回来。
146
+ - **两类不能直接删**:**被场景绑定的**、以及**当前应用的那一份**(后者先点开关「取消应用」就能删);首次打开时自动生成的那份没「应用」过,可以直接删。删除一律进回收站。
147
+ - **快捷提示词**(同页第二段):存一段常用的话,`/` 里点一下就原样贴进输入框;场景可以绑定一组(进入只启用勾的那几条、退出按进场景前还原,也可选「无」)。
139
148
 
140
149
  ### 历史会话
141
150
 
142
151
  - 按项目分组、搜索、批量恢复 / 永久删除、保留期自动清理;工作区登记被删后可一键重新登记。
143
- - 导入 Claude Code / Cursor / Codex / 任意文本(工作区可挑、可浏览、可给路径);导出 Markdown / JSONL,分三档累进:仅正文 → 正文 + 工具 → 正文 + 工具 + 思考。**导出是转录,不是备份** —— 要留全量请用「归档」。
152
+ - 导入 Claude Code / Cursor / Codex / 任意文本(工作区可挑、可浏览、可给路径)。
153
+ - 导出 Markdown / JSONL,分三档累进:仅正文 → 正文 + 工具 → 正文 + 工具 + 思考。**导出是转录,不是备份** —— 要留全量请用「归档」。
144
154
 
145
155
  ### 宿主兼容
146
156
 
@@ -160,9 +170,9 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
160
170
  | 技能策略 / 自定义目录 | `~/.dsh/tool-management/skills-state.json` |
161
171
  | 技能 / 记忆 / 人设 / 预设 | `~/.dsh/tool-management/{skills,memories,subagents,prompts}/` |
162
172
  | 子智能体启停 | `~/.dsh/tool-management/subagents-index.json` |
163
- | 回收站(技能 / 人设 / 预设 / 场景) | `~/.dsh/tool-management/trash/{skills,subagents,prompts,scenes}-trash/` |
164
- | 记忆回收站 | `~/.dsh/tool-management/memories-trash/`(在 hub 根下,不在 `trash/` 里) |
173
+ | 回收站(技能 / 记忆 / 人设 / 预设 / 场景) | `~/.dsh/tool-management/trash/<域>-trash/`(每类一个目录) |
165
174
  | 归档账本 / 保留期 | `~/.dsh/tool-management/history-*.json` |
175
+ | 回收站保留期 | `~/.dsh/tool-management/trash-retention.json`(`0` = 永久保留) |
166
176
  | 记忆索引 / 场景 / 档案 | `~/.dsh/tool-management/memories-index.json` |
167
177
  | MCP 侧车(停用表 / 已知工具 / 备注 / 设置) | `~/.dsh/tool-management/mcp-*.json` |
168
178
  | 注入设置(六个域开关) | `~/.dsh/tool-management/inject-settings.json` |
@@ -172,6 +182,8 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
172
182
 
173
183
  **插件安装目录里不存用户数据**(`dsh plugin update` 会整体替换该目录)。备份按**每份 patch 文件各留 5 份**(全局与每个 profile 各自计),一次批量操作就可能把某层的 5 个槽位吃掉。
174
184
 
185
+ 六类回收站各占 `trash/` 下一个目录:`{skills,memories,subagents,prompts,scenes,quick-prompts}-trash/`。记忆那一类 2026-10-10 起从 hub 根并入 `trash/`,老数据由启动迁移自动搬过去。
186
+
175
187
  ## 配置与安全
176
188
 
177
189
  | 字段 | 说明 |
@@ -191,16 +203,16 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
191
203
 
192
204
  ## 常见问题
193
205
 
194
- | 现象 | 解决 |
195
- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
196
- | 装完没有页面 | 硬刷新;不行重启 DSH。 |
197
- | 重复 MCP 页签 | 删 `cordis.patch.yml` 里的旧 loader 行后重启。 |
198
- | 改坏配置 DSH 起不来 | 从 `~/.dsh/tool-management/backups/` 取最近的 `cordis.patch.yml.<层级>.bak-<时间戳>` 覆盖回去(每份 patch 各留 5 份)。 |
199
- | 升级 DSH 后动作不可用 | 设置 → 工具 → **兼容** 看原因;`doctor.mjs` → `host-deps.mjs --fix`。 |
200
- | 模型调不到某条工具 | 「兼容」页的**模型工具表**看它是不是被关了(出厂默认关着 15 条);面板和脚本不受影响。 |
201
- | `approval=never` 还要确认吗 | 不弹卡,直接放行并记日志;想问回来切回「工作区内修改」。 |
202
- | `subagent_manager_run` 报 provider 不可用 | 对应 provider 没注册:`spawn`(默认)/ `fork`(`inherit`)分别挂 `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` 后重启。 |
203
- | 场景绑了 A 人设,官方 `subagent` 还在跑别的 | 官方那两个是宿主的工具,本插件管不到;贴合人设的走 `subagent_manager_run`,官方只在没有人设贴合或要后台跑时用。 |
206
+ | 现象 | 解决 |
207
+ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
208
+ | 装完没有页面 | 硬刷新;不行重启 DSH。 |
209
+ | 重复 MCP 页签 | 删 `cordis.patch.yml` 里的旧 loader 行后重启。 |
210
+ | 改坏配置 DSH 起不来 | 从 `~/.dsh/tool-management/backups/` 取最近的 `cordis.patch.yml.<层级>.bak-<时间戳>` 覆盖回去(每份 patch 各留 5 份)。 |
211
+ | 升级 DSH 后动作不可用 | 设置 → 工具 → **兼容** 看原因;`doctor.mjs` → `host-deps.mjs --fix`。 |
212
+ | 模型调不到某条工具 | 「兼容」页的**模型工具表**看它是不是被关了(出厂默认关着 15 条);面板和脚本不受影响。 |
213
+ | `approval=never` 还要确认吗 | 不弹卡,直接放行并记日志;想问回来切回「工作区内修改」。 |
214
+ | `subagent_manager_run` 报 provider 不可用 | 对应 provider 没注册:`spawn`(默认)/ `fork`(`inherit`)分别挂 `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` 后重启。 |
215
+ | 场景绑了 A 人设,官方 `subagent` 还在跑别的 | 官方那两个是宿主的工具,本插件管不到;贴合人设的走 `subagent_manager_run`,官方只在没有人设贴合或要后台跑时用。 |
204
216
 
205
217
  ---
206
218
 
package/README_EN.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="docs/images/logo.png" width="120" height="120" alt="dsh-plugin-tool-management">
3
+ </p>
4
+
1
5
  # dsh-plugin-tool-management
2
6
 
3
7
  [![npm version](https://img.shields.io/npm/v/dsh-plugin-tool-management?logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-plugin-tool-management)
@@ -15,10 +19,21 @@
15
19
  An **MCP, skills, scenes, memories, subagents, prompts & archived sessions** manager for DeepSeek Harness. Eight tabs: Scenes / MCP / Skills / Subagents / Prompts / Memories / Sessions / Host.
16
20
 
17
21
  ```sh
18
- dsh plugin --profile web add dsh-plugin-tool-management@latest
22
+ dsh plugin --profile web add dsh-plugin-tool-management@latest # web
23
+ dsh plugin --profile desktop add dsh-plugin-tool-management@latest # desktop
19
24
  ```
20
25
 
21
- Hard-refresh the browser (Cmd/Ctrl+Shift+R) afterwards — a **Tools** panel in Settings means it worked. The plugin only writes its own files, never touches skill sources, and your configuration survives restarts and upgrades.
26
+ Hard-refresh the browser after installing for web (Cmd/Ctrl+Shift+R), or restart the desktop app after installing for desktop — a **Tools** panel in Settings means it worked. The plugin only writes its own files, never touches skill sources, and your configuration survives restarts and upgrades.
27
+
28
+ ---
29
+
30
+ ## Demo
31
+
32
+ <video controls src="https://github.com/user-attachments/assets/91b9673d-d201-462a-83de-8bc663c7629d"></video>
33
+
34
+ Every interface shown is a real screenshot of the running product — no redrawn UI, no fabricated controls.
35
+
36
+ Music: Kevin MacLeod「Limit 70」, [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
22
37
 
23
38
  ---
24
39
 
@@ -39,32 +54,34 @@ Hard-refresh the browser (Cmd/Ctrl+Shift+R) afterwards — a **Tools** panel in
39
54
 
40
55
  In one line: **configure "work / writing / coding" each as a scene and switch the whole stack with one click — and the model always sees whatever this plugin manages.**
41
56
 
42
- | Highlight | What it means |
43
- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------- |
44
- | One-click scene switch | Each scene carries its own MCP / skills / personas / memories; entering applies them, leaving restores. The model can switch for you too |
45
- | Manage without leaving chat | Type `/` for a "Tools" section and toggle any domain's items — one click, done |
46
- | Memories reach the model | A few `.md` files under a scene become its knowledge base, injected automatically |
47
- | Notes for MCP servers | A note you write is seen by the model every turn and acted on |
48
- | Disable a single tool | Mute one tool on a server: invisible to the model and uncallable |
49
- | Skills at a glance | The copy in effect is marked "preferred"; shadowed ones name the winning source |
50
- | Subagent = one file, one role | Write a role file and delegate to it; only the result comes back, never in History |
51
- | Several prompt presets | Keep multiple `AGENTS.md` baselines and switch with one click; each scene can bind its own |
52
- | Sessions no longer lost | Archives grouped by project, searchable, batch-restorable; imports Claude Code / Cursor / Codex transcripts |
53
- | The model always sees it | One context message per domain, republished only when the content changes |
54
- | Lock it and relax | Locking a scene makes create/update/delete across the five domains read-only |
55
- | Deleted is not gone | Skills / memories / personas / presets / scenes land in a recycle bin (permanent session deletion excepted) |
56
- | Safe by default | Only the plugin's own files are written; secrets masked, plaintext needs a token |
57
+ | Highlight | What it means |
58
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
59
+ | One-click scene switch | Each scene carries its own MCP / skills / personas / memories; entering applies them, leaving restores. The model can switch for you too |
60
+ | Manage without leaving chat | Type `/` for a "Tools" section and toggle any domain's items — one click, done |
61
+ | Memories reach the model | A few `.md` files under a scene become its knowledge base, injected automatically |
62
+ | Notes for MCP servers | A note you write is seen by the model every turn and acted on |
63
+ | Disable a single tool | Mute one tool on a server: invisible to the model and uncallable |
64
+ | Skills at a glance | The copy in effect is marked "preferred"; shadowed ones name the winning source |
65
+ | Subagent = one file, one role | Write a role file and delegate to it; only the result comes back, never in History |
66
+ | Several prompt presets | Keep multiple `AGENTS.md` baselines and switch with one click; each scene can bind its own, or none |
67
+ | Sessions no longer lost | Archives grouped by project, searchable, batch-restorable; imports Claude Code / Cursor / Codex transcripts |
68
+ | The model always sees it | One context message per domain, republished only when the content changes |
69
+ | Lock it and relax | Locking a scene makes create/update/delete across the five domains read-only |
70
+ | Deleted is not gone | Skills / memories / personas / presets / scenes land in a recycle bin (permanent session deletion excepted); tick items to delete in bulk, or set a retention period so it cleans itself (keep-forever by default) |
71
+ | Safe by default | Only the plugin's own files are written; secrets masked, plaintext needs a token |
57
72
 
58
73
  ## Quick start
59
74
 
60
- Prerequisites: DSH installed (`dsh web` runs), Node.js ≥ 18.
75
+ Prerequisites: DSH installed (`dsh web` runs), Node.js ≥ 18. Pick the profile matching your client: `--profile web` for the browser app, `--profile desktop` for the desktop app. The desktop profile is initialized by DSH Desktop itself — open the app once, then quit it completely before running the command.
61
76
 
62
77
  ```sh
63
- dsh plugin --profile web add dsh-plugin-tool-management@latest # install / update
64
- dsh plugin --profile web remove dsh-plugin-tool-management # uninstall
78
+ dsh plugin --profile web add dsh-plugin-tool-management@latest # web · install / update
79
+ dsh plugin --profile web remove dsh-plugin-tool-management # web · uninstall
80
+ dsh plugin --profile desktop add dsh-plugin-tool-management@latest # desktop · install / update
81
+ dsh plugin --profile desktop remove dsh-plugin-tool-management # desktop · uninstall
65
82
  ```
66
83
 
67
- Hard-refresh the browser — a **Tools** panel with eight tabs means it worked. Client changes hot-reload; host-side changes need `dsh web` restarted.
84
+ Hard-refresh the browser (web) or restart the desktop app, then a **Tools** panel with eight tabs means it worked. Client changes hot-reload; host-side changes need the client restarted (`dsh web` / the desktop app).
68
85
 
69
86
  You can also ask the model:
70
87
 
@@ -74,81 +91,74 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
74
91
  Then remind me to hard-refresh the browser.
75
92
  ```
76
93
 
94
+ For the desktop app, swap `web` for `desktop` and end with "remind me to restart the desktop app" instead.
95
+
77
96
  ## Features
78
97
 
79
98
  ### Slash commands (manage from the chat box)
80
99
 
81
- - **Type `/` for a "Tools" section**: six rows — scenes / skills / MCP servers / subagents / prompts / memories. Click a row to enter that domain, click an item to apply it; the menu stays open.
82
- - **State is visible**: enabled items carry a green check, disabled ones an empty box, the grey text on the right is the item's note, and each domain row shows a summary.
83
- - **Long lists stay usable**: every domain lists all of its items and the panel scrolls; skills group by source directory, memories by scene, enabled rows first. Each external skill directory gets one row that toggles the whole source.
100
+ - **Type `/` for a "Tools" section**: scenes / skills / MCP servers / subagents / prompts / memories. Click a row to enter that domain, click an item to apply it; the menu stays open.
101
+ - **State is visible**: green check / empty box / note in grey, plus a status summary on the domain row.
102
+ - **Long lists stay out of the way**: every domain lists in full and scrolls on its own; skills group by source directory, memories by scene, enabled ones first.
103
+ - **Both kinds of prompts are here**: the global group picks which one is written into `AGENTS.md` (single-select); the quick group is on/off, and clicking one pastes the saved text into the input box without sending it.
84
104
  - **Only reversible actions**: entering a scene and the various toggles; create / delete / edit / import / export stay on their own pages.
85
- - **Built on the host's official channel**: registered through DSH's input-trigger interface, no patching of official packages; two checkboxes under "Compatibility → Injection".
86
- - **"Tools › Prompts" holds both kinds**: the global group picks which baseline goes into `AGENTS.md` (single choice), the quick group is on/off.
87
- - **A separate "Quick prompts" section is for reuse**: only the enabled ones appear; one click inserts the saved text and sends nothing.
105
+ - **Registered through the host's own channel**: DSH's input-trigger interface, no patching of official packages.
88
106
 
89
107
  ### Scenes & memories
90
108
 
91
- - **A scene = a group, a memory = a `.md` file**: `memories/<scene>/<name>.md`, the whole body is injected; file names may be non-ASCII.
109
+ - **A scene = a group, a memory = a `.md` file**: `memories/<scene>/<name>.md`, the whole body is injected, file names may be Chinese.
92
110
  - **"Enabled" and "entered" are two axes**: enabled decides which scene the injection follows (single-select; none enabled = only `global` and `_shared`); entering applies the scene's whole MCP / skills / personas set and writes its bound prompt into `AGENTS.md`.
93
- - **Scene profile**: each scene combines MCP tools / skills / subagents / memories; ticked = on, unchecked = off, a section never created means that domain is off, and leaving restores the pre-scene state.
94
- - **Scene lock**: create/update/delete across MCP / skills / subagents / memories / prompts becomes read-only.
95
- - **Deleting a scene deletes its memories too**: record, profile and every memory land in one recycle-bin entry and come back as a whole; a running scene refuses deletion.
96
- - **Import / export**: `.md` / `.zip` (directory name = scene, bundles carry attachments); same names are skipped, never overwritten.
97
- - **Injection budget**: 128 KiB by default; oversized memories are skipped with a list.
98
- - **Subagent sessions have no separate switches**: which domains inject is decided by the same table, but scene and memory are top-level only.
111
+ - **Scene profile**: each scene pairs a set of MCP tools (with scene-level note overrides) / skills / subagents / quick prompts / a model tool-table scheme, plus a bound global prompt preset; ticked = on, unchecked = off, a section never created means that domain is off (quick prompts excepted: unbound = left alone on entry); leaving restores the pre-scene state.
112
+ - **Every domain also offers "None"**: this scene leaves that domain alone (the prompt cell = leave `AGENTS.md` as-is; quick prompts = none enabled). It differs from "keep current" — that one really changes nothing.
113
+ - **Scene lock** makes those five domains read-only.
114
+ - **Deleting a scene takes its memories with it**: the record, the profile and every memory go into one recycle-bin entry and come back together; a scene in use refuses to be deleted.
115
+ - **Import / export** `.md` / `.zip` (directory name = scene, bundles carry attachments), same names skipped and never overwritten; the injection budget defaults to 128 KiB, and anything that does not fit is skipped and listed.
99
116
 
100
117
  ### Subagents
101
118
 
102
- - **One file per persona**: `subagents/<persona>.md`, frontmatter entirely optional; `output:` takes one requirement per line.
103
- - **The persona reaches the child inside a role frame**: the body is used verbatim under a `# Persona: <name>` heading with an authorization line and a boundary line.
104
- - **Delegation**: `subagent_manager_run` runs with the persona, returns only its final result, and never enters History; by default the child starts fresh, with `inherit: true` it is seeded with this conversation's finished turns.
105
- - **On/off and catalog**: a disabled persona is neither injected nor visible to the model (file untouched); new / imported / restored personas start disabled. The catalog lists names and descriptions only.
106
- - **Catalog injection depth (`catalogDepth`)**: default `1` = top-level sessions only, `99` = any depth; it does not limit nesting.
107
- - **Tool limits per agent preset**: one allow or deny list per preset (mutually exclusive); the candidates are only that preset's own tools, grouped as "plugin tools / official tools / other tools", and an allow list is merged back with every currently running `mcp__*` tool (ticking only `read` will not stop an MCP shell). The reserved name `run_code` is stripped with a note.
108
- - **Model and provider** are both picked from the host LLM catalogue (choosing a provider narrows the model list to it); empty means inherit the main session.
109
- - **Reasoning effort**: the available levels are declared by the selected model; leaving it empty while a model is set falls back to that model's default.
119
+ - **One file per persona**: `subagents/<persona>.md`, frontmatter entirely optional; `output:` gives one line per requirement for what the result must look like. The body is used verbatim under a `# Persona: <name>` heading, and the file itself needs no changes.
120
+ - **Delegation**: `subagent_manager_run` runs with the persona, returns only its final result, and never enters History; it starts a fresh session by default, and `inherit: true` seeds it with this conversation's finished turns.
121
+ - **On/off and catalogue**: a disabled persona is neither injected nor visible to the model (the file stays put); new / imported / restored personas start disabled. The catalogue lists name + description only.
122
+ - **Tool limits per agent preset**: one allow or deny list per preset (mutually exclusive); candidates list only that preset's own tools, split into "plugin tools / official tools / other tools".
123
+ - **Model and provider**: both are picked from the host LLM catalogue (choosing a provider narrows the model list); empty means inherit the main session, and the reasoning-effort level comes from the chosen model.
110
124
 
111
125
  ### MCP servers
112
126
 
113
- - **CRUD with immediate effect**: written into `cordis.patch.yml`, backed up before every change; levels are global / project.
114
- - **Per-tool switches**: disable individual tools (invisible to the model and blocked at call); whole servers support bulk.
115
- - **Stopped servers still show their tools**: one that is not running keeps the names and descriptions last seen; one that never ran can be probed.
116
- - **Status and notes enter the context**: a server that connected before but cannot right now is listed and labelled; your notes travel along as decision hints.
117
- - **Secret masking**: a credential is replaced as a whole, and "Reveal" needs a token; a masked value is never written back into the patch file.
118
- - **Migrate & back up**: cross-level migration rolls back on failure; JSON export/import.
127
+ - **CRUD with immediate effect**: written into `cordis.patch.yml`, backed up before every change; scope is "global / app-level", and new entries default to global.
128
+ - **Per-tool switches**: disable individual tools (invisible and uncallable to the model), or a whole server in one go.
129
+ - **A stopped server still shows its list**: tools last seen are listed with their descriptions (marked "as of last run"); one that never ran can be started to read them.
130
+ - **Notes and secrets**: a per-server note for the model travels along with the status section; credentials are masked as a whole (`$VAR`, `!!js` and similar indirect references are left alone), and "Reveal" needs a token.
131
+ - **Migration and backups**: a cross-scope migration rolls back on failure; JSON export/import is supported.
119
132
 
120
133
  ### Skills
121
134
 
122
135
  - **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom directories, grouped by source.
123
136
  - **Opposite permissions**: default sources are readable and their skills deletable; external directories can be disabled or removed but their files stay read-only.
124
137
  - **Remove ≠ disable**: removing stops scanning the directory at all (nothing is written, restorable); disabling keeps it listed but uncallable.
125
- - **Who wins a shared name**: the winning copy is marked "preferred", shadowed ones name the source that wins.
126
- - **Custom directories / ZIP import & export / recycle bin.**
138
+ - **The winning copy of a shared name** is marked "preferred", and the ones it shadows are marked with their source.
139
+ - **Custom directories / ZIP import-export / recycle bin.**
127
140
 
128
141
  ### Prompt presets
129
142
 
130
- - Multiple `~/.dsh/AGENTS.md` baselines, applied with one click (next turn), with 5 generations of backups.
131
- - **It remembers the last applied preset**: even after you hand-edit `AGENTS.md`, the origin is still reported.
132
- - Each preset can carry a one-line description that lives in a sibling `meta.json` — shown in this panel, never injected.
133
- - **A referenced preset cannot be deleted** (scene binding / current `AGENTS.md` content); deletes go to the recycle bin.
134
- - **The switch on the left of a card is the answer to "is this one in effect"**: flip it on and that preset is written into `AGENTS.md`; a baseline has no "apply nothing" state, so light up a different one instead (single choice).
135
- - **While a scene drives the baseline, flipping another one rebinds that scene** to the chosen preset; it is refused only while the scene is locked.
136
- - **Quick prompts** (the second section on the same page): save a piece of text you keep typing, then hit `/` and click it — it lands verbatim in the input. It is never injected; its switch only controls whether the row still shows up in the `/` "Quick prompts" section.
137
- - **A scene can bind a set of quick prompts**: entering that scene enables exactly the checked ones and disables the rest, and leaving restores the switches as they were before entering.
138
- - **Both groups are collapsible cards** (click the header to fold); the quick group's header carries a "Select all / Deselect all" button, the global group has none — that one is single choice.
143
+ - **Multiple `~/.dsh/AGENTS.md` baselines**, applied with one click (next turn), with 5 generations of backups; each preset can carry a one-line description that lives only on the plugin side; the last applied preset is always identifiable, even after you edit `AGENTS.md` by hand.
144
+ - **The switch on the left of a card is the answer to "is this one in effect"**: flip it on and that preset is written into `AGENTS.md`; flip it off to **un-apply**. The confirmation says which one it will be (the button turns red when the file is going to be deleted), and a receipt follows.
145
+ - **"Un-apply" goes back to the start of the chain, not one step**: it restores whatever was there before this run of apply / un-apply began (deleting the file if there was none); every intermediate version stays in `__last-applied__/AGENTS.md.bak-*` (5 generations), so it can be applied again.
146
+ - **Two kinds cannot be deleted directly**: a scene-bound preset, and the one currently applied (un-apply it first). The copy auto-created on first open was never applied and can be deleted. Deletes always go to the recycle bin.
147
+ - **Quick prompts** (the second section on the same page): save a piece of text you keep typing, then hit `/` and click it to paste it in; a scene can bind a set of them (only the ticked ones are on while the scene is entered, restored on exit, or pick "None").
139
148
 
140
149
  ### Archived sessions
141
150
 
142
151
  - Grouped by project, searchable, batch restore / delete, retention auto-cleanup; a workspace whose registration was deleted can be re-registered in one click.
143
- - Import Claude Code / Cursor / Codex / any text (pick a registered workspace, browse to a folder, or give a path directly); export Markdown / JSONL in three cumulative modes: text only → plus tool calls → plus reasoning. **An export is a transcript, not a backup** — use archiving when you need the full record.
152
+ - Import Claude Code / Cursor / Codex / any text (pick a workspace, browse for one, or type a path).
153
+ - Export Markdown / JSONL in three cumulative modes: text only → plus tool calls → plus reasoning. **An export is a transcript, not a backup** — use "archive" to keep everything.
144
154
 
145
155
  ### Host compatibility
146
156
 
147
157
  - **Host tab**: host version, usable capability count, per-action routing (native / adapter / unavailable), degradations and reasons; three write entries: access token, injection settings, model tool table.
148
158
  - **Command line**: `node scripts/doctor.mjs` (health check), `node scripts/host-deps.mjs --fix` (align dependencies).
149
159
  - Under a **suppressing preset** such as `minimal`, this plugin's injection is off by default; the Host tab can force any domain back on.
150
- - **Unchecking "Skills" or "Prompt" really stops them** — under standard presets the host delivers those two itself; the other three domains are only ever sent by this plugin, so their toggles work as written.
151
- - **What an injection looks like**: one `<system-reminder>` per domain — a `#` section title, then the body. Any `</system-reminder>` inside your content is escaped.
160
+ - Unchecking "Skills" or "Prompt" really stops them — under standard presets the host delivers those two itself; the other three domains follow the checkbox exactly.
161
+ - **What the injection looks like**: one `<system-reminder>` per domain — `# heading` + body + a "this one wins" line; a `</system-reminder>` inside the body is escaped.
152
162
 
153
163
  ---
154
164
 
@@ -160,9 +170,9 @@ Then remind me to hard-refresh the browser.
160
170
  | Skill policy / custom dirs | `~/.dsh/tool-management/skills-state.json` |
161
171
  | Skills / memories / personas / presets | `~/.dsh/tool-management/{skills,memories,subagents,prompts}/` |
162
172
  | Subagent toggles | `~/.dsh/tool-management/subagents-index.json` |
163
- | Recycle bin (skills / personas / presets / scenes) | `~/.dsh/tool-management/trash/{skills,subagents,prompts,scenes}-trash/` |
164
- | Memory recycle bin | `~/.dsh/tool-management/memories-trash/` (a directory at the hub root, not under `trash/`) |
173
+ | Recycle bin (skills / memories / personas / presets / scenes) | `~/.dsh/tool-management/trash/<domain>-trash/` (one directory per kind) |
165
174
  | Archive ledger / retention | `~/.dsh/tool-management/history-*.json` |
175
+ | Recycle-bin retention | `~/.dsh/tool-management/trash-retention.json` (`0` = keep forever) |
166
176
  | Memory index / scenes / profiles | `~/.dsh/tool-management/memories-index.json` |
167
177
  | MCP sidecars (disabled tools / known tools / notes / settings) | `~/.dsh/tool-management/mcp-*.json` |
168
178
  | Injection settings (six domain switches) | `~/.dsh/tool-management/inject-settings.json` |
@@ -172,35 +182,36 @@ Then remind me to hard-refresh the browser.
172
182
 
173
183
  **No user data is stored inside the plugin's install directory** (`dsh plugin update` replaces it wholesale). `backups/` keeps **5 copies per patch file** — the global patch and each profile patch count separately.
174
184
 
185
+ The six recycle bins each own one directory under `trash/`: `{skills,memories,subagents,prompts,scenes,quick-prompts}-trash/`. The memories one moved in from the hub root on 2026-10-10; existing data is carried over by the startup migration.
186
+
175
187
  ## Configuration & security
176
188
 
177
189
  | Field | What it does |
178
190
  | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
179
191
  | `token` | Access token. Once set, **every write and every plaintext credential** requires `x-dsh-token`; with no token the plaintext endpoints are closed entirely. Prefer not to keep it in the config? Use the `DSH_PLUGIN_TOOL_MANAGEMENT_TOKEN` environment variable. |
180
- | `tokenDisabled` | `true` = the token stays in the config but is not enforced (this is the line written by "Turn protection off"). Writes no longer need it; revealing plaintext still does. |
192
+ | `tokenDisabled` | `true` = the token stays in the config but is not enforced (this is the line written by "Turn protection off"). Writes no longer need it; revealing plaintext still does. |
181
193
  | `maxBodyBytes` | Request body cap, 88 MiB by default. |
182
194
 
183
195
  **Plaintext on disk (read this)**: masking is **display-only**; MCP `env` / `headers` and the plugin's own `token` stay in cleartext inside `cordis.patch.yml` (and each profile copy), and every config change copies the whole file into `~/.dsh/tool-management/backups/` — unencrypted, never rotated, not reclaimed on uninstall. One secret can therefore exist as `5 × (patch files holding it) + 1` plaintext copies. The token gate decides *who may read plaintext over HTTP*; it does nothing about *reading the files*, where the only defence is your filesystem permissions. **To clean up: Settings → Tools → Host → "Clean old backups"**.
184
196
 
185
- - **Browser**: reads and writes go through cookies, no token needed; **plaintext credentials** (reveal / export) do. The token is managed in the **Access token** block on the Host tab — filling it once unlocks the current run, writing it into the config needs a restart.
197
+ - **Browser**: reads and writes go through cookies, no token needed; **plaintext credentials** (reveal / export) do. The token is managed in the **Access token** block on the Host tab.
186
198
  - **Every destructive direction asks for the current token again** (turn protection off / change / delete). Being unlocked this run does not count.
187
- - **curl / scripts**: send `x-dsh-token`, or carry the browser cookie.
188
- - **HTTP status convention**: except for the fence's 401 / 403, a missing token or a business failure is **HTTP 200 + `{ ok: false, error }`** — branch on `body.ok`, not on the status code.
189
- - **Port forwarding**: when the host has no `connection` service the fence falls back to "loopback Host + same origin", which any local process can imitate with `Host: localhost`. If you forward the port to a LAN or the public internet, **configure a token** — a stranger injecting MCP commands is remote code execution. The `dir-list` call behind the folder picker lists any absolute path (read-only) under the same precondition.
190
- - **Avoid `__` in a server name (naming advice)**: a tool's full name is `mcp__<server>__<tool>`, so an extra `__` inside a server name makes it ambiguous and a checkbox in the UI may fail to land on the key used in the disabled-tools table. This release does not tighten validation; the Host tab shows an informational note instead.
199
+ - **curl / scripts**: send `x-dsh-token`, or carry the browser cookie. Except for the fence's 401 / 403, failures come back as **HTTP 200 + `{ ok: false, error }`** — branch on `body.ok`.
200
+ - **Port forwarding**: when the host has no `connection` service the fence falls back to "loopback Host + same origin", which any local process can imitate. If you forward the port to a LAN or the public internet, **configure a token**.
201
+ - **Avoid `__` in a server name**: a tool's full name is `mcp__<server>__<tool>`, so an extra `__` inside a server name makes it ambiguous; the Host tab shows an informational note.
191
202
 
192
203
  ## FAQ
193
204
 
194
- | Symptom | Fix |
195
- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
196
- | Pages missing after install | Hard refresh; restart DSH if that fails. |
197
- | Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
198
- | Broken config, DSH won't boot | Restore the newest `cordis.patch.yml.<level>.bak-<timestamp>` from `~/.dsh/tool-management/backups/` (5 per patch file). |
199
- | Action stopped working after a DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
200
- | The model cannot call a tool it should have | Check the **Model tool table** on the Host tab — 15 tools ship switched off. The panel and scripts are unaffected either way. |
201
- | Still asked to confirm with `approval=never`? | No card appears — straight through with a log line. Switch back to "workspace write" to get the questions again. |
202
- | `subagent_manager_run` reports provider unavailable | The provider is not registered: `spawn` (default) / `fork` (`inherit`) come from `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` — mount and restart. |
203
- | Scene binds persona A, but the official `subagent` ran something else | Those two are host tools and this plugin cannot hide them; work matching a persona goes to `subagent_manager_run`, host tools only when no persona fits or a background job is needed. |
205
+ | Symptom | Fix |
206
+ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
207
+ | Pages missing after install | Hard refresh; restart DSH if that fails. |
208
+ | Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
209
+ | Broken config, DSH won't boot | Restore the newest `cordis.patch.yml.<level>.bak-<timestamp>` from `~/.dsh/tool-management/backups/` (5 per patch file). |
210
+ | Action stopped working after a DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
211
+ | The model cannot call a tool it should have | Check the **Model tool table** on the Host tab — 15 tools ship switched off. The panel and scripts are unaffected either way. |
212
+ | Still asked to confirm with `approval=never`? | No card appears — straight through with a log line. Switch back to "workspace write" to get the questions again. |
213
+ | `subagent_manager_run` reports provider unavailable | The provider is not registered: `spawn` (default) / `fork` (`inherit`) come from `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` — mount and restart. |
214
+ | Scene binds persona A, but the official `subagent` ran something else | Those two are host tools and this plugin cannot hide them; work matching a persona goes to `subagent_manager_run`, host tools only when no persona fits or a background job is needed. |
204
215
 
205
216
  ---
206
217
 
Binary file
package/docs/images/1.png CHANGED
Binary file
Binary file
package/docs/images/2.png CHANGED
Binary file
Binary file
package/docs/images/3.png CHANGED
Binary file
Binary file
package/docs/images/4.png CHANGED
Binary file
Binary file
package/docs/images/5.png CHANGED
Binary file
Binary file
package/docs/images/6.png CHANGED
Binary file
Binary file
package/docs/images/7.png CHANGED
Binary file
Binary file
package/docs/images/8.png CHANGED
Binary file