wechat-bridge-opencode 0.1.2

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 (82) hide show
  1. package/.opencode/tools/send-wechat.ts +88 -0
  2. package/LICENSE +21 -0
  3. package/README.md +244 -0
  4. package/dist/bin/wechat-acp.d.ts +14 -0
  5. package/dist/bin/wechat-acp.d.ts.map +1 -0
  6. package/dist/bin/wechat-acp.js +284 -0
  7. package/dist/bin/wechat-acp.js.map +1 -0
  8. package/dist/bin/wechat-opencode.d.ts +14 -0
  9. package/dist/bin/wechat-opencode.d.ts.map +1 -0
  10. package/dist/bin/wechat-opencode.js +284 -0
  11. package/dist/bin/wechat-opencode.js.map +1 -0
  12. package/dist/package.json +60 -0
  13. package/dist/src/acp/agent-manager.d.ts +23 -0
  14. package/dist/src/acp/agent-manager.d.ts.map +1 -0
  15. package/dist/src/acp/agent-manager.js +134 -0
  16. package/dist/src/acp/agent-manager.js.map +1 -0
  17. package/dist/src/acp/client.d.ts +49 -0
  18. package/dist/src/acp/client.d.ts.map +1 -0
  19. package/dist/src/acp/client.js +219 -0
  20. package/dist/src/acp/client.js.map +1 -0
  21. package/dist/src/acp/opencode-sessions.d.ts +17 -0
  22. package/dist/src/acp/opencode-sessions.d.ts.map +1 -0
  23. package/dist/src/acp/opencode-sessions.js +59 -0
  24. package/dist/src/acp/opencode-sessions.js.map +1 -0
  25. package/dist/src/acp/session.d.ts +75 -0
  26. package/dist/src/acp/session.d.ts.map +1 -0
  27. package/dist/src/acp/session.js +273 -0
  28. package/dist/src/acp/session.js.map +1 -0
  29. package/dist/src/acp/workspace-manager.d.ts +48 -0
  30. package/dist/src/acp/workspace-manager.d.ts.map +1 -0
  31. package/dist/src/acp/workspace-manager.js +141 -0
  32. package/dist/src/acp/workspace-manager.js.map +1 -0
  33. package/dist/src/adapter/inbound.d.ts +10 -0
  34. package/dist/src/adapter/inbound.d.ts.map +1 -0
  35. package/dist/src/adapter/inbound.js +149 -0
  36. package/dist/src/adapter/inbound.js.map +1 -0
  37. package/dist/src/adapter/outbound.d.ts +9 -0
  38. package/dist/src/adapter/outbound.d.ts.map +1 -0
  39. package/dist/src/adapter/outbound.js +25 -0
  40. package/dist/src/adapter/outbound.js.map +1 -0
  41. package/dist/src/adapter/workspace-cmd.d.ts +53 -0
  42. package/dist/src/adapter/workspace-cmd.d.ts.map +1 -0
  43. package/dist/src/adapter/workspace-cmd.js +172 -0
  44. package/dist/src/adapter/workspace-cmd.js.map +1 -0
  45. package/dist/src/bridge.d.ts +42 -0
  46. package/dist/src/bridge.d.ts.map +1 -0
  47. package/dist/src/bridge.js +557 -0
  48. package/dist/src/bridge.js.map +1 -0
  49. package/dist/src/config.d.ts +63 -0
  50. package/dist/src/config.d.ts.map +1 -0
  51. package/dist/src/config.js +88 -0
  52. package/dist/src/config.js.map +1 -0
  53. package/dist/src/index.d.ts +7 -0
  54. package/dist/src/index.d.ts.map +1 -0
  55. package/dist/src/index.js +6 -0
  56. package/dist/src/index.js.map +1 -0
  57. package/dist/src/weixin/api.d.ts +50 -0
  58. package/dist/src/weixin/api.d.ts.map +1 -0
  59. package/dist/src/weixin/api.js +87 -0
  60. package/dist/src/weixin/api.js.map +1 -0
  61. package/dist/src/weixin/auth.d.ts +20 -0
  62. package/dist/src/weixin/auth.d.ts.map +1 -0
  63. package/dist/src/weixin/auth.js +88 -0
  64. package/dist/src/weixin/auth.js.map +1 -0
  65. package/dist/src/weixin/media.d.ts +24 -0
  66. package/dist/src/weixin/media.d.ts.map +1 -0
  67. package/dist/src/weixin/media.js +91 -0
  68. package/dist/src/weixin/media.js.map +1 -0
  69. package/dist/src/weixin/monitor.d.ts +16 -0
  70. package/dist/src/weixin/monitor.d.ts.map +1 -0
  71. package/dist/src/weixin/monitor.js +111 -0
  72. package/dist/src/weixin/monitor.js.map +1 -0
  73. package/dist/src/weixin/send.d.ts +32 -0
  74. package/dist/src/weixin/send.d.ts.map +1 -0
  75. package/dist/src/weixin/send.js +193 -0
  76. package/dist/src/weixin/send.js.map +1 -0
  77. package/dist/src/weixin/types.d.ts +150 -0
  78. package/dist/src/weixin/types.d.ts.map +1 -0
  79. package/dist/src/weixin/types.js +33 -0
  80. package/dist/src/weixin/types.js.map +1 -0
  81. package/package.json +60 -0
  82. package/scripts/install-tool.mjs +14 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * OpenCode custom tool: send files to WeChat.
