dsh-plugin-tool-management 0.18.5 → 0.19.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.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,31 @@
10
10
 
11
11
  ---
12
12
 
13
+ ## [0.19.0] - 2026-10-07
14
+
15
+ 子智能体四件事:人设可以标「允许追问」+ 修好自 0.15.0 起完全不可用的 `subagent_manager_run` + 子代理不再把自己当成主代理 + 人设表单的「高级选项」重排;外加「工具限制」的候选修好并分三段。
16
+
17
+ ### 新增
18
+
19
+ - **人设可以标「允许追问」**:勾上后子代理转后台运行,之后可继续追问。
20
+
21
+ ### 修复
22
+
23
+ - **修好 `subagent_manager_run` 自 0.15.0 起完全不可用**。
24
+ - **子代理不再把自己当成主代理**。
25
+ - **修好「模型来源」选定后模型那一格变窄**。
26
+ - **注入框架不再点名被工具限制砍掉的工具**。
27
+ - **修好「工具限制」的候选不是该模式自己的工具**(此前四个模式列的是同一份宿主平面清单,勾不到 `read` / `write` / `pwsh` 这类官方工具)。
28
+
29
+ ### 变更
30
+
31
+ - **串行语义改为「至多一次启动在途」**。
32
+ - **人设表单的「高级选项」重排**:五个字段分三组,提示文字由九处减到一处;模型来源与模型改为只从宿主目录里选(选定来源后模型只列该来源的;目录外的旧值原样列一条「目录里没有」,不再有手填入口);收起态摘要最多两行、只报有值的项。
33
+ - **「工具限制」的候选按「插件工具 / 官方工具 / 其他工具」分三段**。
34
+ - **「工具限制」的候选不再返回全体并集**。
35
+
36
+ ---
37
+
13
38
  ## [0.18.5] - 2026-10-05
14
39
 
15
40
  会话导出分三档累进(仅正文 → + 工具 → + 思考)+ 导出弹窗放大到看得到列表 + 导入可以挑工作区;修好行内「恢复」必报操作失败。
package/README.md CHANGED
@@ -41,18 +41,18 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
41
41
 
42
42
  | 亮点 | 说明 |
43
43
  | --------------------------- | ----------------------------------------------------------------------------------------- |
44
- | 一键换场景 | 每个场景各配一套 MCP / 技能 / 人设 / 记忆(绑了的话还有快捷提示词),进入时整套切换、退出时还原;模型也能按你说的切 |
45
- | 不离开对话就能管 | 在对话输入框打 `/` 出「工具」段:进场景、启停技能 / MCP / 子智能体 / 提示词 / 记忆,点一下就生效 |
46
- | 记忆自动送到模型眼前 | 每个场景下写几段 `.md` 就是它的资料库,正文自动进上下文,不用每次复制粘贴 |
47
- | 给 MCP 服务器写备注 | 「A 不可用时改用 B 兜底」这类话写进备注,模型每轮都看得到,会照做 |
48
- | 单个工具也能关 | 一台服务器里可以只停某个工具,模型看不见也调不到;「重启」只重连,不改开关状态 |
44
+ | 一键换场景 | 每个场景各配一套 MCP / 技能 / 人设 / 记忆,进入时整套切换、退出时还原;模型也能按你说的切 |
45
+ | 不离开对话就能管 | 对话里打 `/` 出「工具」段,启停各域条目,点一下就生效 |
46
+ | 记忆自动送到模型眼前 | 每个场景下写几段 `.md` 就是它的资料库,正文自动进上下文 |
47
+ | 给 MCP 服务器写备注 | 写进备注的话模型每轮都看得到,会照做 |
48
+ | 单个工具也能关 | 一台服务器里可以只停某个工具,模型看不见也调不到 |
49
49
  | 技能状况一眼看穿 | 哪份在生效标「首选」,被同名覆盖的标出来源 |
50
50
  | 子智能体 = 一个文件一个角色 | 写一份角色说明就能派活;跑完只回结果、不占你的会话记录 |
51
51
  | 提示词备好几套 | `AGENTS.md` 可以存多份、一键切换;场景可以各自绑一份 |
52
52
  | 会话不再丢 | 归档按项目分组、能搜、能批量恢复;Claude Code / Cursor / Codex 的记录能导进来 |
53
- | 模型一定看得见 | 六个域各注入一条上下文,内容没变不重发;压制型预设下默认不注入,可在「兼容」页开 |
54
- | 锁住就不怕手滑 | 场景可以上锁:五个域的增删改整体只读,先解锁才能改 |
55
- | 删了能找回 | 技能 / 记忆 / 人设 / 提示词 / 场景的删除都进回收站(会话永久删除是例外) |
53
+ | 模型一定看得见 | 六个域各注入一条上下文,内容没变不重发 |
54
+ | 锁住就不怕手滑 | 场景可以上锁:五个域的增删改整体只读 |
55
+ | 删了能找回 | 技能 / 记忆 / 人设 / 提示词 / 场景的删除都进回收站(会话永久删除除外) |
56
56
  | 安全、不添乱 | 只写自己的文件;密钥默认打码、看明文要令牌 |
57
57
 
58
58
  ## 快速开始
@@ -78,41 +78,43 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
78
78
 
79
79
  ### 斜杠命令(在对话里直接管)
80
80
 
