Passer au contenu principal
W

dsh-draft-studio

wufeng0105/dsh-draft-studio

One click beside the composer turns a half-formed draft into a structured prompt the AI can act on: goal, constraints, output format and acceptance criteria filled in, placeholders only where a real decision is missing. Rewritten in place and never sent — undo with one click or Ctrl+Z. Four editable presets (general / code / writing / translation), optional conversation context to resolve references, and a model that either follows the session or is pinned to a chosen provider and reasoning effort. Requests survive session switches and typing while a rewrite is in flight; a result that no longer matches the draft is kept for retry instead of overwriting it. Pure JS, no build, no bundled dependencies.

Installer

dsh plugin --profile web add github:wufeng0105/dsh-draft-studio

README

Draft Studio · 草稿工坊

输入框里那个想到一半的草稿,点一下,变成 AI 真能照着干的提示词。

不发送、不弹窗、不换页面——就在输入框里原地改写。不满意就点回去,或者 Ctrl+Z。


1. 它解决什么

你打字往往是一边想一边写:

帮我弄个爬虫抓豆瓣

这句话你自己知道要什么,但交给 AI 就会跑偏——它不知道抓哪些字段、要不要存库、频率多少、出错怎么办。你得多轮来回才能说清。

点一下这个按钮,同样一句话会变成:

用 Python 写一个抓豆瓣电影 Top250 的爬虫,输出字段包括片名、评分、简介、链接。要求:遵守 robots.txt,请求间隔不低于 2 秒,结果存为 JSON 文件。若页面结构变化导致解析失败,输出明确的错误信息而不是静默跳过。<技术栈候选:requests+BeautifulSoup / Playwright>

——目标、约束、输出格式、验收标准都在里面了。而且它不会替你选中任何你还没决定的事:草稿里没说的技术栈,它会列几个候选让你挑,而不是自己拍板。

为什么值得单独装一个

不用它用它
提示词质量取决于你当时写得多细每次都补齐目标、约束、输出格式
来回沟通常要追问两三轮一次说清
会改你的原文吗—会,但你一键能还原

2. 它是怎么做的(够用就行,不必细看)

按钮点下去之后,它拿你的草稿(可选加上当前会话最近几轮发言,用来消解"刚才说的"这类指代)发给模型,要求模型只返回改写后的提示词,然后写回输入框。

  • 模型两档:跟着当前会话走(连思考强度一起跟随),或者在设置里固定一个。
  • 四套预设,每套一颗按钮:通用 / 编程 / 写作 / 翻译。每套是一份完整、可编辑的系统提示词——觉得它改得不符合你口味,就直接改那套提示词。设置页里可以勾选哪几套出现在输入框(默认四套全显示),也可以给它们改名。
  • 不发送:改完还是草稿,发不发、什么时候发,你说了算。

3. 安装 / 卸载

安装:DSH 插件页 → 添加插件 → 本地目录,指向本文件夹。

卸载:插件页 → 本插件 → 移除。只想暂时停用就关掉开关,不必卸载。


4. 用

4.1 按钮

草稿非空时出现在发送按钮左侧,最多四颗,每颗各对应一套预设(通用 / 编程 / 写作 / 翻译),点哪颗就用哪套提示词。显示哪几颗由设置页的勾选决定,默认四套全显示;取消勾选的只是那一颗按钮,那套提示词不会丢,重新勾上就回来。

每颗按钮各自走四种状态:

状态看到什么点它会
空闲一个图标用这套预设开始改写
运行中「已用 N 秒」取消
可回退结果已写回还原成原文
失败悬停看原因重试

一颗在跑,其余几颗置灰:同一会话同一时刻只跑一次,避免两颗按钮的结果互相覆盖。每颗按钮的回退、重试只作用于它自己那次改写。

等待期间你可以继续打字、切到别的会话、甚至直接发送:

  • 草稿已经变了,结果不会覆盖你的新内容,会保留着等你重试;
  • 切走再切回,请求不会断,状态还在;
  • 发送之后,转圈会自己停掉。

4.2 设置页

设置 → 草稿工坊:

  • 一行六格(等宽等高,外层一个框):
    1. 启用 —— 总开关。
    2. 读取上下文 —— 是否读当前会话最近几轮,用来消解「刚才说的」这类指代。
    3. 预设下拉 —— 选中哪套,下面 textarea 编辑的就是哪套。选项显示的是生效名。
    4. 显示按钮 —— 决定这一套是否显示在输入框。不受编辑门限制——藏起一颗按钮不算改内容;全都不勾时输入框不显示任何优化按钮,设置页会给提示。
    5. 编辑 / 完成 —— 编辑门:名称与提示词默认只读,点它才解锁,改完点「完成」。避免扫一眼设置就误改掉一套提示词。点「编辑」时第 3 格的下拉会变成名称输入框,直接就地改名(默认 OptionA–OptionD,最长 12 字,留空即回落默认名;名字只影响显示,不影响请求)。
    6. 默认 —— 把这一套的提示词恢复成内置文本;不受编辑门限制。
  • 提示词编辑:一份完整的系统提示词。清空并保存同样等于恢复内置默认。
  • 模型来源:「跟随会话 / 固定模型」切换。固定时展开两个下拉——模型、思考强度。
  • 上次改写(保存按钮上方一行):勾了「读取上下文」到底生效没有——显示读了几轮、多少字,或没读的具体原因(开关关着 / 拿不到会话 / 本会话还没历史 / 被条数或字数预算筛空)。只有成功的改写才更新;不显示会话正文。
  • 底部:左侧未保存项数,右侧放弃 / 保存。