3
+ *
4
+ * Place this file at:
5
+ * - Global: ~/.config/opencode/tools/send-wechat.ts
6
+ * - Project: .opencode/tools/send-wechat.ts
7
+ *
8
+ * Tool name: send-wechat
9
+ * Reads userId/sessionId from .wechat-bridge-state.json automatically.
10
+ */
11
+
12
+ import { tool } from "@opencode-ai/plugin"
13
+ import path from "node:path"
14
+ import os from "node:os"
15
+ import fs from "node:fs"
16
+
17
+ const API_URL = "http://127.0.0.1:18792/send-wechat"
18
+
19
+ /** Load state from ~/.wechat-opencode/.wechat-bridge-state.json */
20
+ function loadState(): { lastUserId?: string; lastSessionId?: string } {
21
+ try {
22
+ const stateFile = path.join(os.homedir(), ".wechat-opencode", ".wechat-bridge-state.json")
23
+ if (fs.existsSync(stateFile)) {
24
+ return JSON.parse(fs.readFileSync(stateFile, "utf-8"))
25
+ }
26
+ } catch {
27
+ // ignore
28
+ }
29
+ return {}
30
+ }
31
+
32
+ export default tool({
33
+ description: "Send a file to the last active WeChat user through the wechat-opencode bridge. Use this to share files, images, PDFs, etc. with the WeChat contact.",
34
+ args: {
35
+ filePath: tool.schema.string().describe("Absolute path to the file to send (e.g., F:\\report.pdf)"),
36
+ },
37
+ async execute(args) {
38
+ const absolutePath = path.resolve(args.filePath)
39
+
40
+ // Validate file exists
41
+ try {
42
+ if (!fs.existsSync(absolutePath)) {
43
+ return `Error: File not found: ${absolutePath}`
44
+ }
45
+ const stat = fs.statSync(absolutePath)
46
+ if (!stat.isFile()) {
47
+ return `Error: Not a file: ${absolutePath}`
48
+ }
49
+ } catch (err) {
50
+ return `Error accessing file: ${err instanceof Error ? err.message : String(err)}`
51
+ }
52
+
53
+ // Load userId/sessionId from state file
54
+ const state = loadState()
55
+ if (!state.lastUserId && !state.lastSessionId) {
56
+ return "Error: No active WeChat session found. Has anyone messaged you recently? The bridge must be running and have received at least one message."
57
+ }
58
+
59
+ const fileName = path.basename(absolutePath)
60
+
61
+ // Call the bridge API
62
+ try {
63
+ const response = await fetch(API_URL, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({
67
+ filePath: absolutePath,
68
+ userId: state.lastUserId,
69
+ sessionId: state.lastSessionId,
70
+ }),
71
+ })
72
+
73
+ const result = await response.json()
74
+
75
+ if (!response.ok) {
76
+ return `Error: ${result.error || `HTTP ${response.status}`}`
77
+ }
78
+
79
+ return `Successfully sent "${result.fileName || fileName}" to WeChat user ${state.lastUserId}!`
80
+ } catch (err) {
81
+ const msg = err instanceof Error ? err.message : String(err)
82
+ if (msg.includes("ECONNREFUSED")) {
83
+ return `Error: Cannot connect to wechat-opencode bridge at 127.0.0.1:18792. Is the bridge running?`
84
+ }
85
+ return `Error: ${msg}`
86
+ }
87
+ },
88
+ })
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jun Han
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,244 @@
1
+ # WeChat OpenCode
2
+
3
+ Bridge WeChat direct messages to opencode.
4
+
5
+ `wechat-bridge-opencode` (aka `wbo`) logs in with the WeChat iLink bot API, polls incoming 1:1 messages, forwards them to opencode over stdio, and sends the agent reply back to WeChat.
6
+
7
+ <img src="./resources/screenshot.jpg" alt="wbo screenshot" width="400" />
8
+
9
+ ## Features
10
+
11
+ - WeChat QR login with terminal QR rendering
12
+ - One ACP agent session per WeChat user
13
+ - Built-in ACP agent presets for common CLIs
14
+ - Custom raw agent command support
15
+ - Auto-allow permission requests from the agent
16
+ - Direct message only; group chats are ignored
17
+ - Background daemon mode
18
+ - File sending: agent can send files/images back to WeChat via the `send-wechat` tool
19
+ - Automatic model config forwarding for opencode agents
20
+
21
+ ## Requirements
22
+
23
+ - Node.js 20+
24
+ - A WeChat environment that can use the iLink bot API
25
+ - [OpenCode](https://github.com/anomalyco/opencode) installed locally or via `npx`
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npx wbo --agent opencode
31
+ ```
32
+
33
+ That's it — `wbo` will be available globally after first run, and the `send-wechat` tool is automatically installed to `~/.config/opencode/tools/send-wechat.ts`.
34
+
35
+ To install globally:
36
+
37
+ ```bash
38
+ npm install -g wechat-bridge-opencode
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ > **Important**: Run the bridge from your **working directory** (e.g. your project folder), **not** from an arbitrary install directory. Running from the install directory may cause conflicts.
44
+
45
+ ```bash
46
+ cd /path/to/your/workdir
47
+ wbo --agent opencode
48
+ ```
49
+
50
+ Or with a custom agent command:
51
+
52
+ ```bash
53
+ wbo --agent "npx my-agent --acp"
54
+ ```
55
+
56
+ On first run, the bridge will:
57
+
58
+ 1. Start WeChat QR login
59
+ 2. Render a QR code in the terminal
60
+ 3. Save the login token under `~/.wechat-bridge-opencode`
61
+ 4. Begin polling direct messages
62
+
63
+ ## Built-in Agent Presets
64
+
65
+ List the bundled presets:
66
+
67
+ ```bash
68
+ wbo agents
69
+ ```
70
+
71
+ Current presets:
72
+
73
+ - `opencode`
74
+
75
+ These presets resolve to concrete `command + args` pairs internally, so users do not need to type long `npx ...` commands.
76
+
77
+ ## CLI Usage
78
+
79
+ ```text
80
+ wbo --agent <preset|command> [options]
81
+ wbo agents
82
+ wbo stop
83
+ wbo status
84
+ ```
85
+
86
+ Options:
87
+
88
+ - `--agent <value>`: built-in preset name or raw agent command
89
+ - `--cwd <dir>`: working directory for the agent process
90
+ - `--login`: force QR re-login and replace the saved token
91
+ - `--daemon`: run in background after startup
92
+ - `--config <file>`: load JSON config file
93
+ - `--idle-timeout <minutes>`: session idle timeout, default `1440` (use `0` for unlimited)
94
+ - `--max-sessions <count>`: maximum concurrent user sessions, default `10`
95
+ - `--show-thoughts`: forward agent thinking to WeChat (default: off)
96
+ - `-h, --help`: show help
97
+
98
+ Examples:
99
+
100
+ ```bash
101
+ cd /path/to/your/workdir
102
+ wbo --agent opencode
103
+ wbo --agent opencode --cwd D:\code\project
104
+ wbo --agent "npx opencode-ai acp"
105
+ wbo --agent opencode --daemon
106
+ ```
107
+
108
+ ## Configuration File
109
+
110
+ You can provide a JSON config file with `--config`.
111
+
112
+ Example:
113
+
114
+ ```json
115
+ {
116
+ "agent": {
117
+ "preset": "opencode",
118
+ "cwd": "D:/code/project"
119
+ },
120
+ "session": {
121
+ "idleTimeoutMs": 86400000,
122
+ "maxConcurrentUsers": 10
123
+ }
124
+ }
125
+ ```
126
+
127
+ You can also override or add agent presets:
128
+
129
+ ```json
130
+ {
131
+ "agent": {
132
+ "preset": "my-agent"
133
+ },
134
+ "agents": {
135
+ "my-agent": {
136
+ "label": "My Agent",
137
+ "description": "Internal team agent",
138
+ "command": "npx",
139
+ "args": ["my-agent-cli", "--acp"]
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Runtime Behavior
146
+
147
+ - Each WeChat user gets a dedicated ACP session and subprocess.
148
+ - Messages are processed serially per user.
149
+ - Replies are formatted for WeChat before sending.
150
+ - Typing indicators are sent when supported by the WeChat API.
151
+ - Sessions are cleaned up after inactivity (set `idleTimeoutMs` to `0` to disable idle cleanup).
152
+ - Switching workspace or session kills the old agent and spawns a new one immediately.
153
+ - OpenCode session history is resumed via `unstable_resumeSession()` when switching to an existing session.
154
+
155
+ ## WeChat Commands
156
+
157
+ Users can manage workspaces and sessions directly from WeChat:
158
+
159
+ ### Workspace (`/workspace` or `/ws`)
160
+
161
+ | Command | Description |
162
+ |---------|-------------|
163
+ | `/workspace list` | List all directories from OpenCode sessions |
164
+ | `/workspace switch <n\|path>` | Switch to directory by index or path |
165
+ | `/workspace add /path` | Add directory (creates if not exists) |
166
+ | `/workspace status` | Show current directory |
167
+
168
+ ### Session (`/session` or `/s`)
169
+
170
+ | Command | Description |
171
+ |---------|-------------|
172
+ | `/session list` | List recent 10 sessions with directory |
173
+ | `/session switch <n\|slug>` | Switch to session by index or slug |
174
+ | `/session new` | Restart session (clear context) |
175
+ | `/session status` | Show current session info |
176
+
177
+ ### Help
178
+
179
+ | Command | Description |
180
+ |---------|-------------|
181
+ | `/help` | Show all available commands |
182
+
183
+ ## Storage
184
+
185
+ By default, runtime files are stored under:
186
+
187
+ ```text
188
+ ~/.wechat-bridge-opencode
189
+ ```
190
+
191
+ This directory is used for:
192
+
193
+ - saved login token
194
+ - auth tokens
195
+ - tempfile (downloaded media)
196
+ - daemon pid file
197
+ - daemon log file
198
+ - sync state
199
+ - bridge state (`.wechat-bridge-state.json` — tracks last active user/session for the `send-wechat` tool)
200
+
201
+ ## Custom Tool: send-wechat
202
+
203
+ The `send-wechat` tool is automatically installed to `~/.config/opencode/tools/send-wechat.ts`.
204
+
205
+ This tool is available to opencode agents and lets them send files back to WeChat:
206
+
207
+ ```
208
+ send-wechat(filePath: string)
209
+ ```
210
+
211
+ The tool reads `~/.wechat-bridge-opencode/.wechat-bridge-state.json` to automatically determine the target user and session. The agent only needs to provide the file path.
212
+
213
+ ## Current Limitations
214
+
215
+ - Direct messages only; group chats are ignored
216
+ - Permission requests are auto-approved
217
+ - Some preset agents may require separate authentication before they can respond successfully
218
+
219
+ ## Development
220
+
221
+ Clone and build locally:
222
+
223
+ ```bash
224
+ git clone https://github.com/pan17/wechat-bridge-opencode.git
225
+ cd wechat-bridge-opencode
226
+ npm install
227
+ npm run build
228
+ ```
229
+
230
+ Run the CLI locally:
231
+
232
+ ```bash
233
+ node dist/bin/wechat-opencode.js --help # or simply: wbo --help
234
+ ```
235
+
236
+ Watch mode:
237
+
238
+ ```bash
239
+ npm run dev
240
+ ```
241
+
242
+ ## License
243
+
244
+ MIT
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * wechat-acp CLI entry point.
4
+ *
5
+ * Usage:
6
+ * wechat-acp --agent "claude code"
7
+ * wechat-acp --agent "gemini" --cwd /path/to/project
8
+ * wechat-acp --agent "npx tsx ./agent.ts" --login
9
+ * wechat-acp --agent "claude code" --daemon
10
+ * wechat-acp stop
11
+ * wechat-acp status
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=wechat-acp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-acp.d.ts","sourceRoot":"","sources":["../../bin/wechat-acp.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * wechat-acp CLI entry point.
4
+ *
5
+ * Usage:
6
+ * wechat-acp --agent "claude code"
7
+ * wechat-acp --agent "gemini" --cwd /path/to/project
8
+ * wechat-acp --agent "npx tsx ./agent.ts" --login
9
+ * wechat-acp --agent "claude code" --daemon
10
+ * wechat-acp stop
11
+ * wechat-acp status
12
+ */
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import { spawn } from "node:child_process";
16
+ import qrcodeTerminal from "qrcode-terminal";
17
+ import { WeChatAcpBridge } from "../src/bridge.js";
18
+ import { defaultConfig, listBuiltInAgents, resolveAgentSelection, } from "../src/config.js";
19
+ function usage() {
20
+ const presets = listBuiltInAgents()
21
+ .map(({ id }) => id)
22
+ .join(", ");
23
+ console.log(`
24
+ wechat-acp — Bridge WeChat to any ACP-compatible AI agent
25
+
26
+ Usage:
27
+ wechat-acp --agent <preset|command> [options]
28
+ wechat-acp agents List built-in agent presets
29
+ wechat-acp stop Stop a running daemon
30
+ wechat-acp status Check daemon status
31
+
32
+ Options:
33
+ --agent <value> Built-in preset name or raw agent command
34
+ Presets: ${presets}
35
+ Examples: "copilot", "claude", "npx tsx ./agent.ts"
36
+ --cwd <dir> Working directory for agent (default: current dir)
37
+ --login Force re-login (new QR code)
38
+ --daemon Run in background after login
39
+ --config <file> Config file path (JSON)
40
+ --idle-timeout <m> Session idle timeout in minutes (default: 1440)
41
+ Use 0 to disable idle cleanup
42
+ --max-sessions <n> Max concurrent user sessions (default: 10)
43
+ --show-thoughts Forward agent thinking to WeChat (default: off)
44
+ -v, --verbose Verbose logging
45
+ -h, --help Show this help
46
+ `);
47
+ }
48
+ function parseArgs(argv) {
49
+ const result = {
50
+ forceLogin: false,
51
+ daemon: false,
52
+ showThoughts: false,
53
+ verbose: false,
54
+ help: false,
55
+ };
56
+ const args = argv.slice(2);
57
+ let i = 0;
58
+ // Check for subcommand
59
+ if (args[0] && !args[0].startsWith("-")) {
60
+ result.command = args[0];
61
+ i = 1;
62
+ }
63
+ while (i < args.length) {
64
+ const arg = args[i];
65
+ switch (arg) {
66
+ case "--agent":
67
+ result.agent = args[++i];
68
+ break;
69
+ case "--cwd":
70
+ result.cwd = args[++i];
71
+ break;
72
+ case "--login":
73
+ result.forceLogin = true;
74
+ break;
75
+ case "--daemon":
76
+ result.daemon = true;
77
+ break;
78
+ case "--config":
79
+ result.configFile = args[++i];
80
+ break;
81
+ case "--idle-timeout":
82
+ result.idleTimeout = parseInt(args[++i], 10);
83
+ break;
84
+ case "--max-sessions":
85
+ result.maxSessions = parseInt(args[++i], 10);
86
+ break;
87
+ case "--show-thoughts":
88
+ result.showThoughts = true;
89
+ break;
90
+ case "-v":
91
+ case "--verbose":
92
+ result.verbose = true;
93
+ break;
94
+ case "-h":
95
+ case "--help":
96
+ result.help = true;
97
+ break;
98
+ default:
99
+ if (arg?.startsWith("-")) {
100
+ console.error(`Unknown option: ${arg}`);
101
+ process.exit(1);
102
+ }
103
+ }
104
+ i++;
105
+ }
106
+ return result;
107
+ }
108
+ function loadConfigFile(filePath) {
109
+ const content = fs.readFileSync(filePath, "utf-8");
110
+ return JSON.parse(content);
111
+ }
112
+ function handleAgents(config) {
113
+ console.log("Built-in ACP agent presets:\n");
114
+ for (const { id, preset } of listBuiltInAgents(config.agents)) {
115
+ const commandLine = [preset.command, ...preset.args].join(" ");
116
+ console.log(`${id.padEnd(10)} ${commandLine}`);
117
+ if (preset.description) {
118
+ console.log(` ${preset.description}`);
119
+ }
120
+ }
121
+ }
122
+ function handleStop(config) {
123
+ const pidFile = config.daemon.pidFile;
124
+ if (!fs.existsSync(pidFile)) {
125
+ console.log("No daemon running (no PID file found)");
126
+ return;
127
+ }
128
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
129
+ try {
130
+ process.kill(pid, "SIGTERM");
131
+ fs.unlinkSync(pidFile);
132
+ console.log(`Stopped daemon (PID ${pid})`);
133
+ }
134
+ catch (err) {
135
+ if (err.code === "ESRCH") {
136
+ fs.unlinkSync(pidFile);
137
+ console.log(`Daemon not running (stale PID ${pid}), cleaned up`);
138
+ }
139
+ else {
140
+ console.error(`Failed to stop daemon: ${String(err)}`);
141
+ }
142
+ }
143
+ }
144
+ function handleStatus(config) {
145
+ const pidFile = config.daemon.pidFile;
146
+ if (!fs.existsSync(pidFile)) {
147
+ console.log("Not running");
148
+ return;
149
+ }
150
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
151
+ try {
152
+ process.kill(pid, 0); // test if process exists
153
+ console.log(`Running (PID ${pid})`);
154
+ }
155
+ catch {
156
+ console.log(`Not running (stale PID ${pid})`);
157
+ fs.unlinkSync(pidFile);
158
+ }
159
+ }
160
+ function daemonize(config) {
161
+ const logFile = config.daemon.logFile;
162
+ const pidFile = config.daemon.pidFile;
163
+ fs.mkdirSync(path.dirname(logFile), { recursive: true });
164
+ fs.mkdirSync(path.dirname(pidFile), { recursive: true });
165
+ const out = fs.openSync(logFile, "a");
166
+ const err = fs.openSync(logFile, "a");
167
+ // Re-run ourselves with --no-daemon (internal flag) as a detached process
168
+ const args = process.argv.slice(1).filter((a) => a !== "--daemon");
169
+ const child = spawn(process.execPath, args, {
170
+ detached: true,
171
+ stdio: ["ignore", out, err],
172
+ env: { ...process.env, WECHAT_ACP_DAEMON: "1" },
173
+ });
174
+ child.unref();
175
+ fs.writeFileSync(pidFile, String(child.pid), "utf-8");
176
+ console.log(`Daemon started (PID ${child.pid})`);
177
+ console.log(`Logs: ${logFile}`);
178
+ console.log(`PID file: ${pidFile}`);
179
+ process.exit(0);
180
+ }
181
+ function renderQrInTerminal(url) {
182
+ qrcodeTerminal.generate(url, { small: true }, (qr) => {
183
+ console.log(qr);
184
+ });
185
+ }
186
+ async function main() {
187
+ const args = parseArgs(process.argv);
188
+ if (args.help) {
189
+ usage();
190
+ process.exit(0);
191
+ }
192
+ const config = defaultConfig();
193
+ // Load config file if specified
194
+ if (args.configFile) {
195
+ const fileConfig = loadConfigFile(args.configFile);
196
+ Object.assign(config.wechat, fileConfig.wechat ?? {});
197
+ Object.assign(config.agent, fileConfig.agent ?? {});
198
+ Object.assign(config.agents, fileConfig.agents ?? {});
199
+ Object.assign(config.session, fileConfig.session ?? {});
200
+ Object.assign(config.daemon, fileConfig.daemon ?? {});
201
+ Object.assign(config.storage, fileConfig.storage ?? {});
202
+ }
203
+ // Handle subcommands
204
+ if (args.command === "agents") {
205
+ handleAgents(config);
206
+ return;
207
+ }
208
+ if (args.command === "stop") {
209
+ handleStop(config);
210
+ return;
211
+ }
212
+ if (args.command === "status") {
213
+ handleStatus(config);
214
+ return;
215
+ }
216
+ const agentSelection = args.agent ?? config.agent.preset;
217
+ // Require preset or raw command
218
+ if (!agentSelection && !config.agent.command) {
219
+ console.error("Error: --agent is required\n");
220
+ usage();
221
+ process.exit(1);
222
+ }
223
+ if (agentSelection) {
224
+ const resolvedAgent = resolveAgentSelection(agentSelection, config.agents);
225
+ config.agent.preset = resolvedAgent.id;
226
+ config.agent.command = resolvedAgent.command;
227
+ config.agent.args = resolvedAgent.args;
228
+ if (resolvedAgent.env) {
229
+ config.agent.env = { ...(config.agent.env ?? {}), ...resolvedAgent.env };
230
+ }
231
+ }
232
+ if (args.cwd)
233
+ config.agent.cwd = path.resolve(args.cwd);
234
+ if (args.idleTimeout !== undefined) {
235
+ if (!Number.isFinite(args.idleTimeout) || args.idleTimeout < 0) {
236
+ console.error("Error: invalid --idle-timeout value");
237
+ console.error('Use a non-negative integer minute value, where "0" means unlimited.');
238
+ process.exit(1);
239
+ }
240
+ config.session.idleTimeoutMs = args.idleTimeout * 60_000;
241
+ }
242
+ if (args.maxSessions)
243
+ config.session.maxConcurrentUsers = args.maxSessions;
244
+ if (args.showThoughts)
245
+ config.agent.showThoughts = true;
246
+ config.daemon.enabled = args.daemon;
247
+ // Handle daemon mode
248
+ if (args.daemon && !process.env.WECHAT_ACP_DAEMON) {
249
+ daemonize(config);
250
+ return;
251
+ }
252
+ // Create and start bridge
253
+ const bridge = new WeChatAcpBridge(config, (msg) => {
254
+ const ts = new Date().toISOString().substring(11, 19);
255
+ console.log(`[${ts}] ${msg}`);
256
+ });
257
+ // Handle graceful shutdown
258
+ const shutdown = async () => {
259
+ await bridge.stop();
260
+ process.exit(0);
261
+ };
262
+ process.on("SIGINT", () => void shutdown());
263
+ process.on("SIGTERM", () => void shutdown());
264
+ try {
265
+ await bridge.start({
266
+ forceLogin: args.forceLogin,
267
+ renderQrUrl: renderQrInTerminal,
268
+ });
269
+ }
270
+ catch (err) {
271
+ if (err.message === "aborted") {
272
+ // Normal shutdown
273
+ }
274
+ else {
275
+ console.error(`Fatal: ${String(err)}`);
276
+ process.exit(1);
277
+ }
278
+ }
279
+ }
280
+ main().catch((err) => {
281
+ console.error(`Fatal: ${String(err)}`);
282
+ process.exit(1);
283
+ });
284
+ //# sourceMappingURL=wechat-acp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-acp.js","sourceRoot":"","sources":["../../bin/wechat-acp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * wechat-opencode CLI entry point.
4
+ *
5
+ * Usage:
6
+ * wechat-opencode --agent "claude code"
7
+ * wechat-opencode --agent "gemini" --cwd /path/to/project
8
+ * wechat-opencode --agent "npx tsx ./agent.ts" --login
9
+ * wechat-opencode --agent "claude code" --daemon
10
+ * wechat-opencode stop
11
+ * wechat-opencode status
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=wechat-opencode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-opencode.d.ts","sourceRoot":"","sources":["../../bin/wechat-opencode.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}