81
- - **打 `/` 出「工具」段**:六行 —— 场景 / 技能 / MCP 服务器 / 子智能体 / 提示词 / 记忆。点一行原地进入这一域的条目(顶栏面包屑点「工具」回上一级),再点一条直接生效。**点完菜单不关**,接着点下一条也行 —— 连点多个开关是主要用法。
82
- - **状态看得见**:启用项图标位是绿色对勾、停用项是空心框,右侧灰字是条目自己的备注(场景说明 / 技能描述 / MCP 备注 / 人设描述 / 预设描述 / 记忆描述,超 40 字截断;没写备注才退回「已启用 / 未启用」);域行右侧给当前态摘要(`当前:工作`、`3 启用 / 1 停用`),不点进去也知道现在什么状况。点下去立刻翻转(本地乐观状态),写失败会翻回来并说明原因。
83
- - **条目多也不挡路**:每个域全量列出,靠面板自己滚动;技能按来源目录分组、记忆按场景分组,组内已启用的排前面。每个外部技能目录另给一行「目录名 · 目录」,钉在本组最上面,点它就是启停整个来源(开着也列,所以也关得掉;关掉时它里面的技能整组收起,重新启用当场又摆回来)。场景域里两个恒开的保留项(「全局」与公共基线)不出现,但记忆域默认带上「全局」那几条,并把这一组钉在最前面 —— 它们不属于当前场景,却对任何对话都成立。
84
- - **只放可逆动作**:进场景与各类启停。再点当前场景 = 退出场景(只注入全局与公共基线);只有全局提示词那一档关不掉(基线没有"全部不应用"这一态),点当前那一份只回一句「当前就是它」。增删改、导入导出、改配置仍各归各页。
85
- - **走宿主官方通道**:用 DSH 的输入触发器接口注册(官方技能菜单同一条路),不 patch 官方包;宿主没有该服务时这个入口不出现,「兼容」页会照实说明。两段各一颗开关(「工具」/「快捷提示词」),在「兼容 → 注入」块的「斜杠命令入口」一组里,行末那枚标签说的是本次启动真挂上没;两段各挂各的源,关掉一个不影响另一个;两段都关掉后 `/` 菜单回到出厂样子(修改后重启 DSH 即可生效)。
86
- - **「工具 › 提示词」里两类提示词都在,每一行都是启停**:全局那组 = 哪一份写进 `AGENTS.md`(单选,各带分组标题),快捷那组 = 这条还开不开着(与提示词页那颗药丸开关同一个动作、同一份状态)。这一域里连已经关着的快捷词也列 —— 管理那一层不该因为被管起来就找不到。
87
- - **另起一段「快捷提示词」管取用**:只列开着的那几条,点一行把存好的那段话原样替换进输入框,**不自动发送**(发送键留给你),所以那一行不带对勾 —— 它不是启停。
81
+ - **打 `/` 出「工具」段**:六行 —— 场景 / 技能 / MCP 服务器 / 子智能体 / 提示词 / 记忆。点一行进这一域,再点一条直接生效;点完菜单不关。
82
+ - **状态看得见**:启用项绿勾、停用项空框,右侧灰字是条目备注,域行右侧给当前态摘要。
83
+ - **条目多也不挡路**:每域全量列出、面板自己滚;技能按来源目录分组、记忆按场景分组,已启用的排前面。每个外部技能目录另给一行,点它就是启停整个来源。
84
+ - **只放可逆动作**:进场景与各类启停;增删改、导入导出、改配置仍各归各页。
85
+ - **走宿主官方通道**:用 DSH 的输入触发器接口注册,不 patch 官方包;「兼容 → 注入」里两段各一颗开关。
86
+ - **「工具 › 提示词」两类都在**:全局那组选哪一份写进 `AGENTS.md`(单选),快捷那组是启停。
87
+ - **「快捷提示词」另起一段**:只列开着的,点一行把存好的话贴进输入框,不自动发送。
88
88
 
89
89
  ### 场景与记忆
90
90
 
91
91
  - **场景 = 分组,记忆 = `.md` 文件**:`memories/<场景>/<名>.md`,整篇正文自动注入上下文,文件名支持中文。
92
- - **「启用」与「进入」是两件事**:启用决定注入按哪个场景走(单选,全关 = 只注入「全局」与 `_shared`);进入才按档案整套切换 MCP / 技能 / 人设(绑了的话还有快捷提示词),并把绑定的提示词写进 `AGENTS.md`。**两者必须恒等,而这条恒等由服务端兜住**:`rules-set-active` 先把运行时切到位再写启用集合(切不动就一个字都不写),所以面板开关、`/` 菜单、模型工具哪个入口都只发一次调用就两轴齐动。
93
- - **场景档案**:每个场景搭配 MCP 工具集 / 技能集 / 子智能体 / 记忆(任意组合)。语义是**勾的启用、没勾的停用**,整段没建 = 该域全部停用;退出按进场景前的快照还原。场景内这三个域的开关照常可用,改动会同步写进档案。
94
- - **场景锁定**:锁定后 MCP / 技能 / 子智能体 / 记忆 / 提示词五个域的增删改整体只读(界面与服务端双侧拦截);场景自身的启停、MCP 重启、导出不受影响。
95
- - **删除场景 = 连记忆一起删**:场景记录、档案与全部记忆进同一条回收站条目,恢复时按原路径整条放回;使用中的场景拒绝删除。改名会连带改目录与档案。
96
- - **导入导出**:`.md` / `.zip`(目录名 = 场景,bundle 带附件),同名跳过绝不覆盖;导出勾选记忆打包成 zip,只读源文件。
92
+ - **「启用」与「进入」是两件事**:启用决定注入按哪个场景走(单选,全关 = 只注入「全局」与 `_shared`);进入才按档案整套切换 MCP / 技能 / 人设,并把绑定的提示词写进 `AGENTS.md`。
93
+ - **场景档案**:每个场景搭配 MCP 工具集 / 技能集 / 子智能体 / 记忆;勾的启用、没勾的停用,整段没建 = 该域全部停用,退出时按进场景前的快照还原。
94
+ - **场景锁定**:锁定后 MCP / 技能 / 子智能体 / 记忆 / 提示词五域的增删改整体只读。
95
+ - **删除场景 = 连记忆一起删**:场景记录、档案与全部记忆进同一条回收站条目,恢复时整条放回;使用中的场景拒绝删除。
96
+ - **导入导出**:`.md` / `.zip`(目录名 = 场景,bundle 带附件),同名跳过绝不覆盖。
97
97
  - **注入预算**:默认 128 KiB,放不下的跳过并列出清单。
98
- - **子代理会话不注入记忆**:记忆是父会话的现场;子代理需要的事实应由父代理写进任务。
98
+ - **子代理会话不另设开关**:注入哪几个域由同一张表决定,但场景与记忆只在顶层注入。
99
99
 
100
100
  ### 子智能体
101
101
 
