Add baoyu-skills package
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# API Credential Setup
|
||||
|
||||
Guided setup when `WECHAT_APP_ID` / `WECHAT_APP_SECRET` are missing. Invoked by Step 2 of the article-posting workflow.
|
||||
|
||||
## Detection
|
||||
|
||||
Look for the credentials in this order:
|
||||
|
||||
1. Env vars `WECHAT_APP_ID` / `WECHAT_APP_SECRET`
|
||||
2. `<cwd>/.baoyu-skills/.env` with `WECHAT_APP_ID=...`
|
||||
3. `$HOME/.baoyu-skills/.env` with `WECHAT_APP_ID=...`
|
||||
|
||||
If none are present, run the guided setup below.
|
||||
|
||||
## Guided Setup
|
||||
|
||||
Show this message to the user and ask where to save:
|
||||
|
||||
```
|
||||
WeChat API credentials not found.
|
||||
|
||||
To obtain credentials:
|
||||
1. Visit https://mp.weixin.qq.com
|
||||
2. Go to: 开发 → 基本配置
|
||||
3. Copy AppID and AppSecret
|
||||
|
||||
Where to save?
|
||||
A) Project-level: .baoyu-skills/.env (this project only)
|
||||
B) User-level: ~/.baoyu-skills/.env (all projects)
|
||||
```
|
||||
|
||||
After they choose a location, collect the values (prefer a user-input tool, fall back to a numbered prompt per the User Input Tools rule in SKILL.md) and append:
|
||||
|
||||
```
|
||||
WECHAT_APP_ID=<user_input>
|
||||
WECHAT_APP_SECRET=<user_input>
|
||||
```
|
||||
|
||||
## Multi-Account Variant
|
||||
|
||||
If the user has multiple accounts configured (`accounts:` block in EXTEND.md), use prefixed keys instead — see `multi-account.md` → "Credential Resolution".
|
||||
@@ -0,0 +1,95 @@
|
||||
# Article Posting (文章发表)
|
||||
|
||||
Post markdown articles to WeChat Official Account with full formatting support.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Post markdown article
|
||||
${BUN_X} ./scripts/wechat-article.ts --markdown article.md
|
||||
|
||||
# With theme
|
||||
${BUN_X} ./scripts/wechat-article.ts --markdown article.md --theme grace
|
||||
|
||||
# Disable bottom citations for ordinary external links
|
||||
${BUN_X} ./scripts/wechat-article.ts --markdown article.md --no-cite
|
||||
|
||||
# With explicit options
|
||||
${BUN_X} ./scripts/wechat-article.ts --markdown article.md --author "作者名" --summary "摘要"
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `--markdown <path>` | Markdown file to convert and post |
|
||||
| `--theme <name>` | Theme: default, grace, simple, modern |
|
||||
| `--no-cite` | Keep ordinary external links inline instead of converting them to bottom citations |
|
||||
| `--title <text>` | Override title (auto-extracted from markdown) |
|
||||
| `--author <name>` | Author name |
|
||||
| `--summary <text>` | Article summary |
|
||||
| `--html <path>` | Pre-rendered HTML file (alternative to markdown) |
|
||||
| `--profile <dir>` | Chrome profile directory |
|
||||
|
||||
## Markdown Format
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: Article Title
|
||||
author: Author Name
|
||||
---
|
||||
|
||||
# Title (becomes article title)
|
||||
|
||||
Regular paragraph with **bold** and *italic*.
|
||||
|
||||
## Section Header
|
||||
|
||||

