formulahendry/wechat-acp
formulahendry/wechat-acp — dự án mã nguồn mở — đang có 804 sao GitHub. Bridge WeChat chat messages to any ACP-compatible AI agent (Claude, Codex, Copilot, Qwen, Gemini, OpenCode, OpenClaw, Hermes, Kiro, Kimi, Pi and more)
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Snapshot
Cộng tác viên hàng đầu
Xem cộng tác viên hàng đầu
WeChat ACP
Bridge WeChat direct messages to any ACP-compatible AI agent.
wechat-acp logs in with the WeChat iLink bot API, polls incoming 1:1 messages, forwards them to an ACP agent over stdio, and sends the agent reply back to WeChat.
Features
- WeChat QR login with terminal QR rendering
- One ACP agent session per WeChat user
- Built-in ACP agent presets for common CLIs
- Custom raw agent command support
- Agent image output delivered as native WeChat image messages
- Agent audio, embedded resources, and generated files delivered to WeChat
- Auto-allow permission requests from the agent
- Direct message only; group chats are ignored
- Background daemon mode
Requirements
- Node.js 20+
- A WeChat environment that can use the iLink bot API
- An ACP-compatible agent available locally or through
npx
Quick Start
Start with a built-in agent preset:
npx -y wechat-acp@latest --agent copilot
Or use a raw custom command:
npx -y wechat-acp@latest --agent "npx my-agent --acp"
On first run, the bridge will:
- Start WeChat QR login
- Render a QR code in the terminal
- Save the login token under
~/.wechat-acp - Begin polling direct messages
Trying preview builds
Every push to main is automatically published to npm under the next dist-tag, so you can try unreleased changes without waiting for a tagged release:
npx -y wechat-acp@next --agent copilot
These versions are tagged <base>-next.<UTC-timestamp>.<short-sha> (e.g. 0.7.1-next.202605311530.abc1234, where 0.7.1 is the next patch above whatever @latest is). They are built from main after CI passes, but have not been through a release review — expect rough edges. Stable users should keep using wechat-acp@latest.
Built-in Agent Presets
List the bundled presets:
npx wechat-acp agents
Current presets:
copilotclaudegeminiqwencodexopencodeopenclawkirohermeskimipi
These presets resolve to concrete command + args pairs internally, so users do not need to type long npx ... commands.
CLI Usage
wechat-acp --agent <preset|command> [options]
wechat-acp agents
wechat-acp inject --text <text>
wechat-acp stop
wechat-acp status
Options:
--agent <value>: built-in preset name or raw agent command--cwd <dir>: working directory for the agent process--login: force QR re-login and replace the saved token--daemon: run in background after startup--config <file>: load JSON config file--instance <name>: run as a named, isolated instance. See "Running multiple instances" below.--idle-timeout <minutes>: session idle timeout, default1440(use0for unlimited)--max-sessions <count>: maximum concurrent user sessions, default10--session-resume <mode>: persistence policy across bridge restarts:off(default),auto, orrequired--turn-end-message <text>: send a standalone message after each completed agent turn (default: disabled)--inbox-dir <dir>: directory where received binary files are saved (default:<storage.dir>/inbox). The agent sees the absolute saved path in the prompt and can read the file directly.--no-inbox: do not save received files; the agent only sees a size notice.--hide-thoughts: do not forward agent thinking to WeChat (default: forwarded)--show-diffs: forward ACP file diffs to WeChat (default: hidden)--hide-images: do not forward agent image output to WeChat (default: forwarded)--hide-audio: do not forward agent audio output to WeChat (default: forwarded)--hide-resources: do not forward agent resources or generated file attachments to WeChat (default: forwarded)inject --text <text>: enqueue a local text message for the running daemon-V, --version: print version and exit-h, --help: show help
Examples:
npx -y wechat-acp@latest --agent copilot
npx -y wechat-acp@latest --agent claude --cwd D:\code\project
npx -y wechat-acp@latest --agent "npx @github/copilot --acp"
npx -y wechat-acp@latest --agent gemini --daemon
Running multiple instances
By default everything (saved login token, daemon pid/log, sync state, telemetry id) lives under ~/.wechat-acp/, which means a single machine can only host one bridge at a time. Pass --instance <name> to namespace all of that under ~/.wechat-acp/instances/<name>/ and run several bridges side by side, each with its own WeChat account and project directory.
Typical setup: WeChat account 1 drives project A, WeChat account 2 drives project B.
# Terminal 1: scan with WeChat account 1
npx -y wechat-acp@latest --instance projA --agent copilot --cwd D:\code\repo-a
# Terminal 2: scan with WeChat account 2
npx -y wechat-acp@latest --instance projB --agent copilot --cwd D:\code\repo-b
The first run of each instance prints its own QR code. Tokens are saved per instance, so subsequent runs reuse them independently.
The stop and status subcommands also honor --instance:
npx -y wechat-acp@latest status --instance projA
npx -y wechat-acp@latest stop --instance projB
Without --instance, paths fall back to ~/.wechat-acp/ exactly as before, so existing installs are unaffected.
Configuration File
You can provide a JSON config file with --config.
Example:
{
"agent": {
"preset": "copilot",
"cwd": "D:/code/project",
"showDiffs": true
},
"session": {
"idleTimeoutMs": 86400000,
"maxConcurrentUsers": 10,
"resume": "auto",
"turnEndMessage": "✅ Turn complete"
}
}
session.resume controls whether each WeChat user's ACP conversation is
restored after the bridge restarts:
offkeeps the existing behavior and always starts a new ACP session.autoloads a saved session when the agent advertises the ACPloadSessioncapability. It starts a new session when loading is unsupported or the saved session no longer exists, but surfaces other load failures.requiredrequires an existing saved session to load successfully. A user without a saved session can still start their first conversation.
Session IDs are saved only after the first prompt completes. Loading replays history at the ACP protocol level, but the bridge suppresses that replay so old messages are not sent to WeChat again. Sessions are isolated by agent and absolute working directory: built-in presets use their stable preset ID, while raw agents use their command and arguments. Environment variables are never stored or included in the identity.
session.turnEndMessage is optional. When set to a non-empty string, the
bridge sends it as a standalone WeChat message after the ACP prompt resolves
and all output from that turn has been delivered. This makes the real turn
boundary visible even when the agent streamed several earlier messages or was
silent during a long-running tool call. The bridge generates this signal, so it
does not depend on the model following a prompt instruction. The
--turn-end-message CLI option overrides the config file value.
You can also override or add agent presets:
{
"agent": {
"preset": "my-agent"
},
"agents": {
"my-agent": {
"label": "My Agent",
"description": "Internal team agent",
"command": "npx",
"args": ["my-agent-cli", "--acp"]
}
}
}
Customizing bridge command names (aliases)
Bridge slash commands like /acp-config and /acp-cancel have fixed
built-in names that may not feel natural to everyone, and can clash with
slash commands built into the underlying agent. You can map any bridge
command to one or more custom aliases via the commandAliases config map:
{
"commandAliases": {
"/acp-cancel": ["/cancel", "/取消", "取消"],
"/acp-config": ["/config", "/设置"],
"/acp-new": ["/acp-clear", "/new"]
}
}
With this config:
- Sending
/取消cancels the current turn (same as/acp-cancel), and/取消 allworks like/acp-cancel all. - Sending
/设置lists ACP session config (same as/acp-config), and/设置 set <configId> <value>works like/acp-config set .... - The original built-in names always keep working as a fallback.
Two alias styles are supported:
- Slash aliases (start with
/, e.g./cancel) behave like the built-in commands: they match the command token and may be followed by arguments (/cancel all). They must not contain whitespace. - Bare-phrase aliases (no leading
/, e.g.取消) match only when they equal the entire message. This is handy for WeChat voice input, where saying/取消out loud feels unnatural — a transcribed取消triggers the command. Because they require an exact full-message match, they take no arguments.
Notes:
- Keys must be a known bridge command (
/acp-config,/acp-cancel,/acp-new,/acp-more,/acp-prompt-start, or/acp-prompt-done). - An alias may not collide with a built-in command name or be mapped to more than one command. Invalid configs are rejected at startup.
Runtime Behavior
- Each WeChat user gets a dedicated ACP session and subprocess.
- With session resume enabled, persisted sessions can survive subprocess and bridge restarts.
- Messages are processed serially per user.
- Replies are formatted for WeChat before sending.
- Typing indicators are sent when supported by the WeChat API.
- Sessions are cleaned up after inactivity (set
idleTimeoutMsto0to disable idle cleanup).
Fetching text that iLink rejected
WeChat iLink limits how many outbound messages can use one inbound context token. If a long agent reply reaches that limit and iLink reports send failures, the bridge keeps the failed text segments for 10 minutes. Send this command in a new WeChat message to deliver them with its fresh context token:
/acp-more
The command is handled by the bridge and never becomes an ACP prompt. It sends
pending segments in order and stops at the first segment that still fails after
retries. That segment and the remaining segments stay pending for the next
/acp-more. A new normal agent prompt clears older pending output. Storage is
in memory, limited to 50 text segments per active user, and does not include
images, audio, or files.
Aliases work through commandAliases. Bare aliases must match the whole
message, so they are intercepted before the normal ACP enqueue path.
This mitigation can only retain failures reported by iLink. If iLink returns success but silently drops a message, the bridge cannot detect or replay it.
Starting a fresh ACP session
Interactive agent commands such as Copilot CLI's /clear cannot clear context
when they are forwarded as normal ACP prompt text. Use the bridge command
instead:
/acp-new
The command stops the current user's active turn and agent subprocess, drops
messages queued behind that turn, clears any multi-part prompt buffer, and
removes the saved ACP session ID. The user's next normal message starts a new
agent subprocess and session/new conversation with the same agent, working
directory, environment, and bridge configuration.
Reset is isolated to the requesting WeChat user. Other users and the bridge
process keep running. It works with session.resume set to off, auto, or
required, and it is handled by wechat-acp rather than forwarded to the
underlying agent.
Use commandAliases to add names such as /acp-clear or /new.
WeChat ACP config command
wechat-acp reserves a bridge-level chat command for inspecting and changing ACP session configuration without exposing a UI picker in WeChat:
/acp-config
/acp-config set <configId> <value>
Examples:
/acp-config
/acp-config set model gpt-5-mini
/acp-config set mode plan
/acp-config set reasoning_effort low
Notes:
- The command only works after the WeChat user already has an active ACP session. If not, send a normal message first so the session is created.
- Available
configIdvalues come directly from the ACP agent'sconfigOptions, so the exact list depends on the configured agent. - This command is handled by
wechat-acpitself and is not forwarded to the underlying agent. - You can give this command your own aliases via
commandAliases(see Customizing bridge command names).
WeChat ACP cancel command
WeChat does not offer a stop button for an in-flight agent turn, so the bridge exposes a chat command instead:
/acp-cancel
/acp-cancel all
Behavior:
/acp-cancelsendssession/cancelto the agent for the current turn. The in-flightprompt()resolves withstopReason: "cancelled", any partial output already streamed is delivered to WeChat with a[cancelled]suffix, and the next queued message (if any) is processed as usual./acp-cancel alldoes the same and also drops every message that was queued behind the current turn. Local injections (wechat-acp inject) waiting on those queued messages are rejected.- If no turn is in flight, the command replies with a notice and is a no-op.
- This command is handled by
wechat-acpitself and is not forwarded to the underlying agent. - You can give this command your own aliases via
commandAliases(see Customizing bridge command names).
Multi-part message buffering
WeChat does not allow sending images, files, and text in a single message. To work around this, the bridge provides a buffering mode that collects multiple messages and sends them to the agent as one combined request:
/acp-prompt-start
/acp-prompt-done
Usage:
- Send
/acp-prompt-startto enter buffering mode. The bridge replies with a confirmation. - Send any number of messages (text, images, files) in any order. These are collected locally and not forwarded to the agent.
- Send
/acp-prompt-doneto flush the buffer. All collected content is combined into a single agent request.
This avoids triggering multiple agent turns (and multiple replies) when a user needs to send mixed content.
- If
/acp-prompt-doneis sent with nothing buffered, the bridge replies with a warning and no agent request is made. - If
/acp-prompt-startis sent while already buffering, the bridge reminds the user and keeps the existing buffer. - Buffering is per-user and held in memory. It does not persist across bridge restarts.
- Buffers expire after 10 minutes of inactivity. A maximum of 50 content blocks can be collected per buffer.
- This command is handled by
wechat-acpitself and is not forwarded to the underlying agent.
Injecting messages locally
wechat-acp inject lets local automation enqueue a text message for the running daemon. The daemon treats it like an incoming direct message from the target user, sends it to the configured ACP agent, and replies through WeChat.
This is useful for cron or launchd jobs, for example a daily AI news prompt:
npx wechat-acp inject --instance main --text "今日 AI 资讯"
Targets:
- Default target:
last-active-user - Custom target:
--to <wechat-user-id>
The daemon learns last-active-user from real incoming WeChat messages and stores the latest userId + contextToken under the instance storage directory. If no user has messaged the bot yet, ask the target user to send any message once, then retry the injection.
Injected messages are stored as JSON files under:
~/.wechat-acp/inject/
~/.wechat-acp/instances/<name>/inject/
The queue is file-based:
inject/
├── pending/
├── processing/
├── done/
└── failed/
inject only writes to pending/; the daemon moves files through the other directories as it processes them. If the daemon is not running, the message remains queued and will be processed after the daemon starts.
For longer prompts, use a file:
npx wechat-acp inject --instance main --file ./prompt.txt
Example Linux cron entry:
0 7 * * * /usr/local/bin/wechat-acp inject --instance main --text "今日 AI 资讯"
Receiving files
When a WeChat user sends a binary file (PDF, image, audio recording exported as a file, ZIP, etc.), wechat-acp downloads and decrypts it from the WeChat CDN, then saves it to disk so the ACP agent can read it by absolute path. The agent receives a text block like:
[Received file: 报告.pdf (484067 bytes) — saved to: /Users/me/.wechat-acp/inbox/2026-05-21T09-29-12-492Z-报告.pdf]
Any ACP agent that can read local files (Copilot CLI, Claude Code, Codex, …) can then open the saved path with its normal file tools.
Defaults:
- Save location:
<storage.dir>/inbox, i.e.~/.wechat-acp/inboxby default, or~/.wechat-acp/instances/<name>/inboxwhen--instanceis used. - Filename:
<ISO-timestamp>-<original-name>, with filesystem-unsafe characters in the original name replaced by_. Unicode (including Chinese) filenames are preserved. - No automatic cleanup. Files live until you delete them; agents may reference them long after the WeChat message arrives. Periodically run e.g.
find ~/.wechat-acp/inbox -mtime +30 -deleteif you want to prune.
Overrides:
--inbox-dir /some/path— write files somewhere else (handy if you want them under iCloud Drive, a project folder, etc.)--no-inbox— keep the pre-0.3 behavior where the file buffer is dropped after download and the agent only sees[Received file: name, N bytes].
Text-typed files (.md, .json, source code, …) and images keep their previous behavior: their content is embedded inline in the prompt as a resource / image block, no disk write needed.
Receiving agent-generated files
When the ACP agent advertises HTTP MCP support, wechat-acp injects a local
attach_file tool into the session. The agent can call it with a file it
created under the configured working directory, and the bridge sends that
snapshot back as a WeChat file message. Files whose type is a supported image
are delivered as native WeChat images instead of file cards.
The MCP server listens only on a random 127.0.0.1 port, requires a
process-local bearer token, rejects browser-origin requests, and only reads
regular files whose resolved path stays inside the agent working directory.
Files are limited to 25 MiB, kept briefly in memory, and consumed once.
This also handles standard ACP resource_link output and Copilot CLI's
rawOutput.contents[type=resource_link] compatibility shape. Agents that do
not support HTTP MCP injection or do not forward resource links cannot use the
active attach_file flow. --hide-resources disables both the tool injection
and outbound resource/file delivery.
Storage
By default, runtime files are stored under:
~/.wechat-acp
This directory is used for:
- saved login token
- daemon pid file
- daemon log file
- sync state
- anonymous telemetry install id (
telemetry-id, see Telemetry section) inbox/— binary files received from WeChat (see "Receiving files"); disable with--no-inboxor relocate with--inbox-dirstate.json— last active user and context token for local injectioninject/— local injected message queue
When --instance <name> is used, the same files live under ~/.wechat-acp/instances/<name>/ instead, fully isolated from other instances.
Current Limitations
- Direct messages only; group chats are ignored
- Agent-generated file delivery depends on the agent's HTTP MCP and resource-link support
- Permission requests are auto-approved
- Agent communication is subprocess-only over stdio
- Some preset agents may require separate authentication before they can respond successfully
Development
For local development:
npm install
npm run build
Run the built CLI locally:
node dist/bin/wechat-acp.js --help
Watch mode:
npm run dev
Telemetry
wechat-acp collects anonymous usage telemetry via Azure Application Insights to help understand which agent presets are used and to detect crashes.
To disable telemetry, set the WECHAT_ACP_TELEMETRY environment variable to 0, false, or off before running:
WECHAT_ACP_TELEMETRY=0 npx wechat-acp --agent copilot
What is collected (18 event types only):
app.start/app.stop— process lifecycle, agent preset name, daemon flag, uptimelogin.success/login.failure/token.reused— WeChat login outcomes (no token, no QR URL)message.received— message arrived; only the categorical kind (text/image/voice/file/video/empty) and a hashed user idmessage.injected— local injection queued for processing; only target kind (last-active-user/explicit) and a hashed user idcommand.acp_config.view—/acp-configinvoked to list options; whether a session exists and the option countcommand.acp_config.set—/acp-config setsucceeded;configId, option type (select/boolean), and the resolved option value (all from the agent's declaredconfigOptions, never the user's raw input)command.acp_cancel—/acp-cancelinvoked; whether the queue was drained, whether an in-flight turn was actually cancelled, and how many queued messages were droppedcommand.buffer_start—/acp-prompt-startinvoked to enter buffering modecommand.buffer_done—/acp-prompt-doneinvoked to flush buffer; number of content blocks collectedsession.created— new ACP session openedprompt.completed— ACP turn finished; agent preset, stop reason, duration, reply lengthreply.sent— reply pushed back to WeChat; segment count, total lengthreply.image.sent: image reply pushed back to WeChat; byte size, MIME type, durationreply.audio.sent: audio reply pushed back to WeChat as a file message; byte size, MIME type, durationreply.file.sent: agent-generated file pushed back to WeChat; byte size, MIME type, duration
Plus exception reports for monitor, prompt, reply, reply.image, reply.audio, reply.file, artifact_mcp, auth, agent_spawn, enqueue, buffer, command, and state failures.
What is never collected: message bodies, filenames, voice transcripts, image URLs, login tokens, QR codes, raw agent command strings, environment variables, working directory paths, raw WeChat user IDs.
User IDs are sha256-hashed with a per-install salt stored in ~/.wechat-acp/telemetry-id. The salt is generated on first run and never leaves your machine. Delete the file to rotate it.
License
MIT
Repo liên quan
Master programming by recreating your favorite technologies from scratch.
A curated meta-list of curated lists organized by technology domain. The repository acts as a directory pointing to hundreds of specialized awesome lists covering programming languages, platforms, frameworks, and tooling. All content is community-contributed under the CC0 public domain dedication.
Public APIs is a community-curated GitHub repository listing free, publicly accessible APIs across a wide range of categories, with auth type, HTTPS, and CORS noted for each entry. It's a browsable reference, not a library to install.
freeCodeCamp is a free, self-paced curriculum for learning to code, published as open source at freeCodeCamp/freeCodeCamp. It's a 501(c)(3) nonprofit funded by donor support, structured around six certifications in its Full-Stack Developer Curriculum, each gated by required projects instead of open-book quizzes. The repository also carries beta language certifications for developers, interview-prep resources, and the code that runs the live freecodecamp.org platform.
Trả lời nhanh
Đọc thêm về formulahendry/wechat-acp ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/formulahendry/wechat-acp là nguồn chính thức.
formulahendry/wechat-acp có phải mã nguồn mở không?
Có — formulahendry/wechat-acp phát hành theo license MIT, nghĩa là mã nguồn mở để đọc, fork và (tùy license) tái sử dụng. Mã: github.com/formulahendry/wechat-acp.
formulahendry/wechat-acp có trang demo không?
Dự án có trang chủ ở https://www.npmjs.com/package/wechat-acp. Tab "Readme" ở trang này thường có ảnh chụp và hướng dẫn bắt đầu nhanh.
formulahendry/wechat-acp dùng license gì?
formulahendry/wechat-acp phát hành theo license MIT. Nên mở file LICENSE trên GitHub để xác nhận — license metadata đôi khi lệch với thực tế dự án.
formulahendry/wechat-acp là gì?
formulahendry/wechat-acp (formulahendry/wechat-acp) là dự án TypeScript trên GitHub. Theo mô tả gốc: Bridge WeChat chat messages to any ACP-compatible AI agent (Claude, Codex, Copilot, Qwen, Gemini, OpenCode, OpenClaw, Hermes, Kiro, Kimi, Pi and more)
Đọc đầy đủ README ở tab phía trên.
Chưa chắc wechat-acp có hợp với bạn?
Để ChatGPT, Claude hoặc Perplexity tìm hiểu giúp — bấm bên dưới và xem AI nói gì về wechat-acp.