102
- - **一个文件一个人设**:`subagents/<人设>.md`,frontmatter 全可选。`output:` 一行一条写"产出必须长什么样"(可检验的格式要求比一句抽象要求更容易被遵守)。
103
- - **委派**:`subagent_manager_run` 带人设运行、只回最终结果、不进 History。默认新起独立会话(任务要写全);`inherit: true` 则继承本次会话**已完成的轮次**(本轮内容继承不到,此时任务仍要写全)。
104
- - **启停与目录**:停用的人设不注入、模型不可见(文件不动);新建 / 导入 / 恢复默认停用。人设目录只列名字 + 描述;改名后场景绑定自动跟着改。
105
- - **目录注入深度(`catalogDepth`)**:默认 `1` = 只在顶层会话注入目录,`99` = 任何深度都注入。它只管目录,不限制嵌套深度(那由宿主决定)。
106
- - **工具限制按 Agent 预设**:每个预设一份白 / 黑名单(互斥)。两条要知道的行为:白名单会并回当前所有 `mcp__*` 工具,所以"只勾 read"拦不住暴露 shell 的 MCP 服务器;名单里的名字全都对不上时按"不限制"处理。
107
- - **思考强度**:在高级选项里与「模型」并排,档位由所选模型声明。换模型后旧档位若不在新清单里会自动清掉并告知;指定了模型时留空 = 回落到该模型的默认档位,不是沿用主会话那一档。
102
+ - **一个文件一个人设**:`subagents/<人设>.md`,frontmatter 全可选;`output:` 一行一条写"产出必须长什么样"。
103
+ - **人设正文带一层角色框架**:正文原样用在 `# Persona: <名字>` 标题下,附授权与边界各一行;人设文件本身不用改。
104
+ - **委派**:`subagent_manager_run` 带人设运行、只回最终结果、不进 History;默认新起独立会话,`inherit: true` 继承本次会话已完成的轮次。
105
+ - **启停与目录**:停用的人设不注入、模型不可见(文件不动);新建 / 导入 / 恢复默认停用。人设目录只列名字 + 描述。
106
+ - **目录注入深度(`catalogDepth`)**:默认 `1` = 只在顶层会话注入目录,`99` = 任何深度都注入;不限制嵌套深度。
107
+ - **工具限制按 Agent 预设**:每个预设一份白 / 黑名单(互斥),候选只列该预设自己的工具,分「插件工具 / 官方工具 / 其他工具」三段;白名单会并回当前所有 `mcp__*` 工具(只勾 `read` 拦不住 MCP 里的 shell),保留名 `run_code` 会被剔除并注明。
108
+ - **模型与来源**:都从宿主 LLM 目录里选(选定来源后模型只列该来源的);留空 = 继承主会话。
109
+ - **思考强度**:档位由所选模型声明;指定了模型时留空 = 用该模型的默认档位。
108
110
 
109
111
  ### MCP 服务
110
112
 
111
113
  - **增删改查、即改即生效**:写入 `cordis.patch.yml`,改前自动备份。级别分「全局 / 应用级」,新增默认全局。
112
114
  - **工具级开关**:单个工具可独立停用(模型看不见也调不到),整台支持批量。
113
115
  - **停着也能看清单**:没在跑的服务器仍显示上次见过的工具名与描述(标「上次运行时」);从没跑过的可以一键启动读取。
114
- - **备注**:每台服务器可写一句给模型的提示,随状态段一起注入。曾经连上过、现在连不上的服务器会列出来并标注 —— 这样模型会说"它没连上,检查一下",而不是建议你去装一个。
115
- - **密钥打码**:默认把凭据整值打码(`$VAR`、`!!js` 这类间接引用不动;URL 的查询串、`user:pass@` 与 `#片段` 一并打码),看明文要令牌。打码值**不会被写回配置** —— 保存时你原样留着的字段会还原成已存的值,地址里没有可还原的原值时整次保存会被拒绝(静默丢掉查询串会留下一个"连得上但认证失败"的地址)。打码只管界面展示,详见「配置与安全」。
116
+ - **备注**:每台服务器可写一句给模型的提示,随状态段一起注入;曾经连上过、现在连不上的会列出来并标注。
117
+ - **密钥打码**:默认把凭据整值打码(`$VAR`、`!!js` 这类间接引用不动),看明文要令牌;打码值不会被写回配置。
116
118
  - **迁移与备份**:跨项目级 / 全局迁移失败自动回滚;支持 JSON 导出导入。
117
119
 
118
120
  ### 技能
@@ -120,33 +122,33 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
120
122
  - **来源一览**:项目级 / DSH / Agents / Codex / Claude / 自定义目录,按来源分组。
121
123
  - **两组权限相反**:默认来源的技能可删可停;外部目录可以停用或移除,但里面的技能文件只读。
122
124
  - **移除 ≠ 停用**:移除 = 连目录都不扫(文件零改动,可恢复);停用 = 仍列出但不可调用。
123
- - **同名谁在生效**:真正生效的那份标「首选」,被覆盖的标出来源;启用被覆盖的副本会明说"这样不会生效"。
125
+ - **同名谁在生效**:生效的那份标「首选」,被覆盖的标出来源。
124
126
  - **自定义目录 / ZIP 导入导出 / 回收站**。
125
127
 
126
128
  ### 提示词预设
127
129
 
128
130
  - 多套 `~/.dsh/AGENTS.md` 基线一键应用(下一轮对话生效),保留 5 代备份。
129
- - **记得「最近一次应用的是哪份」**:就算你手改过 `AGENTS.md`,也答得出来源(会注明"此后文件有变")。
131
+ - **记得「最近一次应用的是哪份」**:就算你手改过 `AGENTS.md`,也答得出来源。
130
132
  - 每条预设可写一句"这份是干什么的",只存在插件侧、不进 `AGENTS.md`。
131
133
  - **被引用的不能删**(场景绑定 / 当前内容 / 退出场景要恢复的那一份),删除进回收站。
