输入框四档提示词增强——按钮或全局热键把草稿改写为轻量润色、单段提示词、五段任务书或八段系统提示词,支持前后对比、回填与撤销;不改变原意、不凭空编造需求。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-prompt-enhance-cn
# Release 预构建包
dsh plugin --profile web add "https://github.com/qwe3120695033/prompt-enhancer/releases/download/v1.1.0/dsh-prompt-enhance-cn-0.3.0.tgz"
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:qwe3120695033/prompt-enhancer#path:/dsh-plugin
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DeepSeek Harness Web GUI 的「提示词增强」插件 —— 一键把输入框里的草稿改写为结构化提示词:明确的角色与目标、可执行步骤、输出格式、验收标准、边界条件。不改变原意、不凭空编造需求,原文始终保留。
English | 简体中文
为什么需要它
好的智能体提示词会讲清让模型扮演谁、交付什么、以什么格式、怎样算合格——而大多数草稿不会。本插件给 dsh 输入框加上 WorkBuddy 风格的「增强」入口:草稿经低温重写(走 harness 自带的 LLM 服务;基础档也走模型,只是只要求轻度整理)。基础 / 标准 / 专业三档点一下就地把结果写回输入框,不留对话框;系统档因为改的是整个人设,先开面板让你过目再落。撤销只需一键(或 Ctrl+Z),且任何失败路径都不会改动你输入的内容。
功能一览
| ✨ 输入框按钮 | 工具栏内发送键旁的小按钮,随手可及 |
| 🎚️ 四档位 | ✨ 左侧的胶囊显示当前档位(基础/标准/专业/系统),点开即切;规则与 Windows 热键层共用 core/rules.md;基础档只做轻度整理 |
| 🧷 上下文开关 | 下拉里单独一行控制「是否结合上下文」;切档会带上该档的预设值,之后可手动覆盖本会话;行尾那颗圆点把当前状态写成默认,一偏离默认就变空 |
| ⚡ 一键直填 | 基础 / 标准 / 专业档点 ✨ 直接改写输入框草稿,不弹框;请求期间你又动过草稿时自动转为预览,不覆盖新输入 |
| 🔀 对比预览面板 | 系统档(以及被升级的直填)才开:原文与增强结果左右并排,附模型名与耗时 |
| ↩️ 一键撤销 / Ctrl+Z | 直填或回填后输入框上方出现撤销提示,点「撤销」或按 Ctrl+Z 恢复原文;草稿被你再改过就让位给浏览器自己的逐字撤销 |
| ⌨️ 快捷键 | 默认 Ctrl+Shift+Alt+A 可配置,作用于你正在使用的输入框 |
💬 /enhance 命令 |
斜杠面板直接改写任意文本;结果不进入模型历史 |
| 🧠 模型路由 | 设置成对覆盖 → 当前会话模型 → 全局默认模型,依次回退 |
| 🔑 零凭据配置 | 调用走 harness LLM 服务,密钥来自 harness 凭据存储 |
| ⚙️ 配置热生效 | 模型覆盖、温度、预算、系统提示词、快捷键,全部在 设置 → 插件配置 即改即用 |
| 🛡️ 草稿安全 | 空输入、超长、仅图片、含命令块在本地拦截;上游失败映射为可读提示;失败绝不改动草稿 |

