JWeBot
JWeBot is a single-group WeChat automation runtime for Linux. It observes one selected WeChat window through local OCR, routes messages through a durable Edge ledger, runs reviewed command plugins, and sends replies through a visually confirmed GUI bridge.
Current version:
alpha 0.6.0.1015
Runtime Flow
WeChat window
-> adaptive XDamage capture
-> local OCR and group fingerprint gate
-> durable Edge ledger
-> reviewed local plugin
-> DeepSeek direct chat
-> optional cloud agent
-> priority GUI queue
-> guarded draft/send/visual confirmation
The runtime is deliberately bound to one visible group. Plugins cannot select a group, access the GUI, read environment secrets, open arbitrary sockets, invoke shell commands, or access raw SQLite state.
Quick Start
Requirements:
- Linux with systemd user services;
- a working desktop WeChat session on X11/VNC display
:1; - Python 3.9 or newer;
xdotool,scrot,xclip, OpenCV, Pillow, NumPy, and RapidOCR;- an optional loopback Mihomo HTTP proxy for Steam.
Create a private configuration profile:
./tools/jwebot-config.py init personal --activate
Edit files under:
~/.config/jwebot/profiles/personal/
Then compile and validate:
./tools/jwebot-config.py activate personal
PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh
The source profile is never read directly by services. Activation validates and atomically generates:
~/.config/jwebot/current/generated/
runtime.env
root.env
private-context.json
notification.json
manifest.json
See config/README.md for import, redacted export, legacy migration, debug archives, and root deployment settings.
Commands
The built-in command inventory is generated from reviewed plugin descriptors. Common commands include:
/功能列表
/丢骰子 [NdM]
/猜数字 开始 [上限]
/石头剪刀布 [开始|加入|出|状态|结算|结束]
/记住 内容
/人物记忆 显示名
/扫码排行
/复读榜
/查记录 关键词
/状态
/version
/debug
/steam [在线|游戏|全部|刷新]
/steam时长 游戏名[、玩家名]
OCR whitespace is optional for Steam playtime queries. A player selector uses the final separator shown below:
/steam 时长 Dota 2
/steam时长Dota2
/steam时长Dota2、玩家名
/steam时长Dota2人=玩家名
Steam prefers private per-person SteamID mappings from the active profile and uses the corresponding group display IDs and aliases. Without a private roster, it discovers the configured account's public friend list at runtime. No real SteamID, display name, alias, or fixed roster is stored in source. Game and player names support fuzzy matching; all-player requests use bounded concurrency, while player-specific requests read only the selected account's game library. Every request must use the configured loopback proxy.
Configuration Profiles
Each profile is organized like a plugin package:
manifest.toml
components/
bot.toml
providers.toml
runtime.toml
debug.toml
notification.toml
deployment.toml
context/
people.json
secrets/
runtime.env
overrides/
runtime.env
root.env
Real profiles live outside Git with 0700 directories and 0600 files.
Incidents, debug sessions, telemetry, and migrated root material live under
~/.local/state/jwebot/profiles/<profile>/.
Plugins And SDK
The public SDK is in packages/jwebot-sdk/. A minimal extension is available
at examples/hello-command/.
Create a plugin:
./tools/create-plugin.py weather-command /weather \
--author example \
--description "Query approved weather data" \
--help-entry "/weather city"
Validate, package, sign, and activate:
./tools/validate-plugin.py extensions/friends/weather-command/plugin.toml
./tools/package-plugin.py extensions/friends/weather-command --output /tmp/release
./tools/sign-release.py /tmp/release/*.release.json \
--private-key /protected/path/publisher \
--publisher example
Extension registration is dynamic only during startup and freezes before runtime routing.
Deployment
For a new machine, follow docs/runbooks/zero-to-running.md.
For an existing installation, the coordinated deployer preserves the previous runtime, user units, generated configuration, SQLite state, and systemd topology before cutover:
sudo ./deploy/scripts/deploy-jwebot-production.sh /path/to/JWeBot jwebot
The deployer refuses cutover unless the ready-window, empty-queue, Edge health, SQLite integrity, and adaptive restart-stability gates pass. Legacy OCR units remain installed but disabled.
Repository Map
| Path | Purpose |
|---|---|
packages/jwebot-config/ |
Profile validation, generation, import/export, activation, and legacy migration. |
packages/jwebot-sdk/ |
Capability-limited public plugin contracts. |
packages/jwebot-kernel/ |
Routing, ledger, policy, release verification, and Edge runtime. |
packages/jwebot-extension-host/ |
Isolated signed-extension process host. |
packages/jwebot-official-extensions/ |
Reviewed command engine and generated adapters. |
extensions/official/ |
Official service-profile adapters. |
extensions/jwebot/ |
Built-in reviewed command plugins. |
extensions/friends/ |
Contributor plugin area. |
config/ |
Public templates and schemas only. |
deploy/ |
Bootstrap, coordinated deployment, and systemd units. |
docs/ |
Architecture, SDK, configuration, and runbooks. |
tests/ |
Unit, parity, packaging, safety, and deployment contract tests. |
tools/ |
Validation, packaging, signing, activation, scanning, and config CLI. |
The root Python files are compatibility entrypoints used by deployed services;
implementation packages remain under packages/.
Project Status
Config profiles and private migration [####################] 100%
Plugin ownership and SDK boundaries [####################] 100%
Steam status and playtime modes [####################] 100%
Local unit and parity coverage [####################] 100%
Zero-to-running automation [################----] 80%
Cross-distribution staging [########------------] 40%
Percentages describe completed, testable deliverables in this repository. Production readiness still depends on the target desktop, WeChat build, OCR models, proxy, and operator-provided credentials.
Verification
Run the complete local gate:
PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh
Run privacy scans explicitly:
./tools/check-secrets.py
./tools/check-secrets.py --history
The scanner reports only category, path, line, object hash, and a one-way value fingerprint. It never prints the matched value.
Privacy
Do not commit populated profiles, generated environments, private context, screenshots, OCR history, debug payloads, incident archives, SQLite files, publisher private keys, API keys, SteamIDs, or host-specific paths.
The repository includes safe templates and schemas. Default profile export is
redacted; private export requires an explicit --include-private flag.
License
JWeBot is licensed under Apache License 2.0. See LICENSE.