132
- - **生效与否就是卡片左边那颗开关**:点亮 = 把这一份写进 `AGENTS.md`;已经亮着的那颗再点一次 = 重新写回(把被手改的文件拉回来)。基线没有"全部不应用"这一态,所以这颗开关关不掉 —— 想换一份就点亮另一份(单选)。
133
- - 场景接管期间点亮另一份 = 把该场景改绑到那一份(同步写进场景档案);锁定时拒绝。
134
- - **快捷提示词**(同页第二段):存一段常用的话,之后在对话框打 `/` 点一下就原样贴进输入框,可直接编辑再发送。它**不注入上下文**,卡片上那颗开关只管一件事 —— 这条还在不在 `/` 的「快捷提示词」段里出现(关掉时正文与备注都留着;同一颗开关在「工具 › 提示词」那一域里也拨得动)。只由你自己点出来;与全局基线分开存,删除进回收站,也能导出与随迁移快照带走。
135
- - **场景可以绑定一组快捷提示词**:「修改场景」里「提示词预设」下面那颗下拉,默认「当前启用的(保持现状)」= 不绑、进出不碰;改成「按场景勾选」后,进入本场景只启用你勾的那几条、其余停用,**退出场景按进场景前的开关还原**。一条都不勾是"进入后全部停用",和"不绑"是两件事。
136
- - **两组各自是一张可折叠卡片**(点卡片头收起 / 展开,打了字自动展开)。快捷那组的卡片头有一颗「全选 / 取消全选」,只作用于当前可见的那几条;全局那组没有 —— 那一档是单选,"全部应用"没有意义。
134
+ - **生效与否就是卡片左边那颗开关**:点亮 = 把这一份写进 `AGENTS.md`;基线是单选,所以关不掉 —— 想换一份就点亮另一份。
135
+ - 场景接管期间点亮另一份 = 把该场景改绑到那一份;锁定时拒绝。
136
+ - **快捷提示词**(同页第二段):存一段常用的话,`/` 里点一下就原样贴进输入框;它不注入上下文,卡片上那颗开关只管这条在 `/` 里出不出现。
137
+ - **场景可以绑定一组快捷提示词**:进入本场景只启用勾的那几条、其余停用,退出按进场景前的开关还原。
138
+ - **两组各自是一张可折叠卡片**(点卡片头收起 / 展开);快捷那组卡片头有「全选 / 取消全选」,全局那组没有 —— 那一档是单选。
137
139
 
138
140
  ### 历史会话
139
141
 
140
142
  - 按项目分组、搜索、批量恢复 / 永久删除、保留期自动清理;工作区登记被删后可一键重新登记。
141
- - 导入 Claude Code / Cursor / Codex / 任意文本,工作区可以从已登记的里挑、浏览文件夹或直接给路径;导出 Markdown / JSONL,分三档**累进**:仅正文 → 正文 + 工具 → 正文 + 工具 + 思考。**导出仍是可读转录,不是完整备份**:附加段每块有上限并明说截断,token 统计不在里面。要留全量请用「归档」。
143
+ - 导入 Claude Code / Cursor / Codex / 任意文本(工作区可挑、可浏览、可给路径);导出 Markdown / JSONL,分三档累进:仅正文 → 正文 + 工具 → 正文 + 工具 + 思考。**导出是转录,不是备份** —— 要留全量请用「归档」。
142
144
 
143
145
  ### 宿主兼容
144
146
 
145
- - **「兼容」页**:宿主版本、能力可用数、每个动作走原生 / 适配 / 不可用、降级项与原因。这一页有三个写入口:**访问令牌**(重启生效)、**注入设置**、**模型工具表**。
147
+ - **「兼容」页**:宿主版本、能力可用数、每个动作走原生 / 适配 / 不可用、降级项与原因;三个写入口:访问令牌、注入设置、模型工具表。
146
148
  - **命令行**:`node scripts/doctor.mjs`(体检)、`node scripts/host-deps.mjs --fix`(依赖对齐)。
147
- - **压制型预设**(`minimal` 这类)下本插件的注入默认停用(跟随预设的设计意图),可在「兼容」页按域强制打开。
148
- - **关掉「技能」「提示词」的勾选 = 连宿主那份一起停**(这两域在标准预设下由官方送,插件让位);其余三域宿主本来就不送,勾选完全生效。
149
- - **注入长什么样**:每个域一条 `<system-reminder>`,`# 板块标题` + 正文 + 一句"以本份为准",只写"现在是什么"、不写指令。你写的内容里出现 `</system-reminder>` 会被转义。
149
+ - **压制型预设**(`minimal` 这类)下本插件的注入默认停用,可在「兼容」页按域强制打开。
150
+ - **关掉「技能」「提示词」的勾选 = 连宿主那份一起停**(这两域在标准预设下由官方送);其余三域勾选完全生效。
151
+ - **注入长什么样**:每个域一条 `<system-reminder>`,`# 板块标题` + 正文 + 一句"以本份为准";正文里的 `</system-reminder>` 会被转义。
150
152
 
151
153
  ---
152
154
 
@@ -178,14 +180,14 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
178
180
  | `tokenDisabled` | `true` = 令牌保留在配置里但当前不生效(兼容页「关闭保护」写的就是这一行)。写操作不再要求令牌,明文查看仍然要。 |
179
181
  | `maxBodyBytes` | 请求体上限,默认 88 MiB。 |
180
182
 
181
- **磁盘上的明文(必读)**:打码**只发生在界面展示**。MCP 的 `env` / `headers` 与插件自己的 `token` 在 `cordis.patch.yml`(及各 profile 副本)里始终是明文,而每次改配置前插件会把整份文件备份进 `~/.dsh/tool-management/backups/`(不加密、不轮转、卸载也不回收)—— 一份密钥最多有 `5 ×(含它的 patch 文件数)+ 1` 份明文副本。令牌门禁管的是"谁能通过 HTTP 拿到明文",**管不到磁盘读取**:真正的防线是操作系统的文件权限。清理入口:**设置 → 工具 → 兼容 → 「清理旧备份」**(可按层级各删最旧的 N 份,弹窗内二次确认),也可以手工删那个目录下的旧文件。
183
+ **磁盘上的明文(必读)**:打码**只发生在界面展示**;MCP 的 `env` / `headers` 与插件自己的 `token` 在 `cordis.patch.yml`(及各 profile 副本)里始终明文,改配置前整份文件会备份进 `~/.dsh/tool-management/backups/`(不加密、不轮转、卸载也不回收)—— 一份密钥最多有 `5 ×(含它的 patch 文件数)+ 1` 份明文副本。令牌门禁**管不到磁盘读取**,防线是操作系统的文件权限。清理入口:**设置 → 工具 → 兼容 → 「清理旧备份」**。
182
184
 
183
185
  - **浏览器**:读写走 cookie,不需要令牌;**明文密钥**(显示密钥 / 导出)要令牌。令牌在「兼容」页的「访问令牌」块管理:本次启动填一次管到 DSH 退出;写进配置文件要重启生效。