5. 配置项

20 个字段,可在 cordis.patch.yml 的 config: 块或设置页改。改完即时生效——每次请求都重读配置。

字段默认说明
enabledtrue总开关
presetgeneral兜底预设(general / code / writing / translation)。请求没指定 presetId 时用它
promptGeneral / promptCode / promptWriting / promptTranslation内置文本每套预设的完整提示词
presetButtons四套全选输入框显示哪几颗按钮(无序集合,按固定顺序渲染)。空数组 = 一颗都不显示
nameGeneral / nameCode / nameWriting / nameTranslation空(= OptionA–OptionD)每套的显示名,最长 12 字;只影响显示,不参与请求
contextEnabledtrue读取会话上下文
modelModefollowfollow 或 fixed
provider / model空固定模型的 provider 与模型 id
reasoningEffort空(模型默认)固定模型的思考强度
maxOutputTokens5000单次输出上限(实际首发还会 +1500 思考余量;撞满自动翻倍重试,最多 3 次、封顶 16000)
timeoutMs480000单次请求截止时间(含内部的翻倍重试,最坏 3 次调用都算在这一个截止时间里)
contextMaxMessages / contextMaxChars8 / 4000上下文条数与字符预算

6. 边界(说在前面)

  • 命令芯片:草稿里含 / 命令标签(从 / 菜单认领的那种)时,结果可能写不回去——宿主没发布这类标签的坐标换算数据。原稿不会丢,结果会保留待重试;把那个标签删掉再点即可。@ 引用标签不受影响。
  • 手打的 /xxx 是普通文字,不是芯片,无影响。
  • 思考强度被拒:固定模型不支持所选档位时,自动按该模型默认强度重试——结果正常,只是强度覆盖失效。
  • 耗时取决于模型与强度:跟随模式会继承会话强度(会话是 Max 就跑满 Max)。要快要省,固定模型里选低强度或轻量模型。
  • 超时 480 秒;超时后草稿不变,可重试。
  • 不做:自动发送、多轮改写、模板库、历史记录、重启后的上下文回放。
  • 设置服务不可用时降级:如果 configForms 拿不到(例如 profile 里没有设置基础包),设置页会显示"不可用",输入框旁退回一颗按钮、请求不带 presetId——行为与 1.0.x 完全等价,不会报错。这是设计兜底,不是故障。

7. DSH 升级后跑一下

DSH 每升一次版本,先跑这个,三十秒内知道插件还活着没有:

npm run self-check -- -SkipLive -Port <当前端口>

四层验证:源码语法 → 清单契约 → 宿主运行时 → 端到端真打一次接口。任一失败会给出可操作提示并以退出码 1 结束;只想验证不花模型额度就加 -SkipLive。

两个容易踩的点:

  • -- 不能省。npm 不转发未知参数,写成 npm run self-check -SkipLive 时 npm 只会打印一行警告,然后执行不带参数的脚本——等于偷偷真打了一次模型接口。
  • 端口要现填。宿主每次启动会换端口,取 Web GUI 地址栏里的那个;脚本内置的三个候选端口不一定命中。

本包故意不声明 engines.dsh:一旦声明,宿主在遇到不认识的 rc 版本时会拒绝装载整个插件(不是警告,是直接不加载);而不声明的回落检查对我们恒为兼容。所以 DSH 升级后插件照常出现,靠这一节的两条命令确认它还活着。官方库的声明方式变了是另一处常见故障,脚本会直接报出来。


8. 源码地图

纯 JavaScript,无构建、无 node_modules(依赖由宿主提供)。验证方式:node --check + self-check + 真机。

文件职责
index.js宿主半包:Config schema(20 字段全 volatile)、三级模型路由、上下文装配、resolvePresetKey(按请求选的 presetId 定套)、generate(finish.kind 分派 + 预算翻倍重试 + 强度回退)、POST /dsh-draft-studio/refine(请求栅栏:POST 方法 / Host 必须 loopback / Origin 必须 loopback / Content-Type 必须 application/json;另有 1 MiB 上限与 AbortSignal.timeout)
client.js浏览器半包:createPresetStore(勾选与名称快照)、RefineControl + RefineButton(最多四颗,每颗四态)、insertText 写回(draftRev 守卫 + 芯片坐标折算)、一键回退、模块级任务注册表、设置页(名称 / 勾选 / 编辑门)、中英文案
cordis.patch.yml装载声明(一行 insert,entry id 全局唯一)
package.jsondsh.bundle.patch + dsh.client;@deepseek-ai/schemastery 为 peerDependencies
locale/*.json市场卡片元数据

改提示词文本看 index.js 的 PROMPT_BASE / PRESETS;改交互看 client.js 的 RefineControl;改模型路由看 index.js 的 resolveRoute;设置页控件看 client.js 的 SettingsSection。

动了任何宿主 API,先改 docs/HOST-CONTRACT.md——那一页列了我们依赖的 25 个契约点,以及每个点断了会长什么样。


9. 更多

Plugins associés