tianji-qingtian/dsh-composer-polish
DeepSeek Harness 插件:输入框草稿一键 ✨ 润色,flash 改写、自动回填
项目介绍Project Overview
dsh-composer-polish 是 DeepSeek Harness 的一个插件,在 composer 工具栏添加一个 ✨ 润色按钮,把草稿文本直接送入 deepseek-v4-flash 改写后再回填到输入框,全程不调用主模型、不污染会话日志,也不修改图片附件。适用场景:快速整理口述式草稿、清理冗词而保留语气与代码片段。注意:超过 50KB 的草稿会被截断;改写期间草稿被编辑则结果丢弃。
dsh-composer-polish is a DeepSeek Harness plugin that adds a ✨ Polish button to the composer tool row. It sends the draft to deepseek-v4-flash for a zero-prefix rewrite and writes the result back into the input via the official setDraft path. Use it to quickly clean up rambling drafts while keeping your voice, language, and code intact, without involving the main model or the session log. Note: drafts over 50KB are truncated, and edits made during a rewrite cause the new result to be discarded.
请帮我了解并安装插件:【dsh-composer-polish】【https://github.com/tianji-qingtian/dsh-composer-polish】
把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.
或使用命令行安装(适合开发者)Or use CLI install (for developers)
命令行安装CLI Install
dsh plugin --profile web add "github:tianji-qingtian/dsh-composer-polish#v0.1.4"
把 tianji-qingtian/dsh-composer-polish 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-composer-polish
One-click draft polisher for the DeepSeek Harness (dsh) composer. Type a rambling draft, hit the ✨ 润色 / Polish button in the input tool row, and a few seconds later the polished text replaces the draft in the input box — you preview, maybe edit, then send. No scoring, no evaluations: draft in → better draft out.
The harness is in developer preview and iterates quickly — expect compatibility-breaking changes.
中文说明见 README.zh.md。
Features
- ✨ button in the tool row — sits in
conversation.input.right, the official seat for clickable controls beside the send button. Disabled while the draft is empty or pure whitespace, shows a spinner while polishing, and never lets double-clicks fire a second request. - Zero-prefix flash rewrite — the host half rewrites the draft with a single
deepseek-v4-flashstream (reasoningEffort: 'off', ~2000 token cap). The main model never runs and its prefix cache is never touched. If the pinned model id is missing from the provider catalog, it retries once with a flash-class model discovered viallm.listModels. - Fill-back, not chat — the polished text goes straight into the input box through
inputActions.setDraft, the official public draft write path. You can edit it again or polish a second time; nothing is sent until you press send. Image attachments are never touched — only the text is replaced. - Fails silent — a failed or empty rewrite leaves the draft untouched (console log only, no toasts).
- Privacy — the
/polishcommand registers withrecordInput: false, so the raw draft never lands in the session log; only the polished result is recorded incommand/done. - No custom wire protocol — Client→Host rides the harness's built-in
commandsremote (the same channel the shipped/commands use). - i18n zh/en — button label and tooltip follow the harness
localeservice. - Language and voice follow the draft — the rewrite answers in the draft's language and keeps the user's voice (it strips filler but won't turn the text more formal, salesy, or robotic); code blocks, file paths, command lines, identifiers, and technical terms stay verbatim.
Screenshots
The ✨ Polish button in the composer tool row, next to the send button:

Install
Prerequisites
The dsh CLI must be on your PATH. If you only ever ran the harness through npx, dsh is not installed and you will get zsh: command not found: dsh — install it globally first:
npm install -g @deepseek-ai/dsh
pnpm add -g @deepseek-ai/dsh also works if your pnpm global bin dir is on PATH (otherwise pnpm asks you to run pnpm setup first). Alternatively skip the global install and prefix the commands below with npx @deepseek-ai/dsh ….
Add the bundle
# 1. add the bundle to your web profile (pnpm-backed; the built lib/ artifacts
# are committed in this repo, so no build script runs at install time)
dsh plugin --profile web add "github:tianji-qingtian/dsh-composer-polish#v0.1.4"
# 2. restart the harness with that profile — `add` only edits the profile
# files; a running instance does not hot-load the new bundle
dsh --profile web
After the restart the ✨ button appears in the composer tool row, next to the send button, and the /polish command is registered once the host half loads. Verify under Settings → Plugins that dsh-composer-polish is listed.
How it works
| Piece | Mechanism |
|---|---|
| Button seat | conversation.input.right list slot (session scope); the standard kit's selector hook useInput((s) => s) reads the draft, inputActions.setDraft() writes it back |
| Client → Host | built-in commands remote, hard-injected (inject: ['remote', 'remote.commands']): ctx.remote.commands.execute(sessionId, '/polish ' + draft) — the same roundtrip the shipped slash commands use; no custom RPC |
| Host rewrite | /polish command handler → zero-prefix ctx.llm.stream on deepseek-official / deepseek-v4-flash (reasoningEffort: 'off', maxTokens 2000), one-shot, with a one-time catalog fallback when the pinned model id is unavailable |
| Result channel | handler returns { kind: 'success', text }; the client reads it from CommandExecution.result.text and fills it back via setDraft |
| Privacy | recordInput: false → command/run omits args, so the raw draft is never written to the session log |
| Stale-edit guard | the client captures draftRev at click time; if the draft changed while polishing, the result is discarded instead of clobbering newer edits |
| Draft cap | both halves cap the draft at 50 KB; longer drafts are truncated client-side before sending |
Behavior spec (from REQUIREMENTS.md)
| # | Scenario | Behavior |
|---|---|---|
| 1 | Non-empty draft, click ✨ | read draft → flash rewrite → fill back |
| 2 | Empty / whitespace-only draft | button disabled |
| 3 | Rewrite fails / returns empty | draft untouched, console log only, no toast |
| 4 | Rewrite in flight | button shows spinner, repeat clicks blocked |
| 5 | Draft has image attachments | only the text is polished; images untouched |
| 6 | Chinese / English draft | rewritten in the draft's language |
| 7 | Code blocks / lists / technical terms | structure kept, code verbatim, no accuracy changes |
Build
pnpm install
pnpm build # tsdown: lib/index.js (ESM host) + lib/client.js (ModuleLoader client bundle)
Known limitations
- The fill-back is skipped when the draft changed during the rewrite (stale-edit guard) — by design, your newer edits always win.
- Drafts over 50 KB are truncated before the rewrite (a draft of that size is beyond what a single flash call can meaningfully restructure anyway).
- The polished result is recorded in
command/done(the commands channel's own lifecycle log); only the original draft is kept out of the log viarecordInput: false. deepseek-v4-flashis pinned as the rewrite model; if the harness renames model ids, the catalog fallback picks a flash-class replacement and logs a line.
License
MIT
nexu-io/open-design
ruvnet/ruflo
amruthpillai/reactive-resume
esengine/DeepSeek-Reasonix
volcengine/OpenViking
Molunerfinn/PicGo
titanwings/distilly
titanwings/colleague-skill