184
- - **销毁方向一律要当场再输一次当前令牌**(关闭保护 / 修改 / 删除)—— 本次启动解锁过不算,否则"能打开界面就能关掉保护"。
186
+ - **销毁方向一律要当场再输一次当前令牌**(关闭保护 / 修改 / 删除)—— 本次启动解锁过不算。
185
187
  - **curl / 脚本**:带 `x-dsh-token`,或带浏览器 cookie。
186
188
  - **HTTP 状态码**:除安全栅栏的 401 / 403 外,一律 HTTP 200 + `{ ok: false, error }` —— 脚本分流请以 `body.ok` 为准。
187
- - **端口转发**:宿主缺 `connection` 服务时栅栏退到「Host 回环 + 同源」判定,本机进程伪造 `Host: localhost` 即可调用写 op。转发到局域网 / 公网的场景**务必配令牌** —— 陌生人注入 MCP 命令等同远程执行。「选择文件夹」弹窗用的 `dir-list` 能列出任意绝对路径(只读),同一条前提。
188
- - **服务器名里的 `__`(起名建议)**:工具全名是 `mcp__<服务器名>__<工具名>`,所以服务器名里再出现 `__` 会让它**切不唯一** —— `mcp__a__b__c` 既可能是服务器 `a` 的工具 `b__c`,也可能是服务器 `a__b` 的工具 `c`;两个服务器名互为 `__` 前缀(`a` 与 `a__b`)同理。本轮**不收紧校验**(今天放行 `__` 的 5 处校验一旦收紧,存量服务器会从"能管"变成"管不了",而服务器本身照跑),改为在**兼容页**出一条提示。工具照常可用,只是界面上的勾选可能落不到停用表里那条键上 —— **起名时避开 `__` 就没有这个问题**。
189
+ - **端口转发**:宿主缺 `connection` 服务时栅栏退到「Host 回环 + 同源」判定,本机进程伪造 `Host: localhost` 即可调用写 op。转发到局域网 / 公网的场景**务必配令牌** —— 陌生人注入 MCP 命令等同远程执行;「选择文件夹」弹窗用的 `dir-list` 能列出任意绝对路径(只读),同一条前提。
190
+ - **服务器名避开 `__`(起名建议)**:工具全名是 `mcp__<服务器名>__<工具名>`,服务器名里再有 `__` 会让它切不唯一,界面上的勾选可能落不到停用表里那条键上。本轮不收紧校验,改为在**兼容页**出一条提示;起名时避开 `__` 就没有这个问题。
189
191
 
190
192
  ## 常见问题
191
193
 
@@ -198,7 +200,7 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
198
200
  | 模型调不到某条工具 | 「兼容」页的**模型工具表**看它是不是被关了(出厂默认关着 15 条);面板和脚本不受影响。 |
199
201
  | `approval=never` 还要确认吗 | 不弹卡,直接放行并记日志;想问回来切回「工作区内修改」。 |
200
202
  | `subagent_manager_run` 报 provider 不可用 | 对应 provider 没注册:`spawn`(默认)/ `fork`(`inherit`)分别挂 `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` 后重启。 |
201
- | 场景绑了 A 人设,官方 `subagent` 还在跑别的 | 官方那两个是宿主的工具,本插件管不到它们的可见性;插件会把分界写进上下文 —— 贴合人设的走 `subagent_manager_run`,官方只在没有人设贴合或要后台跑时用。 |
203
+ | 场景绑了 A 人设,官方 `subagent` 还在跑别的 | 官方那两个是宿主的工具,本插件管不到;贴合人设的走 `subagent_manager_run`,官方只在没有人设贴合或要后台跑时用。 |
202
204
 
203
205
  ---
204
206
 
package/README_EN.md CHANGED
@@ -39,21 +39,21 @@ Hard-refresh the browser (Cmd/Ctrl+Shift+R) afterwards — a **Tools** panel in
39
39
 
40
40
  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
41
 
42
- | Highlight | What it means |
43
- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
- | One-click scene switch | Each scene carries its own MCP / skills / personas / memories (plus a bound set of quick prompts, if you set one); entering applies them, leaving restores. The model can switch them for you too |
45
- | Manage without leaving chat | Type `/` in the composer for a “Tools” section: enter a scene, toggle skills / MCP / subagents / prompts / memories — one click, done |
46
- | Memories reach the model | A few `.md` files under a scene become its knowledge base — injected automatically, no copy-pasting |
47
- | Notes for MCP servers | Write "if A is down, fall back to B" as a note; the model sees it every turn and acts on it |
48
- | Disable a single tool | Keep a server but mute one tool: invisible and uncallable. "Restart" only reconnects and never flips your switches |
49
- | Skills at a glance | The copy in effect is marked *preferred*; shadowed ones name the source that wins |
50
- | Subagent = one file, one role | Write a role file and delegate to it; only the result comes back, and it never clutters your 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. Under suppressing presets nothing is injected by default — force any domain on in the Host tab |
54
- | Lock it and relax | Locking a scene makes create/update/delete across the five domains read-only until you unlock |
55
- | Deleted is not gone | Skills / memories / personas / presets / scenes land in a recycle bin and can be restored (permanent session deletion is the exception) |
56
- | Safe by default | Secrets masked, plaintext needs a token, only the plugin's own files are written. Masking is display-only — see Configuration & security |
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
57
 
58
58
  ## Quick start
59
59
 
@@ -78,42 +78,43 @@ Then remind me to hard-refresh the browser.
78
78
 
79
79
  ### Slash commands (manage from the chat box)
80
80
 