工作原理
flowchart LR
A[输入框草稿] --> B{本地守卫<br/>空 / 超长 / 命令块 / 占用}
B -- 通过 --> C["POST /prompt-enhance/enhance<br/>(仅回环的宿主路由)"]
B -- 拒绝 --> P["输入框上方内联提示<br/>(草稿不动)"]
C --> D["ctx.llm.stream<br/>按档位规则重写"]
D --> E[规范化:<br/>剥围栏 / 去空白 / 拒空]
E --> Q{档位 = 系统?<br/>或草稿已被改动?}
Q -- 否(基础/标准/专业) --> G["setDraft(增强文本)<br/>原文压入撤销栈"]
Q -- 是 --> F[预览面板:<br/>原文 / 增强结果]
F -- 回填 --> G
F -- 取消 / 复制 --> H[草稿不动]
G --> U["撤销条 / Ctrl+Z:一键恢复"]
插件是单个 npm 包、双半区结构,完全遵循 dsh 插件规范:
- 宿主半区(
exports ".",Node):注册prompt-enhance设置节(schemastery,由内置插件配置页自动渲染)、共享 webserver 上的POST /prompt-enhance/enhance路由(仅回环、限长),以及/enhance斜杠命令。模型调用走ctx.llm.stream并做规范化处理——与 harness 对会话标题相同的辅助调用纪律:超时与调用方取消在流过程中和结束后复查、终结 finish 校验、拒绝工具调用。 - 浏览器半区(
exports "./client"):把增强按钮注册进conversation.input.right插槽、撤销条注册进conversation.input.dock插槽,绑定设置命名空间的实时镜像,并安装全局快捷键。全部文案经 harness locale 系统提供中英双语。
环境要求
dsh >= 0.1.1-rc.2 < 0.3.0—— 这个区间表示实际验证过的范围,而不是无限期的承诺。- 实测环境:
0.1.1-rc.2、0.1.2-alpha.3、0.1.7-rc.2、0.2.0-rc.2均已 boot 验证(插件层挂载、增强路由应答、客户端 bundle 构建通过;alpha 上走新版ctx.settings.installSection注册路径,0.2.0-rc.2上还通过了运行时的插件兼容性闸门)。其中0.2.0-rc.2的验证包含 dsh 桌面应用——也就是本插件日常实际运行的环境。在0.2.x运行时上,可能会发现别的插件从界面消失:凡peerDependencies把@deepseek-ai/dsh-*锁在旧区间的 bundle 都会被闸门跳过(实测被跳过的是dshmarket、dsh-find-plugin、dsh-better-sidebar)。宿主在插件用到的两处 API 上做过破坏性变更:@deepseek-ai/dsh-settings的注册入口在两条早期版本线之间变了;0.1.5-rc.3起 settings 服务改为SettingsForms(不再有同步get),同时dsh-agent-default-model把全局默认模型收进了自己的ctx.agentDefaultModel.currentSelection()服务。插件对三种形态均做运行时探测并自动适配,无需配置。 - 上界覆盖整条
0.2.x线(含其预发布版本);0.3.x尚未验证,因此不在区间内。dsh.engines是加载器与插件管理器读取的声明性元数据——它表达支持范围,并不强制拦截。 - Node
^22.19.0 || >=24.0.0(仅从源码构建时需要) - 浏览器侧 peer
react/react-dom(^18.2.0)由 Web 壳的模块注册表提供。宿主半区用到的@deepseek-ai/dsh-llm是由 dsh 宿主提供的运行时模块,不从 npm 安装(lib/产物把包引用全部保持为外部),因此声明为可选 peer:未提供它的环境不会出现安装警告,增强时按正常错误路径报错,而不是加载失败。
| dsh | >= 0.1.1-rc.2 < 0.3.0 |
| Node | ^22.19.0 || >=24.0.0 |
| 插件 | 0.2.x |
安装
从 npm(推荐):
dsh plugin --profile web add dsh-prompt-enhance-cn
# 重启 dsh web
从 Release 的 tarball(构建产物 lib/ 已在包内,安装无需本地构建):
dsh plugin --profile web add https://github.com/qwe3120695033/prompt-enhancer/releases/download/vX.Y.Z/dsh-prompt-enhance-cn-X.Y.Z.tgz
插件在仓库的 dsh-plugin/ 子目录里,仓库根是 Windows 热键程序,所以 dsh plugin add github:qwe3120695033/prompt-enhancer 找不到它,请用上面的 tarball 地址或 npm 包名。
从本地检出(开发用,改代码重建 + 重启即生效):
git clone https://github.com/qwe3120695033/prompt-enhancer.git
cd prompt-enhancer/dsh-plugin && npm install && npm run build
dsh plugin --profile web add link:C:\path\to\prompt-enhancer\dsh-plugin
卸载:
dsh plugin --profile web remove dsh-prompt-enhance-cn
# 检查 profile 的 package.json 中 `dsh.profile.bundles` 数组是否残留
# "dsh-prompt-enhance-cn" 行,有则手动删除,然后重启 dsh web
使用方法
输入框按钮 / 快捷键 —— 输入(或留着)草稿,点 ✨ 或按 Ctrl+Shift+Alt+A:
- 先跑本地守卫:空草稿、超长草稿(不自动截断——截断会改变原意)、仅图片草稿、含命令或文件引用块的草稿,都会被拒绝并给出明确提示。引用块被拒是因为回填会破坏它们。
- 基础 / 标准 / 专业档:✨ 换成转动的圆环,输入框上方出现「正在增强… + 已用秒数 + 取消」。结果到齐后整段写进草稿,一次写完,那一行换成「已替换 / 撤销」。全程不弹框,不打断你;秒数一直跳说明调用还活着,✕ 可以随时中止(中止不算失败,输入框一个字符都没被动过)。基础档同样走模型,只是只要轻度整理,超过原文 1.5 倍会被拦下。
- 系统档:打开预览面板,左右并排两份文本。回填写回输入框并升起撤销条;复制进剪贴板;取消(
Esc或点击遮罩)丢弃一切。直填期间你若又改了草稿,结果同样进这个面板等你显式回填——绝不覆盖你新打的字。面板档不显示「正在增强」那一行,因为面板自己就是进度指示。 - 撤销:「撤销」链接或
Ctrl+Z恢复原文。你继续输入后,撤销条会安静地自我退位,Ctrl+Z也会让给浏览器自己的逐字撤销——过期的原文永远不会覆盖你更新的编辑。撤销记录只存在于当前页面内存(每个会话最多 3 条),刷新页面、重启 Web 或切换会话后即失效。
/enhance <文本> —— 从斜杠菜单改写任意文本。结果在命令面板渲染(可复制),不进入会话历史与模型上下文。要增强输入框里的草稿请用按钮或快捷键——草稿在浏览器里。正在运行的 /enhance 取消跟随 harness 命令面板能力;客户端未提供取消入口时,调用会执行到完成或超时。
语言一致性:重写策略默认要求模型保持输入语言(中文进中文出)——尽力而为的约束,无法严格保证。
配置
全部配置位于 prompt-enhance 设置命名空间,在 Web GUI 的 设置 → 插件配置 页编辑。改动作用于下一次调用——无需重启。每次增强都是一次计费的 LLM 调用——maxOutputTokens 约束单次成本,并发/限流字段约束调用频率。
| 字段 | 默认 | 说明 |
|---|---|---|
enabled |
true |
总开关;关闭隐藏按钮并停用所有触发方式 |
provider + model |
空 | 显式路由覆盖;必须成对填写(或都留空以跟随当前会话模型) |
temperature |
0.3 |
低温使改写更忠实于原意 |
maxOutputTokens |
2048 |
单次增强调用的输出 token 预算 |
maxInputChars |
12000 |
输入字符数上限(按 Unicode 字符统计,不是 token 数;一个 emoji 算一个字符);超限拒绝而不截断 |
timeoutMs |
60000 |
单次调用的端到端超时 |
defaultTier |
standard |
默认档位:base 只轻度理顺、standard 输出一个连续段落、professional 输出五段结构化提示词、system 输出八段系统提示词。胶囊里每行右端的圆点改的就是这一项——客户端同时存一份 localStorage 副本并优先读它,所以宿主这份落后时胶囊仍记得你的选择;system 不能设为默认 |
systemPrompt |
内置策略 | 自定义增强策略文本;与内置策略如何组合见 strategyMode |
strategyMode |
replace-default |
自定义策略的组合方式:replace-default 整体替换内置策略(向后兼容,但「不改变原意、不编造、只输出正文、镜像输入语言」等硬性约束不会自动保留,需自行写入);extend-default 把自定义文本追加在内置策略之后,硬性约束继续生效 |
shortcut |
ctrl+shift+alt+a |
快捷键规格(至少一个修饰键 + 单个字母/数字/功能键——纯裸键会被忽略,绝不会吞掉正常打字);留空禁用 |
maxConcurrent |
2 |
单个 Host 进程内的并发上限;超出的请求返回 429(concurrency-limit)。浏览器 UI 因单预览面板天然只允许 1 个在途请求,此上限主要保护 /enhance 命令入口与多客户端调用 |
rateLimitPerMinute |
10 |
单个 Host 进程内的每分钟滑动窗口限流,只统计成功完成的增强——失败(超时 / 上游错误 / 取消)不消耗窗口,连续失败不会把自己限流;超出的请求返回 429(rate-limit),响应附 Retry-After 秒数 |
streaming |
true |
模型边写边展示,而非等整段写完——仅影响显示节奏,最终文本仍是归一化的完整结果;系统档把增量写进预览面板,其余三档不走流式,结果到齐后整段替换(每次增量都是一次 setDraft,逐字写框会让 composer 每帧重渲染并抢走光标);宿主或网络不支持 text/event-stream 时客户端会自动回退为一次性 JSON 请求 |
contextAware |
true |
读取当前对话的近期历史,用于消解代词、补全已声明的约束、镜像已确立的栈与术语。无会话、无历史、或关闭此开关时,自动回退为单条增强——上下文是优化、不是前置条件。隐私: 装配好的历史片段会随草稿一起发给当前配置的 LLM;若当前会话含密钥、token、内部代号等敏感内容,请关闭 contextAware(或先结束该会话再开新会话增强) |
contextMaxMessages |
8 |
上下文窗口广度——最多参考多少条 user/assistant 轮;0 表示不参考 |
contextMaxChars |
4000 |
上下文窗口深度——历史片段的字符预算,从最新一条起向前装配;0 表示不参考 |
provider + model 取值 |
— | 与 harness 设置一致:设置文件 llm-pi-ai.providers 下的键就是 provider(如 zhipu、muyuu),其 models[].id 就是 model(如 glm-5.3-flash)。示例:provider: zhipu + model: glm-5.3-flash |
模型路由优先级: 设置成对覆盖 → 当前会话请求头中记录的路由 → 全局默认模型(agent-default-model)。三者都指不出路由时(例如全新会话且无默认模型),插件给出可操作的报错而不是乱猜。
四档位与规则真源
本 fork 把上游的单套内置策略换成了四档位,规则文本与 Windows 热键层共用同一份 core/rules.md(仓库根目录):
| 档位 | 输出形态 |
|---|---|
base 基础 |
轻度整理,走模型:理顺语序与连接词、补全缺失的标点/空格/分段、修正错别字;不扩写、不重排结构、不加目标/步骤/验收,也不主动加标题与分点。输出超过原文 1.5 倍会被拦下 |
standard 标准(默认) |
一个连续自然段,80~220 汉字,不带标题、编号、项目符号、表格、代码块 |
professional 专业 |
五段固定结构:任务目标 / 背景与范围 / 执行要求 / 约束条件 / 交付要求,250~500 汉字(软上限 700) |
system 系统 |
八段系统提示词:角色定位 / 核心目标 / 工作原则与优先级 / 规则与约束 / 能力与知识边界 / 输入处理 / 输出规范 / 异常处理与自检 |
四档共用的 [COMMON] 段承载保真底线(__PO_SKILL_0001__ 这类 Skill 占位符原样保留)、不编造、只输出正文等硬性约束,所以切到任何档位都不会丢掉安全底线。
规则文件是唯一真源:npm run gen:tiers 把它切段生成 src/generated/tier-rules.ts(构建前 --check 会校验生成物是否落后于规则文件,落后即失败)。改措辞只需改 core/rules.md 再跑一次生成。
上下文开关:档位给出一组预设(基础档永不带上文,标准 4 条 / 3000 字,专业与系统各 12 条 / 6000 字),切档时自动套用;下拉里那一行可当场覆盖,覆盖只作用于当前会话,不动持久默认。预设与 contextMaxMessages / contextMaxChars 取较小值,所以调小全局上限依然有效。
内置增强策略
默认系统提示词让模型扮演提示词重写专家,按草稿的实际需要施加:
- 角色与目标 —— 写明助手扮演谁、交付物是什么。
- 背景与约束 —— 只补全草稿可推断的信息;绝不编造事实、数据、名称或需求。
- 步骤 —— 把模糊或多头需求拆成编号、可执行的步骤。
- 输出格式 —— 在有暗示处指明结构、语言、长度与风格。
- 验收标准 —— 写明怎样判断结果正确。
- 边界条件 —— 列出边界情况与信息缺失时的做法。
硬性规则:精确保留原意(不删除、不篡改、不与用户信息冲突);绝不编造——未知细节插入显式占位符如 (待补充:…) / (TBD: …);保持任务范围不变;只输出改写后的正文(无解释、无围栏、无客套);镜像输入语言;长度约为原文 1–3 倍;已经成形的提示词只做轻度润色而不注水。
在设置中填写 systemPrompt 即可自定义策略,组合方式由 strategyMode 决定:默认 replace-default 是完全替换——内置策略中的安全约束(不改变原意、不编造、只输出正文、镜像输入语言、原文视为纯数据)不会自动保留,自定义策略需要自行包含这些约束;改为 extend-default 则把你的文本追加在内置策略之后,硬性约束继续生效。
异常与边界
| 情形 | 行为 |
|---|---|
| 空 / 纯空白 / 零宽字符草稿 | 本地拒绝:「输入框为空」 |
草稿超过 maxInputChars |
本地与路由双重拒绝并给出精确字符数;不自动截断 |
| 只附加了图片没有文本 | 拒绝:仅支持文本 |
| 草稿含命令 / 文件引用块 | 拒绝:回填会破坏引用块 |
| 提交中 / 占用阶段 / 已有请求在途 | 拒绝并提示「稍后再试」 |
| 每分钟次数超限 | 429(rate-limit),响应携带 Retry-After 秒数,宿主消息给出精确等待时长;窗口只统计成功完成的调用——失败不消耗窗口 |
| 并发已满 | 429(concurrency-limit),无 Retry-After——空出的时机不可预测,等一个在途调用结束即可 |
| 上游模型失败 | 稳定错误码映射为可读提示:AUTH → 检查 API Key、RATE_LIMIT → 稍后重试、QUOTA_EXCEEDED → 检查余额、CONTEXT_WINDOW_EXCEEDED → 精简输入、NO_ADAPTER/未配置 → 先配置模型 |
输出达到 maxOutputTokens |
拒绝并提示调大上限或精简原文 |
| 模型返回空 / 围栏包裹 / 工具调用 | 规范化(剥围栏)或拒绝;可重试 |
| 超时 | 映射为 504 的提示并给出配置秒数;可重试 |
| 浏览器中途关闭 | 宿主路由侦测连接断开,立即中止模型调用 |
| 切换会话 | 面板状态、撤销栈、快捷键目标均按会话隔离;切换即关闭面板并清理撤销记录 |
所有失败只出现在插件自己的面板里;失败的调用绝不修改输入框草稿,手动输入不受任何干扰。
错误码与本地化
宿主路由返回的结构化错误形如 { code, message?, params? }:主文案由浏览器按 code + params 从当前语言字典渲染,message 只是可选的诊断细节(如模型服务商的原始报错、配置错误原文),原样展示在主文案下方。/enhance 命令平面没有 locale 字典,由宿主侧的同源渲染函数直接产出中文文本。
| 错误码 | HTTP 状态 | 浏览器主文案(字典键) | 参数 |
|---|---|---|---|
rejected |
403 / 413 / 415 / 422 | error.rejected 通用;携带 { count, max } 时复用 error.tooLong |
超长输入: { count, max } |
rate-limit |
429 | error.rateLimit |
{ limit, retryAfterSeconds } |
concurrency-limit |
429 | error.concurrencyLimit |
{ max } |
timeout |
504 | error.timeout |
{ seconds } |
unconfigured |
409 | error.unconfigured |
— |
upstream |
502 | error.upstream 通用;携带 reason 时用 error.upstream.{reason}(如 auth / quota / rateLimit / empty / contextWindow / toolCall / maxTokens / invalidCredential) |
{ reason } |
internal |
500 / 502 | error.internal |
— |
故障排查
按钮不出现 / 快捷键无响应
设置 → 插件配置 → prompt-enhance 节的 enabled 是否为 true;插件是否成功安装(dsh plugin --profile web list)并重启了 dsh web;浏览器控制台是否有插件应用报错。
「尚未确定增强用的模型」
插件遵循设置成对覆盖 → 当前会话模型 → 全局默认模型的路由优先级,三者都为空时无法调用。在设置中成对填写 provider/model,或先在当前会话发一条消息让会话带上模型路由。检查 agent-default-model 设置节是否配置。
「鉴权失败」
message 细节行会带出具体原因(如 401)。检查对应 provider 在 harness 凭据存储中的 API Key;配额/余额问题对应 quota 提示。
连续失败后立刻被限流(429)
不应发生——限流窗口只统计成功调用,失败不消耗窗口。若仍遇到,确认同时挂载了多个 profile / 多进程(各自独立计数会叠加),或 rateLimitPerMinute 配置过低。
结果不理想(编造、丢要求、格式乱)
strategyMode 为 replace-default 时自定义 systemPrompt 会整体替换内置策略——内置的「不编造、只输出正文、镜像输入语言」等硬性约束不会自动保留,请自行写入;或改用 extend-default。
升级后行为变了
0.1.6 起宿主错误不再携带中文主文案,浏览器端按错误码本地化渲染(非中文界面不再混入中文);rate-limit 窗口改为只统计成功调用。升级后无需改配置。
安全模型
增强路由由你自己的 dsh 宿主提供服务,仅限本机访问:
- 套接字栅栏 —— 非回环地址(
127.0.0.1/::1之外)的请求一律拒绝。注意这意味着本机任意进程都可以调用该路由;路由本身不带用户鉴权。 - Host 白名单 —— 路由同时校验
Host头是否为localhost/127.0.0.1/[::1],可防御 DNS 重绑定(重绑定的攻击者域名虽然落在回环套接字上,但携带的是攻击者主机名,会被拒绝)。响应均为cache-control: no-store。 - 滥用上限 ——
Origin门拒绝来自非本地页面的浏览器调用;路由还执行并发上限(maxConcurrent,默认 2)与每分钟限流(rateLimitPerMinute,默认 10),超限返回429。这两项计数保存在单个宿主进程的内存中——多进程、cluster 或多个 profile 同时挂载时各自独立计数,全局上限会被突破;本插件只支持单进程部署,也不提供共享限流存储。 - 代理请求拒绝 —— 携带
X-Forwarded-For/Forwarded头的请求直接拒绝:这些头只会在链路上存在代理时出现,而代理场景不在本路由的信任模型内。 - 请求级超时由宿主与 Node 兜底 —— 插件层只限制 body 字节数(含 Content-Length 快速拒绝)与单次模型调用的
timeoutMs;连接级超时(headers timeout / request timeout / keep-alive)是共享http.Server的 server 级配置,插件不覆盖,由宿主与 Node 默认值(headers 60 秒 / request 300 秒)兜底。 - 不要经反向代理暴露 —— 若把 dsh web 放在监听局域网的代理后面,外部调用者在路由看来就是回环地址,栅栏形同虚设。除非在代理层自行加鉴权,否则不要暴露。
- 提示注入边界 —— 草稿被框在
<raw_prompt>标签之间,草稿内的字面闭合标签会被中和,策略提示词把框内文本视为纯数据——降低简单标签逃逸的风险;基于提示词的边界是尽力而为,并非完整防护。增强只使用你自己的凭据,结果也只回显给你本人。 - 会话上下文数据外发 ——
contextAware默认开启时,本插件会装配当前会话近期的user/assistant历史(条数与字符数受contextMaxMessages/contextMaxChars限制),随草稿一起发给当前配置的 LLM。该历史可能携带你之前在会话里输入过的密钥、token、内网主机名、客户名称等,模型提供方会原文看到。把contextAware视为隐私边界:不该外发的会话先关闭该开关,或结束会话、开新会话再增强。策略提示词里关于上下文的硬性约束可以禁止模型「基于上下文凭空加东西」,但无法撤回已经发出去的内容。
架构
src/
├── index.ts 宿主 apply():设置节 + 路由 + 命令
├── config.ts schemastery 模式 + 解析校验(成对路由)
├── prompts.ts 内置策略系统提示词 + <raw_prompt> 框架
├── enhancer.ts ctx.llm 辅助调用(路由解析、超时竞速、finish 校验、
│ 结构化错误 code+params + 宿主侧渲染)
├── enhance-routes.ts POST /prompt-enhance/enhance 与 /enhance-stream(回环栅栏、
│ 限长、准入闸门)
├── enhance-command.ts /enhance 斜杠命令(宿主命令注册表)
├── orchestrate.ts 两条宿主入口共用的路由解析 + 上下文装配
├── context.ts 有界、去框架化的 <conversation_context> 片段
├── loopback.ts 路由的 127.0.0.1/::1 栅栏
├── http.ts 限长 JSON body 读取 / 写出
├── sse.ts 带背压的 SSE 帧写入器
├── shared/ 传输协议类型、输入校验、输出规范化(两端共用)
└── client/ 浏览器半区
├── index.tsx 插槽注册 + 设置镜像 + 快捷键监听
├── EnhanceButton conversation.input.right 条目:守卫链 + 调用编排
├── ResultPanel 浮层面板:对比 / 回填 / 复制 / 取消 / 重试
├── UndoBar conversation.input.dock 条目:恢复入口
├── ui-state.ts 组件共享的外部 store(面板、撤销、会话注册表)
├── enhance-client fetch 客户端(可中止 + 类型化错误;SSE 与一次性两条路径)
├── undo-stack.ts 按会话的 LIFO 栈(每会话深度 3,全局 60 条,LRU 淘汰)
├── session-key.ts 每个输入框的 UI key(宿主 sessionId,否则稳定兜底 id)
├── shortcut.ts 纯函数的组合键解析 / 匹配
├── settings.ts 设置命名空间的客户端镜像
├── locales.ts 中英文字典(harness locale 命名空间)
└── styles.ts 自注入样式表(dsh-pe- 前缀类名)
构建产物:lib/index.js(宿主半区,ESM,包引用保持外部)与 lib/client.js(浏览器半区,打包为 CJS 并包进 dsh web 壳要求的 window.__ModuleLoader__.load({ id, factory }) 信封)。两者都随仓库提交,因此 GitHub 直装无需构建;CI 会在 lib/ 与 src/ 不一致时拒绝合并。
开发
日常调试闭环(link 安装 + watch):先用 dsh plugin --profile web add link:... 装一次,再挂 npm run watch;宿主半区改动需重启 dsh web——详见 CONTRIBUTING.md。
npm install
npm run typecheck # tsc --noEmit
npm test # 单元 + 真实 HTTP + 组件测试套件
npm run build # 规则生成校验 + 类型检查 + 双半区构建
npm run watch # esbuild 监听构建双半区
npm run gen:tiers # 改了 core/rules.md 之后重新生成档位常量
npm run install:profile # 把构建产物同步进 DSH profile(默认 desktop profile)
npm run verify:profile # 比对 profile 拷贝与本次构建的 sha256,不一致退出 1
改完怎么生效: 客户端半区(src/client/)刷新页面即可;宿主半区(src/)要重启 DSH。profile 里存的是实体目录而不是软链,所以每次 npm run build 之后都要再跑一次 npm run install:profile,改完用 npm run verify:profile 确认确实同步了。⚠️ 在 DSH 里装/卸任何插件都会触发一次 pnpm install,那会把 profile 里的这份拷贝换回 npm 上的上游 0.2.7——发现改动「没生效」时先跑 verify:profile,再跑一次 install:profile。不要改用 link: 依赖图省事:软链会让 @deepseek-ai/dsh-llm 解析到本仓库 devDependencies 里的另一份实例,cordis 服务身份冲突,插件会静默挂不上。
测试覆盖: 输入校验(空 / 零宽字符 / 超长)、输出规范化(剥围栏、折行、拒空)、以桩 ctx.llm 流驱动的增强器(正常路径、AUTH/NO_ADAPTER/max-tokens 终结、空输出、挂起流失超时、预中止的调用方、路由优先级)、路由的真实 node:http 端到端套件(回环栅栏、方法守卫、畸形 body、结构化错误信封、停用开关)、档位组合与上下文窗口收窄、档位胶囊交互、撤销栈、快捷键解析与匹配、配置解析、客户端设置解码器。
发版流程(维护者):
npm version patch # 或 minor / major —— 更新 package.json 并打 tag
npm run build # 让 lib/ 与 src/ 一致
git push --follow-tags
npm publish # 带 2FA OTP,或使用勾选了 "bypass 2FA" 的细粒度令牌
CI 在每次 push/PR 上运行类型检查 + 测试 + 构建,并在 lib/ 与已提交构建不一致时拒绝合并。
FAQ
为什么草稿里有 /命令 或 @引用 时被拒绝?
回填通过 inputActions.setDraft 写纯文本,会破坏引用块。先移除它们,增强后再插回。
为什么不自动截断超长输入? 截断会无声地改变你的原意——插件宁可拒绝并给出精确字符数。
能固定用某个模型吗?
在设置中成对填写 provider 与 model(例如 harness 已配置的 provider 路由)。都留空则跟随当前会话模型。
我的草稿会被发到哪里? 浏览器 → 你自己的 dsh 宿主(仅回环路由)→ harness LLM 服务 → 配置的模型服务商。不会发往其他任何地方,增强行为也绝不进入会话的模型历史。
官方 DeepSeek 路由能用吗?
能——调用走 ctx.llm,harness 支持的所有 provider(DeepSeek 官方、OpenAI 兼容网关)都可用。
安装后手工冒烟清单
安装并重启 dsh web 后:
- 设置 → 插件配置 出现
prompt-enhance配置节。 - 发送键旁出现 ✨ 按钮;
Ctrl+Shift+Alt+A触发相同流程。 - 空输入 → 拒绝面板;有效草稿 → 预览含模型信息;回填生效;撤销恢复;复制可用。
/enhance <文本>输出可复制结果,且不进入模型历史。- 三种模型路由都通:设置成对覆盖、会话模型、全局默认模型。
致谢
插件结构、回环栅栏与设置节模式遵循 dsh 插件家族的既有惯例——特别是 @linxin666/dsh-tool-describe-image。
许可证
链接
同类插件
zhu1090093659/dsh-web#packages/dsh-task-board★ 9262
侧边栏多列任务看板:卡片交给真实 DSH 智能体会话执行,支持 cron 定时(Host 侧到点执行,关浏览器也生效)。
zhu1090093659/dsh-web#packages/dsh-web-all★ 9262
DSH Web UI 插件与皮肤合集:任务看板、git 图、右侧面板、远程移动端 UI、桌宠、实时 token 统计与皮肤中心。
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 5677
右下角常驻的小鲸鱼挂件:余额、今日已用与每轮对话消耗(含峰谷价),余额预警与今日预算的泡泡内容都可编辑;泡泡点击序列模块化自定义,支持并列加权 A/B、随机台词与随机图片;内置 30+ 厂商模板(OpenAI / OpenRouter / Kimi / 硅基流动 / 方舟 / 智谱 / MiniMax 等),按模型查余额与订阅额度;另有任务结束音效、导入音频、自定义角色与资源管理。数据全在本机,无遥测。
ccch1mneyyy/dsh-TUI★ 5125
Claude Code 风格全屏终端 UI:像素鲸鱼顶栏、实时工作状态行、思考流式展开。
omdsh-dev/DSH-better-sidebar★ 4413
侧边栏完整工作台:内置文件渲染编辑、终端、Git 与子代理,支持三方插件注册新 Tab。
Devin-AXIS/deepseek-design#deepseek-idesign★ 1491
可视化设计工作室,支持网站、App 原型、海报、信息卡、报告和杂志的模板创建、元素编辑、选区级 AI 草稿衔接与导出。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。