omp-wechat 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +190 -0
  2. package/dist/index.js +707453 -0
  3. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # OMP-Wechat
2
+
3
+ Bridge WeChat messages to [OMP (Oh My Pi)](https://omp.sh) / [Pi](https://pi.dev) — receive WeChat messages, process them with OMP/Pi's AI engine, and reply back automatically.
4
+
5
+ Uses the [Tencent iLink Bot API](https://www.wechatbot.dev/zh/protocol) (the official WeChat personal-account Bot API behind ClawBot) for message transport, and the OMP/Pi SDK as the AI brain.
6
+
7
+ ## How It Works
8
+
9
+ ```
10
+ WeChat user → iLink Bot API → [OMP/Pi process] → SDK → AI provider
11
+ ↑ │
12
+ └──── reply ← message_end ─┘
13
+ ```
14
+
15
+ The extension runs **inside** the OMP/Pi process. On `session_start`, the iLink long-poll loop starts in-process. The host keeps the process alive; the poll loop runs as a background promise. When the process exits, the poll loop stops and all sessions are disposed.
16
+
17
+ For boot-time persistence, install a launchd/systemd service via `/wechat install`. The service runs `omp --mode rpc` (or `pi --mode rpc`) with `KeepAlive`/`Restart=always`, so the host (and the poll loop) survive crashes and reboots.
18
+
19
+ - **Typing indicator**: shows "Typing..." on WeChat while the model is thinking
20
+ - **No external `bun` required** — OMP/Pi is a standalone binary with an embedded runtime
21
+ - **No detached daemon** — the poll loop runs in-process, lifecycle tied to the host
22
+ - **Cross-platform** — launchd (macOS) or systemd (Linux), no sudo on macOS
23
+ - **iLink layer**: long-polls `getupdates` for inbound messages, sends replies via `sendmessage`
24
+ - **AI engine**: one in-memory session per WeChat chat, prompts injected via `session.prompt()`
25
+ - **Access control**: pairing-based — strangers must pair before their messages are delivered
26
+
27
+ ## Features
28
+
29
+ - **OMP/Pi extension**: installs via `omp plugin link .` or `pi plugin link .`, auto-starts poll loop on `session_start`
30
+ - **Slash commands**: `/wechat login`, `/wechat status`, `/wechat pair`, `/wechat allow`, `/wechat revoke`, `/wechat list`, `/wechat stop`, `/wechat install`, `/wechat uninstall`
31
+ - **Bidirectional**: receive and reply to WeChat text messages
32
+ - **Per-chat sessions**: each WeChat chat gets an independent AI session (concurrent, isolated)
33
+ - **LRU pool**: caps memory usage by evicting least-recently-used sessions (default: 50)
34
+ - **Typing indicator**: native WeChat "typing..." shown during AI processing
35
+ - **Access control**: pairing / allowlist / disabled modes
36
+ - **Long text chunking**: splits replies >2000 chars at paragraph/line/space boundaries
37
+ - **Boot service**: optional launchd/systemd service for auto-start on boot
38
+
39
+ ## Quick Start
40
+
41
+ ### Prerequisites
42
+
43
+ - [OMP](https://omp.sh) or [Pi](https://pi.dev) installed and authenticated (`omp login` / `pi login`)
44
+ - WeChat (latest iOS version with ClawBot support)
45
+
46
+ ### Install
47
+
48
+ ```bash
49
+ git clone <your-repo-url> OMP-Wechat
50
+ cd OMP-Wechat
51
+ bun install # build dependency only
52
+ bun run build
53
+ omp plugin link . # or: pi plugin link .
54
+ ```
55
+
56
+ This links the extension into OMP/Pi. The poll loop starts automatically on your next `session_start`.
57
+
58
+ ### Login (scan QR code)
59
+
60
+ ```
61
+ /wechat login
62
+ ```
63
+
64
+ A QR code appears in the terminal. Scan it with WeChat and confirm on your phone. Credentials are saved to `~/.omp-wechat/credentials.json`.
65
+
66
+ ### Run
67
+
68
+ No explicit run command needed — the poll loop auto-starts on `session_start`. Once running, send a message to the bot on WeChat — it will be processed and the reply sent back.
69
+
70
+ To check status: `/wechat status`. To stop: `/wechat stop`.
71
+
72
+ ### Boot-time auto-start (optional)
73
+
74
+ ```
75
+ /wechat install
76
+ ```
77
+
78
+ Installs a launchd (macOS) or systemd (Linux) service that runs the host (`omp --mode rpc` or `pi --mode rpc`) at boot. The host stays alive via `KeepAlive`/`Restart=always`, keeping the poll loop running across crashes and reboots.
79
+
80
+ Logs: `~/.omp-wechat/logs/rpc.log`
81
+ Manage: `launchctl start|stop com.omp-wechat` (macOS) or `sudo systemctl start|stop omp-wechat` (Linux)
82
+
83
+ To remove: `/wechat uninstall`
84
+
85
+ ## Configuration
86
+
87
+ Configuration is loaded from `~/.omp-wechat/config.yml`, falling back to built-in defaults. Model, working directory, and tools are inherited from the OMP/Pi session automatically.
88
+
89
+ ```yaml
90
+ # ~/.omp-wechat/config.yml
91
+ maxSessions: 50
92
+ dmPolicy: pairing
93
+ systemPrompt: |
94
+ You are an AI assistant chatting via WeChat.
95
+ Keep replies concise and in plain text.
96
+ ```
97
+
98
+ | Field | Default | Description |
99
+ |---|---|---|
100
+ | `maxSessions` | `50` | Session pool cap (LRU eviction) |
101
+ | `dmPolicy` | `pairing` | Access policy: `pairing` / `allowlist` / `disabled` |
102
+ | `systemPrompt` | Built-in | System prompt for WeChat chat sessions |
103
+
104
+ > **Model, working directory, and tools are managed by OMP/Pi.** `createAgentSession()` automatically calls `discoverAuthStorage()`, reusing your existing `omp login` / `pi login` OAuth, `~/.omp/agent/agent.db` API keys, or `models.yml` config. This project never touches API keys.
105
+
106
+ ## Slash Commands
107
+
108
+ | Command | Description |
109
+ |---|---|
110
+ | `/wechat login` | Scan QR code to log in |
111
+ | `/wechat status` | Show poll loop state, session pool, boot service, authorized users |
112
+ | `/wechat pair <code>` | Approve a pairing request |
113
+ | `/wechat allow <wxid>` | Directly authorize a user |
114
+ | `/wechat revoke <wxid>` | Revoke a user's authorization |
115
+ | `/wechat list` | List authorized users |
116
+ | `/wechat stop` | Stop the poll loop |
117
+ | `/wechat install` | Install boot-time launchd/systemd service |
118
+ | `/wechat uninstall` | Remove boot-time service |
119
+
120
+ ## Access Control
121
+
122
+ | Mode | Behavior |
123
+ |---|---|
124
+ | `pairing` (default) | Unknown senders get a pairing code; they must be approved via `/wechat pair <code>` |
125
+ | `allowlist` | Only users in the allowlist can send messages; others are silently dropped |
126
+ | `disabled` | All inbound messages are dropped |
127
+
128
+ The logged-in user (who scanned the QR code) is automatically added to the allowlist.
129
+
130
+ ## Lifecycle
131
+
132
+ | Scenario | Behavior |
133
+ |---|---|
134
+ | Host session starts | Poll loop starts automatically |
135
+ | Host session exits | Poll loop stops, all sessions disposed |
136
+ | Host crashes | launchd/systemd restarts the host (if `/wechat install` was run) |
137
+ | Machine reboots | Service auto-starts the host (if installed), poll loop resumes |
138
+ | No boot service | Poll loop only runs while a host session is active |
139
+
140
+ Logs: `~/.omp-wechat/logs/daemon.log`
141
+
142
+ ## Project Structure
143
+
144
+ ```
145
+ OMP-Wechat/
146
+ ├── package.json # omp.extensions / pi.extensions manifest
147
+ ├── tsconfig.json
148
+ ├── .env.example
149
+ ├── src/
150
+ │ ├── index.ts # OMP/Pi extension entry (session_start + /wechat commands)
151
+ │ ├── bridge.ts # In-process poll loop + message handling
152
+ │ ├── service.ts # Boot-time launchd/systemd install
153
+ │ ├── config.ts # Config loading (env + config.yml + defaults)
154
+ │ ├── ilink/
155
+ │ │ ├── types.ts # iLink Bot API type definitions
156
+ │ │ ├── client.ts # iLink API client (poll/send/typing)
157
+ │ │ └── login.ts # QR code login flow
158
+ │ ├── engine/
159
+ │ │ ├── session.ts # AI session creation + reply subscription
160
+ │ │ ├── pool.ts # Session pool (LRU eviction, concurrency)
161
+ │ │ └── prompt.ts # Barrel exports
162
+ │ ├── access/
163
+ │ │ └── control.ts # Access control (pairing/allowlist/disabled)
164
+ │ ├── utils/
165
+ │ │ ├── chunk.ts # Long text chunking
166
+ │ │ └── logger.ts # stderr + file logger
167
+ │ └── types/
168
+ │ └── qrcode-terminal.d.ts
169
+ ├── dist/ # Built output (index.js)
170
+ └── README.md
171
+ ```
172
+
173
+ ## Limitations
174
+
175
+ - **Reply-only**: iLink requires `context_token` from an inbound message; you cannot initiate conversations
176
+ - **1:1 only**: iLink Bot API does not support group chats
177
+ - **No message history**: WeChat provides no history API; session context is lost on restart (in-memory sessions)
178
+ - **Single instance**: iLink allows only one bot connection per account
179
+ - **Text only (Phase 1)**: images/voice/video are represented as `(image)` / `(voice)` placeholders; media support is planned
180
+
181
+ ## Roadmap
182
+
183
+ - [ ] **Phase 2**: Media support (inbound images as base64, voice transcription)
184
+ - [ ] **Phase 3**: Persistent sessions (`SessionManager.create()` per chat directory)
185
+ - [ ] **Phase 4**: Per-chat model selection (smol for simple questions, slow for complex)
186
+ - [ ] **Phase 5**: Fine-grained permissions (per-user tool restrictions, bash approval via WeChat)
187
+
188
+ ## License
189
+
190
+ MIT