81
- - **Type `/` to get a “Tools” section**: six rows — scenes / skills / MCP servers / subagents / prompts / memories. Click a row to drop into that domain's items in place (the breadcrumb's “Tools” step goes back), click an item to apply it. **The menu stays open after a click** — keep toggling the next one; batch toggling is the main use.
82
- - **State is visible**: enabled items carry a green check in the icon slot, disabled ones an empty box, and the grey text on the right is the item's own note (scene description / skill description / MCP note / persona description / preset description / memory description, clipped to 40 chars; rows without one fall back to “Enabled / Not enabled”). Each domain row shows a summary (`now: Work`, `3 on / 1 off`), so you know where you stand without opening it. The check flips the moment you click (optimistic); a failed write flips back and says why.
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 inside each group. Each external skill directory also gets one "directory name · directory" row pinned at the top of its group — clicking it toggles the entire source (it is listed while enabled too, so you can switch it off here; its skills collapse with it and come straight back when it is enabled again). The two always-on reserved scenes ("Global" and the shared baseline) don't appear under scenes, but the memories domain includes the global ones by default and pins that group at the top: they aren't in the current scene yet they hold in every conversation.
84
- - **Only reversible actions**: entering a scene and the various toggles. Clicking the scene that's already active leaves it (only global and shared keep injecting); the one thing that can't be switched off is the global prompt — there is no "apply nothing" state for a baseline, so clicking the preset already in effect just says it is the current one. 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 (the same one the official skills menu uses) — no patching of official packages. If the host lacks that service the entry simply never appears and the compatibility page says so. Each section gets its own checkbox (“Tools” / “Quick prompts”) inside the “Slash command entry” group under “Compatibility → Injection”, and the tag at the end of each row says whether it really mounted this startup. The two sections register independently, so switching one off leaves the other alone; turning both off restores the stock `/` menu (restart DSH for the slash-command change to take effect).
86
- - **“Tools › Prompts” holds both kinds of prompt, and every row there is a switch**: the global group is which baseline is written into `AGENTS.md` (single choice), the quick group is whether that snippet is on at all — the same action and the same state as the pill switch on the Prompts page. Quick prompts that are switched off stay listed here: the place you manage things from should not hide an item the moment you manage it.
87
- - **A separate “Quick prompts” section is for reuse**: only the enabled ones appear, and one click replaces the typed token with the saved text in the composer — **nothing is sent for you**; the send key stays yours. Those rows carry no check mark on purpose: clicking one inserts text, it doesn't toggle state.
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.
84
+ - **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.
88
88
 
89
89
  ### Scenes & memories
90
90
 
