dsh-plugin-tool-management 0.20.3 → 0.21.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 +37 -0
- package/README.md +4 -1
- package/README_EN.md +4 -1
- package/docs/update.md +1 -0
- package/lib/client.js +117 -11
- package/lib/compat/capability-specs.js +60 -1
- package/lib/compat/host-contracts.js +72 -0
- package/lib/compat/host-probe.js +59 -0
- package/lib/compat/host-roots.js +1 -1
- package/lib/compat/probe.js +84 -13
- package/lib/context-inject-frame.js +134 -26
- package/lib/context-inject.js +12 -9
- package/lib/http-api.js +3 -2
- package/lib/http-fence.js +26 -1
- package/lib/index.js +5 -2
- package/lib/mcp/manager.js +6 -1
- package/lib/mcp/state-section.js +75 -34
- package/lib/memories/constants.js +39 -7
- package/lib/memories/projection.js +18 -18
- package/lib/memories/service.js +8 -7
- package/lib/memories/snapshot.js +27 -17
- package/lib/ops/compat.js +64 -2
- package/lib/ops/memory.js +2 -2
- package/lib/ops/prompts.js +30 -2
- package/lib/request-gate.js +5 -4
- package/lib/skills/catalog.js +2 -2
- package/lib/subagents/catalog.js +4 -4
- package/lib/subagents/child-preset.js +120 -0
- package/lib/subagents/persona-parse.js +9 -9
- package/lib/subagents/run-provider.js +218 -62
- package/lib/subagents/tool-filter.js +12 -12
- package/lib/subagents/tools.js +29 -22
- package/lib/tools/deps.js +4 -4
- package/lib/tools/mcp.js +34 -34
- package/lib/tools/memory.js +34 -34
- package/lib/tools/prompt.js +5 -5
- package/lib/tools/remove.js +17 -17
- package/lib/tools/scene.js +66 -66
- package/lib/tools/skills.js +21 -21
- package/lib/tools/subagent.js +13 -13
- package/lib/tools/table.js +2 -2
- package/package.json +25 -24
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,43 @@
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [0.21.0] - 2026-10-17
|
|
14
|
+
|
|
15
|
+
适配 DSH 0.2.1-rc.2。
|
|
16
|
+
|
|
17
|
+
### 新增
|
|
18
|
+
|
|
19
|
+
- **提示词页显示共享的全局指令文件**:`~/.agents/AGENTS.md` 也在被注入,改这里没生效时能看出是那一份在说话。
|
|
20
|
+
- **兼容页功能总览新增四条宿主契约行**:子智能体人设委派、子代理工具限制、子代理创建时序、Web 连接准入 —— 这几项缺了不抛错、只是功能少一半,升级后第一眼可见。
|
|
21
|
+
- **兼容页新增「裸模块解析」一块**:列出插件按裸名 require 的四个官方包(MCP 客户端 / 人设 / AGENTS.md / 技能目录)与各自守住的契约标识,官方撤包或改契约从此在界面上可见,不再只有命令行能看见。
|
|
22
|
+
- **兼容页功能总览的依据写实**:子智能体与提示词两行改报「依赖的宿主模块在场」,不再用一句恒真的「无降级上报」糊过去。
|
|
23
|
+
|
|
24
|
+
### 修复
|
|
25
|
+
|
|
26
|
+
- **人设的工具限制不再慢一步**:改为在子代理创建时就施加,首轮工具调用前已生效。
|
|
27
|
+
- **面板可以挂在反向代理子路径下**:请求地址按页面地址解析,不再固定写死根路径。
|
|
28
|
+
- **带工具限制的 fork 委派会明确报错**,不再静默放宽权限。
|
|
29
|
+
- **Web 版鉴权补上调用方身份**:只有本机所有者身份的请求才会被受理。
|
|
30
|
+
|
|
31
|
+
### 变更
|
|
32
|
+
|
|
33
|
+
- **插件依赖与兼容范围对齐 DSH 0.2.1-rc.2**:兼容范围按代设上界,跨 minor 升级需同步适配。
|
|
34
|
+
- **doctor 不再把 `connection.admit` 误报成缺失**:该包不是插件依赖,静态检查改从宿主安装读取;宿主安装也取不到时如实报「只能对活宿主查」,而不是编一个「缺失」。
|
|
35
|
+
- **子智能体临时预设改为引用计数**:同一组合复用定义,失败时释放,不再在预设库里堆积。
|
|
36
|
+
- **允许追问的回执改说结算通知**:完成后会收到一条带着最终产出的通知。
|
|
37
|
+
- **子代理嵌套深度的注释修正为官方默认 1**。
|
|
38
|
+
- **注入到模型的模板文案改成英文**:板块标题、取代声明、补充说明、清空 / 截断 / 未列出这些提示;提示词正文首行改用官方的 `Instructions from:` 写法。场景名与说明、记忆正文、备注、`AGENTS.md` 等你自己写的内容仍原样注入。
|
|
39
|
+
- **模型侧的工具输出与报错也改英文**:工具回执、校验失败与警告一律英文;面板文案仍中英双语,你自己写的名称与正文原样。
|
|
40
|
+
- **技能、MCP、子智能体三个注入了工具名的板块补上触发条件**:写清什么时候该查这张表、什么时候该走带人设的委派;并说明取正文的工具被关掉、服务器未连接、人设不可调用时该怎么读。技能块首句补一句定义(技能是按需加载的任务指令集)。
|
|
41
|
+
- **场景块补一句定义**:说明记忆、提示词、工具与人设都已按当前场景筛过,不再只给场景名与说明。
|
|
42
|
+
- **MCP 段常驻,并补上第三档状态**:只要有一台该说的 server 就发,不因没有备注而省略;「连着但工具全被停掉」标成 `no tools enabled here`,不再与「没配过」混为一谈;说明行仍按内容发,超过上限时点名 `mcp_manager_list`。
|
|
43
|
+
- **记忆段的截断态改成给模型读的文案**:截断标记不再是一句 HTML 注释,未注入清单不再带字节数;真截断时不再声称「这是全部」。
|
|
44
|
+
- **「已清空」通知按原因分叉**:官方接管时说明是官方在送、旧内容作废;用户关掉或子会话不适用时说明这里不发送。
|
|
45
|
+
- **注入的首份内容不再带「取代」声明**:「同一类内容以最新一份为准」只在替换旧消息时发,「只列了启用的技能」这类边界陈述每份都发。
|
|
46
|
+
- **提示词块补一句效力声明**:说明这些规则要遵循、你在对话里说的优先。
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
13
50
|
## [0.20.3] - 2026-10-17
|
|
14
51
|
|
|
15
52
|
界面与官方对齐一批:焦点环、圆角、等宽字体改用官方 token;修好 MCP 连接失败时状态灯不红、新建记忆弹窗误关丢内容。
|
package/README.md
CHANGED
|
@@ -147,6 +147,7 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
|
|
|
147
147
|
- **「取消应用」一步回到链起点**,不是只退一步:这一串应用 / 取消往复开始之前是什么样就恢复成什么样(起点没有 `AGENTS.md` 就把文件删掉);中途每一份内容都留在 `__last-applied__/AGENTS.md.bak-*`(保留 5 代),随时能再应用回来。
|
|
148
148
|
- **两类不能直接删**:**被场景绑定的**、以及**当前应用的那一份**(后者先点开关「取消应用」就能删);首次打开时自动生成的那份没「应用」过,可以直接删。删除一律进回收站。
|
|
149
149
|
- **快捷提示词**(同页第二段):存一段常用的话,`/` 里点一下就原样贴进输入框;场景可以绑定一组(进入只启用勾的那几条、退出按进场景前还原,也可选「无」)。
|
|
150
|
+
- **共享的全局指令也能看见**:`~/.agents/AGENTS.md` 与别的 agent 工具共用、也在被注入;它存在时提示词页会标出来(只读,改它要去改那个文件)。
|
|
150
151
|
|
|
151
152
|
### 历史会话
|
|
152
153
|
|
|
@@ -157,10 +158,11 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
|
|
|
157
158
|
### 宿主兼容
|
|
158
159
|
|
|
159
160
|
- **「兼容」页**:宿主版本、能力可用数、每个动作走原生 / 适配 / 不可用、降级项与原因;三个写入口:访问令牌、注入设置、模型工具表。
|
|
161
|
+
- **兼容页功能总览**:一行一个功能点,宿主契约四条(子智能体人设委派 / 工具限制 / 创建时序 / Web 准入)与「裸模块解析」四包都列在这里,升级后哪一处悄悄不工作一眼可见。
|
|
160
162
|
- **命令行**:`node scripts/doctor.mjs`(体检)、`node scripts/host-deps.mjs --fix`(依赖对齐)。
|
|
161
163
|
- **压制型预设**(`minimal` 这类)下本插件的注入默认停用,可在「兼容」页按域强制打开。
|
|
162
164
|
- **关掉「技能」「提示词」的勾选 = 连宿主那份一起停**(这两域在标准预设下由官方送);其余三域勾选完全生效。
|
|
163
|
-
- **注入长什么样**:每个域一条 `<system-reminder
|
|
165
|
+
- **注入长什么样**:每个域一条 `<system-reminder>` —— 英文模板(`# Current …` 等板块标题 + 一句"以本份为准")包着你自己的内容,名称、说明、备注、正文一律原样注入;正文里的 `</system-reminder>` 会被转义。
|
|
164
166
|
|
|
165
167
|
---
|
|
166
168
|
|
|
@@ -211,6 +213,7 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
|
|
|
211
213
|
| 重复 MCP 页签 | 删 `cordis.patch.yml` 里的旧 loader 行后重启。 |
|
|
212
214
|
| 改坏配置 DSH 起不来 | 从 `~/.dsh/tool-management/backups/` 取最近的 `cordis.patch.yml.<层级>.bak-<时间戳>` 覆盖回去(每份 patch 各留 5 份)。 |
|
|
213
215
|
| 升级 DSH 后动作不可用 | 设置 → 工具 → **兼容** 看原因;`doctor.mjs` → `host-deps.mjs --fix`。 |
|
|
216
|
+
| 升级 DSH 后装不上 / 提示 peer 不符 | 兼容范围逐代带上界(当前一代到 `<0.2.2`),跨 minor 升级要等插件同步适配(装新宿主前先升插件)。 |
|
|
214
217
|
| 模型调不到某条工具 | 「兼容」页的**模型工具表**看它是不是被关了(出厂默认关着 19 条);面板和脚本不受影响。 |
|
|
215
218
|
| `approval=never` 还要确认吗 | 不弹卡,直接放行并记日志;想问回来切回「工作区内修改」。 |
|
|
216
219
|
| `subagent_manager_run` 报 provider 不可用 | 对应 provider 没注册:`spawn`(默认)/ `fork`(`inherit`)分别挂 `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` 后重启。 |
|
package/README_EN.md
CHANGED
|
@@ -145,6 +145,7 @@ For the desktop app, swap `web` for `desktop` and end with "remind me to restart
|
|
|
145
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
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
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").
|
|
148
|
+
- **The shared global instruction file is visible too**: `~/.agents/AGENTS.md` is shared with other agent tools and is also injected; when it exists the page says so (read-only — edit that file to change it).
|
|
148
149
|
|
|
149
150
|
### Archived sessions
|
|
150
151
|
|
|
@@ -155,10 +156,11 @@ For the desktop app, swap `web` for `desktop` and end with "remind me to restart
|
|
|
155
156
|
### Host compatibility
|
|
156
157
|
|
|
157
158
|
- **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.
|
|
159
|
+
- **Compatibility page overview**: one row per feature point. The four host contracts (subagent persona delegation / tool restriction / creation ordering / Web admission) and the "bare module resolution" block all live there — a feature that silently stops working after a host upgrade shows up at a glance.
|
|
158
160
|
- **Command line**: `node scripts/doctor.mjs` (health check), `node scripts/host-deps.mjs --fix` (align dependencies).
|
|
159
161
|
- Under a **suppressing preset** such as `minimal`, this plugin's injection is off by default; the Host tab can force any domain back on.
|
|
160
162
|
- 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 — `#
|
|
163
|
+
- **What the injection looks like**: one `<system-reminder>` per domain — an English frame (`# Current …` headings plus a "this one wins" line) around your own content: names, descriptions, notes and bodies are injected verbatim; a `</system-reminder>` inside the body is escaped.
|
|
162
164
|
|
|
163
165
|
---
|
|
164
166
|
|
|
@@ -208,6 +210,7 @@ The six recycle bins each own one directory under `trash/`: `{skills,memories,su
|
|
|
208
210
|
| Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
|
|
209
211
|
| 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
212
|
| Action stopped working after a DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
|
|
213
|
+
| Won't install / peer mismatch after a DSH upgrade | Each generation has its own upper bound (the current one stops below 0.2.2); a minor upgrade needs a matching plugin release (upgrade the plugin before the host). |
|
|
211
214
|
| The model cannot call a tool it should have | Check the **Model tool table** on the Host tab — 19 tools ship switched off. The panel and scripts are unaffected either way. |
|
|
212
215
|
| 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
216
|
| `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. |
|
package/docs/update.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| 版本 | 发布 | 主题 |
|
|
6
6
|
| ------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| [0.21.0](../CHANGELOG.md#0210---2026-10-17) | 2026-10-17 | 适配 DSH 0.2.1-rc.2:人设工具限制提到创建时生效、面板可挂反代子路径、Web 鉴权补调用方身份、提示词页显示 ~/.agents/AGENTS.md;兼容页补四条宿主契约行与「裸模块解析」一块;注入模板文案改英文(自己的内容原样注入) |
|
|
7
8
|
| [0.20.3](../CHANGELOG.md#0203---2026-10-17) | 2026-10-17 | 界面与官方对齐一批(焦点环、圆角、等宽字体);修好 MCP 连接失败状态灯不红、新建记忆弹窗误关丢内容、焦点环盖掉宿主「不要轮廓」设定(#18) |
|
|
8
9
|
| [0.20.2](../CHANGELOG.md#0202---2026-10-16) | 2026-10-16 | 界面降噪一批:行尾动作收进 ⋯、没在用的分组默认折叠、会话整行可点勾选;修好折叠卡片要点两次才展开与 npm 包带上演示视频 |
|
|
9
10
|
| [0.20.1](../CHANGELOG.md#0201---2026-10-16) | 2026-10-16 | 修好技能状态文件出错时全线停用等三处;新增五个域的删除 / 回收站工具;MCP 支持粘贴补丁片段导入;创建技能可带附件;弹窗误关不再丢内容;一批排版与文案收短 |
|
package/lib/client.js
CHANGED
|
@@ -1658,7 +1658,12 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
1658
1658
|
// without a CORS preflight that this route never answers.
|
|
1659
1659
|
const headers = { 'content-type': 'application/json', 'x-dsh-plugin': 'dsh-plugin-tool-management' }
|
|
1660
1660
|
if (TOKEN) headers['x-dsh-token'] = TOKEN
|
|
1661
|
-
|
|
1661
|
+
// **按 document.baseURI 解析**,不写死 '/':宿主可以被挂在反代 / 静态服务器的
|
|
1662
|
+
// 子路径下(base 存在于 index.html 的 <base> 里),写死 '/' 时浏览器会向宿主
|
|
1663
|
+
// 站点的根本身发请求,面板整页 404 —— 而那时宿主与插件都"装对了"。
|
|
1664
|
+
// baseURI 总是绝对 URL(文档没有 base 时等于 location.href 去掉 query/hash),
|
|
1665
|
+
// 所以这里不需要再判断它是不是绝对路径。
|
|
1666
|
+
return fetch(new URL('dsh-plugin-tool-management/api', document.baseURI).toString(), {
|
|
1662
1667
|
method: 'POST',
|
|
1663
1668
|
headers,
|
|
1664
1669
|
body: JSON.stringify({ op, args: args || {} }),
|
|
@@ -1914,6 +1919,20 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
1914
1919
|
list: 'compat.op.list', archive: 'compat.op.archive', unarchive: 'compat.op.unarchive',
|
|
1915
1920
|
batch: 'compat.op.batch', delete: 'compat.op.delete',
|
|
1916
1921
|
}
|
|
1922
|
+
/**
|
|
1923
|
+
* 0.2.1 起**新增**的宿主契约能力 id(capability-specs.ts 的那四条)。
|
|
1924
|
+
*
|
|
1925
|
+
* 与上面那排 action 的区别:action 是"这个操作走哪条路",这些是"某个契约还在不在"。
|
|
1926
|
+
* 它们缺了都不抛错、只是功能少一半,所以单独一块而不是混进 action 表 —— 混进去会让
|
|
1927
|
+
* "删除不可用"和"工具限制失效"看起来一样严重,实际后者不影响你删任何东西。
|
|
1928
|
+
*
|
|
1929
|
+
* 键集必须与服务端 `CONTRACT_CAPABILITY_IDS` 对齐:那里按 feature-overview 的行 key 映射
|
|
1930
|
+
* 到能力 id,这里按能力 id 过滤 findings。两边任一处改名,另一处会在界面上静默失效
|
|
1931
|
+
* (契约行不再出现),所以加了就两处一起加。
|
|
1932
|
+
*/
|
|
1933
|
+
var CONTRACT_CAPABILITY_IDS = [
|
|
1934
|
+
'agentPreset.register', 'tools.restrict-method', 'agent.created-event', 'connection.admit',
|
|
1935
|
+
]
|
|
1917
1936
|
/**
|
|
1918
1937
|
* 「最近改动」流水里 op 的人类名(0.15.0 B2)。
|
|
1919
1938
|
*
|
|
@@ -2644,6 +2663,10 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
2644
2663
|
case 'sessions.cold-announce': return t('compat.cap.sessionsColdAnnounce')
|
|
2645
2664
|
case 'projection.write': return t('compat.cap.projectionWrite')
|
|
2646
2665
|
case 'projection.table-delete': return t('compat.cap.projectionTableDelete')
|
|
2666
|
+
case 'agentPreset.register': return t('compat.cap.agentPresetRegister')
|
|
2667
|
+
case 'tools.restrict-method': return t('compat.cap.toolsRestrictMethod')
|
|
2668
|
+
case 'agent.created-event': return t('compat.cap.agentCreatedEvent')
|
|
2669
|
+
case 'connection.admit': return t('compat.cap.connectionAdmit')
|
|
2647
2670
|
case 'archive': return t('compat.cap.opArchive')
|
|
2648
2671
|
case 'unarchive': return t('compat.cap.opUnarchive')
|
|
2649
2672
|
case 'batch': return t('compat.cap.opBatch')
|
|
@@ -2679,6 +2702,10 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
2679
2702
|
case 'prompts': return t('compat.ov.prompts')
|
|
2680
2703
|
case 'subagents': return t('compat.ov.subagents')
|
|
2681
2704
|
case 'scenes': return t('compat.ov.scenes')
|
|
2705
|
+
case 'subagent-persona': return t('compat.ov.subagentPersona')
|
|
2706
|
+
case 'subagent-tool-restrict': return t('compat.ov.subagentToolRestrict')
|
|
2707
|
+
case 'subagent-created-event': return t('compat.ov.subagentCreatedEvent')
|
|
2708
|
+
case 'web-admission': return t('compat.ov.webAdmission')
|
|
2682
2709
|
default: return null
|
|
2683
2710
|
}
|
|
2684
2711
|
}
|
|
@@ -2763,8 +2790,17 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
2763
2790
|
if (row.asarHost) return t('compat.ov.hostIdentity.asar', { version: row.version, name: row.asarName || 'app.asar' })
|
|
2764
2791
|
return t('compat.ov.hostIdentity.ok', { version: row.version })
|
|
2765
2792
|
}
|
|
2793
|
+
if (row.key === 'subagent-persona' || row.key === 'subagent-tool-restrict' || row.key === 'subagent-created-event' || row.key === 'web-admission') {
|
|
2794
|
+
// 宿主契约行:可用时说的是"运行时看到的那份实现"(它的 detail 由探针写成"成员齐备"),
|
|
2795
|
+
// 降级时说的是"这条契约没了,对应功能少一半"——两个方向都得按语言说。
|
|
2796
|
+
return row.state === 'unknown' ? t('compat.ov.route.unknown')
|
|
2797
|
+
: row.state === 'ok' ? t('compat.ov.contract.ok')
|
|
2798
|
+
: t('compat.ov.contract.degraded', { detail: row.detail })
|
|
2799
|
+
}
|
|
2766
2800
|
if (row.state === 'ok' && (row.key === 'memory' || row.key === 'prompts' || row.key === 'subagents' || row.key === 'scenes')) {
|
|
2767
|
-
|
|
2801
|
+
// 有宿主模块可核的域(提示词 / 子智能体)按实况说;确实没有可核对象的才说"无降级上报"。
|
|
2802
|
+
if (row.key === 'memory' || row.key === 'scenes') return t('compat.ov.plain.ok')
|
|
2803
|
+
return t('compat.ov.domain.contract', { detail: row.detail })
|
|
2768
2804
|
}
|
|
2769
2805
|
return row.detail
|
|
2770
2806
|
}
|
|
@@ -3439,7 +3475,8 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
3439
3475
|
card(t('compat.caps'), String(usableCount) + '/' + String(findings.length), capsNote, degraded.length > 0)))
|
|
3440
3476
|
|
|
3441
3477
|
// 版本栅栏(B3):实际宿主与本插件验证过的版本不同时说出来 —— 否则"照旧版本的印象
|
|
3442
|
-
// 判断"会让人把探测结果当成 bug。只提示、不拦(peer
|
|
3478
|
+
// 判断"会让人把探测结果当成 bug。只提示、不拦(peer 的上界只管**安装期**收不收,
|
|
3479
|
+
// 这里管的是"已经跑起来了,版本对不上要说一声":同代的 rc 差异提示一次即可)。
|
|
3443
3480
|
const hostVersion = (data.host && data.host.version) || ''
|
|
3444
3481
|
if (hostVersion && data.verifiedVersion && hostVersion !== data.verifiedVersion) {
|
|
3445
3482
|
push(React.createElement('p', { className: 'dsm-help' },
|
|
@@ -3481,6 +3518,24 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
3481
3518
|
blockers.map(function (item, i) { return React.createElement('li', { key: i }, item) })))))
|
|
3482
3519
|
}
|
|
3483
3520
|
|
|
3521
|
+
// 宿主契约(0.2.1 新增的三处适配面 + Web 连接准入):这几条在能力表里是**必填项**,
|
|
3522
|
+
// 不是"宿主没有、插件自己顶上"的可选槽。缺了不抛错,只是功能少一半 —— 所以单独一块
|
|
3523
|
+
// 列出来,让"升级后某处悄悄不工作"有一个显眼的位置。
|
|
3524
|
+
const contractFindings = findings.filter(function (item) {
|
|
3525
|
+
return CONTRACT_CAPABILITY_IDS.indexOf(item.id) !== -1 && item.state !== 'ok'
|
|
3526
|
+
})
|
|
3527
|
+
push(section(t('compat.contracts'), t('compat.contracts.hint'),
|
|
3528
|
+
contractFindings.length === 0
|
|
3529
|
+
? React.createElement('p', { className: 'dsm-help' }, t('compat.contracts.allOk'))
|
|
3530
|
+
: React.createElement('div', { className: 'dsm-compat-mod-list dsm-compat-cards' },
|
|
3531
|
+
contractFindings.map(function (item) {
|
|
3532
|
+
return React.createElement('div', { className: 'dsm-compat-mod-row', key: item.id },
|
|
3533
|
+
React.createElement('span', { className: 'dsm-compat-name' }, capLabel(item.id, item.label)),
|
|
3534
|
+
React.createElement('span', { className: 'dsm-compat-pill dsm-compat-pill-warn' }, t('compat.contracts.missing')),
|
|
3535
|
+
React.createElement('span', { className: 'dsm-compat-mod dsm-compat-mod-self' },
|
|
3536
|
+
React.createElement('span', { className: 'dsm-compat-label' }, t('compat.reason')), item.detail))
|
|
3537
|
+
}))))
|
|
3538
|
+
|
|
3484
3539
|
// 动作可用性:一行一个动作 + 路径标记(不可用的标红)。
|
|
3485
3540
|
push(section(t('compat.ops'), t('compat.ops.hint'),
|
|
3486
3541
|
React.createElement('div', { className: 'dsm-compat-mod-list' },
|
|
@@ -3520,6 +3575,10 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
3520
3575
|
// 其它非 ok 项:`optional` 表示"宿主没有这个入口,插件自己顶上"——功能完好,
|
|
3521
3576
|
// 既不算降级,也不能说按钮被禁用(那句只对真降级成立;早先把两者混在一起
|
|
3522
3577
|
// 会让用户以为删除功能坏了,实际它照常可用)。
|
|
3578
|
+
//
|
|
3579
|
+
// 与上面「宿主契约」那块的区别:这里的条目缺了,插件**自有等价实现**(适配路完整可用);
|
|
3580
|
+
// 那块的条目缺了,没有替代实现,功能就是少一半。两块都是"非 ok",但后果不同,
|
|
3581
|
+
// 所以分开显示、各自的胶囊文案也不同。
|
|
3523
3582
|
const optionalAbsent = findings.filter(function (item) { return item.state !== 'ok' && item.optional === true })
|
|
3524
3583
|
if (optionalAbsent.length) {
|
|
3525
3584
|
push(section(t('compat.others'), t('compat.others.hint'),
|
|
@@ -3566,6 +3625,31 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
3566
3625
|
React.createElement('span', { className: 'dsm-compat-pill ' + cls }, text))
|
|
3567
3626
|
}))))
|
|
3568
3627
|
|
|
3628
|
+
// 裸模块解析(与上面那一块的分工:上面比的是**同一份物理模块**,这里看的是**包还在不在**)。
|
|
3629
|
+
//
|
|
3630
|
+
// 为什么分开:上面那 6 个包是插件的 peerDependency,「两份不同拷贝」那种故障只可能发生在
|
|
3631
|
+
// 它们身上;而下面这 4 个包是插件按**裸模块名**在运行时 require 的官方包,宿主不要求插件
|
|
3632
|
+
// 依赖它们。官方撤掉其中一个,对应功能静默降级,而身份比对那一栏根本看不见它们 —— 所以
|
|
3633
|
+
// 必须在这里列一行。canary 缺失不是「包坏了」,是「该人工复核这条契约」,显示成提示而非红色。
|
|
3634
|
+
const contractPackages = (data && data.contracts && data.contracts.packages) || []
|
|
3635
|
+
if (contractPackages.length) {
|
|
3636
|
+
push(section(t('compat.bareModules'), t('compat.bareModules.hint'),
|
|
3637
|
+
React.createElement('div', { className: 'dsm-compat-mod-list dsm-compat-cards' },
|
|
3638
|
+
contractPackages.map(function (item) {
|
|
3639
|
+
const missing = item.resolved === null
|
|
3640
|
+
const drifted = !missing && (item.missingMarkers || []).length > 0
|
|
3641
|
+
return React.createElement('div', { className: 'dsm-compat-mod-row', key: item.package },
|
|
3642
|
+
React.createElement('span', { className: 'dsm-compat-name dsm-compat-mod' }, item.package),
|
|
3643
|
+
React.createElement('span', { className: 'dsm-compat-pill ' + (missing ? 'dsm-compat-pill-bad' : drifted ? 'dsm-compat-pill-warn' : 'dsm-compat-pill-ok') },
|
|
3644
|
+
missing ? t('compat.bareModules.absent') : drifted ? t('compat.bareModules.drift') : t('compat.bareModules.present')),
|
|
3645
|
+
React.createElement('span', { className: 'dsm-compat-mod dsm-compat-mod-self' },
|
|
3646
|
+
React.createElement('span', { className: 'dsm-compat-label' }, t('compat.reason')),
|
|
3647
|
+
missing ? t('compat.bareModules.absentWhy', { feature: item.feature })
|
|
3648
|
+
: drifted ? t('compat.bareModules.driftWhy', { feature: item.feature, markers: (item.missingMarkers || []).join('、') })
|
|
3649
|
+
: t('compat.bareModules.presentWhy', { feature: item.feature })))
|
|
3650
|
+
}))))
|
|
3651
|
+
}
|
|
3652
|
+
|
|
3569
3653
|
// 「无法比对」必须给原因:否则一排未知标记看起来只是噪音,用户会当成正常现象。
|
|
3570
3654
|
// 归档宿主的说明排最前 —— 它解释的正是这一排「无法比较」的成因,而且必须讲明白
|
|
3571
3655
|
// **不要去跑 host-deps --fix**:那条命令会把插件的依赖指向 npx 缓存里另一个版本。
|
|
@@ -4249,6 +4333,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4249
4333
|
// 是服务端动态中文尾巴,EN 界面显示英文框架 + 中文细节(比整句中文可读)。
|
|
4250
4334
|
"error.rules.sceneNotFound": "场景不存在:{group}(请先在「场景」页创建该场景)",
|
|
4251
4335
|
"error.rules.reservedScene": "「{name}」是保留场景,不可{action}{reason}",
|
|
4336
|
+
"error.rules.sceneNotActive": "场景未启动:先启动再锁定",
|
|
4252
4337
|
"error.rules.singleSceneOnly": "除「全局」外同时只能启用一个场景{detail}",
|
|
4253
4338
|
"error.agentsMd.sceneRebindFailed": "无法把场景「{scene}」的提示词绑定改成「{target}」:{reason}",
|
|
4254
4339
|
"error.agentsMd.referenced": "「{id}」不能删除:{refs}。先解除引用再删 —— 场景绑定的去场景页换绑提示词、或退出场景;正被应用的那份先点左边那颗开关「取消应用」。", "error.agentsMd.refProbeFailed": "无法确认「{id}」是否被引用,已拒绝删除:引用探测失败(场景绑定 / AGENTS.md 当前内容 / 进场景前的基线,这三类里至少有一类没读到)。请稍后重试。", "error.agentsMd.noUnapplyBackup": "没有可恢复的「应用之前的状态」:AGENTS.md 的当前内容不是由「应用」写进去的(例如首次打开时自动生成的那份预设),所以没有起点可回。要改掉文件里的内容:应用别的预设,或直接编辑 AGENTS.md 本身。", "error.agentsMd.unapplyWhileScene": "场景「{scene}」正在驱动全局基线,不能在这里取消应用:先退出场景,或到场景页改掉它的提示词绑定。",
|
|
@@ -4464,7 +4549,9 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4464
4549
|
"compat.op.batch": "批量归档", "compat.op.delete": "永久删除",
|
|
4465
4550
|
"compat.op.native": "宿主原生入口", "compat.op.adapter": "插件适配层", "compat.op.unavailable": "不可用(已禁用)",
|
|
4466
4551
|
"compat.degraded": "已降级能力", "compat.degraded.hint": "缺什么 + 后果", "compat.reason": "原因:",
|
|
4467
|
-
"compat.others": "其它能力项", "compat.others.hint": "不算降级:宿主没有这些入口时,由插件自己顶上",
|
|
4552
|
+
"compat.others": "其它能力项", "compat.others.hint": "不算降级:宿主没有这些入口时,由插件自己顶上",
|
|
4553
|
+
"compat.contracts": "宿主契约", "compat.contracts.hint": "本版适配依赖的宿主成员:缺了不抛错,但对应功能会少一半", "compat.contracts.missing": "不在位", "compat.contracts.allOk": "本版依赖的宿主契约全部在位。",
|
|
4554
|
+
"compat.bareModules": "裸模块解析", "compat.bareModules.hint": "插件在运行时按裸模块名 require 的官方包:它们不是 peer,所以不参与上面的模块比对", "compat.bareModules.present": "在位", "compat.bareModules.absent": "宿主未提供", "compat.bareModules.drift": "契约疑似漂移", "compat.bareModules.presentWhy": "影响:{feature}", "compat.bareModules.absentWhy": "宿主已不提供这个包:{feature}会降级", "compat.bareModules.driftWhy": "{feature}的契约标识有缺失({markers})—— 请人工核对该包的实现是否改过",
|
|
4468
4555
|
"compat.fallback.substituted": "插件适配层(宿主无此入口)",
|
|
4469
4556
|
"compat.fallback.native": "改走原生入口", "compat.fallback.refuse": "该操作会被拒绝", "compat.fallback.blocked": "相关按钮已禁用", "compat.fallback.inform": "不影响写入",
|
|
4470
4557
|
"compat.modules": "模块实体(插件 vs 宿主)", "compat.modules.hint": "同一份模块才谈得上适配", "compat.module.same": "同一份模块", "compat.module.separate": "两份拷贝(需修复)", "compat.module.sameVersion": "同版本(分处归档内外)", "compat.module.unknown": "无法比较", "compat.module.realpath": "无法比较(路径取不到真实形态)", "compat.modules.realpath": "有 {count} 个包**比不了**:它们的路径取不到真实形态({names})—— 这不是「两份拷贝」,而是这项校验没做成。", "compat.modules.realpathSides": "宿主侧:{host};插件侧:{plugin}。修好路径(权限 / 路径长度 / 重新安装)后重新打开本页即重算。", "compat.modules.realpathNone": "无", "compat.modules.unverified": "有 {count} 个包没能比对(宿主的解析锚点里找不到:{names})—— 这不是「两份拷贝」,而是这项校验没做成。可运行 node scripts/doctor.mjs 查看。",
|
|
@@ -4496,7 +4583,11 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4496
4583
|
"compat.ov.nativeDelete": "宿主原生删除入口", "compat.ov.nativeDelete.ok": "宿主未提供原生删除入口(本插件自有完整序列)",
|
|
4497
4584
|
"compat.ov.hostIdentity": "宿主身份与模块", "compat.ov.hostIdentity.ok": "模块与宿主同源(宿主 DSH {version})", "compat.ov.hostIdentity.asar": "官方包与宿主同版本(DSH {version}),但宿主跑在 {name} 里、插件在归档外", "compat.ov.hostIdentity.degraded": "存在阻塞项:{list}",
|
|
4498
4585
|
"compat.ov.memory": "记忆", "compat.ov.prompts": "提示词", "compat.ov.subagents": "子智能体", "compat.ov.scenes": "场景档案",
|
|
4586
|
+
"compat.ov.subagentPersona": "子智能体人设委派", "compat.ov.subagentToolRestrict": "子代理工具限制", "compat.ov.subagentCreatedEvent": "子代理创建时序", "compat.ov.webAdmission": "Web 连接准入",
|
|
4499
4587
|
"compat.ov.plain.ok": "无降级上报(装配失败会出现在这里)",
|
|
4588
|
+
"compat.ov.contract.ok": "宿主契约在位(这一项缺了,对应功能会静默少一半)",
|
|
4589
|
+
"compat.ov.contract.degraded": "宿主契约不在位:{detail}",
|
|
4590
|
+
"compat.ov.domain.contract": "依赖的宿主模块在位:{detail}",
|
|
4500
4591
|
// ── 斜杠命令「工具」段(对话输入框里直接管六个域;实现见 48-slash.js)──────
|
|
4501
4592
|
// 段标题与六个域名出现在宿主 `/` 菜单里;域名要短 —— 菜单行右侧还要留位置给摘要与 › 箭头。
|
|
4502
4593
|
"slash.section.tools": "工具",
|
|
@@ -4576,6 +4667,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4576
4667
|
"compat.cap.workspaceIndexHeader": "索引会话头部", "compat.cap.workspaceArchiveNative": "宿主原生归档入口", "compat.cap.workspaceUnarchiveNative": "宿主原生恢复入口",
|
|
4577
4668
|
"compat.cap.workspaceBatchNative": "宿主原生批量入口", "compat.cap.workspaceDeleteNative": "宿主原生删除入口", "compat.cap.sessionsDetachLive": "实时会话落盘与分离",
|
|
4578
4669
|
"compat.cap.sessionsColdAnnounce": "冷会话移除广播", "compat.cap.projectionWrite": "投影缓存写入路径", "compat.cap.projectionTableDelete": "投影缓存行删除",
|
|
4670
|
+
"compat.cap.agentPresetRegister": "临时子预设注册", "compat.cap.toolsRestrictMethod": "工具限制施加(restrict)", "compat.cap.agentCreatedEvent": "子代理创建事件(agent/created)", "compat.cap.connectionAdmit": "连接准入(admit)",
|
|
4579
4671
|
"compat.cap.opArchive": "归档", "compat.cap.opUnarchive": "恢复", "compat.cap.opBatch": "批量操作", "compat.cap.opDelete": "删除", "compat.cap.opList": "历史列表",
|
|
4580
4672
|
"compat.reach": "预设注入边界", "compat.reach.hint": "每个预设下这些内容到不到得了模型",
|
|
4581
4673
|
"compat.reach.suppressing": "压制型",
|
|
@@ -4775,7 +4867,6 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4775
4867
|
"scenes.skills.shadowed.hint": "被同名技能覆盖,在这个场景里不可能生效,因此不能勾选。要改用这一份,请到「技能」页点它的「启用这个」。",
|
|
4776
4868
|
"scenes.skills.invalid.hint": "技能结构不完整(缺 frontmatter / 名字非法 / 描述为空),无法启停,因此不能勾选。",
|
|
4777
4869
|
"scenes.filter.skills": "筛选技能/目录名称", "scenes.filter.subagents": "筛选人设(名称或描述)", "scenes.filter.servers": "筛选服务器",
|
|
4778
|
-
|
|
4779
4870
|
"scenes.mem.title": "记忆", "scenes.mem.search": "在本场景内筛选记忆(名称或描述)",
|
|
4780
4871
|
"scenes.mem.noMatch": "没有匹配项", "scenes.mem.emptyScene": "该场景还没有记忆",
|
|
4781
4872
|
"scenes.mem.createNeedScene": "先在左边填好场景名", "scenes.mem.pending": "{count} 条待创建", "scenes.mem.pendingTag": "待创建", "scenes.mem.attach.tip": "带 {count} 个附件 · 共 {size}", "scenes.mem.removePending": "移除",
|
|
@@ -4915,7 +5006,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4915
5006
|
"scenes.preview.bind.tool": "模型工具表:切到「{name}」(关 {count} 条)",
|
|
4916
5007
|
"scenes.preview.bind.toolMissing": "模型工具表:「{name}」已不存在,这次不切换",
|
|
4917
5008
|
"scenes.preview.bind.toolKeep": "模型工具表:保持现状(本场景未绑定)", "scenes.preview.row.notes": "用场景备注覆盖 {count} 台服务器的备注", "scenes.field.toolTable": "模型工具表方案", "scenes.field.quickPrompts": "快捷提示词", "scenes.field.quickPrompts.current": "当前设置", "scenes.field.quickPrompts.customCount": "自定义({picked}/{total})", "scenes.field.quickPrompts.none": "还没有快捷提示词,先到「提示词」页新增",
|
|
4918
|
-
"scenes.field.quickPrompts.noneOption": "无", "scenes.field.quickPrompts.list": "本场景启用", "scenes.field.quickPrompts.pick": "选择", "scenes.quickPick.title": "选择本场景启用的快捷提示词", "scenes.quickPick.hint": "勾选的进入本场景后启用,没勾的停用;退出场景时按进入前那批开关还原。", "scenes.quickPick.confirm": "确定", "scenes.form.section.basic": "基本信息", "scenes.form.section.binding": "场景绑定", "scenes.field.toolTable.none": "当前设置", "scenes.field.toolTable.factory": "出厂默认(关 {count} 条)", "scenes.field.toolTable.count": "关 {count} 条", "scenes.field.toolTable.missing": "方案已不存在", "scenes.preview.more": " 等", "scenes.preview.truncated": "(每一类最多列前 60 项)", "scenes.preview.stale": "档案里有 {count} 项在当前环境里已经不存在,这次不会生效:{items}", "scenes.doctor.title": "有 {count} 处引用指向已经不存在的名字", "scenes.doctor.noneButSkipped": "体检没发现悬空引用", "scenes.doctor.hint": "改名或删除留下的:这一条看着还绑着,运行时按那个名字已经找不到东西了。改回正确的名字,或到档案里取消勾选。", "scenes.doctor.row": "{where}:「{name}」已不存在", "scenes.doctor.more": "另有 {count} 处未列出", "scenes.doctor.skipped": "({domains} 这次没读到,这一类没有算进体检)", "agm.restore.tag": "退出场景后恢复它", "agm.restore.tag.hint": "它是进场景前的全局提示词,退出场景时会按快照里的正文恢复;快照存的是正文,删这份预设不影响恢复", "agm.file.mismatch": "文件里不是它", "agm.file.mismatch.hint": "AGENTS.md 当前内容与这份预设不一致(可能被手动改过);点左边那颗开关把它写回", "hist.restore.note.registered": "已恢复 {count} 个会话;工作区「{title}」已重新登记,会话已挂回该组。", "hist.restore.note.attached": "已恢复 {count} 个会话,并挂回工作区「{title}」。", "hist.restore.note.skip": "{count} 个会话的工作区归属未能恢复:{reason}", "hist.purge.title": "永久删除?", "hist.purge.one": "永久删除会话「{title}」及其全部记录,不可恢复", "hist.purge.batch": "永久删除所选 {count} 个会话及其全部记录,不可恢复", "hist.btn.restore": "恢复", "hist.btn.purge": "永久删除", "hist.btn.confirmPurge": "确认删除", "hist.selectGroup": "全选组 {title}", "hist.select": "选择此会话", "hist.group.count": "{count} 个", "hist.selectAll": "全选", "hist.deselectAll": "取消全选", "hist.btn.import": "导入", "hist.btn.export": "导出", "hist.btn.restoreSelected": "恢复所选 ({count})", "hist.btn.deleteSelected": "删除所选 ({count})", "hist.stat.archived": "归档", "hist.stat.projects": "工作区", "hist.stat.retention": "保留期", "hist.search.placeholder": "搜索标题 / 会话 ID / 项目路径", "hist.loading": "加载中…", "hist.empty.search": "无匹配的归档会话", "hist.empty.none": "暂无归档会话", "hist.import.cwd": "工作区(可留空)", "hist.import.cwd.placeholder": "从已登记工作区选,或直接输入绝对路径;留空 = 归入未分组", "hist.import.workspace": "选工作区", "hist.import.workspace.none": "本机还没有已登记的工作区:可以直接输入绝对路径。", "hist.import.done": "已创建会话 {id}({count} 条消息),可在 DSH 会话列表中继续对话。", "hist.import.lossy": "⚠ 整份文本没有识别出任何说话人标记,已折成一条用户消息:原对话的分轮结构可能已丢失。若源文件是 JSONL 或 Markdown 转录稿,请按原扩展名重新导入。", "hist.export.hint": "导出选中会话为转录文件,可再次导入", "hist.export.dir": "导出目录(绝对路径,自动创建)", "hist.export.browse": "浏览并选择文件夹", "hist.btn.browse": "选择", "hist.export.pickDir": "选择导出目录", "hist.export.format": "格式", "hist.export.detail": "导出内容", "hist.export.detail.simple": "仅正文", "hist.export.detail.tools": "正文 + 工具", "hist.export.detail.full": "正文 + 工具 + 思考", "hist.export.scope": "会话范围", "hist.export.workspace": "工作区", "hist.export.sessions": "会话({count} 个)", "hist.export.loading": "加载会话列表…", "hist.cwd.missing": "⚠ 工作区目录已不存在:", "hist.tag.archived": "已归档", "hist.tag.live": "未归档", "hist.export.empty": "没有符合条件的会话", "hist.result.exported": "已导出 {count} 个会话到 {dir}", "hist.result.skipped": ";跳过 {count} 个({ids})", "hist.export.busy": "处理中…", "hist.btn.exportSelected": "导出 {count} 个会话", "hist.error.title": "操作失败", "hist.error.unknown": "未知错误",
|
|
5009
|
+
"scenes.field.quickPrompts.noneOption": "无", "scenes.field.quickPrompts.list": "本场景启用", "scenes.field.quickPrompts.pick": "选择", "scenes.quickPick.title": "选择本场景启用的快捷提示词", "scenes.quickPick.hint": "勾选的进入本场景后启用,没勾的停用;退出场景时按进入前那批开关还原。", "scenes.quickPick.confirm": "确定", "scenes.form.section.basic": "基本信息", "scenes.form.section.binding": "场景绑定", "scenes.field.toolTable.none": "当前设置", "scenes.field.toolTable.factory": "出厂默认(关 {count} 条)", "scenes.field.toolTable.count": "关 {count} 条", "scenes.field.toolTable.missing": "方案已不存在", "scenes.preview.more": " 等", "scenes.preview.truncated": "(每一类最多列前 60 项)", "scenes.preview.stale": "档案里有 {count} 项在当前环境里已经不存在,这次不会生效:{items}", "scenes.doctor.title": "有 {count} 处引用指向已经不存在的名字", "scenes.doctor.noneButSkipped": "体检没发现悬空引用", "scenes.doctor.hint": "改名或删除留下的:这一条看着还绑着,运行时按那个名字已经找不到东西了。改回正确的名字,或到档案里取消勾选。", "scenes.doctor.row": "{where}:「{name}」已不存在", "scenes.doctor.more": "另有 {count} 处未列出", "scenes.doctor.skipped": "({domains} 这次没读到,这一类没有算进体检)", "agm.restore.tag": "退出场景后恢复它", "agm.restore.tag.hint": "它是进场景前的全局提示词,退出场景时会按快照里的正文恢复;快照存的是正文,删这份预设不影响恢复", "agm.file.mismatch": "文件里不是它", "agm.file.mismatch.hint": "AGENTS.md 当前内容与这份预设不一致(可能被手动改过);点左边那颗开关把它写回", "agm.agentsHome.present": "另有一份全局指令 {path} 也在注入(与别的 agent 工具共用);要改这里的内容去改那个文件。", "hist.restore.note.registered": "已恢复 {count} 个会话;工作区「{title}」已重新登记,会话已挂回该组。", "hist.restore.note.attached": "已恢复 {count} 个会话,并挂回工作区「{title}」。", "hist.restore.note.skip": "{count} 个会话的工作区归属未能恢复:{reason}", "hist.purge.title": "永久删除?", "hist.purge.one": "永久删除会话「{title}」及其全部记录,不可恢复", "hist.purge.batch": "永久删除所选 {count} 个会话及其全部记录,不可恢复", "hist.btn.restore": "恢复", "hist.btn.purge": "永久删除", "hist.btn.confirmPurge": "确认删除", "hist.selectGroup": "全选组 {title}", "hist.select": "选择此会话", "hist.group.count": "{count} 个", "hist.selectAll": "全选", "hist.deselectAll": "取消全选", "hist.btn.import": "导入", "hist.btn.export": "导出", "hist.btn.restoreSelected": "恢复所选 ({count})", "hist.btn.deleteSelected": "删除所选 ({count})", "hist.stat.archived": "归档", "hist.stat.projects": "工作区", "hist.stat.retention": "保留期", "hist.search.placeholder": "搜索标题 / 会话 ID / 项目路径", "hist.loading": "加载中…", "hist.empty.search": "无匹配的归档会话", "hist.empty.none": "暂无归档会话", "hist.import.cwd": "工作区(可留空)", "hist.import.cwd.placeholder": "从已登记工作区选,或直接输入绝对路径;留空 = 归入未分组", "hist.import.workspace": "选工作区", "hist.import.workspace.none": "本机还没有已登记的工作区:可以直接输入绝对路径。", "hist.import.done": "已创建会话 {id}({count} 条消息),可在 DSH 会话列表中继续对话。", "hist.import.lossy": "⚠ 整份文本没有识别出任何说话人标记,已折成一条用户消息:原对话的分轮结构可能已丢失。若源文件是 JSONL 或 Markdown 转录稿,请按原扩展名重新导入。", "hist.export.hint": "导出选中会话为转录文件,可再次导入", "hist.export.dir": "导出目录(绝对路径,自动创建)", "hist.export.browse": "浏览并选择文件夹", "hist.btn.browse": "选择", "hist.export.pickDir": "选择导出目录", "hist.export.format": "格式", "hist.export.detail": "导出内容", "hist.export.detail.simple": "仅正文", "hist.export.detail.tools": "正文 + 工具", "hist.export.detail.full": "正文 + 工具 + 思考", "hist.export.scope": "会话范围", "hist.export.workspace": "工作区", "hist.export.sessions": "会话({count} 个)", "hist.export.loading": "加载会话列表…", "hist.cwd.missing": "⚠ 工作区目录已不存在:", "hist.tag.archived": "已归档", "hist.tag.live": "未归档", "hist.export.empty": "没有符合条件的会话", "hist.result.exported": "已导出 {count} 个会话到 {dir}", "hist.result.skipped": ";跳过 {count} 个({ids})", "hist.export.busy": "处理中…", "hist.btn.exportSelected": "导出 {count} 个会话", "hist.error.title": "操作失败", "hist.error.unknown": "未知错误",
|
|
4919
5010
|
},
|
|
4920
5011
|
en: {
|
|
4921
5012
|
"title": "Skills", "desc": "Manage skills: enable, import, create, trash.", "link.project": "GitHub", "link.feedback": "Issues",
|
|
@@ -4968,6 +5059,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
4968
5059
|
"fm.label.name": "Name", "fm.label.description": "Description", "fm.label.when-to-use": "When to use", "fm.label.user-invocable": "User invocable", "fm.label.disable-model-invocation": "Model invocation disabled", "fm.label.allowed-tools": "Allowed tools", "fm.label.license": "License", "fm.label.version": "Version", "fm.label.author": "Author", "fm.label.category": "Category", "fm.label.tags": "Tags", "fm.label.metadata": "Metadata", "fm.label.homepage": "Homepage", "fm.yes": "Yes", "fm.no": "No",
|
|
4969
5060
|
"error.rules.sceneNotFound": "Scene not found: {group} (create it on the Scenes page first)",
|
|
4970
5061
|
"error.rules.reservedScene": "「{name}」 is a reserved scene: {action} is not allowed{reason}",
|
|
5062
|
+
"error.rules.sceneNotActive": "The scene is not started: start it before locking",
|
|
4971
5063
|
"error.rules.singleSceneOnly": "Only one scene besides 「global」 may be enabled at a time{detail}",
|
|
4972
5064
|
"error.agentsMd.sceneRebindFailed": "Cannot change the prompt binding of scene 「{scene}」 to 「{target}」: {reason}",
|
|
4973
5065
|
"error.agentsMd.referenced": "“{id}” cannot be deleted: {refs}. Remove that reference first — for a scene binding, rebind the prompt on the scene page or leave the scene; for the one currently applied, flip the switch on the left to un-apply.", "error.agentsMd.refProbeFailed": "Cannot tell whether “{id}” is still referenced, so the delete was refused: the reference probe failed (at least one of scene bindings / the current AGENTS.md content / the pre-scene baseline could not be read). Please try again later.", "error.agentsMd.noUnapplyBackup": "There is no “state from before the apply” to restore: the current AGENTS.md was not written by “Apply” (the preset created automatically the first time you open this page is one such case), so there is no starting point to go back to. To change what AGENTS.md holds: apply another preset, or edit AGENTS.md itself.", "error.agentsMd.unapplyWhileScene": "Scene “{scene}” is driving the global baseline, so it cannot be un-applied here: leave the scene first, or change its prompt binding on the Scenes page.",
|
|
@@ -5178,7 +5270,9 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
5178
5270
|
"compat.op.batch": "Batch archive", "compat.op.delete": "Delete permanently",
|
|
5179
5271
|
"compat.op.native": "Host-native entry", "compat.op.adapter": "Plugin adapter", "compat.op.unavailable": "Unavailable (disabled)",
|
|
5180
5272
|
"compat.degraded": "Degraded capabilities", "compat.degraded.hint": "what is missing + the consequence", "compat.reason": "Reason:",
|
|
5181
|
-
"compat.others": "Other capability slots", "compat.others.hint": "not degraded: the plugin supplies its own implementation when the host has no such entry",
|
|
5273
|
+
"compat.others": "Other capability slots", "compat.others.hint": "not degraded: the plugin supplies its own implementation when the host has no such entry",
|
|
5274
|
+
"compat.contracts": "Host contracts", "compat.contracts.hint": "host members this release depends on: absence never throws, but the matching feature loses half of itself", "compat.contracts.missing": "absent", "compat.contracts.allOk": "Every host contract this release depends on is present.",
|
|
5275
|
+
"compat.bareModules": "Bare module resolution", "compat.bareModules.hint": "official packages the plugin requires by bare name at runtime; they are not peers, so they take no part in the module comparison above", "compat.bareModules.present": "present", "compat.bareModules.absent": "not shipped by host", "compat.bareModules.drift": "contract drift suspected", "compat.bareModules.presentWhy": "affects: {feature}", "compat.bareModules.absentWhy": "the host no longer ships this package: {feature} degrades", "compat.bareModules.driftWhy": "{feature} is missing contract markers ({markers}) — please re-check that package's implementation manually",
|
|
5182
5276
|
"compat.fallback.substituted": "Plugin adapter (no host entry)",
|
|
5183
5277
|
"compat.fallback.native": "Falls back to native entry", "compat.fallback.refuse": "Operation refused", "compat.fallback.blocked": "Affected buttons disabled", "compat.fallback.inform": "Writes unaffected",
|
|
5184
5278
|
"compat.modules": "Module identity (plugin vs host)", "compat.modules.hint": "adapting only works on one shared module", "compat.module.same": "same module", "compat.module.separate": "separate copy (repair needed)", "compat.module.sameVersion": "same version (inside/outside the archive)", "compat.module.unknown": "not comparable", "compat.module.realpath": "not comparable (real path unavailable)", "compat.modules.realpath": "{count} package(s) could **not be compared**: their real path could not be read ({names}) — that is not \"a separate copy\", it means the check could not run.", "compat.modules.realpathSides": "Host side: {host}; plugin side: {plugin}. Fix the path (permissions / path length / reinstall) and reopen this page to re-check.", "compat.modules.realpathNone": "none", "compat.modules.unverified": "{count} package(s) could not be compared (not resolvable from the host anchor: {names}) — that is not \"a separate copy\", it means the check could not run. Try node scripts/doctor.mjs.",
|
|
@@ -5210,7 +5304,11 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
5210
5304
|
"compat.ov.nativeDelete": "Host native delete entry", "compat.ov.nativeDelete.ok": "The host offers no native delete entry (this plugin ships its own full sequence)",
|
|
5211
5305
|
"compat.ov.hostIdentity": "Host identity & modules", "compat.ov.hostIdentity.ok": "Modules are shared with the host (host DSH {version})", "compat.ov.hostIdentity.asar": "Official packages match the host version (DSH {version}), but the host runs inside {name} while the plugin sits outside it", "compat.ov.hostIdentity.degraded": "Blockers present: {list}",
|
|
5212
5306
|
"compat.ov.memory": "Memory", "compat.ov.prompts": "Prompts", "compat.ov.subagents": "Subagents", "compat.ov.scenes": "Scene profiles",
|
|
5307
|
+
"compat.ov.subagentPersona": "Subagent persona delegation", "compat.ov.subagentToolRestrict": "Subagent tool restriction", "compat.ov.subagentCreatedEvent": "Subagent creation ordering", "compat.ov.webAdmission": "Web connection admission",
|
|
5213
5308
|
"compat.ov.plain.ok": "No degradation reported (assembly failures would appear here)",
|
|
5309
|
+
"compat.ov.contract.ok": "Host contract present (its absence would silently halve the feature)",
|
|
5310
|
+
"compat.ov.contract.degraded": "Host contract absent: {detail}",
|
|
5311
|
+
"compat.ov.domain.contract": "Required host modules present: {detail}",
|
|
5214
5312
|
// Slash-command "Tools" section (chat composer). Domain labels stay short — the row keeps
|
|
5215
5313
|
// room on the right for the summary and the drill chevron.
|
|
5216
5314
|
"slash.section.tools": "Tools",
|
|
@@ -5289,6 +5387,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
5289
5387
|
"compat.cap.workspaceIndexHeader": "Index session headers", "compat.cap.workspaceArchiveNative": "Host native archive entry", "compat.cap.workspaceUnarchiveNative": "Host native restore entry",
|
|
5290
5388
|
"compat.cap.workspaceBatchNative": "Host native batch entry", "compat.cap.workspaceDeleteNative": "Host native delete entry", "compat.cap.sessionsDetachLive": "Persist & detach live sessions",
|
|
5291
5389
|
"compat.cap.sessionsColdAnnounce": "Cold session removal broadcast", "compat.cap.projectionWrite": "Projection cache write path", "compat.cap.projectionTableDelete": "Projection cache row deletion",
|
|
5390
|
+
"compat.cap.agentPresetRegister": "Temporary child-preset registration", "compat.cap.toolsRestrictMethod": "Tool restriction (restrict)", "compat.cap.agentCreatedEvent": "Subagent creation event (agent/created)", "compat.cap.connectionAdmit": "Connection admission (admit)",
|
|
5292
5391
|
"compat.cap.opArchive": "Archive", "compat.cap.opUnarchive": "Restore", "compat.cap.opBatch": "Batch operations", "compat.cap.opDelete": "Delete", "compat.cap.opList": "History list",
|
|
5293
5392
|
"compat.reach": "Preset injection reach", "compat.reach.hint": "whether these contents reach the model under each preset",
|
|
5294
5393
|
"compat.reach.suppressing": "suppressing",
|
|
@@ -5482,7 +5581,6 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
5482
5581
|
"scenes.skills.shadowed.hint": "Shadowed by a same-name skill, so it can never take effect in this scene and cannot be checked. To use this copy instead, click “Use this one” for it on the Skills page.",
|
|
5483
5582
|
"scenes.skills.invalid.hint": "Incomplete skill (missing frontmatter / invalid name / empty description): it cannot be enabled or disabled, so it cannot be checked.", "scenes.subagents.hint": "Check the personas this scene should turn on; anything unchecked (or with no section at all) is turned off when you enter, and restored to its previous switch when you exit.", "scenes.subagents.hint.short": "Add the section, then check the personas to turn on", "scenes.subagents.empty": "No personas yet — create one on the Subagents page.",
|
|
5484
5583
|
"scenes.filter.skills": "Filter skills / directories", "scenes.filter.subagents": "Filter personas (name or description)", "scenes.filter.servers": "Filter servers",
|
|
5485
|
-
|
|
5486
5584
|
"scenes.mem.title": "Memories", "scenes.mem.search": "Filter memories in this scene (name or description)",
|
|
5487
5585
|
"scenes.mem.noMatch": "Nothing matches", "scenes.mem.emptyScene": "This scene has no memories yet",
|
|
5488
5586
|
"scenes.mem.createNeedScene": "Fill in the scene name first", "scenes.mem.pending": "{count} pending", "scenes.mem.pendingTag": "Pending", "scenes.mem.attach.tip": "Carries {count} attachment(s) · {size} total", "scenes.mem.removePending": "Remove",
|
|
@@ -5624,7 +5722,7 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
5624
5722
|
"scenes.preview.bind.tool": "Tool table: switch to scheme “{name}” (hides {count})",
|
|
5625
5723
|
"scenes.preview.bind.toolMissing": "Tool table: scheme “{name}” no longer exists — nothing switches this time",
|
|
5626
5724
|
"scenes.preview.bind.toolKeep": "Tool table: stays as it is (this scene binds none)", "scenes.preview.row.notes": "Overrides the notes of {count} server(s) with scene notes", "scenes.field.toolTable": "Model tool-table scheme", "scenes.field.quickPrompts": "Quick prompts", "scenes.field.quickPrompts.current": "Current settings", "scenes.field.quickPrompts.customCount": "Custom ({picked}/{total})", "scenes.field.quickPrompts.none": "No quick prompts yet — add some on the Prompts page",
|
|
5627
|
-
"scenes.field.quickPrompts.noneOption": "None", "scenes.field.quickPrompts.list": "Enabled in this scene", "scenes.field.quickPrompts.pick": "Choose", "scenes.quickPick.title": "Choose the quick prompts enabled in this scene", "scenes.quickPick.hint": "Checked ones are enabled when you enter this scene, unchecked ones are disabled; leaving the scene restores the switches from before you entered.", "scenes.quickPick.confirm": "Done", "scenes.form.section.basic": "Basics", "scenes.form.section.binding": "Scene bindings", "scenes.field.toolTable.none": "Current settings", "scenes.field.toolTable.factory": "Factory default (hides {count})", "scenes.field.toolTable.count": "hides {count}", "scenes.field.toolTable.missing": "scheme no longer exists", "scenes.preview.more": " etc.", "scenes.preview.truncated": "(each kind lists its first 60 entries only)", "scenes.preview.stale": "{count} profile entry(ies) no longer exist in this environment and will not take effect: {items}", "scenes.doctor.title": "{count} reference(s) point at a name that no longer exists", "scenes.doctor.noneButSkipped": "The check found no dangling references", "scenes.doctor.hint": "Left behind by a rename or a delete: it still looks bound here, but nothing matches that name at runtime. Point it at the right name, or untick it in the profile.", "scenes.doctor.row": "{where}: “{name}” no longer exists", "scenes.doctor.more": "{count} more not listed", "scenes.doctor.skipped": "({domains} could not be read, so that kind was not checked)", "agm.restore.tag": "Restored after the scene", "agm.restore.tag.hint": "The global prompt from before the scene; leaving the scene restores it from the snapshot's text, so deleting this preset does not break the restore", "agm.file.mismatch": "Not in AGENTS.md", "agm.file.mismatch.hint": "AGENTS.md does not currently match this preset (it may have been edited by hand); flip the switch on the left to write it back", "hist.restore.note.registered": "Restored {count} session(s); workspace “{title}” was registered again and the sessions are back in that group.", "hist.restore.note.attached": "Restored {count} session(s) and attached them to workspace “{title}”.", "hist.restore.note.skip": "Workspace ownership could not be restored for {count} session(s): {reason}", "hist.purge.title": "Delete forever?", "hist.purge.one": "Delete “{title}” and all of its records forever — this cannot be undone", "hist.purge.batch": "Delete the {count} selected sessions and all of their records forever — this cannot be undone", "hist.btn.restore": "Restore", "hist.btn.purge": "Delete forever", "hist.btn.confirmPurge": "Delete", "hist.selectGroup": "Select group {title}", "hist.select": "Select this session", "hist.group.count": "{count}", "hist.selectAll": "Select all", "hist.deselectAll": "Deselect all", "hist.btn.import": "Import", "hist.btn.export": "Export", "hist.btn.restoreSelected": "Restore selected ({count})", "hist.btn.deleteSelected": "Delete selected ({count})", "hist.stat.archived": "Archived", "hist.stat.projects": "Workspaces", "hist.stat.retention": "Retention", "hist.search.placeholder": "Search title / session id / project path", "hist.loading": "Loading…", "hist.empty.search": "No matching archived sessions", "hist.empty.none": "No archived sessions yet", "hist.import.cwd": "Workspace (optional)", "hist.import.cwd.placeholder": "Pick a registered workspace or type an absolute path; leave blank to go to Ungrouped", "hist.import.workspace": "Workspace", "hist.import.workspace.none": "No registered workspace on this machine yet — type an absolute path.", "hist.import.done": "Created session {id} ({count} messages); continue it from the DSH session list.", "hist.import.lossy": "⚠ No speaker markers were found in the text, so it was folded into a single user message: the original turn structure may have been lost. If the source is a JSONL or Markdown transcript, import it with its original extension.", "hist.export.hint": "Export the selected sessions as transcript files that can be imported again", "hist.export.dir": "Export directory (absolute path, created automatically)", "hist.export.browse": "Browse and choose a folder", "hist.btn.browse": "Choose", "hist.export.pickDir": "Choose export directory", "hist.export.format": "Format", "hist.export.detail": "Export detail", "hist.export.detail.simple": "Text only", "hist.export.detail.tools": "Text + tools", "hist.export.detail.full": "Text + tools + thinking", "hist.export.scope": "Session scope", "hist.export.workspace": "Workspace", "hist.export.sessions": "Sessions ({count})", "hist.export.loading": "Loading sessions…", "hist.cwd.missing": "⚠ The workspace directory no longer exists: ", "hist.tag.archived": "Archived", "hist.tag.live": "Not archived", "hist.export.empty": "No matching sessions", "hist.result.exported": "Exported {count} session(s) to {dir}", "hist.result.skipped": "; skipped {count} ({ids})", "hist.export.busy": "Working…", "hist.btn.exportSelected": "Export {count} session(s)", "hist.error.title": "Operation failed", "hist.error.unknown": "Unknown error",
|
|
5725
|
+
"scenes.field.quickPrompts.noneOption": "None", "scenes.field.quickPrompts.list": "Enabled in this scene", "scenes.field.quickPrompts.pick": "Choose", "scenes.quickPick.title": "Choose the quick prompts enabled in this scene", "scenes.quickPick.hint": "Checked ones are enabled when you enter this scene, unchecked ones are disabled; leaving the scene restores the switches from before you entered.", "scenes.quickPick.confirm": "Done", "scenes.form.section.basic": "Basics", "scenes.form.section.binding": "Scene bindings", "scenes.field.toolTable.none": "Current settings", "scenes.field.toolTable.factory": "Factory default (hides {count})", "scenes.field.toolTable.count": "hides {count}", "scenes.field.toolTable.missing": "scheme no longer exists", "scenes.preview.more": " etc.", "scenes.preview.truncated": "(each kind lists its first 60 entries only)", "scenes.preview.stale": "{count} profile entry(ies) no longer exist in this environment and will not take effect: {items}", "scenes.doctor.title": "{count} reference(s) point at a name that no longer exists", "scenes.doctor.noneButSkipped": "The check found no dangling references", "scenes.doctor.hint": "Left behind by a rename or a delete: it still looks bound here, but nothing matches that name at runtime. Point it at the right name, or untick it in the profile.", "scenes.doctor.row": "{where}: “{name}” no longer exists", "scenes.doctor.more": "{count} more not listed", "scenes.doctor.skipped": "({domains} could not be read, so that kind was not checked)", "agm.restore.tag": "Restored after the scene", "agm.restore.tag.hint": "The global prompt from before the scene; leaving the scene restores it from the snapshot's text, so deleting this preset does not break the restore", "agm.file.mismatch": "Not in AGENTS.md", "agm.file.mismatch.hint": "AGENTS.md does not currently match this preset (it may have been edited by hand); flip the switch on the left to write it back", "agm.agentsHome.present": "Another global instruction file at {path} is also injected (shared with other agent tools); edit that file to change it.", "hist.restore.note.registered": "Restored {count} session(s); workspace “{title}” was registered again and the sessions are back in that group.", "hist.restore.note.attached": "Restored {count} session(s) and attached them to workspace “{title}”.", "hist.restore.note.skip": "Workspace ownership could not be restored for {count} session(s): {reason}", "hist.purge.title": "Delete forever?", "hist.purge.one": "Delete “{title}” and all of its records forever — this cannot be undone", "hist.purge.batch": "Delete the {count} selected sessions and all of their records forever — this cannot be undone", "hist.btn.restore": "Restore", "hist.btn.purge": "Delete forever", "hist.btn.confirmPurge": "Delete", "hist.selectGroup": "Select group {title}", "hist.select": "Select this session", "hist.group.count": "{count}", "hist.selectAll": "Select all", "hist.deselectAll": "Deselect all", "hist.btn.import": "Import", "hist.btn.export": "Export", "hist.btn.restoreSelected": "Restore selected ({count})", "hist.btn.deleteSelected": "Delete selected ({count})", "hist.stat.archived": "Archived", "hist.stat.projects": "Workspaces", "hist.stat.retention": "Retention", "hist.search.placeholder": "Search title / session id / project path", "hist.loading": "Loading…", "hist.empty.search": "No matching archived sessions", "hist.empty.none": "No archived sessions yet", "hist.import.cwd": "Workspace (optional)", "hist.import.cwd.placeholder": "Pick a registered workspace or type an absolute path; leave blank to go to Ungrouped", "hist.import.workspace": "Workspace", "hist.import.workspace.none": "No registered workspace on this machine yet — type an absolute path.", "hist.import.done": "Created session {id} ({count} messages); continue it from the DSH session list.", "hist.import.lossy": "⚠ No speaker markers were found in the text, so it was folded into a single user message: the original turn structure may have been lost. If the source is a JSONL or Markdown transcript, import it with its original extension.", "hist.export.hint": "Export the selected sessions as transcript files that can be imported again", "hist.export.dir": "Export directory (absolute path, created automatically)", "hist.export.browse": "Browse and choose a folder", "hist.btn.browse": "Choose", "hist.export.pickDir": "Choose export directory", "hist.export.format": "Format", "hist.export.detail": "Export detail", "hist.export.detail.simple": "Text only", "hist.export.detail.tools": "Text + tools", "hist.export.detail.full": "Text + tools + thinking", "hist.export.scope": "Session scope", "hist.export.workspace": "Workspace", "hist.export.sessions": "Sessions ({count})", "hist.export.loading": "Loading sessions…", "hist.cwd.missing": "⚠ The workspace directory no longer exists: ", "hist.tag.archived": "Archived", "hist.tag.live": "Not archived", "hist.export.empty": "No matching sessions", "hist.result.exported": "Exported {count} session(s) to {dir}", "hist.result.skipped": "; skipped {count} ({ids})", "hist.export.busy": "Working…", "hist.btn.exportSelected": "Export {count} session(s)", "hist.error.title": "Operation failed", "hist.error.unknown": "Unknown error",
|
|
5628
5726
|
}
|
|
5629
5727
|
};
|
|
5630
5728
|
|
|
@@ -7598,6 +7696,13 @@ button.dsm-rowselect-box:disabled{cursor:default;opacity:.45}
|
|
|
7598
7696
|
// 「锁定时只显示锁定横幅」,提示词页此前漏了这层互斥,于是同一件事说了两遍
|
|
7599
7697
|
// (用户 2026-09-19 截图:提示词页两条黄条,其他管理页只有一条)。
|
|
7600
7698
|
(state.anyLocked !== true && sceneDriver) ? React.createElement('div', { className: 'dsm-feedback dsm-warning', role: 'status' }, t('agm.sceneLock.notice', { scene: sceneDriverLabel, id: sceneDriver.presetId })) : null,
|
|
7699
|
+
// 共享 agents 根那一份 AGENTS.md(`~/.agents/AGENTS.md`)**只读提示**:0.2.1 起
|
|
7700
|
+
// 官方把用户全局链扩成两份并列(`$DSH_HOME/AGENTS.md` → `<agentsHome>/AGENTS.md`),
|
|
7701
|
+
// 这一页只管得到前一份。所以"改了没生效"有了第二个解释 —— 真正在说话的是后一份。
|
|
7702
|
+
// 只提示、不给写入入口:这不是本插件的预设,写它会与官方的去重/刷新规则互相覆盖。
|
|
7703
|
+
(state.current && state.current.agentsHomeAgentsMd && state.current.agentsHomeAgentsMd.exists)
|
|
7704
|
+
? React.createElement('div', { className: 'dsm-feedback', role: 'status' }, t('agm.agentsHome.present', { path: state.current.agentsHomeAgentsMd.path }))
|
|
7705
|
+
: null,
|
|
7601
7706
|
// 一次性拒绝说明(被引用的预设删不掉):不替换列表,只加一条横幅。
|
|
7602
7707
|
state.deny ? React.createElement(Notice, { kind: 'warn', text: state.deny }) : null,
|
|
7603
7708
|
// 搜索框:页头之下、列表之前(与 MCP / 技能 / 记忆页同一位置与样式)。
|
|
@@ -14508,8 +14613,8 @@ function enabledMemoryCount(rules) {
|
|
|
14508
14613
|
//
|
|
14509
14614
|
// 目录注入深度:人设目录注入到哪些会话(默认 1 = 只在顶层)。
|
|
14510
14615
|
// ⚠️ 它**不是**递归上限。2026-09-17 用户实测后改名(原名 maxDepth /「委派预算」):
|
|
14511
|
-
//
|
|
14512
|
-
//
|
|
14616
|
+
// 官方按自己的 `maxDepth` 配置决定能不能继续嵌套(0.2.1 默认 1),本插件也不再
|
|
14617
|
+
// 向官方传 maxDepth。这个字段只决定常驻目录出现在哪些深度的会话里。
|
|
14513
14618
|
React.createElement('div', { className: 'dsm-field-row' },
|
|
14514
14619
|
React.createElement('div', { className: 'dsm-field' },
|
|
14515
14620
|
React.createElement('span', { className: 'dsm-label' }, t('subagents.field.catalogDepth')),
|
|
@@ -14598,6 +14703,7 @@ function enabledMemoryCount(rules) {
|
|
|
14598
14703
|
* 提到组件外是为了能被 `useMemo` 包住:这段要遍历全部记忆并逐桶排序,而本页的
|
|
14599
14704
|
* 编辑器弹窗每敲一个字都会重渲染整页(`editor` 是页内 state)。传进来的 `q` 已防抖。
|
|
14600
14705
|
*/
|
|
14706
|
+
|
|
14601
14707
|
function memoryView(data, q, sceneFilter) {
|
|
14602
14708
|
function matchRule(r) {
|
|
14603
14709
|
if (sceneFilter !== '' && sceneOfGroup(r.group) !== sceneFilter) return false
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// 这张表就是与宿主的契约本体 —— 纯字面量,判定逻辑在 probe.ts 的 inspectCapability,
|
|
4
4
|
// 取数原语在 host-probe.ts。缺一个成员时界面给出的是这一行点名的降级,而不是删除序列
|
|
5
5
|
// 中途抛出的一次异常。
|
|
6
|
-
import { callableWithSentinel, isFn, PROBE_SENTINEL } from './host-probe.js';
|
|
6
|
+
import { callableWithSentinel, isFn, PROBE_SENTINEL, resolvableFromHost } from './host-probe.js';
|
|
7
7
|
/**
|
|
8
8
|
* The capability table. This IS the contract with the host: everything the
|
|
9
9
|
* adapters reach for is listed here with what happens when it is absent, so a
|
|
@@ -318,4 +318,63 @@ export const CAPABILITY_SPECS = [
|
|
|
318
318
|
return undefined;
|
|
319
319
|
},
|
|
320
320
|
},
|
|
321
|
+
// ---- 0.2.1 的四处新契约面 ------------------------------------------------
|
|
322
|
+
// 这四条都是**本版适配真实依赖**的宿主成员。它们与上面那些的区别是:上面那些从 0.1.x
|
|
323
|
+
// 起就在表里,而这四个是 0.2.1 才出现的 —— 下一代宿主改掉其中任何一个,对应的功能会
|
|
324
|
+
// **静默失效**(不抛错、只少一半),所以必须在升级后第一眼可见。
|
|
325
|
+
//
|
|
326
|
+
// 逐条的后果:
|
|
327
|
+
// ① register 没了 → 带人设的子代理委派失败(临时预设注册不上去);
|
|
328
|
+
// ② restrict 没了 → 人设的 tools/toolsDeny 不生效,子代理继承父级全部工具;
|
|
329
|
+
// ③ agent/created 不串行 → 工具限制慢一步(首轮看到的还是继承来的工具集);
|
|
330
|
+
// ④ admit 没了 → Web 鉴权退回本地回环判定,本机任意进程可调写 op。
|
|
331
|
+
{
|
|
332
|
+
id: 'agentPreset.register',
|
|
333
|
+
label: '临时子预设注册',
|
|
334
|
+
kind: 'write',
|
|
335
|
+
owner: 'presetRoster',
|
|
336
|
+
fallback: 'refuse-operation',
|
|
337
|
+
methods: ['register'],
|
|
338
|
+
// 只查存在性 + 与参考副本的文本比对,**不真注册**:register 会真的树上挂一棵插件树。
|
|
339
|
+
probe: (t) => isFn(t?.register) ? undefined : '宿主预设名册缺少 register():带人设的子代理委派无法创建独立预设',
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: 'tools.restrict-method',
|
|
343
|
+
label: '工具限制施加(restrict)',
|
|
344
|
+
kind: 'write',
|
|
345
|
+
owner: 'tools',
|
|
346
|
+
fallback: 'disable-destructive',
|
|
347
|
+
methods: ['restrict'],
|
|
348
|
+
probe: (t) => isFn(t?.restrict) ? undefined : '宿主工具服务缺少 restrict():人设的工具限制不生效,子代理将继承父级全部工具',
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
// 探测的是 **agent 作用域**上 `on` 在场这一事实。真正的时序保证(announce 等待
|
|
352
|
+
// 串行 agent/created 监听全部完成后才放行收件箱)藏在宿主源码里,探针看不见 ——
|
|
353
|
+
// 这一条能抓的是"ctx.on 整个没了 / 改名",那时监听器挂不上、限制退化成事后施加。
|
|
354
|
+
id: 'agent.created-event',
|
|
355
|
+
label: '子代理创建事件(agent/created)',
|
|
356
|
+
kind: 'read',
|
|
357
|
+
owner: 'agentContext',
|
|
358
|
+
fallback: 'disable-destructive',
|
|
359
|
+
methods: ['on'],
|
|
360
|
+
probe: (t) => isFn(t?.on) ? undefined : 'agent 作用域缺少 on():无法在子代理创建时施加工具限制',
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
// 0.2.1 起宿主把鉴权栅栏拆成 admit()/requestRejection() 两层(见 http-fence.ts)。
|
|
364
|
+
// admit 不在场时插件退回 requestRejection,再缺则退回本地回环判定 —— 每一级都少一层,
|
|
365
|
+
// 但都不抛错,所以必须单列一条让人看得见现在停在哪一级。
|
|
366
|
+
id: 'connection.admit',
|
|
367
|
+
label: '连接准入(admit)',
|
|
368
|
+
kind: 'read',
|
|
369
|
+
owner: 'connection',
|
|
370
|
+
fallback: 'refuse-operation',
|
|
371
|
+
methods: ['admit'],
|
|
372
|
+
probe: (t) => isFn(t?.admit) ? undefined : '宿主 connection 缺少 admit():Web 鉴权降级(退到 requestRejection / 本地回环判定)',
|
|
373
|
+
// 静态检查的门槛:`dsh-client-connection` **不是**本插件的 peer(宿主不要求插件直接依赖
|
|
374
|
+
// 它),doctor 从插件锚点解析不到它。那时不能报 `missing` —— 那等于断言"宿主没有这个
|
|
375
|
+
// 能力",而运行时探针看到的是 Web 组合里真实的 connection 服务(0.2.1 起一定带 admit)。
|
|
376
|
+
// 门槛取宿主侧:至少一个宿主锚点解析得到才查;解析不到退回 `runtime-only`(如实标注
|
|
377
|
+
// "只能对活的宿主查"),而不是编一个"缺失"。
|
|
378
|
+
staticWhen: () => resolvableFromHost('@deepseek-ai/dsh-client-connection'),
|
|
379
|
+
},
|
|
321
380
|
];
|