252 lines
7.1 KiB
Markdown
252 lines
7.1 KiB
Markdown
# 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:
|
|
|
|
```text
|
|
alpha 0.6.0.1015
|
|
```
|
|
|
|
## Runtime Flow
|
|
|
|
```text
|
|
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:
|
|
|
|
```sh
|
|
./tools/jwebot-config.py init personal --activate
|
|
```
|
|
|
|
Edit files under:
|
|
|
|
```text
|
|
~/.config/jwebot/profiles/personal/
|
|
```
|
|
|
|
Then compile and validate:
|
|
|
|
```sh
|
|
./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:
|
|
|
|
```text
|
|
~/.config/jwebot/current/generated/
|
|
runtime.env
|
|
root.env
|
|
private-context.json
|
|
notification.json
|
|
manifest.json
|
|
```
|
|
|
|
See [config/README.md](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:
|
|
|
|
```text
|
|
/功能列表
|
|
/丢骰子 [NdM]
|
|
/猜数字 开始 [上限]
|
|
/石头剪刀布 [开始|加入|出|状态|结算|结束]
|
|
/记住 内容
|
|
/人物记忆 显示名
|
|
/扫码排行
|
|
/复读榜
|
|
/查记录 关键词
|
|
/状态
|
|
/version
|
|
/debug
|
|
/steam [在线|游戏|全部|刷新]
|
|
/steam时长 游戏名[、玩家名]
|
|
```
|
|
|
|
OCR whitespace is optional for Steam playtime queries. A player selector uses
|
|
the final separator shown below:
|
|
|
|
```text
|
|
/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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```sh
|
|
./tools/create-plugin.py weather-command /weather \
|
|
--author example \
|
|
--description "Query approved weather data" \
|
|
--help-entry "/weather city"
|
|
```
|
|
|
|
Validate, package, sign, and activate:
|
|
|
|
```sh
|
|
./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](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:
|
|
|
|
```sh
|
|
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
|
|
|
|
```text
|
|
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:
|
|
|
|
```sh
|
|
PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh
|
|
```
|
|
|
|
Run privacy scans explicitly:
|
|
|
|
```sh
|
|
./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](LICENSE).
|