WeChat Official Account typesetting workbench: renders Markdown into inline-styled HTML you paste straight into the WeChat editor, with a sidebar panel, 11 themes and five model tools for block-level revision.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-fishpai
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:OMSociety/dsh-fishpai
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
This plugin publishes its README in Chinese only.
这是什么 • 核心特性 • 效果 • 安装方式 • 模型工具 • 面板快捷键 • 开发 • 许可证与作者
这是什么
鱼排编辑器把 Markdown 排成内联样式 HTML:整段粘进微信公众号编辑器就得到成品排版。
它同时是一个人在回路里的改稿台——面板与模型看的是同一篇文档,谁改了什么一目了然。
渲染内核与主题来自 MoPai 墨排 / mopai-markdown(MIT),
本仓库把同一套管线重构为 DSH 插件。署名与许可链条见 NOTICE.md。
核心特性
| 特性 | 说明 |
|---|---|
| Markdown 快捷键 | 选中后 Ctrl/⌘+B 加粗、+I 斜体、+K 链接、+Alt+1/2/3 标题、+Shift+8/7 列表;列表里回车自动续写 |
| 图片直接粘进来 | 截图 Ctrl/⌘+V 粘入(也可以拖进来)→ 存到文档同级的 assets/,正文自动插入引用,预览立刻可见 |
| 实时预览 + 手机宽度 | 打字 300ms 后预览跟着变;栏位够宽左右并排,窄了自动单栏;可切 375px 看公众号真实观感 |
| 批注与占位 | 光标所在段落加批注(模型下次 fishpai_read 就能看到);正文里写 <!-- 鱼排: 这里补个过渡 --> 也一样;点批注「定位」直接选中它引用的那段 |
| 块级 diff 与局部改稿 | 模型只改该改的块,你的其它改动原样保留;写入必须带 base_revision,不符先拒并回带"自你上次写入以来的改动" |
| 冲突不丢字 | 模型与你同时改时给出「用我的覆盖 / 看 AI 的版本」,采用 AI 版会先把你的草稿存进历史 |
| 主题与主题色 | 11 套主题,按"是否适合公众号"分组;主题色只对「默认公众号」生效(用不上的取色行会自动隐藏),有风险的主题直接提示原因;另有工作目录级的「自定义主题」(模型可在内置主题上只改几个槽位) |
| 复制与导出 | 复制为 text/html + text/plain 双格式;本地图片内嵌 base64,粘过去不用手动重传;也能导出成自包含 .html |
| 五个模型工具 | fishpai_open / read / write / render / theme,配一份教模型怎么用的技能 |
效果
同一份 HTML 用「导出 HTML」存成文件、在浏览器里打开,看到的就是面板右侧那个样子。
安装方式
从 npm 安装
# 先停掉正在运行的 DSH(运行中的服务会锁住依赖,装完再起)
dsh plugin --profile <profile> add "dsh-fishpai"
装好后刷新一下浏览器页面,「鱼排编辑器」从右侧栏的引导页打开——只重启宿主不够,客户端产物是页面加载时取的;入口与布局按会话记忆,新会话第一次要点一次(模型调
fishpai_open时也会自动打开)。 本插件零运行时依赖,不受minimumReleaseAge影响。
装完怎么用
- 让模型
fishpai_open打开一篇 Markdown → 右侧栏应自动弹出鱼排并显示正文与预览 - 在面板里打字 → 预览跟着变;选中文字按
Ctrl/⌘+B→ 变成**加粗**,Ctrl+Z能撤销 - 截图后
Ctrl/⌘+V→ 正文出现,预览里能看到图,文档同级多出assets/目录 - 光标放在某段上点「+批注」写一句要求,再到正文里写一行
<!-- 鱼排: 这里补个过渡 --> - 让模型
fishpai_read→ 它应当说出你改了哪一块、批注要求什么、占位在哪一行 - 让模型
fishpai_write(mode: "patch")→ 只有那块变了,你其它改动原样保留 - 点「复制到公众号」→ 粘进公众号编辑器,版式正确(标题 / 列表 / 引用 / 表格 / 信息卡片)
模型工具
| 工具 | 作用 | 关键参数 |
|---|---|---|
fishpai_open |
打开 / 新建文档,并在右侧栏弹出面板 | path(可省扩展名,自动补 .md)、markdown(新建时写正文)、theme |
fishpai_read |
改稿前必做:读块级 diff、批注、占位、图片提醒与块 id | doc_key、include |
fishpai_write |
改稿。必须带 base_revision;优先按块改 |
doc_key、base_revision、mode(patch / replace)、patches[{block_id 或 block_index, op, markdown}] |
fishpai_render |
导出可粘贴 / 归档的自包含 HTML(本地图片内嵌 base64) | out_path(可省扩展名)、theme、theme_spec(临时自定义主题,不落盘)、publish(false = 预览原样形态)、embed_images |
fishpai_theme |
工作目录级的**「自定义主题」**(一套,set / show / clear):模型在某套内置主题上只覆盖想改的槽位,面板主题列表里就是那一个占位 |
action、theme_spec |
模型的标准动作顺序是 open → 等你改 → read → write → 你点复制;技能 fishpai
(随插件注册)里写明了这套纪律与排版口径,模型会在需要时自己读。
面板快捷键
| 快捷键 | 作用 | 快捷键 | 作用 |
|---|---|---|---|
Ctrl/⌘ + B |
加粗 | Ctrl/⌘ + Alt + 1/2/3 |
一级 / 二级 / 三级标题 |
Ctrl/⌘ + I |
斜体 | Ctrl/⌘ + Alt + 0 |
正文(去掉标题) |
Ctrl/⌘ + E |
行内代码 | Ctrl/⌘ + Shift + . |
引用 |
Ctrl/⌘ + K |
链接 | Ctrl/⌘ + Shift + 8 / + 7 |
无序 / 有序列表 |
Ctrl/⌘ + Shift + X |
删除线 | Tab / Shift + Tab |
缩进 / 反缩进 |
Ctrl/⌘ + S |
保存 | Ctrl/⌘ + Shift + C |
复制到公众号 |
Ctrl/⌘ + V |
粘贴图片(或拖进来) | Ctrl/⌘ + Enter |
添加批注(在批注框里) |
编辑器右上角的「快捷键」按钮里就是这份表(Mac 显示 ⌘、Windows 显示 Ctrl)。
数据放在哪
| 位置 | 内容 | 说明 |
|---|---|---|
你指定的 .md |
文档正文 | 普通 Markdown,任何编辑器都能改;鱼排不往正文里塞标记 |
.fishpai/docs/ |
没指定路径时新建的文档 | fishpai_open 省略 path 就落在这里,按标题命名 |
<文档同级>/assets/ |
粘贴进来的图片 | 相对路径引用(assets/xxx.png),文档搬走图也跟着走 |
.fishpai/state/ |
主题、revision、baseline、批注 | 按文档路径哈希命名;删掉会丢批注、历史与「模型上次写入的基线」(正文不动,但模型暂时看不出你改了什么) |
.fishpai/history/ |
历史快照(最多 50 份) | 面板「历史」抽屉里可一键回滚 |
.fishpai/theme.json |
「自定义主题」(工作目录级,只有一套) | fishpai_theme set 写、clear 删;改坏了静默退回「默认公众号」 |
.fishpai/.gitignore |
忽略 state/、history/、theme.json |
插件自建,只追加缺失的行(你写的改动一字不动);正文与图片是否入库由你自己决定,主题想跟仓库走就用 git add -f |
开发
npm install # 只有 devDependencies(esbuild / typescript / @types/react / @types/react-dom / @deepseek-ai/cordis)
npm test # 全量回归:golden + 站点对照 + 块/diff/批注/补丁 + 宿主红线 + 微信兼容层 + 主题规格 + 主题图标内联核对 + bundle + 快捷键 + 挂载 + 客户端 store 时序 + 接口层(api)
npm run typecheck # 客户端 TSX 类型检查
npm run build # 重新打包 lib/client.js(改完客户端必须跑,并提交产物)
npm run check:build # 确认 lib/ 无漂移
目录与「改东西去哪」:
plugin/index.mjs 宿主入口:注册工具 + /fishpai/api 路由 + fishpai 技能
plugin/core/ 渲染内核(ESM,零依赖):runtime / markdown / render / diff / notes / patch / theme-info / theme-spec
plugin/host/ 宿主侧:工具契约、HTTP 路由、文档存储、图片、自定义主题
plugin/vendor/ 上游 themes.js + markdown-it 14.1.0 + highlight.js 11.9.0 + hljs-map.json
client/ 客户端源码(TSX → esbuild 打成 lib/client.js)
lib/client.js 客户端 bundle(入库;dsh plugin add 不做构建)
skills/fishpai/ 鱼排技能:教模型怎么选主题、怎么按块改稿
test/ golden、站点对照、块/diff/批注/补丁、宿主红线、微信兼容层、主题规格、主题图标内联核对、bundle 形态、快捷键、真实 Cordis 挂载、客户端 store 时序、接口层(api)
用微信官方校验器复验(需要本机 Chrome,不进依赖):
git clone --depth 1 https://github.com/wechatjs/verify-article-structure-spec "$env:TEMP\was"
cd "$env:TEMP\was\cli"; $env:PUPPETEER_SKIP_DOWNLOAD='true'; npm install
$env:PUPPETEER_EXECUTABLE_PATH='C:\Program Files\Google\Chrome\Application\chrome.exe'
npx tsx src/index.ts <导出的 article.html> --json # isValid: true 即通过
支持与致谢
如果这个插件对你有帮助,欢迎点亮 Star,有问题和建议请提交 Issue 或 Pull Request;动手前请读
CONTRIBUTING.md,安全相关问题走SECURITY.md的私密渠道。想改主题或加一套自己的:主题定义集中在
plugin/vendor/themes.js,加完跑npm run test:golden:regen重生成 goldenMoPai 墨排 / mopai-markdown(MIT):渲染管线、主题、以及"复制到公众号"的整套行为都来自这里
markdown-it(MIT)与 highlight.js(BSD-3-Clause):随包内嵌的 vendor 资产
DeepSeek Harness:插件、右侧栏与技能的宿主
许可证与作者
MIT。上游 mopai-markdown © 2026 @ye4wzp;本仓库新增部分 © 2026 @OMSociety。
Links
More in this category
tt-a1i/archify#integrations/deepseek-harness★ 89901
Generate validated, self-contained interactive architecture, workflow, sequence, data-flow, and lifecycle diagrams from repositories or system descriptions.
dream-num/dsh-univer-office★ 614
Give DeepSeek Harness a real office environment. Univer Office Plugin brings spreadsheets, docs, slides, canvases, relational tables, and more into one runtime — with connected data, validation, versioned changes, and isolated worktrees for multi-agent collaboration.
ECNU/EduWork#dsh-knowledge-studio★ 246
A workspace-based Studio for source-grounded reports, slides, tables, mind maps, quizzes, flashcards, audio and video, using DSH models and shared artifact services. Office generation requires Python 3.12+ with its dependencies and DSH_OFFICE_PYTHON configured; media rendering requires Chromium, and local ASR additionally requires whisper.cpp and a model.
PerryLink/dsh-industry-research★ 214
Deterministic industry research reports for DeepSeek Harness — company and industry research flows produce structured, verifiable reports from staged evidence.
HuanLinOTO/dsh-plugin-mineru★ 48
Expose MineRU document parsing tools to the model.
PolinniZhong/dsh-knit★ 47
Puts the Markdown documents, source files, images and video that already exist anywhere in the session workspace into the DSH sidebar, ranked by relevance to the current conversation. The default lexical mode matches your recent messages against title, summary and body locally with IDF weighting (BM25) — no model calls, no network, nothing leaves the machine. The list comes from scanning the workspace rather than from a recent-files list, so restarting DSH or opening a new session does not empty it. Results are organised into a three-tier reading order (primary / supporting / related) with a verifiable reason on every row — which field matched, which document cites this one — and one click opens an in-place preview: Markdown as rendered text, relative-path images actually drawn, source code with the host's own syntax highlighting, video streamed over HTTP Range. The same Context Pack is exposed to the agent as a knit_docs tool. Later versions added read evidence and lifecycle tracking (attribution is frozen at the moment of reading), pin / exclude (exclusion applies before retrieval, and is undoable), relation evidence (references / imports / tests, with line numbers) and an incremental index reused across restarts. Since v0.23 there is also an optional hybrid mode: it is off by default and only runs once you configure an Ollama or OpenAI-compatible embedding provider yourself. When it runs, what leaves the machine is your query text plus each candidate file's title and summary — a Markdown summary is an excerpt of the body's first paragraph (at most 60 characters), a code file's summary is its workspace-relative directory, and an image or video contributes its file name; full bodies and absolute paths are not sent, and a loopback provider keeps everything on this machine. Since v0.24 it also associates uncommitted changes: a read-only git status (fixed argv, no shell, whitelisted child-process environment) combined with the same reference / import / test / mention evidence shows which files a change is likely to drag along, and it is off by default. The benefit of semantic retrieval still awaits a real-provider run, so no recall improvement is claimed.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.