🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

微信草稿工作流 geekjourneyx/dsh-md2wechat

DeepSeek Harness
geekjourneyx1 天前有提交已提供中文文档扫描:含敏感能力

DSH 一站式公众号创作插件,集成写作润色、标题优化、主题与高级模块排版、智能配图,支持预览、导出及保存到公众号草稿箱。

36.1/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add geekjourneyx/dsh-md2wechat
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · platform
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 1 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/29) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包@geekjourneyx/dsh-md2wechat(未发布到 npm,仅可源码安装)
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 00:32:38

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 66 处,展示前 47 条)
  • 发起网络请求
    src/creator/delivery.ts:162
    const outcome = await deps.approval.request({ agent: exec.agent, callId: exec.callId, toolName, reason, signal: exec.signal })
  • 写入本地文件
    src/creator/documents.ts:137
    await mkdir(terminal, { mode: 0o700 }).catch(error => { if (!isExists(error)) throw error })
  • 写入本地文件
    src/creator/documents.ts:162
    await mkdir(pending, { mode: 0o700 })
  • 写入本地文件
    src/creator/documents.ts:164
    await mkdir(join(pending, token), { mode: 0o700 })
  • 读取本地文件
    src/creator/documents.ts:200
    const entries = await readdir(root, { withFileTypes: true })
  • 读取本地文件
    src/creator/documents.ts:205
    const attempts = await readdir(pending, { withFileTypes: true })
  • 读取本地文件
    src/creator/documents.ts:210
    if ((await readdir(join(pending, attempt.name))).length) throw new Error('creator delivery attempt must be empty')
  • 删除本地文件
    src/creator/documents.ts:217
    if (status.token) { await rmdir(join(pending, status.token)); await syncDirectory(pending) }
  • 删除本地文件
    src/creator/documents.ts:218
    await rmdir(pending); await syncDirectory(root)
  • 读取本地文件
    src/creator/documents.ts:233
    const entries = await readdir(root, { withFileTypes: true })
  • 读取本地文件
    src/creator/documents.ts:247
    const entries = await readdir(articleRoot, { withFileTypes: true })
  • 读取本地文件
    src/creator/documents.ts:252
    if ((await readdir(terminal)).length !== 0) throw new Error('creator document owner authority terminal must be empty')
  • 写入本地文件
    src/creator/documents.ts:294
    if (create) await mkdir(current, { mode: 0o700 }).catch(error => { if (!isExists(error)) throw error })
  • 发起网络请求
    src/creator/runtime.ts:187
    const imageApproval: typeof ctx.approval = { request: request => ctx.approval.request({ ...request, reason: `${request.reason} Image provider origin:
  • 发起网络请求
    src/creator/ui-approval.ts:9
    return turns.run(request.agent, signal, approvalSignal => approval.request({ ...request, signal: approvalSignal }))
  • 写入本地文件
    src/workspace/artifact-store.ts:241
    await mkdir(dirname(destination), { recursive: true })
  • 写入本地文件
    src/workspace/artifact-store.ts:245
    await mkdir(this.fs.processPath(tempParent), { recursive: true, mode: 0o700 })
  • 删除本地文件
    src/workspace/artifact-store.ts:311
    await rm(this.fs.processPath(current))
  • 写入本地文件
    src/workspace/artifact-store.ts:439
    mkdirSync(destinationPath)
  • 写入本地文件
    src/workspace/artifact-store.ts:475
    await mkdir(this.fs.processPath(reservedParent), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/workspace/artifact-store.ts:590
    await mkdir(initialDirectory, { recursive: true })
  • 读取本地文件
    src/workspace/artifact-store.ts:683
    const tempInfo = lstatSync(tempPath)
  • 读取本地文件
    src/workspace/artifact-store.ts:686
    const currentBytes = readFileSync(tempPath)
  • 删除本地文件
    src/workspace/artifact-store.ts:797
    await rmdir(this.fs.processPath(checkedDirectory))
  • 读取本地文件
    src/workspace/artifact-store.ts:883
    const info = await lstat(path)
  • 读取本地文件
    src/workspace/artifact-store.ts:895
    const info = lstatSync(path)
  • 删除本地文件
    src/workspace/artifact-store.ts:954
    await rm(path)
  • 读取本地文件
    src/workspace/draft.ts:32
    const entries = await readdir(root, { withFileTypes: true })
  • 读取本地文件
    src/workspace/draft.ts:37
    if ((await readdir(join(root, 'started'))).length !== 0) throw new Error('draft started authority must be empty')
  • 读取本地文件
    src/workspace/draft.ts:44
    const digests = await readdir(complete, { withFileTypes: true })
  • 读取本地文件
    src/workspace/draft.ts:47
    if ((await readdir(terminal)).length !== 0) throw new Error('draft completed authority terminal must be empty')
  • 写入本地文件
    src/workspace/draft.ts:60
    try { await mkdir(join(root, 'started'), { mode: 0o700 }) } catch (error) {
  • 写入本地文件
    src/workspace/draft.ts:80
    try { await mkdir(completed, { mode: 0o700 }) } catch (error) { if (!(error instanceof Error && 'code' in error && error.code === 'EEXIST')) throw err
  • 写入本地文件
    src/workspace/draft.ts:83
    try { await mkdir(terminal, { mode: 0o700 }) } catch (error) { if (!(error instanceof Error && 'code' in error && error.code === 'EEXIST')) throw erro
  • 读取本地文件
    src/workspace/draft.ts:102
    const canonicalState = await realpath(this.stateDir)
  • 读取本地文件
    src/workspace/draft.ts:103
    const canonical = await realpath(runtime)
  • 写入本地文件
    src/workspace/draft.ts:115
    if (create) await mkdir(this.stateDir, { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/workspace/draft.ts:130
    if (create) await mkdir(current, { mode: 0o700 }).catch(error => { if (!(error instanceof Error && 'code' in error && error.code === 'EEXIST')) throw
  • 写入本地文件
    src/workspace/image-plan-state.ts:52
    if (create) await mkdir(this.stateDir, { recursive: true, mode: 0o700 })
  • 读取本地文件
    src/workspace/image-plan-state.ts:55
    const canonicalState = await realpath(this.stateDir)
  • 写入本地文件
    src/workspace/image-plan-state.ts:75
    try { await mkdir(terminal, { mode: 0o700 }) }
  • 读取本地文件
    src/workspace/image-plan-state.ts:119
    const rootCanonical = await realpath(root)
  • 写入本地文件
    src/workspace/image-plan-state.ts:127
    if (create) await mkdir(current, { mode: 0o700 }).catch(error => { if (!(error instanceof Error && 'code' in error && error.code === 'EEXIST')) throw
  • 读取本地文件
    src/workspace/image-plan-state.ts:129
    const canonical = await realpath(current)
  • 读取本地文件
    src/workspace/image-plan-state.ts:136
    const entries = await readdir(planRoot, { withFileTypes: true })
  • 读取本地文件
    src/workspace/image-plan-state.ts:142
    if ((await readdir(terminal)).length !== 0) throw new Error('image plan authority terminal directory must be empty')
  • 读取本地文件
    src/workspace/image-plan-state.ts:146
    const info = await lstat(path)
扫描于 2026/11/3(0 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-api-gateway@deepseek-ai/dsh-api-session-controller@deepseek-ai/dsh-api-workspace-files@deepseek-ai/dsh-client-ui-conversation@deepseek-ai/dsh-client-ui-layout@deepseek-ai/dsh-client-ui-renderer@deepseek-ai/dsh-client-ui-session@deepseek-ai/dsh-client-ui-sidebar@deepseek-ai/dsh-client-ui-sidebar-right
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • Markdown文章审校
  • 导出微信草稿

面向 DeepSeek Harness 的安全 Markdown 转微信公众号草稿工作流插件

README

由 DeepSeek 最新模型翻译生成
dsh-md2wechat DSH 一站式公众号创作插件 在 DeepSeek Harness(DSH) 里完成公众号写作、文字润色、标题优化、排版和配图,预览确认后导出 HTML 或保存到公众号草稿箱。排版与交付能力由 md2wechat 提供。 功能介绍 · 安装 · 开始创作 · 配置 · 常见问题 当前版本 2.0.0-rc.5 为预发布版,可从 发布页 下载。历史 v1.0.0 是更早的工具流程,使用不同的宿主版本。 功能介绍 | 功能 | 可以做什么 | | 对话写作 | 在 DSH 中描述选题,让助手写成文章,并直接打开文章编辑器 | | 文字润色 | 获取修改建议、比较前后差异,选择采用或继续编辑正文 | | 标题优化 | 直接修改标题,或让助手提供新的标题建议 | | 主题排版 | 切换公众号主题,查看实际排版效果 | | 高级排版模块 | 点击「高级排版」,按文章选择主视觉、行动引导、卡片、分割线等模块;整篇最多 8 个,确认建议后应用 | | 封面与正文配图 | 导入本地图片或使用生图能力,选择封面,并为指定段落配图 | | 导出与草稿 | 导出已审阅的 HTML,或准备微信素材后保存到公众号草稿箱 | | 文章历史 | 保存文章、主题、图片选择和修订记录,继续之前的创作 | 在「正文配图与文字建议」中,点击润色按钮旁的「高级排版」。
展开完整文档(README 剩余 1 节)
dsh-md2wechat

DSH 一站式公众号创作插件

在 DeepSeek Harness(DSH) 里完成公众号写作、文字润色、标题优化、排版和配图,预览确认后导出 HTML 或保存到公众号草稿箱。排版与交付能力由 md2wechat 提供。

功能介绍 · 安装 · 开始创作 · 配置 · 常见问题

当前版本 2.0.0-rc.5 为预发布版,可从 发布页 下载。历史 v1.0.0 是更早的工具流程,使用不同的宿主版本。

功能介绍

| 功能 | 可以做什么 |
| 对话写作 | 在 DSH 中描述选题,让助手写成文章,并直接打开文章编辑器 |
| 文字润色 | 获取修改建议、比较前后差异,选择采用或继续编辑正文 |
| 标题优化 | 直接修改标题,或让助手提供新的标题建议 |
| 主题排版 | 切换公众号主题,查看实际排版效果 |
| 高级排版模块 | 点击「高级排版」,按文章选择主视觉、行动引导、卡片、分割线等模块;整篇最多 8 个,确认建议后应用 |
| 封面与正文配图 | 导入本地图片或使用生图能力,选择封面,并为指定段落配图 |
| 导出与草稿 | 导出已审阅的 HTML,或准备微信素材后保存到公众号草稿箱 |
| 文章历史 | 保存文章、主题、图片选择和修订记录,继续之前的创作 |

在「正文配图与文字建议」中,点击润色按钮旁的「高级排版」。助手会读取当前 md2wechat 支持的模块,结合文章提出建议,已有模块也计入 8 个上限,不会为了凑数堆满。动画分割线仅在当前版本支持时使用,微信内的动效以实际显示为准。高级排版模块由 md2wechat 的 API 排版服务处理。模块用法见 高级排版指南,实际效果以当前服务返回的预览为准。

md2wechat 还提供多公众号账号配置,以及微信接口 IP 白名单和固定出口的接入说明。插件当前使用 DSH 中配置的一组公众号凭据,不提供界面内多账号切换或批量投递;相关配置见 多账号与 IP 白名单。完整能力与配置文档请查看 md2wechat-skill。

安装

环境要求

- DSH 宿主与网页客户端: 使用相互匹配的 0.2.0-rc.2、0.2.1-rc.2、0.2.1-rc.3、0.2.1-rc.4 或 0.2.1-rc.5。
- Node.js: ^22.19.0 或 >=24.0.0,且 dsh 命令可用。
- 包管理器: 通过 npm 启动的 DSH 需要可用的 pnpm;打包宿主可能已内置。源码构建使用 pnpm 11.7.0。
- md2wechat CLI: 单独安装,支持 v1 JSON 协议及插件需要的命令。3.3.0 和 3.8.0 是回归验证目标,不是唯一允许的版本。
- 工作区: Markdown 文件和本地图片放在当前会话工作区内。
- 凭据: 预览和导出需要排版服务的 API Key;保存公众号草稿及备用生图另需相应凭据,见 配置。

多版本兼容范围

| DSH 版本 | 本插件支持情况 |
| 0.2.0-rc.2 | 保留支持 |
| 0.2.1-rc.2、0.2.1-rc.3、0.2.1-rc.4、0.2.1-rc.5 | 支持,宿主与网页客户端须使用相同版本 |
| 0.2.2-alpha.2 | 本次完整验收未通过,暂不声明支持 |
| 其他版本或后续版本 | 尚未验证,不自动放行 |

目前维护上述 5 个明确版本。新版本通过安装、页面交互和重启恢复验证后再加入;不会仅修改版本范围来绕过 DSH 的兼容检查。旧版是否退出支持会提前说明,不随新版本发布自动删除。官方版本及变化见 DSH 发布记录。

先安装 md2wechat CLI

npm install -g @geekjourneyx/md2wechat

具体配置文档可查看 md2wechat-skill。已有兼容版本可以继续使用;插件及其发布包不包含、也不会自动安装或升级 md2wechat。

安装后可检查版本和能力:

md2wechat version --json
md2wechat capabilities --json

插件启动时还会检查协议和必需命令,不会仅凭版本号判断兼容。外部 CLI 的平台支持以其发行说明为准。

安装插件

DSH 0.2.1-rc.5 用户: 请使用 2.0.0-rc.5 安装包;旧版插件 2.0.0-rc.3 和 2.0.0-rc.4 未声明支持此宿主,仅重装旧包不会解决版本拦截。
从 v2.0.0-rc.5 发布页 下载 geekjourneyx-dsh-md2wechat-2.0.0-rc.5.tgz 和 SHA256SUMS,放在同一目录,先校验:

sha256sum --check SHA256SUMS

macOS 可改用:

shasum -a 256 --check SHA256SUMS

确认校验成功后,在该目录安装:

dsh plugin --profile web add ./geekjourneyx-dsh-md2wechat-2.0.0-rc.5.tgz

使用发布包不需要克隆或构建本仓库。插件通过 GitHub 发布包分发,不是通过 npm 安装;前面的 npm 命令安装的是 md2wechat CLI。

插件从 DSH 宿主进程的 PATH 查找 md2wechat。如果单独安装在其他位置,启动 DSH 前设置可执行文件的绝对路径:

替换为你实际安装的可执行文件路径,不要填写目录。
export MD2WECHAT_BINARY_PATH=/absolute/path/to/md2wechat

从同一终端启动或重启 DSH。在另一个终端设置变量,不会改变已经运行的宿主。也可以在配置中设置 binaryPath,并保留 配置 中的凭据引用。指定路径无效时插件会报错,不会自动换用其他程序。

检查并启用

dsh plugin --profile web why @geekjourneyx/dsh-md2wechat
dsh --profile web --dump-config

确认安装的插件版本是 2.0.0-rc.5,然后重启对应配置的 DSH,让宿主和网页客户端加载同一版本。CLI 缺失或不兼容时,插件会停止启用并提示原因。用户自行在 DSH 中添加所需凭据后,即可打开文章生成预览。

交给助手安装

把下面这段发给助手:

请阅读 https://github.com/geekjourneyx/dsh-md2wechat 的 README,按「安装」章节安装 2.0.0-rc.5 预发布版。
先检查环境;尚未安装 md2wechat CLI 时,执行 npm install -g @geekjourneyx/md2wechat,已有兼容版本则继续使用。
不要强制安装不兼容版本,不要配置或读取密钥。完成后告诉我实际看到的插件版本和 md2wechat 版本。

从源码构建

仅修改本仓库时需要。在 pnpm 11.7.0 环境下运行,无需另行克隆 DSH 源码:

git clone https://github.com/geekjourneyx/dsh-md2wechat.git
cd dsh-md2wechat
pnpm install --frozen-lockfile
pnpm pack --pack-destination ./dist
dsh plugin --profile web add ./dist/geekjourneyx-dsh-md2wechat-2.0.0-rc.5.tgz

这里打包的是当前源码,文件名中的版本取自 package.json。

安装历史 v1.0.0

v1.0.0 使用早期工具流程,目标宿主是 DSH 0.1.0-rc.5。仅在明确需要旧版时使用,并阅读 旧版说明:

dsh plugin --profile web add https://github.com/geekjourneyx/dsh-md2wechat/releases/download/v1.0.0/geekjourneyx-dsh-md2wechat-1.0.0.tgz

开始创作

在 DSH 对话里告诉助手要写什么。文章生成后,点击「打开文章」或工具卡片上的「预览与调整文章」,在右侧文章栏继续编辑,对话和输入框仍然可用。

1. 用「排版主题」切换主题,直接编辑标题,或请求新标题。
2. 点击「编辑正文」修改内容,也可让助手润色或改善阅读体验,再决定采用哪些建议。
3. 选择封面和正文图片,为指定段落配图。
4. 生成或更新预览,检查最终标题、正文和图片。
5. 点击「存为草稿」,完成素材准备和审阅后「确认保存到草稿箱」;只需本地文件时可导出已审阅的 HTML。

插件只保存未发布草稿,不发布、不群发。发布前仍需到公众号后台确认。

源文件不会被覆盖。对话导入正文上限为 2 MiB,工作区文件上限为 8 MiB,图片上限为 8 MiB,支持 PNG、JPEG、GIF、WebP。含本地或相对图片引用的正文,应从原工作区文件打开,或先替换这些引用。

预览与定稿

预览会把文章发送到配置的排版服务,并非离线排版。文章界面的预览操作直接执行;助手发起的预览工具调用仍需宿主授权。

- 刷新失败时保留上一次结果,但会标记为过期。
- 检查服务返回的实际公众号标题,文章头部信息可能影响最终标题。
- 正文、主题或图片变化后,需要重新预览和审阅。
- 普通 HTML 导出会在审阅前嵌入经过检查的本地图片,导出内容与审阅结果一致,不需要封面、生图或公众号凭据。
- 已有微信图片链接保持远程引用;其他远程图片需先导入本地,受保护的预览不会直接显示它们。

预览采用隔离显示,不能保证与每一种微信客户端逐像素一致。

配图

优先使用本地图片或 DSH 已有的生图能力。图片须位于当前工作区并通过检查;导入候选图片不会自动选中或上传。

封面生成会请求三个候选。正文图片关联到指定段落,可放置、替换或移除;不会猜测代码、文章头部信息、列表、表格、引用、原始 HTML 或自定义模块内部的插图位置。

备用生图及上传说明

仅当当前助手没有其他生图能力时,才使用 CLI 备用生图。它会生成并上传每张请求的候选图到微信素材库,包括最终未选中的图片,可能产生费用,执行前需要单独确认。取消选择不会撤回已经上传的素材或费用。
备用生图读取宿主环境中的 IMAGE_PROVIDER、IMAGE_API_BASE、IMAGE_MODEL、IMAGE_SIZE。当前插件接受 OpenAI、ModelScope、OpenRouter、Volcengine、Tuzi;Tuzi 需要明确的 HTTPS API 地址。不支持或含糊的配置会被拒绝。

保存到公众号草稿箱

1. 选择一个封面和需要保留的正文图片。
2. 确认准备微信素材:只上传当前选中的封面和本地正文图片,未选中的本地候选不会上传;之前备用生图产生的上传不会撤回。
3. 本地图片替换为微信素材链接后,检查最终预览和公众号标题。
4. 审阅当前版本,再导出 HTML,或确认保存一条未发布草稿。

上传、生图、导出和保存草稿分别确认。上传前的审阅不能代替对最终内容的审阅。上传或保存结果不明时,应先到公众号后台核对;插件不会自动重复投递。

继续之前的文章

从「文章历史」选择同一会话,继续已保存文章。主题、图片选择、修订和撤回记录会保留;共享目录的不同会话仍有各自的文章列表。

重启不会重放未完成的建议或生图任务,也不会恢复旧预览的审阅授权。继续交付前需重新预览和审阅。原 Markdown 已变化时,明确选择保存版本或导入新文章。

旧版只有修订文件、没有文章记录时,可用「选择已保存版本」恢复兼容修订。恢复不会删除旧文件,也不会猜测原始文件路径或还原从未保存的选择。若旧格式无法恢复,可把保留的 article.md 作为新文章打开。

配置

插件通过 DSH 凭据服务读取以下引用:

| 引用名 | 用途 |
| MD2WECHAT_API_KEY | 排版预览与已审阅结果校验 |
| WECHAT_APPID、WECHAT_SECRET | 上传微信素材、创建公众号草稿 |
| IMAGE_API_KEY | 可选备用生图 |

由用户在 DSH 中配置密钥,不要写进聊天、正文或插件配置文件。凭据只在需要时读取,不保存在文章文件中。排版使用 md2wechat API 服务,需要有效的 API Key;服务范围与费用见 md2wechat 文档。

多账号与 IP 白名单

- 多公众号账号: md2wechat CLI 支持命名账号及指定目标账号,配置方法见 多账号配置文档。当前插件保存草稿时使用 DSH 配置的 WECHAT_APPID 和 WECHAT_SECRET,不会自动采用 CLI 的命名账号列表。使用其他公众号前,需配置对应的 DSH 凭据,并重新预览、核对目标账号和确认保存。
- IP 白名单: 调用微信接口需要满足账号的 IP 白名单要求。配置步骤见 微信凭证与 IP 白名单指南。md2wechat 高级 API 服务可提供固定出口能力,具体开通条件以服务说明为准;插件不会自动修改微信后台白名单。

可选功能开关

草稿与备用生图开关默认开启,但不代表批准了具体操作。若要保留草稿、关闭备用生图,可在对应配置目录的 cordis.patch.yml 中加入下面的配置。DSH 会替换整段 config,因此需保留路径和凭据引用:

- id: dsh-md2wechat
config:
binaryPath: !!js process.env.MD2WECHAT_BINARY_PATH
credentialRefs:
MD2WECHAT_API_KEY: MD2WECHAT_API_KEY
WECHAT_APPID: WECHAT_APPID
WECHAT_SECRET: WECHAT_SECRET
IMAGE_API_KEY: IMAGE_API_KEY
enableWechatWriteTools: true
enableFallbackImageTool: false

enableWechatWriteTools: false 会关闭草稿和备用生图工具;备用生图需要两个开关都开启。

修订文件默认位于工作区的 .dsh/md2wechat。私有图片计划和操作记录默认位于 $DSH_HOME/plugins/dsh-md2wechat,未设置 DSH_HOME 时使用 ~/.dsh/plugins/dsh-md2wechat。

常见问题

安装、恢复与权限问题

- 配置目录锁报 EPERM: 宿主无法访问配置目录锁,发生在插件依赖安装前。检查目录权限和宿主允许的访问范围,不要使用 sudo 绕过。
- 宿主版本不匹配: 当前插件支持 DSH 0.2.0-rc.2、0.2.1-rc.2、0.2.1-rc.3、0.2.1-rc.4 或 0.2.1-rc.5,不支持 v1 使用的 0.1.0-rc.5。不要强制安装不兼容依赖;插件不会升级宿主。
- CLI 无法启用: 检查可执行文件路径、宿主 PATH,以及 version --json、capabilities --json 的输出。更换 CLI 后需要重新预览和审阅。
- 旧包提示 protocol/remote-info 缺失: 在受支持的宿主中安装修正后的插件包,不要修改宿主导出或强行放宽版本要求。
- 安装后没有文章入口: 确认宿主和客户端版本匹配,重启后从「文章历史」选择会话,或在对话里请助手重新打开文章。
- 文件只读或在工作区外: 使用会话允许的位置,或通过宿主调整访问权限。插件不会自行扩大权限;覆盖导出文件也需确认。
- 旧文章或快捷入口无法恢复: 选择兼容的已保存版本,或把原 Markdown、保留的 article.md 重新打开为新文章,再生成和审阅预览。不会自动迁移或降低检查要求。
- 缺少凭据: 在 DSH 中添加相应引用,不要把密钥贴进对话。
- 状态目录被拒绝: 自定义 stateDir 必须是位于工作区、文章产物和临时目录之外的绝对路径。
- 上传或草稿结果不明: 先到微信后台核对,再明确恢复。重开面板不会自动重试;CLI 内部可能重试上传,确认时会说明这一点。

md2wechat 是独立运行的外部程序。插件不会安装、升级或单独隔离它,请使用宿主的执行控制并检查其配置。

预览失败如何处理

请按页面显示的具体原因处理。标题最多 32 个字符、作者最多 16 个字符、摘要最多 128 个字符,超过限制时先缩短相应内容。密钥被拒绝与无法连接验证服务会分别提示;原因尚未确认时,不会建议反复修改配置或重新导入文章。上传或保存草稿超时后,应先核对公众号后台,避免重复提交。

开发与验证

pnpm test
pnpm typecheck
pnpm lint
pnpm run check:boundaries
pnpm run build
pnpm run pack:check

安装验收说明 使用真实打包产物和官方 DSH 宿主;浏览器验收流程 用于检查安装后的文章界面、窄屏布局和对话入口。

已在上述 5 个 DSH 版本与 CLI 3.8.0 上完成自动化验证:856 项测试通过,并在真实宿主与浏览器中检查了文章入口、标题和正文编辑、换主题、应用建议、文章历史、窄屏显示、刷新及重启恢复、审阅与导出。排版使用本地测试服务,图片上传和存草稿使用模拟微信写入;不代表付费生图或真实公众号投递已验证。

持续集成包含五种受支持的 DSH 版本与 CLI 3.3.0、3.8.0 的十组组合,具体通过状态以对应运行结果为准。

发布由 v* 标签触发,标签需与包版本一致且指向 main 上的提交。发布流程检查、构建并上传 .tgz 和 SHA256SUMS,预发布版本会标为预发布;合并 PR 本身不会发布,也不会上传到 npm。

许可证

本项目采用 AGPL-3.0 许可证(AGPL-3.0-only)。md2wechat CLI 和外部服务遵循各自的许可与服务条款。

© 2026 geekjourneyx · 更新记录
预览分享卡片长什么样 ↓geekjourneyx/dsh-md2wechat
分享 · DeepSeek Harness Hub
geekjourneyx/dsh-md2wechat

DSH 一站式公众号创作插件,集成写作润色、标题优化、主题与高级模块排版、智能配图,支持预览、导出及保存到公众号草稿箱。

回到顶部