91
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.
92
- - **"Enabled" and "entered" are two axes.** Enabled decides which scene the injection follows (single-select; none enabled = only `global` and `_shared` inject). Entering applies the scene's whole MCP / skills / personas set and writes its bound prompt into `~/.dsh/AGENTS.md` (5 generations of backups, restored on exit). **They stay identical, and the server is what holds that invariant**: `rules-set-active` brings the runtime in line before it writes the enabled set — and writes nothing at all if the runtime refuses — so every entry point (the UI toggle, the `/` menu, the model tool) needs a single call.
93
- - **Scene profile**: each scene combines MCP tools / skills / subagents / memories. The rule is *ticked = on, unchecked = off*, and a section that was never created means that whole domain is off. Leaving restores the pre-scene state verbatim. While a scene is active, the switches in those three domains still work and are written back into its profile; only locking freezes them.
94
- - **Scene lock**: once locked, create/update/delete across MCP / skills / subagents / memories / prompts is read-only (UI disabled plus a server-side guard). Creating, renaming, binding a prompt, activating or entering a scene, the recycle bin, MCP restart and exports stay outside the frozen list. A scene must be running to lock, and a locked scene cannot be turned off until you unlock it.
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; renaming follows through to the directory and profiles.
96
- - **Import / export**: `.md` / `.zip` (directory name = scene, bundles carry attachments); same names are skipped, never overwritten, and over-limit items are reported. Export packs the memories you tick and only reads source files.
97
- - **Injection budget**: 128 KiB by default; oversized memories are skipped with a list. Deletes go to the recycle bin.
98
- - **Subagent sessions do not receive memories**: memories are the parent's situation, not the facts a child needs. A child's context stays "persona + task" — put what it needs into the task. Other domains are unaffected (MCP / skills / prompts still inject; the persona catalog follows each persona's `catalogDepth`).
92
+ - **"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.
99
99
 
100
100
  ### Subagents
101
101
 
102
- - **One file per persona**: `subagents/<persona>.md`, frontmatter entirely optional. `output:` takes one requirement per line — a checkable output contract (format, severities, bans) gets followed where one abstract sentence does not.
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 (it governs *how* it works, not *what* it may do). The persona file itself needs no change.
104
- - **Delegation**: `subagent_manager_run` runs with the persona, returns only its final result, and never enters History. By default the child starts fresh (so the task must be self-contained); with `inherit: true` it is seeded with this conversation's **finished** turns — not the current one, so a delegation made mid-turn still needs the full story.
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, so the model knows what it can delegate to; personas are renameable and scene bindings follow.
106
- - **Catalog injection depth (`catalogDepth`)**: default `1` = top-level sessions only; `2` also reaches subagent sessions; the UI's "No nesting limit" writes `99`. **It does not limit nesting** — how deep delegation may go is the host's decision, and this plugin never passes `maxDepth`.
107
- - **Tool limits per agent preset**: one allow or deny list per preset (mutually exclusive). Two behaviours worth knowing: **an allow list is merged back with every currently running `mcp__*` tool**, so ticking only `read` will not stop an MCP server that exposes a shell; and **if none of the listed names exists right now, the result is "no restriction"** (fail-open). Naming the reserved `run_code` is stripped from the list with a note, because the host would throw and the subagent would never start.
108
- - **Reasoning effort** sits next to *model* in the advanced options, and the available levels are declared by the selected model. After a model change, a level no longer offered is cleared and you are told. Leaving it empty while a model is set falls back to that model's own default — not the main session's level.
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.
109
110
 
110
111
  ### MCP servers
111
112
 
112
- - **CRUD with immediate effect**: written into `cordis.patch.yml`, backed up before every change. Levels are global / project, and new servers default to global.
113
+ - **CRUD with immediate effect**: written into `cordis.patch.yml`, backed up before every change; levels are global / project.
113
114
  - **Per-tool switches**: disable individual tools (invisible to the model and blocked at call); whole servers support bulk.
114
- - **Stopped servers still show their tools**: one that is not running keeps the names and descriptions last seen (marked "as of last run"); one that never ran can be probed with "start server to read tools".
115
- - **Status and notes enter the context**: currently usable servers are listed, and **one that connected before but cannot right now is listed and labelled too** — so the model says "it is not connected, check it" instead of reading "configured but unreachable" as "not configured" and suggesting you install one. Servers that never connected are omitted; your notes travel along as decision hints.
116
- - **Secret masking**: a credential is replaced **as a whole** by `••••••`, and only for keys that look sensitive; `$VAR` and `!!js` are indirections and stay readable, and a URL's query string, its `user:pass@` userinfo and its `#fragment` are all masked. "Reveal" needs a token. A masked value is never written back into the patch file — on save the plugin restores the stored value for any field you left alone, and refuses the whole save when a URL has nothing to restore from (a silently stripped query string would leave an address that connects but fails authentication).
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.
117
118
  - **Migrate & back up**: cross-level migration rolls back on failure; JSON export/import.
118
119
 
119
120
  ### Skills
@@ -121,35 +122,33 @@ Then remind me to hard-refresh the browser.
121
122
  - **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom directories, grouped by source.
122
123
  - **Opposite permissions**: default sources are readable and their skills deletable; external directories can be disabled or removed but their files stay read-only.
123
124
  - **Remove ≠ disable**: removing stops scanning the directory at all (nothing is written, restorable); disabling keeps it listed but uncallable.
124
- - **Who wins a shared name**: the winning copy is marked "preferred", shadowed ones name the source that wins, and enabling a shadowed copy says plainly that it will not take effect.
125
+ - **Who wins a shared name**: the winning copy is marked "preferred", shadowed ones name the source that wins.
125
126
  - **Custom directories / ZIP import & export / recycle bin.**
126
127
 
127
128
  ### Prompt presets
128
129
 
129
- - Multiple `~/.dsh/AGENTS.md` baselines, applied with one click (the host re-reads that file each turn, so it lands next turn), with 5 generations of backups.
130
- - **It remembers the last applied preset**: even after you hand-edit `AGENTS.md`, the origin is still reported (flagged "the file changed since").
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.
131
132
  - Each preset can carry a one-line description that lives in a sibling `meta.json` — shown in this panel, never injected.
132
- - **A referenced preset cannot be deleted** (scene binding / current `AGENTS.md` content / the copy to restore on scene exit); deletes go to the recycle bin.
133
- - **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`; clicking the one that is already on writes it again (undoing hand edits). There is no "apply nothing" state for a baseline, so this switch cannot be turned off — light up a different one instead (single choice).
134
- - **While a scene drives the baseline, flipping another one rebinds that scene** to the chosen preset (written into the scene profile, realigned immediately); it is refused only while the scene is locked. The global baseline is restored from the snapshot on exit.
135
- - **Quick prompts** (the second section on the same page): save a piece of text you keep typing, then hit `/` in the composer and click it — it lands verbatim in the input, ready to edit and send. It is **never injected**; its switch controls exactly one thing — whether the row still shows up in the `/` “Quick prompts” section (text and note survive when it's off; the same switch is reachable under “Tools › Prompts”). Stored apart from the baselines, deletable to the recycle bin, exportable and included in the migration snapshot.
136
- - **A scene can bind a set of quick prompts**: a new dropdown under “Prompt preset” in “Edit scene”. The default, “The enabled ones (keep as is)”, means the scene does not touch this domain at all; switch it to “Pick per scene” and entering that scene enables exactly the checked ones and disables the rest, **leaving the scene restores the switches as they were before entering**. Checking nothing is "disable all inside this scene", which is the opposite of "not bound".
137
- - **Both groups are collapsible cards** (click the header to fold, and a search query forces them open). The quick group's header carries a “Select all / Deselect all” button that applies to the currently visible rows only; the global group has none — that one is single choice, so "apply every baseline" has no meaning.
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.
138
139
 
139
140
  ### Archived sessions
140
141
 
141
- - Grouped by project, searchable, batch restore / delete, retention auto-cleanup; a workspace whose registration was deleted is rebuilt from the session directories and can be re-registered in one click.
142
- - 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 and results and attachment names → plus reasoning. **An export is still a readable transcript, not a full backup**: the added blocks are capped and say so, and token stats are not included. Use archiving when you need the full record.
142
+ - 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.
143
144
 
144
145
  ### Host compatibility
145
146
 
146
- The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they must be the same physical modules, or every "adapt to the host" decision degrades into guesswork.
147
-
148
- - **Host tab**: host version, usable capability count, per-action routing (native / adapter / unavailable), degradations and reasons. The page has three write entries: **access token** (needs a restart), **injection settings**, **model tool table**.
149
- - **Command line**: `node scripts/doctor.mjs` (health check), `node scripts/host-deps.mjs --fix` (align dependencies), `npm run sync:profile` (mirror the build into the profile's local install — a `file:` install is a hard-linked copy, so files a build *adds* never show up there on their own).
150
- - Under a **suppressing preset** such as `minimal`, this plugin's injection is **off by default** (following the preset's intent) and the prompt and skills are absent because their official rows are not mounted — the Host tab marks this per column, and its Injection block can force any domain back on.
151
- - **Unchecking "Skills" or "Prompt" really stops them** — under standard presets the host delivers those two itself, so unchecking also stops the host's copy. The other three domains are only ever sent by this plugin, so their toggles work as written.
152
- - **What an injection looks like**: one `<system-reminder>` per domain — a `#` section title, then the body (MCP and subagents add one line each). The frame carries **only what is now**: no "when to recall me" instructions, no explanation of the other sections. Any `</system-reminder>` inside your content is escaped, and each message closes with "this copy replaces earlier copies of the same kind in this session" — injections are re-sent only when the content changes, so the model must be told which copy to trust.
147
+ - **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
+ - **Command line**: `node scripts/doctor.mjs` (health check), `node scripts/host-deps.mjs --fix` (align dependencies).
149
+ - 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.
153
152
 
154
153
  ---
155
154
 
@@ -171,24 +170,24 @@ The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they mu
171
170
  | Scene page preference (preview card before entering a scene) | `~/.dsh/tool-management/scene-settings.json` |
172
171
  | Runtime log / patch backups | `~/.dsh/tool-management/tool-management.log` · `backups/` |
173
172
 
174
- **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 — so one bulk action can consume all five slots of a layer.
173
+ **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.
175
174
 
176
175
  ## Configuration & security
177
176
 
178
177
  | Field | What it does |
179
178
  | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
180
179
  | `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. |
181
- | `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. Turning it back on needs no retype. |
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. |
182
181
  | `maxBodyBytes` | Request body cap, 88 MiB by default. |
183
182
 
184
- **Plaintext on disk (read this)**: masking is **display-only**. MCP `env` / `headers` and the plugin's own `token` stay in cleartext inside `~/.dsh/cordis.patch.yml` (and each profile copy), and every config change copies the **whole file** into `~/.dsh/tool-management/backups/` — unencrypted, never rotated, not even 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 real defence is your filesystem permissions. **To clean up: Settings → Tools → Host → "Clean old backups"** — pick how many to delete per layer and confirm once more in the dialog; only backup files are touched. You can also delete them by hand.
183
+ **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"**.
185
184
 
186
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.
187
- - **Every destructive direction asks for the current token again** (turn protection off / change / delete). Being unlocked this run does not count — otherwise anyone who can open the GUI could drop the guard.
186
+ - **Every destructive direction asks for the current token again** (turn protection off / change / delete). Being unlocked this run does not count.
188
187
  - **curl / scripts**: send `x-dsh-token`, or carry the browser cookie.
189
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.
190
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.
191
- - **`__` 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** — `mcp__a__b__c` can be server `a`'s tool `b__c` or server `a__b`'s tool `c`; the same goes for two server names that are `__`-prefix related (`a` and `a__b`). This release deliberately **does not tighten validation** (the 5 places that accept `__` today would turn existing servers from "manageable" into "unmanageable" while the servers themselves keep running); instead the Host tab shows an informational note. The tools keep working — only a checkbox in the UI may fail to land on the key used in the disabled-tools table. **Avoid `__` when naming and none of this applies.**
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.
192
191
 
193
192
  ## FAQ
194
193
 
@@ -201,7 +200,7 @@ The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they mu
201
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. |
202
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. |
203
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. |
204
- | Scene binds persona A, but the official `subagent` ran something else | Those two are host tools and this plugin cannot hide them; it writes the boundary into the context instead — work matching a persona goes to `subagent_manager_run`, host tools only when no persona fits or a background job is needed. |
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
204
 
206
205
  ---
207
206
 
@@ -217,7 +216,7 @@ npm run doctor # host compatibility check
217
216
 
218
217
  `lib/` is not tracked — run `npm run build` after cloning. Changes need `dsh web` restarted. Runtime deps: `fflate` (export bundling) and `js-yaml` (parse check before writing host patches, loaded lazily); `@deepseek-ai/*` all come from the host.
219
218
 
220
- > **Deployment note**: the profile mirror produced by `npm run build` does **not** include `node_modules`, so a runtime dependency added locally (e.g. `js-yaml`) must either be installed on the profile side or accepted as "patch-write check skipped and reported" — the missing checker only disables that one safety net and never blocks writes. Regular `npm install` deployments are unaffected.
219
+ > **Deployment note**: the profile mirror produced by `npm run build` does **not** include `node_modules`, so a runtime dependency added locally (e.g. `js-yaml`) must either be installed on the profile side or accepted as "patch-write check skipped and reported". Regular `npm install` deployments are unaffected.
221
220
 
222
221
  ## License
223
222
 
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
package/docs/update.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  | 版本 | 发布 | 主题 |
6
6
  | ---------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | [0.19.0](#0190---2026-10-07) | 2026-10-07 | 子智能体人设可标「允许追问」+ 修好自 0.15.0 起不可用的 `subagent_manager_run` + 子代理不再把自己当成主代理 + 人设表单「高级选项」重排(模型来源与模型只从目录里选)与模型框变窄修好 + 注入框架不再点名被工具限制砍掉的工具 + 「工具限制」候选修好并分「插件工具 / 官方工具 / 其他工具」三段 |
7
8
  | [0.18.5](#0185---2026-10-05) | 2026-10-05 | 会话导出分三档累进(仅正文 → 正文 + 工具 → 正文 + 工具 + 思考,工具结果有上限并明说截断)+ 导出弹窗放大到 720×760、字段压成三行把位置还给会话列表 + 导入会话可以从已登记工作区里挑 / 浏览文件夹 + 修好归档列表每行「恢复」必弹「操作失败」(其实已经恢复了)与导出的正文里混着思考 |
8
9
  | [0.18.0](#0180---2026-10-01) | 2026-10-01 | 斜杠命令「工具」段(对话里打 `/` 就能进场景、启停六个域,点完不关)+ 快捷提示词(`/` 里点一下贴进输入框;场景可绑定一组)+ 兼容页两段开关与挂载实况 + 提示页药丸开关与可折叠卡片 + 修好分组卡片收不起来、退出场景回执说「什么都没改」、`/` 进 / 出场景不跟着切档案 |
9
10
  | [0.17.0](#0170---2026-09-30) | 2026-09-30 | 对抗性审查收尾(三批 19 条 + 复审 14 条 + 2 条替代项,全部处理):修好 3 处数据丢失与 2 处凭据外泄、停用 MCP 工具仍可调用等**执行侧**守卫失效、场景回收站与记忆索引的恢复问题;MCP 工具全名的切分收敛成一套规则、服务器名含 `__` 的歧义会出声提示 |
@@ -29,6 +30,23 @@
29
30
 
30
31
  ---
31
32
 
33
+ ## 0.19.0 - 2026-10-07
34
+
35
+ - **人设可以标「允许追问」**:勾上后子代理转后台运行,之后可继续追问。
36
+ - **追问与中止复用宿主自带工具**,插件不新增工具。
37
+ - **人设目录与工具列表标「(允许追问)」**。
38
+ - **串行语义改为「至多一次启动在途」**。
39
+ - **修好 `subagent_manager_run` 自 0.15.0 起完全不可用**。
40
+ - **子代理不再把自己当成主代理**。
41
+ - **修好「模型来源」选定后模型那一格变窄**。
42
+ - **注入框架不再点名被工具限制砍掉的工具**。
43
+ - **人设表单「高级选项」重排**:五个字段分三组,提示文字由九处减到一处;模型来源与模型改为只从宿主目录里选(选定来源后模型只列该来源的;目录外的旧值原样列一条「目录里没有」,不再有手填入口);收起态摘要最多两行、只报有值的项。
44
+ - **修好「工具限制」的候选不是该模式自己的工具**:此前四个模式列的是同一份宿主平面清单,界面勾不到 `read` / `write` / `pwsh` 这类官方工具。
45
+ - **「工具限制」的候选按「插件工具 / 官方工具 / 其他工具」分三段**。
46
+ - **「工具限制」的候选不再返回全体并集**。
47
+
48
+ ---
49
+
32
50
  ## 0.18.5 - 2026-10-05
33
51
 
34
52
  - **导出分三档,累进**:仅正文 → 正文 + 工具 → 正文 + 工具 + 思考,每档都是上一档的超集。工具结果按上限截断并写明原文一共多长 —— 一次文件读取就能有几 MB,不设限的话一个会话就能导出上百 MB。