# DSH md2wechat plugin `@geekjourneyx/md2wechat` adds a guarded Markdown-to-WeChat-draft workflow to DeepSeek Harness (DSH). It keeps the source Markdown unchanged and stops after WeChat creates a draft. The plugin repository starts at release `v1.0.0`; its matching root package and CLI version is `3.3.0`. These versions track the plugin repository and the md2wechat CLI separately and must not be substituted for each other. ## Prerequisites and installation Use DSH `0.1.0-rc.5` with the Web profile. This first release is available from GitHub only and is not published to npm. Download `geekjourneyx-md2wechat-3.3.0.tgz` and one matching platform package from the [v1.0.0 Release](https://github.com/geekjourneyx/dsh-md2wechat/releases/tag/v1.0.0). For macOS Apple Silicon, run this in the download directory: ```bash dsh plugin --profile web add --ignore-scripts --save-exact \ ./geekjourneyx-md2wechat-darwin-arm64-3.3.0.tgz \ ./geekjourneyx-md2wechat-3.3.0.tgz ``` Choose `darwin-x64`, `linux-x64`, `linux-arm64`, or `win32-x64` on another host. The root and platform tarballs must be installed together. There are no install scripts: no download runs from `preinstall`, `install`, or `postinstall`. Before a write workflow, configure md2wechat's API, image provider, and a named or default WeChat account. The exact DSH secret-store and `credentialRefs` setup is below; do not put secrets in a project prompt or article. ## Credentials and md2wechat configuration DSH's managed credential store is `$DSH_HOME/.credentials.yaml` (or `~/.dsh/.credentials.yaml` when `DSH_HOME` is unset). It stores secret values; the plugin configuration stores only their reference names. Create the owner-only file and edit it locally: Preview and draft workflows require `MD2WECHAT_API_KEY` in the DSH-managed store and a matching `credentialRefs` mapping. A key stored only in md2wechat's own configuration does not satisfy the plugin. This stricter isolation is intentional so the plugin never silently inherits an existing key that was not explicitly granted to DSH. ```bash export DSH_HOME="${DSH_HOME:-$HOME/.dsh}" mkdir -p "$DSH_HOME" chmod 700 "$DSH_HOME" touch "$DSH_HOME/.credentials.yaml" chmod 600 "$DSH_HOME/.credentials.yaml" "${EDITOR:-vi}" "$DSH_HOME/.credentials.yaml" ``` Use a YAML mapping with only the values you actually need: ```yaml MD2WECHAT_API_KEY: "replace-with-md2wechat-key" WECHAT_APPID: "replace-with-wechat-appid" WECHAT_SECRET: "replace-with-wechat-secret" IMAGE_API_KEY: "replace-with-image-provider-key" ``` In the Web profile's `cordis.patch.yml`, connect those names to the plugin. This is the complete supported reference set: ```yaml - id: md2wechat config: layoutBaseUrl: "https://www.md2wechat.cn" credentialRefs: MD2WECHAT_API_KEY: MD2WECHAT_API_KEY WECHAT_APPID: WECHAT_APPID WECHAT_SECRET: WECHAT_SECRET IMAGE_API_KEY: IMAGE_API_KEY ``` `MD2WECHAT_API_KEY is required for preview`; it is also required by draft creation. `WECHAT_APPID` and `WECHAT_SECRET` are WeChat credentials that DSH can supply to `md2wechat_create_draft` and to the WeChat upload in the fallback `md2wechat_generate_images` tool. Do not map them when the selected md2wechat account already supplies them in its own configuration. DSH itself does not need `IMAGE_API_KEY` when it creates the images. When the fallback image provider needs a key, map `IMAGE_API_KEY` only if the md2wechat configuration does not already provide it; a mapped DSH value overrides the md2wechat configuration value. The plugin's `layoutBaseUrl` chooses the layout service for DSH preview and explicitly injects `MD2WECHAT_BASE_URL` for that preview call. md2wechat's own configuration (`~/.config/md2wechat/config.yaml` by default) still owns the image provider/base URL/model and direct or named WeChat account definitions. The DSH store only supplies or overrides configured secrets; it does not replace those account and image-service settings. Check both layers with `md2wechat config validate --json` and `md2wechat config wechat-accounts --json`, then run `md2wechat_doctor` in DSH. ## Tools | Tool | What it does | Remote effect | | --- | --- | --- | | `md2wechat_doctor` | Reads local CLI capability, configuration, image-provider, and account facts. | None | | `md2wechat_start_article` | Makes a versioned working copy and records the chosen render and account inputs. | None | | `md2wechat_improve_article` | Returns a focused article-improvement handoff for the current DSH Agent. | None | | `md2wechat_plan_images` | Saves the requested cover, infographic, and article-image plan. | None | | `md2wechat_generate_images` | Uses the configured md2wechat image provider only when DSH has no image-generation ability. | Image generation and WeChat upload after approval | | `md2wechat_preview` | Creates an approved, immutable HTML preview for the current working revision. | Layout conversion after approval | | `md2wechat_create_draft` | Uploads approved images and creates one WeChat draft from the approved preview. | WeChat upload and draft creation after approval | | `md2wechat_export` | Copies selected revision-owned results to a workspace destination. | Local files only | ## Source-to-draft workflow 1. Run `md2wechat_doctor` and address its blocked configuration result. 2. Run `md2wechat_start_article` with a workspace Markdown `sourcePath`. Keep its returned `manifestPath`; the source file is not edited. 3. Ask the current DSH Agent to improve the working copy through `md2wechat_improve_article`, if needed. 4. Save a cover/image plan with `md2wechat_plan_images`. If DSH can generate images, use that capability and save each result at the plan's `targetPath`. 5. If DSH cannot generate images, use `md2wechat_generate_images` only when the fallback is enabled and after its one-shot approval. 6. Run `md2wechat_preview` and inspect the returned preview artifact. 7. Only after the user explicitly asks for a WeChat draft, run `md2wechat_create_draft` with the same `manifestPath`. The preview and draft must match the same revision. The draft tool checks the approved preview, selected account, cover, current article bytes, and staged request again before its single draft request. A completed draft cannot be repeated by default; an uncertain result also blocks another create attempt. ## Images, artifacts, and accounts DSH-image-first is the normal rule. `md2wechat_generate_images` is a fallback: it calls the image provider already configured for md2wechat only when the current DSH Agent has no image-generation capability. It does not start another agent. Artifacts stay inside the workspace at `.dsh/md2wechat` by default. Each revision contains the article work copy, `article.json` manifest, operation record, image plan and results, preview HTML and receipt, plus draft request/approval/result records when a draft is requested. Use `md2wechat_export` to copy selected manifest-owned files elsewhere; do not treat the source Markdown as an artifact that the plugin overwrites. Choose the account when starting the article with its optional `account` value. `md2wechat_doctor` reports available account candidates. Preview and draft bind to the selected account identity; a later different or changed account is rejected. ## Approvals and non-interactive sessions Every external operation uses a one-shot DSH approval tied to that tool call. Preview asks before layout conversion; the fallback image tool asks before image generation/upload; draft asks before upload and draft creation. A refusal, cancellation, or unavailable approval answer stops the operation without treating it as consent. In Web, answer the approval card for that one operation. In ACP or another headless session, headless without an approval answerer fails closed. Provide an approval answerer only when that automation is intentionally allowed to perform the matching external effect. ## Administrator switches In the profile's `cordis.patch.yml`, the DSH administrator can disable WeChat-writing tools without changing articles: ```yaml - id: md2wechat config: enableWechatWriteTools: false ``` This hides both `md2wechat_generate_images` and `md2wechat_create_draft`; the remaining six local/read workflow tools stay available. `enableFallbackImageTool: false` also removes only the image fallback while leaving draft creation available when write tools are enabled. ## Troubleshooting and removal - If `md2wechat_doctor` says configuration is incomplete, run the CLI's `md2wechat config validate --json`, configure the required account/provider, then rerun doctor. - If preview is blocked, correct the current working revision and make a new preview; do not reuse an old preview receipt. - If draft is blocked for account mismatch, restart or preview with the intended named account. If draft is uncertain, inspect the WeChat account before deciding whether a human should create a new revision. - If the npm binary cannot be found, reinstall the root package at the exact version with its matching platform optional package available from the registry; npm lifecycle scripts are not involved. Remove the plugin from its profile with: ```bash dsh plugin --profile web remove @geekjourneyx/md2wechat ``` ## Scope boundary This plugin is draft-only: the plugin stops at draft creation and never publishes. It does not send a WeChat publication request, schedule an article, or alter the original Markdown source.