dsh-modes · 模式管理
English | 中文
DeepSeek Harness(dsh)的模式管理器。它在 Web 界面的设置里加一个「模式管理」页:用开关决定每个模式能做什么,按模式编辑系统提示词和模型读到的工具描述,按模式管理技能(可以保存版本、新建技能,或从 Codex、Claude Code 和任意文件夹导入),用模板新建自己的模式,dsh 升级后一键合并官方更新。
它能帮你做什么
- 看懂每个模式:每个模式一张卡片,标出它能做的事(运行命令、读写文件、上网、子代理……),不用展开就能比较。
- 用开关决定能力:15 项能力各一个开关,比如关掉「运行命令」,或者把文件设成只读。不用面对几十个插件名。
- 改提示词:按模式编辑系统提示词,可以预览、保留历史版本;还可以让改动立刻作用到正在运行的会话,或者允许模型在对话里改(每次保存都要你批准)。
- 改工具描述:改写模型看到的任意工具的描述,可以一次改多个模式;一键把一个工具、一个模式或全部恢复成内置原文。工具本身的定义不会被修改。
- 新建自己的模式:从「开发、写作、聊天、只读调研」四个模板起步,或者复制任意现有模式。
- 按模式控制技能:按模式或在所有模式里开关某个技能,把某个模式固定在技能的某个已保存版本上,并保留可以查看、恢复、删除的版本历史。开关和固定版本都不会移动技能文件。
- 新建和导入技能:在页面里写一个新技能,或者从 Codex、Claude Code、任意文件夹批量复制技能进来。导入的技能来源有变化时,页面会提示,可以一键重新导入。
- 更新插件本身:页面会告诉你本插件有新版本,确认后用 DSH 自己的安装器升级。
- 跟上 dsh 升级:dsh 更新内置模式后,一键把官方的变化合并进来,同时保留你的修改;有插件加载失败时,一键关掉出问题的那几个。
- 页面出错时:页面自己出错时,会显示错误原文和「重新加载」,而不是一片空白。
安装
需要 dsh 的 Web 界面(dsh web),兼容的版本见兼容性。
dsh plugin --profile web add dsh-modes
如果你是从 dsh 源码运行的,在源码目录里把命令换成 pnpm dsh plugin --profile web add dsh-modes。装好后重新启动 dsh web,打开 设置 → 模式管理。
快速上手
- 打开 设置 → 模式管理,看看内置的几个模式:卡片上的小标签就是它们能做的事。
- 点右上角 新建模式,选「只读调研」,直接点创建。
- 新模式的卡片会展开到「能力」页:「运行命令」是关的,「文件」打开但「允许修改文件」是关的。
- 点卡片上的 用它新建会话,让它改一个文件:这个模式里没有写文件、编辑文件或运行命令的工具,它只能读和搜索。
- 回到这张卡片的「提示词」页,改一句提示词并保存。新开的会话就会用上它;想让正在运行的会话也立刻用上,打开下方的「即时生效」。
功能说明
模式列表
每个模式一张卡片:
- 卡片头:名称和描述,以及「默认」「自定义」标记。
- 能力标签:它能做的事,例如「运行命令 · 只读文件 · 网页」。
- 状态行:已启用的插件数、有几个会话在用、改过几项,以及是否开了即时生效。
- 按钮:「用它新建会话」用这个模式开一个新会话。「⋯」菜单里是其他操作:设为默认、复制、查看配置(YAML)、编辑信息、恢复内置、删除。
- 提示条:有需要你处理的事时,卡片上会出现一条,例如「内置模式有更新」「有插件加载失败」「有未保存的提示词草稿」,并带处理按钮。
点卡片可以展开,里面有「能力」「提示词」「全部插件」三个标签页。
能力
| 分组 | 能力 |
|---|---|
| 能做的事 | 运行命令、文件(可单独关掉「允许修改文件」)、网页、子代理与工作流、扩展自身(插件管理、插件市场、插件接口查询) |
| 工作方式 | 计划模式、待办清单、会话目标、技能、向你提问、交付文件、定时提醒 |
| 上下文 | 工作区指令(AGENTS.md、CLAUDE.md 等)、时间感知、上下文压缩 |
- 打开一项能力,会把它恢复成内置模式里的样子:按运行环境自动开关的插件(例如 Bash 和 PowerShell)恢复成「自动」;官方本来就关着的插件(例如 Codex 子代理)仍然关着。
- 关闭一项能力,会关掉它包含的所有插件。
- 只开了一部分插件的能力会标「部分开启」。
- 模式里没有的能力不会显示,例如 dsh 0.2.1 之前没有「定时提醒」。
提示词
- 系统提示词:编辑这个模式的系统提示词,点按钮插入
{{model}}等变量,输入时实时检查变量是否可用;「预览完整系统提示词」可以看到模型实际收到的全部内容。 - 高级设置:结尾提示词(追加在工具说明、工作区规则之后)、「只用开头这段作为完整提示词」、「附带运行时上下文」。
- 保存:点「保存」或按 ⌘/Ctrl + Enter。以上内容都要保存后才生效。
- 历史版本:每次保存都会记一个版本(最多 30 个),标明是在设置页、对话中还是别处改的,任何版本都能载回编辑器。
- 导入导出:支持导入、导出
.md文件。 - 恢复内置:「恢复内置提示词」会先问一次。
- 不怕丢:没保存的修改会作为草稿留在浏览器里,刷新页面也不会丢;如果你编辑期间提示词在别处被改了,保存会被拒绝,并让你选择载入最新内容,或用自己的版本覆盖。
「在对话中」一栏有两个开关,点一下就保存,对之后新建的会话生效:
- 即时生效:保存提示词后,正在运行的会话从下一步起就使用新提示词。
- 允许在对话里修改提示词:你可以直接对模型说「把你的提示词改成……」。模型通过
mode_prompt工具读取或修改这个模式的提示词,每次保存前都会弹出审批。
工具描述
打开「设置 → 模式管理 → 工具描述」。这里改写的是工具的描述,也就是告诉模型这个工具做什么、什么时候用的那段文字。工具本身的定义不会被修改,所以内置原文随时可以恢复。
- 选模式:顶部的「模式」菜单和技能页共用,页面会在这个浏览器里记住你的选择。选一个模式就只改它;选「所有模式」会出现模式列表,勾选改动要应用到哪些(一开始全部勾选)。一个都不勾时,列表显示所有可编辑模式的工具,此时不能保存。代码模式(PTC)和由其他插件声明的模式会列出并写明原因,不能选;如果在技能页选的模式在这里不能用,页面会说明并显示所有模式。模式卡片菜单里的「编辑工具描述」会打开这个页面并选中该模式。
- 批量修改:可以把一个工具同时改给多个模式,也可以改好几个工具后用「保存全部」一起保存。草稿会保留到你保存或放弃,切到别的页面再回来也还在。每个工具展开后能看到内置原文、它在每个已勾选模式里的状态,以及可以载回编辑框的更早版本。
- 一键恢复:可以恢复一个模式里的一个工具、所有已勾选模式里的一个工具、已勾选模式的全部,或所有模式的全部。每一种都会先确认。恢复就是去掉你的修改,所以内置原文会原样回来。
- 内置说明已更新:dsh 升级后,如果某个工具的内置描述和你修改时依据的不一样,会显示「内置说明已更新」。你的修改仍然生效;展开「内置原文」对照,再选择恢复,或重新保存以接受新的内置文字作为基准。
- 复制:复制模式时,会一起复制它的工具描述修改。
- 限制:描述最多 20000 字,不能为空(想还原请用恢复)。只改描述,不会改工具名和参数。列表显示的是每个模式注册的工具,每个工具后面是它当前描述的第一行,不需要先打开会话。
技能
打开「设置 → 模式管理 → 技能」,这里列出各模式能找到的所有技能,以及它的描述和文件位置。装了 Skill 管理(dsh-mode-skills)时,页面会提示它的侧栏页面和这里是同一份设置;它通过本插件保存。
- 新建技能:点「新建技能」,填名字(小写字母、数字和连字符)、一句话描述,选放在哪(
~/.dsh/skills只给 DSH 用,~/.agents/skills和其他 Agent 工具共用),再勾选在哪些模式开启。页面会生成<文件夹>/<名字>/SKILL.md,并直接打开编辑器。 - 导入:「导入技能」会列出
~/.codex/skills、~/.claude/skills和~/.claude/plugins里 Claude Code 插件带的技能;切到「文件夹」可以填一个路径(一个技能文件夹,或装着多个技能的文件夹;Windows「复制为路径」带的引号也能识别)。每一项都标明状态:可导入、已导入、来源有更新、已有同名技能(可以改名导入,或者先给现有技能存一个版本再覆盖)、名字 DSH 不认(按建议的名字导入,并改写副本里的name)。Codex 自带的技能默认折叠、不勾选,因为它们依赖 Codex 自己的工具。 - 导入是复制:文件会复制到你选的文件夹,在 DSH 里修改不会动到来源。指向技能外部的链接、
.git和.DS_Store不会复制。之后来源有变化,技能那一行会显示「来源有更新」,展开后点「从来源重新导入」,会先把当前文件存成一个版本再覆盖。 - 按模式查看:顶部的「模式」菜单(和工具描述页共用)可以选所有模式或某个模式。选中某个模式时,列表只显示这个模式能找到的技能,并显示开着几个;每一行的开关和版本下拉框直接作用于这个模式;「全部打开」「全部关闭」(关闭前会确认)作用于列出的所有技能。模式卡片菜单里的「管理技能」会直接打开这个模式的视图。
- 开关:查看所有模式时,技能那一行右侧的开关会在所有模式里关闭它;查看单个模式时,这个总开关在展开区里。展开后,每个有技能工具的模式各有一个开关;找不到这个技能或没有技能工具的模式会标明不受影响。
- 未开启「技能」能力的模式:这样的模式没有技能工具,技能对它不起作用,所以不会出现在按模式的开关里。页面顶部会列出这些模式,并给出「开启」按钮,效果和模式卡片「能力」页签里的开关一样。用「聊天」模板新建的模式默认没开这项能力。
- 固定版本:每个模式都有一个版本下拉框:「当前文件」或某个已保存的版本。固定后,这个模式用的是那个版本的描述和正文,资源文件也来自保存的副本;其他模式仍然用当前文件。
- 版本:「保存当前为新版本」会复制技能的文件(最多 1000 个文件、25 MB),可以写备注。在页面里编辑文件或恢复某个版本之前,都会先把当前文件存成一个版本,并标明来源。「查看」显示版本里的
SKILL.md;「恢复到文件」把它复制回当前文件,版本里没有的文件会保留;有模式正在使用的版本不能删除。 - 编辑 SKILL.md:在页面里直接编辑。如果文件在你编辑期间被改动,除非你选择覆盖,否则不会写入。
- 只读的技能:
node_modules里的技能属于 DSH 或某个插件,可以按模式关闭、保存版本,但不能编辑或恢复它的文件。~/.agents/skills里的技能和其他 Agent 工具共用,编辑前页面会提示。 - 复制:复制模式时会一起复制它的技能设置;「恢复内置」和删除模式会清除这些设置,已保存的版本保留。
全部插件
列出模式里的每个插件,适合需要逐个调整的情况:
- 页面内可以搜索,也可以只看改动过的插件。
- 按运行环境切换的插件可以选「自动 / 开 / 关」。
- 改过的插件可以单独「还原」。
- 「详情」里能看到行 id、模块和完整配置。
新建模式
| 起步方式 | 开着的能力 | 适合 |
|---|---|---|
| 开发 | 与标准模式相同 | 日常写代码 |
| 写作 | 读写文件、工作区指令、待办、交付文件、技能、上下文压缩、提问、时间;没有终端 | 写文档、改稿 |
| 聊天 | 网页、上下文压缩、提问、时间;不碰文件和终端 | 问答、聊天 |
| 只读调研 | 读取和搜索文件、网页、工作区指令、待办、技能、上下文压缩、提问、时间;不能改文件、不能运行命令 | 看代码、查资料 |
| 复制现有模式 | 与被复制的模式相同 | 在已有模式上微调 |
每个模板都带一段起步提示词,按界面语言选中文或英文。名称和 ID 会自动填好,之后都可以改。
跟上 dsh 升级
- 同步内置更新:dsh 升级后,改过的内置模式,以及基于内置模式创建的自定义模式,会提示「内置模式有更新」。同步前会列出新增、移除和有官方更新的插件;确认后:
- 你没动过的插件跟随官方;
- 你改过的设置保留你的值;
- 新增的插件在模板模式里默认关闭。
- 一键修复:模式里有插件加载失败时,整个模式会用不了。卡片上会列出失败的插件和原因,一键只关掉这几个,模式就能恢复使用。
- 删除前提醒:删除自定义模式前,会告诉你有多少个打开的和已保存的会话在用它;删除后,这些会话就打不开了。
更新
页面会检查本插件有没有新版本,并且可以直接安装。
- 检查:打开页面时,插件向 DSH 配置的 npm 仓库(国内镜像也行)询问
dsh-modes的最新版本,最多每 12 小时一次。请求里只有包名。可以用页面底部的「自动检查更新」关掉;「立即检查」仍然可用。本地开发安装(link:)从不检查。 - 升级:有新版本时,页面顶部出现横幅和「升级…」按钮。确认后,由 DSH 自己的安装器从仓库下载那个版本的压缩包并安装,过程中显示进度,可以点「取消安装」。安装失败或被取消时,安装器会把 profile 的文件还原。只会提供
latest正式版,不会升到预发布版本;压缩包地址必须是这个包在应答的那个仓库里的文件。 - 升级之后:通常新版本在重启 dsh 后生效(网页版重新运行
dsh web;桌面应用退出后重新打开),正在运行的会话不受影响,你的模式和修改都会保留。有些 DSH 版本会当场替换插件,这时页面会请你刷新。横幅里会给出退回旧版本的命令。之后打开页面会显示「已升级到」新版本,点「知道了」后不再显示。如果 profile 里已经装着这个版本(之前装过、还没加载),横幅会说已经装好、重启 dsh 后生效。 - 从 GitHub 安装的:横幅显示命令
dsh plugin --profile web add github:xiaohai-78/dsh-modes,没有升级按钮。 - 手动升级:Plugins 页面 →「添加插件」→ 粘贴
https://registry.npmjs.org/dsh-modes/-/dsh-modes-<版本号>.tgz;或者在终端运行dsh plugin --profile web add dsh-modes@latest。不带@latest的命令什么都不会做,因为 DSH 会保留安装时的版本。 - 旧版本:在加入更新检查之前发布的版本没有横幅,需要先手动升级一次。
改动什么时候生效
- 所有改动都只对之后新建的会话生效,正在运行的会话保持原样。唯一的例外是开启了「即时生效」的模式:它保存的提示词文字会从下一步起作用到正在运行的会话。
- 技能:一个模式第一次设置时会加上本插件的一行,所以只对新会话生效;之后的改动会从下一步起作用到这个模式正在运行的会话。输入框的
/菜单要刷新页面后才更新列表。 - 新建和导入的技能:DSH 会监听技能文件夹,新技能不用重启,从下一步起就会出现在正在运行的会话的技能目录里;输入框的
/菜单要刷新页面后才显示。 - 工具描述:一个模式第一次被改写时,会给它加上本插件的一行,所以这次改动只对新会话生效;之后每次保存或恢复,都会从下一步起作用到这个模式正在运行的会话。
- 改动写在当前 dsh profile 的
cordis.patch.yml里,用同一个 profile 打开的其他窗口也会看到。Desktop 应用用的是另一个 profile,不受影响。 - 每次操作的结果显示在页面底部的提示条里;出错的提示会一直留着,直到你关闭。保存工具描述或技能设置后,提示条还会说明什么时候生效:已有设置的模式从下一步起作用到正在运行的会话,模式第一次设置则只对新会话生效,此时如果只涉及一个模式,会带一个「用它新建会话」按钮。第一次设置之前就已开始的会话,之后的改动也不会作用到它,需要新建会话。
兼容性
| dsh 版本 | 结果 |
|---|---|
0.2.0-rc.2(npm latest) |
可用。这个版本的 dsh 不提供插件的中文名,本插件会用各插件官方的中文名称代替 |
0.2.1-alpha.3 |
可用 |
0.2.1-rc.1(npm next) |
可用。rc.1 给内置模式新增了插件市场工具,改过的模式会提示「内置模式有更新」,同步后加入(默认关闭) |
以上版本都实际安装测试过,包括用本地假模型检查发给模型的真实请求。插件用到的 dsh 接口还没有稳定,其他版本可能需要适配。
常见问题
改了开关或提示词,但对话里没变化?
改动只对之后新建的会话生效,用「用它新建会话」开一个新的试试。只有开启了「即时生效」的模式,提示词文字才会作用到正在运行的会话。
dsh 升级后某个模式用不了了?
展开那个模式的卡片,如果提示有插件加载失败,点「关闭这些插件」;如果提示「内置模式有更新」,点「同步内置更新」。
改乱了,怎么回到原样?
- 单个插件:在「全部插件」里点「还原」;
- 提示词:在「历史版本」里载回任意旧版本,或点「恢复内置提示词」;
- 整个内置模式:在「⋯」菜单里选「恢复内置」。
在对话里让模型改提示词,没有反应?
「允许在对话里修改提示词」只对打开之后新建的会话生效。另外,dsh 的审批策略如果设为「从不」(例如无人值守运行),保存会被拒绝。
插件的数据存在哪里?
- 模式配置:在 profile 的 cordis.patch.yml 里;
- 同步基准和提示词历史:在 profile 目录下的 .dsh-modes/ 文件夹里;
- 未保存的草稿:只在当前浏览器里。
卸载
dsh plugin --profile web remove dsh-modes
卸载后,被本插件改过的模式仍能正常使用。本插件往内置模式里加的每一行,保存时都带一个条件:插件包不在了,这一行就自动关闭。开了「即时生效」的模式还会多一行官方的身份行,提示词和你保存的一样,只在插件卸载后才启用。卸载后:
- 技能设置、工具描述的修改和「允许在对话里修改提示词」不再生效,技能和工具回到原样。
- 开了「即时生效」的模式保留你最后保存的提示词,变成普通的提示词。
- 对内置模式的其他修改,比如关掉的插件、改过的提示词,会保留下来。想完全还原,就在卸载前对这些模式点「恢复内置」。
- 自己新建的模式会随插件一起消失。
- profile 目录下的
.dsh-modes/文件夹会保留,重新安装后所有设置都能回来;想清理可以删掉它。
0.8.0 及更早版本保存的行没有这个条件。卸载前请先升级,并启动一次 dsh:插件启动时会给它改过的每个内置模式补上条件。如果卸载后某个模式已经用不了(模式列表里找不到它,或者新建会话报 agent-preset/invalid: ... never started),重新安装本插件,或者先换一个模式。
已知限制
- 同步依赖记录:同步内置更新依赖上次保存时记下的内置插件列表。用 0.5.0 之前的版本改过的模式没有这份记录,第一次同步时,和官方不一致的地方都会按你的修改保留;之后每次保存都会补上记录。
- 为其他工具写的技能:DSH 只读取
name、description、whenToUse、metadata、disable-model-invocation和user-invocable;其他字段(比如 Claude Code 的allowed-tools、model)不起作用。依赖其他工具自带功能的技能(比如 Codex 的生图)可以导入,但在 DSH 里可能用不了。 - 导入扫描的位置:
$CODEX_HOME/skills(默认~/.codex/skills)、$CLAUDE_CONFIG_DIR/skills(默认~/.claude/skills),以及~/.claude/plugins往下六层以内的skills/<名字>/SKILL.md;同一个插件缓存了多个版本时,只列最近改动的那份。项目里的技能(比如<项目>/.claude/skills)请用「文件夹」导入。单文件形式的<名字>.md技能不会列出。 - Windows 上覆盖:文件是逐个覆盖的,中途出错会留下新旧混合的文件。可以在这个技能的版本列表里恢复导入前自动保存的版本。
- 刚写入的技能:页面会等 0.8 秒让 DSH 的文件监听发现它,再读取列表。如果新技能仍显示「这个模式找不到它」,点「刷新」。
- 即时生效的范围:只作用于提示词的开头和结尾两段文字;「完整提示词」「运行时上下文」两项仍然只对新会话生效。
- 对话改提示词的范围:
mode_prompt只读写提示词的开头这段。 - 列出的技能:页面列出的是不指定工作区时各模式能找到的技能:用户级、自定义目录和包里自带的技能。项目里的技能(
<项目>/.dsh/skills、<项目>/.agents/skills)取决于会话的工作区,不会列出。 - 在所有模式里关闭的技能:这需要每个模式里都有本插件的一行,所以每个内置模式都会被写入一份 profile 覆盖。
- 和其他技能插件的先后:这一行的条目排序值是 -1000。如果别的插件在同一作用域里注册了排序值更小的条目,它会胜过本插件。
- 被隐藏技能的信息:一个技能在所有模式里都被隐藏后,页面显示的是它最后一次可见时的描述和文件位置。
- 更新检查:需要能连上仓库。连不上时页脚会显示检查失败。镜像可能比 npm 慢,最新版本可能晚一点才出现。
- 升级后的版本记录:在页面里升级后,依赖在
package.json里记成压缩包地址,而不是版本号。这不影响使用和以后的升级。 - 新版本启动失败:DSH 不会继续运行旧版本。请在终端运行横幅里给出的退回命令。
- 代码模式(PTC):暂不支持工具描述。代码模式里,模型读到的工具描述是生成出来的 SDK 文本里的注释,修改不会改写它。
- 会话启动时才注册的工具:列表来自每个模式注册的工具。只在会话启动时才注册的工具(例如
subagent),要等这个模式的会话发出第一次请求后才会出现。 - 会复述工具描述的插件:把描述抄进提示词的插件(例如 tool-activator 的 `` 列表)仍然显示内置原文;发给模型的工具定义带的是你的修改。
- 手工修改文件:插件读取
tool-descriptions.json后会缓存,只有在页面保存后才会重新读取。手工改过这个文件后请重启 dsh。文件损坏时会报错,不会被覆盖。 - 会话统计:删除前统计已保存的会话要读取每个会话的记录,会话很多时最多统计 8 秒,没统计完会显示「至少 N 个」。
- 权限:写操作只依赖 dsh 自带的登录校验。
开发者参考:工作原理
组成
| 文件 | 作用 |
|---|---|
index.js |
宿主端插件。提供 POST /api/dsh-modes,以及给另外两个模块用的 dshModes 服务。修改内置模式时,用 configEditor.edit() 在 profile 里写入该模式行的覆盖;插件的显示信息来自 pluginInventory.list() |
container.js |
自定义模式容器:配置里保存 presets 列表,并对每一项调用 agentPresets.register() |
rebase.js |
同步内置更新用的三方合并:以上次保存时的内置插件列表为基准,把你的修改合并到最新的内置列表上。冲突时保留你的值 |
tool-descriptions.js |
应用工具描述修改的行:放进模式里,在 system-prompt/assemble 的监听链最前面,替换每次请求的工具列表里被修改工具的 description |
tool-edit.js |
工具描述修改的纯计划逻辑:校验、带冲突检查的批量修改、恢复、历史,以及每个模式的工具列表 |
skill-policy.js |
技能设置行:放进模式里,在模式的作用域注册一个技能来源;对每个被关闭的技能返回一个谁都不能调用的条目,对每个固定版本的技能返回保存的版本,排序值 -1000 |
skill-store.js |
技能设置的纯函数:把「所有模式」的设置并入单个模式、批量修改、版本编号、哪些模式需要这一行、读取 SKILL.md 的 frontmatter |
skill-files.js |
把技能复制成一个版本、把版本恢复到当前文件,以及透过链接写文件 |
skill-import.js |
在 Codex、Claude Code 和指定文件夹里找技能文件夹;读取候选技能的 frontmatter;给技能文件夹算指纹、复制、替换;生成新技能的 SKILL.md |
update.js |
不依赖 DSH 服务的版本检查和升级辅助函数:版本比较、profile 怎样依赖这个包、要询问的仓库,以及对仓库返回的压缩包地址的校验 |
state.js |
profile 目录下的 .dsh-modes/state.json(同步基准,以及自定义模式基于哪个内置模式、用了哪个模板)、history.json(提示词历史)、tool-descriptions.json(工具描述修改及其历史)、settings.json(更新检查的开关,以及升级给新版本留下的记录)和 skills.json(技能设置、每个技能最后一次可见时的信息、版本索引;版本的文件在 skill-versions/<技能>/<版本>/)。写入时先写临时文件再替换 |
install-guard.js |
让改过的内置模式在卸载后仍能加载:本插件模块的每一行保存时都带一个 !!js 的 disabled 条件,找不到 dsh-modes 包时为真;即时生效的身份行后面再放一行同样提示词的官方身份行,条件相反。自建模式不加条件,因为它们会随插件一起消失 |
live-persona.js |
即时生效用的身份行:替换模式里的 @deepseek-ai/dsh-persona 行,注册同样的两个提示词分段,每次组装提示词时读取最新保存的文字 |
prompt-tool.js |
mode_prompt 工具:作为一行插件放进模式里,所以只有这个模式的会话能看到它;写入前通过 tools/pre-execute 要求用户审批 |
client.js |
Web 设置页(中英文) |
cordis.patch.yml |
插入 index.js 和 container.js 两个宿主端插件行 |
/api/dsh-modes 的动作:
- 读取:
list、read、prompt、history、usage、tools、updateStatus、upgradeStatus、skills、readSkillFile、readSkillVersion; - 技能:
setSkillModes(一批{ preset, skill, enabled?, pin? })、setSkillGlobal、saveSkillVersion、restoreSkillVersion、deleteSkillVersion、writeSkillFile; - 插件行:
toggle、followPlatform、applyRows、resetRow; - 整个模式:
reset、sync、repair、create、update、remove、setDefault; - 提示词:
setPrompt、setLive、setPromptTool; - 更新:
setUpdateCheck、dismissUpgraded、upgrade(启动安装并立即应答)、cancelUpgrade; - 工具描述:
setToolDescriptions(一批{ preset, tool, text, expected? },每一项各返回一个结果)、restoreToolDescriptions(items、presets或all)。
系统提示词
- 提示词的位置:提示词是模式里身份行的
prefix(开头)和suffix(结尾)。complete: true时,开头这段就是完整的系统提示词。 - 变量校验:变量以当前 dsh 实际注册的为准,例如
0.2.0-rc.2还有{{cwd}},0.2.1-alpha.2起已移除。dsh 解析变量很严格,写错一个会让该模式的每一步都失败,所以保存前(包括在对话里保存)会检查。 - 冲突检测:保存时会带上开始编辑时的版本;如果版本已经变了,返回
prompt-conflict,不会覆盖。 - 即时生效的实现:dsh 会把新的系统提示词作为一条系统消息追加到会话历史里,而不是改写最开头的那段,所以之前缓存的提示词前缀仍能命中。这个变化会记录在会话日志里。
工具描述
- 在哪里替换文字:
system-prompt/assemble的输出里带着发给模型的工具定义。这一行在那里替换description,在它包住的其他监听器都跑完之后才替换,所以不会被别的插件改回去。注册表里的定义不会被修改,这就是恢复能得到原样内置文字的原因。 - 存储:
.dsh-modes/tool-descriptions.json按模式保存每个被改的工具{ text, base },base是修改当时的内置文字,另外保存最近 100 次改动。这一行在每一步模型请求前读取它。 - 工具列表:
agentPresets.acquireScope(id)让注册表为模式挂载一份插件并在用完后释放,tools.schemas(scope)就能在没有会话的情况下列出它的工具。模式的行不变时,一次扫描结果复用五分钟;点「刷新」会重新扫描。 - 行:模式第一次被改写时加入
dsh-modes-tool-descriptions这一行,config.preset指向该模式;恢复掉最后一条修改时这一行会被移除。复制模式时,复制出来的行会指向新模式。
技能
- 机制:DSH 的技能注册表会合并一个 agent 作用域链上的所有来源;同名时离得最近的作用域直接胜出,同一作用域里排序值小的胜出。每个模式都有自己的
skill-filesystem行,所以设置行注册在同一作用域、排序值 -1000。被关闭的技能得到一个modelInvocable和userInvocable都为 false 的条目,它就从模型的技能目录和/菜单里消失;固定版本的技能得到一个条目,正文是保存的版本,resourceBase指向保存的副本。 - 实时生效:每次修改后,管理器调用这些来源的
invalidate,tool-skill在下一步追加一份替换后的目录;之前的目录留在历史里。 - 新建和导入:新技能写到
$DSH_HOME/skills或$DSH_AGENTS_HOME/skills(默认~/.dsh/skills和~/.agents/skills),也就是文件系统技能提供者扫描的两个用户目录。DSH 会监听技能根目录里的每个文件夹,而 Windows 不能改名正在被监听的文件夹。所以在 Windows 上,复制时直接写进目标文件夹,SKILL.md最后写;覆盖时在原文件夹里逐个覆盖文件(SKILL.md最后),再删掉来源里没有的文件。其他系统上,复制时先写到目标旁边再改名放到位,覆盖时先复制完新内容再整体替换。链接形式的文件夹不会被替换。skills.json用skills.<名字>.imported记录每次导入:来源文件夹、来源类型和两个指纹,一个基于文件路径、大小和修改时间,一个基于路径和内容,所以来源没变时不用读文件就能判断。 - 列表:用
agentPresets.acquireScope(id)和skills.snapshot({ scope })取得每个模式的技能,用tools.schemas(scope)判断模式有没有技能工具,都不需要会话。网页版 profile 关闭了宿主自己的skill-filesystem行,模式之外没有一份未被隐藏的副本,所以页面会在技能可见时记下它的信息。
更新
- 检查:宿主端用进程自带的
fetch请求<仓库>/dsh-modes/latest,所以 DSH 的出站代理设置会生效。仓库来自pluginManager.registries()(先是配置的那个,再是它的备用仓库);结果复用 12 小时,失败后复用 30 分钟。 - profile 怎样依赖这个包:读取 profile 的
package.json里dependencies['dsh-modes']:版本号或标签(registry)、压缩包地址(tarball)、git 地址(git)、路径(link)。不使用插件管理器自己的记录,因为0.2.0-rc.2没有提供这个字段。 - 安装:
pluginManager.installBundle(压缩包地址, { requestId })。压缩包地址不直接写出已安装的包名,所以管理器允许它覆盖已安装的包,并且在安装失败或被取消时还原清单和锁文件。宿主端不等它完成:页面每秒查询一次upgradeStatus。如果安装器在安装期间替换了本插件,页面会收到未知动作或空闲状态,就提示刷新。
验证方式
- 测试环境:每个兼容版本都用隔离的
DSH_HOME安装测试。 - 请求检查:用 dsh 自带的本地假模型和一个记录请求的代理,检查发给模型的真实请求:
- 「只读调研」模式的工具列表里,没有任何写文件、编辑或终端工具;
- 即时生效后,同一会话的下一步请求就带上了新提示词;
- 模型调用
mode_prompt时界面弹出审批,批准后下一步请求就带上了修改后的提示词; - 技能:在新建的 Standard 会话里,被关闭的技能不在目录中;固定版本的技能显示保存版本的描述,加载到的也是保存的正文,而文件里是编辑后的内容;在所有模式里关闭某个技能后,运行中会话的下一次请求里它就消失了;恢复版本前会先保存编辑后的文件,然后文件回到原来的内容。在
0.2.0-rc.2和0.2.1-rc.1上都检查过; - 更新:把一份标成
0.5.0的构建,用真实的 npm 仓库检测到最新版本,并通过 DSH 的安装器升级。依赖记成仓库的压缩包地址,插件保持启用;0.2.0-rc.2上安装器要求重启,0.2.1-rc.1上当场替换插件。在 Plugins 页面里用同类安装方式升级,也检查过重启之后的状态:升级前建的自定义模式仍然可用。安装失败时清单、锁文件和文件保持原样。npm 和国内镜像返回的最新版本信息都能通过压缩包地址的校验。开关、手动检查和本地开发安装都在页面里检查过; - 新建和导入技能:在
0.2.1-rc.2(npm)和0.2.1-rc.1(源码)上,用放在 Codex、Claude Code、Claude Code 插件和普通文件夹里的示例技能检查过:导入列表显示的状态正确;需要改名的技能用新名字复制,副本里的name也改写了;每个模式的技能目录(skills.snapshot)都列出了新技能;新建时不勾选的模式里它是关闭的;来源改动后会被标出来,重新导入前会先存一个版本。没有用模型请求检查:正在运行的会话拿到新技能; - 工具描述:改过的模式新建会话后,发出的请求里恰好只有被改的工具带着新文字;正在运行的会话在下一次请求就带上之后的修改;恢复之后下一次请求又是内置原文。在
0.2.0-rc.2和0.2.1-rc.1上都检查过; - 卸载:在
0.2.1-rc.2上给标准模式设了技能设置、即时生效并改了提示词、mode_prompt和一条工具描述修改。dsh plugin remove并删掉插件文件后,标准模式仍在模式列表里,能新建会话,本插件的行都已关闭,组装出的提示词里改过的文字出现一次。重新安装后所有设置都回来了。0.8.0 保存的标准模式覆盖在第一次启动时补上了条件。没有这些条件时,同样的卸载会让标准模式从模式列表里消失,新建会话报agent-preset/invalid。
测试
npm test
运行三方合并、工具描述计划逻辑、描述行、版本检查辅助函数的单元测试,对着假插件管理器的升级流程测试,技能设置、版本文件、技能设置行和技能导入(文件夹扫描、指纹、跳过外部链接的复制、改名和覆盖)的测试,卸载条件(加在哪些行上,有没有插件包时各自的结果)的测试,以及页面中英文文案是否一一对应的测试。
许可证
MIT