|
||||
|
||||
- List item 1
|
||||
- List item 2
|
||||
|
||||
> Blockquote text
|
||||
|
||||
[Link text](https://example.com)
|
||||
```
|
||||
|
||||
Markdown mode converts ordinary external links into bottom citations by default for WeChat-friendly output. Use `--no-cite` to disable that behavior.
|
||||
|
||||
## Image Handling
|
||||
|
||||
1. **Parse**: Images in markdown are replaced with `WECHATIMGPH_N`
|
||||
2. **Render**: HTML is generated with placeholders in text
|
||||
3. **Paste**: HTML content is pasted into WeChat editor
|
||||
4. **Replace**: For each placeholder:
|
||||
- Find and select the placeholder text
|
||||
- Scroll into view
|
||||
- Press Backspace to delete the placeholder
|
||||
- Paste the image from clipboard
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `wechat-article.ts` | Main article publishing script |
|
||||
| `md-to-wechat.ts` | Markdown to HTML with placeholders |
|
||||
| `md/render.ts` | Markdown rendering with themes |
|
||||
|
||||
## Example Session
|
||||
|
||||
```
|
||||
User: /post-to-wechat --markdown ./article.md
|
||||
|
||||
Claude:
|
||||
1. Parses markdown, finds 5 images
|
||||
2. Generates HTML with placeholders
|
||||
3. Opens Chrome, navigates to WeChat editor
|
||||
4. Pastes HTML content
|
||||
5. For each image:
|
||||
- Selects WECHATIMGPH_1
|
||||
- Scrolls into view
|
||||
- Presses Backspace to delete
|
||||
- Pastes image
|
||||
6. Reports: "Article composed with 5 images."
|
||||
```
|
||||
@@ -0,0 +1,224 @@
|
||||
---
|
||||
name: first-time-setup
|
||||
description: First-time setup flow for baoyu-post-to-wechat preferences
|
||||
---
|
||||
|
||||
# First-Time Setup
|
||||
|
||||
## Overview
|
||||
|
||||
When no EXTEND.md is found, guide user through preference setup.
|
||||
|
||||
**BLOCKING OPERATION**: This setup MUST complete before ANY other workflow steps. Do NOT:
|
||||
- Ask about content or files to publish
|
||||
- Ask about themes or publishing methods
|
||||
- Proceed to content conversion or publishing
|
||||
|
||||
ONLY ask the questions in this setup flow, save EXTEND.md, then continue.
|
||||
|
||||
## Setup Flow
|
||||
|
||||
```
|
||||
No EXTEND.md found
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| AskUserQuestion |
|
||||
| (all questions) |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
+---------------------+
|
||||
| Create EXTEND.md |
|
||||
+---------------------+
|
||||
|
|
||||
v
|
||||
Continue to Step 1
|
||||
```
|
||||
|
||||
## Questions
|
||||
|
||||
**Language**: Use user's input language or saved language preference.
|
||||
|
||||
Use AskUserQuestion with ALL questions in ONE call:
|
||||
|
||||
### Question 1: Default Theme
|
||||
|
||||
```yaml
|
||||
header: "Theme"
|
||||
question: "Default theme for article conversion?"
|
||||
options:
|
||||
- label: "default (Recommended)"
|
||||
description: "Classic layout - centered title with border, white-on-color H2 (default: blue)"
|
||||
- label: "grace"
|
||||
description: "Elegant - text shadows, rounded cards, refined blockquotes (default: purple)"
|
||||
- label: "simple"
|
||||
description: "Minimal modern - asymmetric rounded corners, clean whitespace (default: green)"
|
||||
- label: "modern"
|
||||
description: "Large rounded corners, pill headings, spacious (default: orange)"
|
||||
```
|
||||
|
||||
### Question 2: Default Color
|
||||
|
||||
```yaml
|
||||
header: "Color"
|
||||
question: "Default color preset? (theme default if not set)"
|
||||
options:
|
||||
- label: "Theme default (Recommended)"
|
||||
description: "Use the theme's built-in default color"
|
||||
- label: "blue"
|
||||
description: "#0F4C81 经典蓝"
|
||||
- label: "red"
|
||||
description: "#A93226 中国红"
|
||||
- label: "green"
|
||||
description: "#009874 翡翠绿"
|
||||
```
|
||||
|
||||
Note: User can choose "Other" to type any preset name (vermilion, yellow, purple, sky, rose, olive, black, gray, pink, orange) or hex value.
|
||||
|
||||
### Question 3: Default Publishing Method
|
||||
|
||||
```yaml
|
||||
header: "Method"
|
||||
question: "Default publishing method?"
|
||||
options:
|
||||
- label: "api (Recommended)"
|
||||
description: "Fast, requires API credentials (AppID + AppSecret)"
|
||||
- label: "browser"
|
||||
description: "Slow, requires Chrome and login session"
|
||||
- label: "remote-api"
|
||||
description: "Fast, tunnels WeChat API calls through SSH to a server whose IP is on the WeChat allowlist"
|
||||
```
|
||||
|
||||
If the user selects `remote-api`, prompt for `remote_publish_host` and (optionally) `remote_publish_user`, `remote_publish_identity_file`. These can also be filled in later by editing EXTEND.md.
|
||||
|
||||
### Question 4: Default Author
|
||||
|
||||
```yaml
|
||||
header: "Author"
|
||||
question: "Default author name for articles?"
|
||||
options:
|
||||
- label: "No default"
|
||||
description: "Leave empty, specify per article"
|
||||
```
|
||||
|
||||
Note: User will likely choose "Other" to type their author name.
|
||||
|
||||
### Question 5: Open Comments
|
||||
|
||||
```yaml
|
||||
header: "Comments"
|
||||
question: "Enable comments on articles by default?"
|
||||
options:
|
||||
- label: "Yes (Recommended)"
|
||||
description: "Allow readers to comment on articles"
|
||||
- label: "No"
|
||||
description: "Disable comments by default"
|
||||
```
|
||||
|
||||
### Question 6: Fans-Only Comments
|
||||
|
||||
```yaml
|
||||
header: "Fans only"
|
||||
question: "Restrict comments to followers only?"
|
||||
options:
|
||||
- label: "No (Recommended)"
|
||||
description: "All readers can comment"
|
||||
- label: "Yes"
|
||||
description: "Only followers can comment"
|
||||
```
|
||||
|
||||
### Question 7: Save Location
|
||||
|
||||
```yaml
|
||||
header: "Save"
|
||||
question: "Where to save preferences?"
|
||||
options:
|
||||
- label: "Project (Recommended)"
|
||||
description: ".baoyu-skills/ (this project only)"
|
||||
- label: "User"
|
||||
description: "~/.baoyu-skills/ (all projects)"
|
||||
```
|
||||
|
||||
## Save Locations
|
||||
|
||||
| Choice | Path | Scope |
|
||||
|--------|------|-------|
|
||||
| Project | `.baoyu-skills/baoyu-post-to-wechat/EXTEND.md` | Current project |
|
||||
| User | `~/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md` | All projects |
|
||||
|
||||
## After Setup
|
||||
|
||||
1. Create directory if needed
|
||||
2. Write EXTEND.md
|
||||
3. Confirm: "Preferences saved to [path]"
|
||||
4. Continue to Step 0 (load the saved preferences)
|
||||
|
||||
## EXTEND.md Template
|
||||
|
||||
### Single Account (Default)
|
||||
|
||||
```md
|
||||
default_theme: [default/grace/simple/modern]
|
||||
default_color: [preset name, hex, or empty for theme default]
|
||||
default_publish_method: [api/browser/remote-api]
|
||||
default_author: [author name or empty]
|
||||
need_open_comment: [1/0]
|
||||
only_fans_can_comment: [1/0]
|
||||
chrome_profile_path:
|
||||
|
||||
# Remote API publishing — only fill in if default_publish_method is remote-api
|
||||
# or you plan to pass --remote on the CLI.
|
||||
remote_publish_host:
|
||||
remote_publish_user:
|
||||
remote_publish_port:
|
||||
remote_publish_identity_file:
|
||||
remote_publish_known_hosts_file:
|
||||
remote_publish_strict_host_key_checking:
|
||||
remote_publish_connect_timeout:
|
||||
remote_publish_proxy_jump:
|
||||
```
|
||||
|
||||
Raw `ssh` / `scp` options are intentionally not supported; only the typed keys above are honored. Authentication is SSH key only.
|
||||
|
||||
### Multi-Account
|
||||
|
||||
```md
|
||||
default_theme: [default/grace/simple/modern]
|
||||
default_color: [preset name, hex, or empty for theme default]
|
||||
|
||||
accounts:
|
||||
- name: [display name]
|
||||
alias: [short key, e.g. "baoyu"]
|
||||
default: true
|
||||
default_publish_method: [api/browser/remote-api]
|
||||
default_author: [author name]
|
||||
need_open_comment: [1/0]
|
||||
only_fans_can_comment: [1/0]
|
||||
app_id: [WeChat App ID, optional]
|
||||
app_secret: [WeChat App Secret, optional]
|
||||
# Remote API publishing (optional, per-account override of globals)
|
||||
remote_publish_host:
|
||||
remote_publish_user:
|
||||
remote_publish_identity_file:
|
||||
- name: [second account name]
|
||||
alias: [short key, e.g. "ai-tools"]
|
||||
default_publish_method: [api/browser/remote-api]
|
||||
default_author: [author name]
|
||||
need_open_comment: [1/0]
|
||||
only_fans_can_comment: [1/0]
|
||||
```
|
||||
|
||||
## Adding More Accounts Later
|
||||
|
||||
After initial setup, users can add accounts by editing EXTEND.md:
|
||||
|
||||
1. Add an `accounts:` block with list items
|
||||
2. Move per-account settings (author, publish method, comments) into each account entry
|
||||
3. Keep global settings (theme, color) at the top level
|
||||
4. Each account needs a unique `alias` (used for CLI `--account` arg and Chrome profile naming)
|
||||
5. Set `default: true` on the primary account
|
||||
|
||||
## Modifying Preferences Later
|
||||
|
||||
Users can edit EXTEND.md directly or delete it to trigger setup again.
|
||||
@@ -0,0 +1,94 @@
|
||||
# Image-Text Posting (贴图发表, formerly 图文)
|
||||
|
||||
Post image-text messages with multiple images to WeChat Official Account.
|
||||
|
||||
> **Note**: WeChat has renamed "图文" to "贴图" in the Official Account menu (as of 2026).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Post with images and markdown file (title/content extracted automatically)
|
||||
${BUN_X} ./scripts/wechat-browser.ts --markdown source.md --images ./images/
|
||||
|
||||
# Post with explicit title and content
|
||||
${BUN_X} ./scripts/wechat-browser.ts --title "标题" --content "内容" --image img1.png --image img2.png
|
||||
|
||||
# Save as draft
|
||||
${BUN_X} ./scripts/wechat-browser.ts --markdown source.md --images ./images/ --submit
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `--markdown <path>` | Markdown file for title/content extraction |
|
||||
| `--images <dir>` | Directory containing images (sorted by name) |
|
||||
| `--title <text>` | Article title (max 20 chars, auto-compressed if too long) |
|
||||
| `--content <text>` | Article content (max 1000 chars, auto-compressed if too long) |
|
||||
| `--image <path>` | Single image file (can be repeated) |
|
||||
| `--submit` | Save as draft (default: preview only) |
|
||||
| `--profile <dir>` | Chrome profile directory |
|
||||
|
||||
## Auto Title/Content from Markdown
|
||||
|
||||
When using `--markdown`, the script:
|
||||
|
||||
1. **Parses frontmatter** for title and author:
|
||||
```yaml
|
||||
---
|
||||
title: 文章标题
|
||||
author: 作者名
|
||||
---
|
||||
```
|
||||
|
||||
2. **Falls back to H1** if no frontmatter title:
|
||||
```markdown
|
||||
# 这将成为标题
|
||||
```
|
||||
|
||||
3. **Compresses title** to 20 characters if too long:
|
||||
- Original: "如何在一天内彻底重塑你的人生"
|
||||
- Compressed: "一天彻底重塑你的人生"
|
||||
|
||||
4. **Extracts first paragraphs** as content (max 1000 chars)
|
||||
|
||||
## Image Directory Mode
|
||||
|
||||
When using `--images <dir>`:
|
||||
|
||||
- All PNG/JPG files in directory are uploaded
|
||||
- Files are sorted alphabetically by name
|
||||
- Naming convention: `01-cover.png`, `02-content.png`, etc.
|
||||
|
||||
## Constraints
|
||||
|
||||
| Field | Max Length | Notes |
|
||||
|-------|------------|-------|
|
||||
| Title | 20 chars | Auto-compressed if longer |
|
||||
| Content | 1000 chars | Auto-compressed if longer |
|
||||
| Images | 9 max | WeChat limit |
|
||||
|
||||
## Example Session
|
||||
|
||||
```
|
||||
User: /post-to-wechat --markdown ./article.md --images ./xhs-images/
|
||||
|
||||
Claude:
|
||||
1. Parses markdown meta:
|
||||
- Title: "如何在一天内彻底重塑你的人生" → "一天内重塑你的人生"
|
||||
- Author: from frontmatter or default
|
||||
2. Extracts content from first paragraphs
|
||||
3. Finds 7 images in xhs-images/
|
||||
4. Opens Chrome, navigates to WeChat "图文" editor
|
||||
5. Uploads all images
|
||||
6. Fills title and content
|
||||
7. Reports: "Image-text posted with 7 images."
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `wechat-browser.ts` | Main image-text posting script |
|
||||
| `cdp.ts` | Chrome DevTools Protocol utilities |
|
||||
| `copy-to-clipboard.ts` | Clipboard operations |
|
||||
@@ -0,0 +1,152 @@
|
||||
# Multi-Account Support
|
||||
|
||||
Details for managing multiple WeChat Official Accounts through one EXTEND.md. SKILL.md only covers single-account flow and the selection prompt — read this file when the user has an `accounts:` block, asks to publish to a specific account, or needs per-account credentials.
|
||||
|
||||
## Compatibility
|
||||
|
||||
| Condition | Mode | Behavior |
|
||||
|-----------|------|----------|
|
||||
| No `accounts` block | Single-account | Original behavior, no changes |
|
||||
| `accounts` with 1 entry | Single-account | Auto-select, no prompt |
|
||||
| `accounts` with 2+ entries | Multi-account | Prompt to select before publishing |
|
||||
| `accounts` with `default: true` | Multi-account | Pre-select default; user can switch |
|
||||
|
||||
## EXTEND.md Example
|
||||
|
||||
```md
|
||||
default_theme: default
|
||||
default_color: blue
|
||||
|
||||
accounts:
|
||||
- name: 宝玉的技术分享
|
||||
alias: baoyu
|
||||
default: true
|
||||
default_publish_method: api
|
||||
default_author: 宝玉
|
||||
need_open_comment: 1
|
||||
only_fans_can_comment: 0
|
||||
app_id: your_wechat_app_id
|
||||
app_secret: your_wechat_app_secret
|
||||
- name: AI工具集
|
||||
alias: ai-tools
|
||||
default_publish_method: browser
|
||||
default_author: AI工具集
|
||||
need_open_comment: 1
|
||||
only_fans_can_comment: 0
|
||||
```
|
||||
|
||||
## Per-Account vs Global Keys
|
||||
|
||||
**Per-account** (also accepted globally as fallback): `default_publish_method`, `default_author`, `need_open_comment`, `only_fans_can_comment`, `app_id`, `app_secret`, `chrome_profile_path`, `remote_publish_host`, `remote_publish_user`, `remote_publish_port`, `remote_publish_identity_file`, `remote_publish_known_hosts_file`, `remote_publish_strict_host_key_checking`, `remote_publish_connect_timeout`, `remote_publish_proxy_jump`.
|
||||
|
||||
**Global-only** (always shared): `default_theme`, `default_color`.
|
||||
|
||||
## Account Selection (Step 0.5)
|
||||
|
||||
Insert between Step 0 (Load EXTEND.md) and Step 1 (Determine input type):
|
||||
|
||||
```
|
||||
if no accounts block:
|
||||
→ single-account mode (original behavior)
|
||||
elif accounts.length == 1:
|
||||
→ auto-select the only account
|
||||
elif --account <alias> CLI arg:
|
||||
→ select matching account
|
||||
elif one account has default: true:
|
||||
→ pre-select, display: "Using account: <name> (--account to switch)"
|
||||
else:
|
||||
→ prompt user to choose from the list
|
||||
```
|
||||
|
||||
## Credential Resolution (API Method)
|
||||
|
||||
For the selected account with alias `{alias}`, try in this order (first hit wins):
|
||||
|
||||
1. `app_id` / `app_secret` inline in the EXTEND.md account block
|
||||
2. Env vars `WECHAT_{ALIAS}_APP_ID` / `WECHAT_{ALIAS}_APP_SECRET` (alias uppercased, hyphens → underscores)
|
||||
3. `.baoyu-skills/.env` with the prefixed key `WECHAT_{ALIAS}_APP_ID`
|
||||
4. `~/.baoyu-skills/.env` with the prefixed key
|
||||
5. Fallback to unprefixed `WECHAT_APP_ID` / `WECHAT_APP_SECRET`
|
||||
|
||||
### .env Multi-Account Example
|
||||
|
||||
```bash
|
||||
# Account: baoyu
|
||||
WECHAT_BAOYU_APP_ID=your_wechat_app_id
|
||||
WECHAT_BAOYU_APP_SECRET=your_wechat_app_secret
|
||||
|
||||
# Account: ai-tools
|
||||
WECHAT_AI_TOOLS_APP_ID=your_ai_tools_wechat_app_id
|
||||
WECHAT_AI_TOOLS_APP_SECRET=your_ai_tools_wechat_app_secret
|
||||
```
|
||||
|
||||
## Chrome Profile (Browser Method)
|
||||
|
||||
Each account uses an isolated Chrome profile so logins don't collide.
|
||||
|
||||
| Source | Path |
|
||||
|--------|------|
|
||||
| Account `chrome_profile_path` in EXTEND.md | Use as-is |
|
||||
| Auto-generated from alias | `{shared_profile_parent}/wechat-{alias}/` |
|
||||
| Single-account fallback | Shared default profile |
|
||||
|
||||
## CLI `--account` Flag
|
||||
|
||||
All publishing scripts accept `--account <alias>`:
|
||||
|
||||
```bash
|
||||
${BUN_X} {baseDir}/scripts/wechat-api.ts <file> --theme default --account ai-tools
|
||||
${BUN_X} {baseDir}/scripts/wechat-article.ts --markdown <file> --theme default --account baoyu
|
||||
${BUN_X} {baseDir}/scripts/wechat-browser.ts --markdown <file> --images ./photos/ --account baoyu
|
||||
```
|
||||
|
||||
## Remote API Publishing
|
||||
|
||||
`wechat-api.ts` supports a `remote-api` mode that tunnels WeChat API calls through an SSH SOCKS5 dynamic port forward to a server whose IP is on WeChat's allowlist. Markdown rendering, image processing, draft assembly, and HTML rewriting still happen locally; only outbound HTTPS calls to `api.weixin.qq.com` traverse the tunnel. No files are written to the remote host and `AppSecret` never leaves the local process. The remote host needs only `sshd` and outbound network access.
|
||||
|
||||
### Per-Account Configuration
|
||||
|
||||
```md
|
||||
default_theme: default
|
||||
default_color: blue
|
||||
default_publish_method: browser # browser remains the default
|
||||
|
||||
accounts:
|
||||
- name: 宝玉的技术分享
|
||||
alias: baoyu
|
||||
default: true
|
||||
default_publish_method: api
|
||||
default_author: 宝玉
|
||||
app_id: your_wechat_app_id
|
||||
app_secret: your_wechat_app_secret
|
||||
- name: AI工具集
|
||||
alias: ai-tools
|
||||
default_publish_method: remote-api
|
||||
default_author: AI工具集
|
||||
app_id: your_ai_tools_app_id
|
||||
app_secret: your_ai_tools_app_secret
|
||||
remote_publish_host: ai-tools-server.example.com
|
||||
remote_publish_user: deploy
|
||||
remote_publish_port: 22
|
||||
remote_publish_identity_file: /home/me/.ssh/id_ed25519
|
||||
remote_publish_known_hosts_file: /home/me/.ssh/known_hosts
|
||||
remote_publish_strict_host_key_checking: accept-new
|
||||
```
|
||||
|
||||
Account-level `remote_publish_*` values override top-level globals. CLI `--remote-*` flags override both.
|
||||
|
||||
### CLI Usage
|
||||
|
||||
```bash
|
||||
# Use the account's default_publish_method (remote-api here):
|
||||
${BUN_X} {baseDir}/scripts/wechat-api.ts <file> --theme default --account ai-tools
|
||||
|
||||
# Force remote mode regardless of default_publish_method:
|
||||
${BUN_X} {baseDir}/scripts/wechat-api.ts <file> --theme default --account baoyu --remote --remote-host other-server.example.com
|
||||
```
|
||||
|
||||
### Security Notes
|
||||
|
||||
- Authentication is SSH key only. Passwords and `ssh-askpass` are not used.
|
||||
- Only the typed `remote_publish_*` keys are read; raw `ssh` / `scp` options are intentionally not supported.
|
||||
- The tunnel forwards raw TCP; TLS verification for `api.weixin.qq.com` is still performed end-to-end by the local process.
|
||||
Reference in New Issue
Block a user