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,284 @@
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
+ 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 { WeChatOpencodeBridge } 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-opencode — Bridge WeChat to any ACP-compatible AI agent
25
+
26
+ Usage:
27
+ wechat-opencode --agent <preset|command> [options]
28
+ wechat-opencode agents List built-in agent presets
29
+ wechat-opencode stop Stop a running daemon
30
+ wechat-opencode 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_OPENCODE_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_OPENCODE_DAEMON) {
249
+ daemonize(config);
250
+ return;
251
+ }
252
+ // Create and start bridge
253
+ const bridge = new WeChatOpencodeBridge(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-opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-opencode.js","sourceRoot":"","sources":["../../bin/wechat-opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "wechat-bridge-opencode",
3
+ "version": "0.1.2",
4
+ "description": "Bridge WeChat to any Opencode",
5
+ "type": "module",
6
+ "files": [
7
+ "dist/",
8
+ ".opencode/tools/send-wechat.ts",
9
+ "scripts/install-tool.mjs",
10
+ "README.md",
11
+ "package.json"
12
+ ],
13
+ "bin": {
14
+ "wbo": "dist/bin/wechat-opencode.js"
15
+ },
16
+ "main": "./dist/src/index.js",
17
+ "types": "./dist/src/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/src/index.js",
21
+ "types": "./dist/src/index.d.ts"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "prepack": "npm run build",
27
+ "start": "node dist/bin/wechat-opencode.js",
28
+ "dev": "tsc --watch",
29
+ "postinstall": "node scripts/install-tool.mjs"
30
+ },
31
+ "dependencies": {
32
+ "@agentclientprotocol/sdk": "^0.16.1",
33
+ "better-sqlite3": "^12.8.0",
34
+ "qrcode-terminal": "^0.12.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/better-sqlite3": "^7.6.13",
38
+ "@types/node": "^22.0.0",
39
+ "typescript": "^5.5.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=20.0.0"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/pan17/wechat-opencode.git"
47
+ },
48
+ "homepage": "https://github.com/pan17/wechat-opencode#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/pan17/wechat-opencode/issues"
51
+ },
52
+ "license": "MIT",
53
+ "keywords": [
54
+ "wechat",
55
+ "opencode",
56
+ "agent-client-protocol",
57
+ "ai-agent",
58
+ "bridge"
59
+ ]
60
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Spawn and manage ACP agent subprocesses.
3
+ */
4
+ import { type ChildProcess } from "node:child_process";
5
+ import * as acp from "@agentclientprotocol/sdk";
6
+ import type { WeChatAcpClient } from "./client.js";
7
+ export interface AgentProcessInfo {
8
+ process: ChildProcess;
9
+ connection: acp.ClientSideConnection;
10
+ sessionId: string;
11
+ }
12
+ export declare function spawnAgent(params: {
13
+ command: string;
14
+ args: string[];
15
+ cwd: string;
16
+ env?: Record<string, string>;
17
+ client: WeChatAcpClient;
18
+ log: (msg: string) => void;
19
+ /** Existing OpenCode session ID to resume */
20
+ existingSessionId?: string;
21
+ }): Promise<AgentProcessInfo>;
22
+ export declare function killAgent(proc: ChildProcess): void;
23
+ //# sourceMappingURL=agent-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-manager.d.ts","sourceRoot":"","sources":["../../../src/acp/agent-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuBnD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,GAAG,CAAC,oBAAoB,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,eAAe,CAAC;IACxB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmG5B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAQlD"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Spawn and manage ACP agent subprocesses.
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ import { Writable, Readable } from "node:stream";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ import fs from "node:fs";
9
+ import * as acp from "@agentclientprotocol/sdk";
10
+ import packageJson from "../../package.json" with { type: "json" };
11
+ /**
12
+ * Resolve the global opencode config path.
13
+ * Priority: OPENCODE_CONFIG env > ~/.config/opencode/opencode.json
14
+ */
15
+ function resolveOpencodeConfig() {
16
+ if (process.env.OPENCODE_CONFIG)
17
+ return process.env.OPENCODE_CONFIG;
18
+ const candidates = [
19
+ path.join(os.homedir(), ".config", "opencode", "opencode.json"),
20
+ path.join(os.homedir(), ".config", "opencode", "opencode.jsonc"),
21
+ ];
22
+ for (const p of candidates) {
23
+ try {
24
+ fs.accessSync(p);
25
+ return p;
26
+ }
27
+ catch {
28
+ // not found
29
+ }
30
+ }
31
+ return undefined;
32
+ }
33
+ export async function spawnAgent(params) {
34
+ const { command, args, cwd, env, client, log, existingSessionId } = params;
35
+ // On Windows, shell mode avoids EINVAL/ENOENT for command shims like npx/claude/gemini.
36
+ const useShell = process.platform === "win32";
37
+ log(`Spawning agent: ${command} ${args.join(" ")} (cwd: ${cwd}, shell=${useShell})`);
38
+ // Resolve opencode config path to ensure global config (with plugins) is loaded
39
+ const opencodeConfig = resolveOpencodeConfig();
40
+ const rawEnv = { ...process.env, ...env };
41
+ const mergedEnv = {};
42
+ for (const [k, v] of Object.entries(rawEnv)) {
43
+ if (v !== undefined)
44
+ mergedEnv[k] = v;
45
+ }
46
+ if (opencodeConfig && !mergedEnv.OPENCODE_CONFIG) {
47
+ mergedEnv.OPENCODE_CONFIG = opencodeConfig;
48
+ }
49
+ if (opencodeConfig && !mergedEnv.OPENCODE_CONFIG) {
50
+ mergedEnv.OPENCODE_CONFIG = opencodeConfig;
51
+ }
52
+ const proc = spawn(command, args, {
53
+ stdio: ["pipe", "pipe", "inherit"],
54
+ cwd,
55
+ env: mergedEnv,
56
+ shell: useShell,
57
+ });
58
+ proc.on("error", (err) => {
59
+ log(`Agent process error: ${String(err)}`);
60
+ });
61
+ proc.on("exit", (code, signal) => {
62
+ log(`Agent process exited: code=${code} signal=${signal}`);
63
+ });
64
+ if (!proc.stdin || !proc.stdout) {
65
+ proc.kill();
66
+ throw new Error("Failed to get agent process stdio");
67
+ }
68
+ const input = Writable.toWeb(proc.stdin);
69
+ const output = Readable.toWeb(proc.stdout);
70
+ const stream = acp.ndJsonStream(input, output);
71
+ const connection = new acp.ClientSideConnection(() => client, stream);
72
+ // Initialize
73
+ log("Initializing ACP connection...");
74
+ const initResult = await connection.initialize({
75
+ protocolVersion: acp.PROTOCOL_VERSION,
76
+ clientInfo: {
77
+ name: packageJson.name,
78
+ title: packageJson.name,
79
+ version: packageJson.version,
80
+ },
81
+ clientCapabilities: {
82
+ fs: {
83
+ readTextFile: true,
84
+ writeTextFile: true,
85
+ },
86
+ },
87
+ });
88
+ log(`ACP initialized (protocol v${initResult.protocolVersion})`);
89
+ // Create or resume session
90
+ let sessionResult;
91
+ if (existingSessionId) {
92
+ log(`Resuming ACP session: ${existingSessionId}`);
93
+ try {
94
+ sessionResult = await connection.unstable_resumeSession({
95
+ sessionId: existingSessionId,
96
+ cwd,
97
+ mcpServers: [],
98
+ });
99
+ log(`ACP session resumed: ${sessionResult.sessionId}`);
100
+ }
101
+ catch (err) {
102
+ log(`Failed to resume session ${existingSessionId}: ${String(err)}, creating new one`);
103
+ sessionResult = await connection.newSession({
104
+ cwd,
105
+ mcpServers: [],
106
+ });
107
+ log(`ACP session created (fallback): ${sessionResult.sessionId}`);
108
+ }
109
+ }
110
+ else {
111
+ log("Creating ACP session...");
112
+ sessionResult = await connection.newSession({
113
+ cwd,
114
+ mcpServers: [],
115
+ });
116
+ log(`ACP session created: ${sessionResult.sessionId}`);
117
+ }
118
+ return {
119
+ process: proc,
120
+ connection,
121
+ sessionId: sessionResult.sessionId,
122
+ };
123
+ }
124
+ export function killAgent(proc) {
125
+ if (!proc.killed) {
126
+ proc.kill("SIGTERM");
127
+ // Force kill after 5s if still alive
128
+ setTimeout(() => {
129
+ if (!proc.killed)
130
+ proc.kill("SIGKILL");
131
+ }, 5_000).unref();
132
+ }
133
+ }
134
+ //# sourceMappingURL=agent-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../../src/acp/agent-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * ACP Client implementation for WeChat.
3
+ *
4
+ * Implements the acp.Client interface: handles session updates (accumulates
5
+ * text chunks), auto-allows all permission requests, and provides filesystem
6
+ * access for the agent.
7
+ */
8
+ import type * as acp from "@agentclientprotocol/sdk";
9
+ export interface MediaContent {
10
+ type: "image" | "resource";
11
+ data?: string;
12
+ mimeType?: string;
13
+ uri?: string;
14
+ blob?: string;
15
+ resourceMimeType?: string;
16
+ fileName?: string;
17
+ }
18
+ export interface WeChatAcpClientOpts {
19
+ sendTyping: () => Promise<void>;
20
+ onThoughtFlush: (text: string) => Promise<void>;
21
+ onMediaFlush: (blocks: MediaContent[]) => Promise<void>;
22
+ log: (msg: string) => void;
23
+ showThoughts: boolean;
24
+ }
25
+ export declare class WeChatAcpClient implements acp.Client {
26
+ private chunks;
27
+ private thoughtChunks;
28
+ private mediaBlocks;
29
+ private opts;
30
+ private lastTypingAt;
31
+ private static readonly TYPING_INTERVAL_MS;
32
+ constructor(opts: WeChatAcpClientOpts);
33
+ updateCallbacks(callbacks: {
34
+ sendTyping: () => Promise<void>;
35
+ onThoughtFlush: (text: string) => Promise<void>;
36
+ onMediaFlush: (blocks: MediaContent[]) => Promise<void>;
37
+ }): void;
38
+ requestPermission(params: acp.RequestPermissionRequest): Promise<acp.RequestPermissionResponse>;
39
+ sessionUpdate(params: acp.SessionNotification): Promise<void>;
40
+ readTextFile(params: acp.ReadTextFileRequest): Promise<acp.ReadTextFileResponse>;
41
+ writeTextFile(params: acp.WriteTextFileRequest): Promise<acp.WriteTextFileResponse>;
42
+ /** Get accumulated text and reset the buffer. Also flushes any remaining thoughts. */
43
+ flush(): Promise<string>;
44
+ /** Flush media blocks via callback and reset. */
45
+ private flushMedia;
46
+ private maybeFlushThoughts;
47
+ private maybeSendTyping;
48
+ }
49
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/acp/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAE3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,YAAY,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,eAAgB,YAAW,GAAG,CAAC,MAAM;IAChD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAEvC,IAAI,EAAE,mBAAmB;IAIrC,eAAe,CAAC,SAAS,EAAE;QACzB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,YAAY,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACzD,GAAG,IAAI;IASF,iBAAiB,CACrB,MAAM,EAAE,GAAG,CAAC,wBAAwB,GACnC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;IAiBnC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+G7D,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAShF,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IASzF,sFAAsF;IAChF,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAe9B,iDAAiD;YACnC,UAAU;YASV,kBAAkB;YAalB,eAAe;CAU9B"}