weacpx 0.1.1 → 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.
package/README.md CHANGED
@@ -1,31 +1,17 @@
1
1
  # weacpx
2
2
 
3
- 通过微信 ClawBot 远程控制通过 `acpx` 控制 Claude Code、Codex 等 Agents。
4
-
5
- ## weacpx 是什么
6
-
7
- `weacpx` 基于以下组件工作:
8
-
9
- - `weixin-agent-sdk`
10
- - `acpx`
11
- - `acpx` 已支持的 agent driver,或自定义 ACP agent
12
-
13
- 它适合这样的场景:
14
-
15
- - 你已经在本机使用 `acpx`
16
- - 你希望通过微信远程发起或继续一个 agent 会话
17
- - 你希望在手机上完成常见的会话切换、目录切换和对话操作
3
+ 使用微信 ClawBot 随时随地通过 `acpx` 控制 Claude Code、Codex 等 Agents。
18
4
 
19
5
  ## 安装前准备
20
6
 
21
7
  开始前,至少需要:
22
8
 
23
- - Node.js 22+
24
- - Bun
9
+ - Node.js 22+ 或 Bun
25
10
  - 一个可用的微信登录环境
26
- - 本机可以运行 `acpx` 及其目标 agent
11
+ - Claude Code Codex
27
12
 
28
- 正常情况下,不需要再额外全局安装 `acpx`。
13
+ > `weacpx` 基于 `weixin-agent-sdk` 与 `acpx` 实现。
14
+ > 正常情况下,不需要再额外全局安装 `acpx`。
29
15
 
30
16
  ## 安装
31
17
 
@@ -34,17 +20,10 @@
34
20
  ```bash
35
21
  # 使用 NPM 全局安装
36
22
  npm install -g weacpx
37
- # 或使用 bun 全局安装
23
+ # 或使用 Bun 全局安装
38
24
  bun add -g weacpx
39
25
  ```
40
26
 
41
- 如果你是从源码仓库直接使用,请先安装依赖并构建:
42
-
43
- ```bash
44
- bun install
45
- bun run dev
46
- ```
47
-
48
27
  ## 快速开始
49
28
 
50
29
  第一次使用建议按这个顺序:
@@ -58,19 +37,9 @@ bun run dev
58
37
  ```bash
59
38
  weacpx login
60
39
  weacpx start
61
- weacpx status
62
40
  ```
63
41
 
64
- 如果你是在仓库里本地运行:
65
-
66
- ```bash
67
- bun run login
68
- bun run dev
69
- ```
70
-
71
- `weacpx login` 和 `bun run login` 都会在终端里显示二维码。
72
-
73
- 启动后,在微信里先发:
42
+ `weacpx login` 会在终端里显示二维码,使用微信扫描登录。`weacpx start` 启动后,在微信里发:
74
43
 
75
44
  ```text
76
45
  /ss codex -d /absolute/path/to/your/repo
@@ -78,8 +47,9 @@ bun run dev
78
47
  /help
79
48
  ```
80
49
 
81
- 第一行的意思是:开启或挂在一个会话,并切换到该会话。使用 Codex,并指定工作目录为 `/absolute/path/to/your/repo`。
82
- 第二行的意思是:查看帮助信息。
50
+ `/ss codex -d /absolute/path/to/your/repo`:开启或挂在一个会话,并切换到该会话。使用 Codex,并指定工作目录为 `/absolute/path/to/your/repo`。
51
+
52
+ `/help` 查看帮助信息。
83
53
 
84
54
  然后就可以直接发普通消息,例如:
85
55
 
@@ -87,6 +57,17 @@ bun run dev
87
57
  hello
88
58
  ```
89
59
 
60
+ 如果你是从源码仓库直接使用:
61
+
62
+ ```bash
63
+ # 先安装依赖
64
+ bun install
65
+ # 登录微信
66
+ bun run login
67
+ # 启动服务
68
+ bun run dev
69
+ ```
70
+
90
71
  普通文本会默认发送到当前选中的 session。
91
72
 
92
73
  ## CLI 命令
@@ -106,27 +87,55 @@ hello
106
87
  - `status` 查看后台状态、PID、配置路径和日志路径
107
88
  - `stop` 停止后台实例
108
89
 
109
- ## 微信中如何使用
90
+ ## 微信中使用说明
110
91
 
111
- ### Agent
92
+ ### 管理 Agent
112
93
 
113
- 内置 `codex` 与 `claude` 两个常见模板,也支持添加你自己的 agent。
94
+ 内置 `codex` 与 `claude` 两个常见 agent,也支持添加你自己的 agents
114
95
 
115
- - `/agents` 查看当前已添加的 agent
116
- - `/agent add codex` 添加 codex agent
117
- - `/agent add claude` 添加 claude agent
118
- - `/agent rm <name>` 删除 agent
96
+ | 命令 | 说明 |
97
+ |------|------|
98
+ | `/agents` | 查看当前已添加的 agent |
99
+ | `/agent add codex` | 添加 codex agent |
100
+ | `/agent add claude` | 添加 claude agent |
101
+ | `/agent rm <name>` | 删除 agent |
119
102
 
120
103
  说明:
121
104
 
122
105
  - 内置 `codex` 和 `claude` 走 `acpx` 的 driver alias,通常不需要额外写 `agent.command`
123
106
  - 如果你接入的是自定义 agent,再考虑显式配置 `agent.command`
124
107
 
108
+ `config.json` 中的 `agent.command` 用于显式指定 agent 的原始启动命令,完整字段如下:
109
+
110
+ | 字段 | 类型 | 必填 | 说明 |
111
+ |------|------|------|------|
112
+ | `driver` | `string` | 是 | agent 驱动类型,传递给 acpx 的第一位置参数 |
113
+ | `command` | `string` | 否 | 显式指定自定义 agent 的原始命令。不填则使用 acpx 默认行为 |
114
+
115
+ 示例 — 配置一个自定义 agent:
116
+
117
+ ```json
118
+ {
119
+ "agents": {
120
+ "my-agent": {
121
+ "driver": "codex",
122
+ "command": "/path/to/acpx codex --arg1 value1"
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ - 内置 `codex` 和 `claude` 建议只写 `driver`,让 `acpx` 自己解析对应 alias
129
+ - `command` 主要用于自定义 agent,不建议给内置 driver 手写原始命令
130
+ - 旧版 `codex` raw command 配置会被自动忽略,回退为 `acpx codex ...`
131
+
125
132
  ### Workspace 工作目录
126
133
 
127
- - `/workspaces` `/workspace` 或 `/ws` 可查看当前已添加的工作目录
128
- - `/ws new <name> -d <path>` 添加工作目录,`-d` 后面接的是目录在电脑的绝对路径
129
- - `/workspace rm <name>` 删除工作目录
134
+ | 命令 | 说明 |
135
+ |------|------|
136
+ | `/workspaces` / `/workspace` / `/ws` | 查看当前已添加的工作目录 |
137
+ | `/ws new <name> -d <path>` | 添加工作目录,`-d` 后面接的是目录在电脑的绝对路径 |
138
+ | `/workspace rm <name>` | 删除工作目录 |
130
139
 
131
140
  说明:
132
141
 
@@ -135,15 +144,17 @@ hello
135
144
 
136
145
  ### Session 会话
137
146
 
138
- - `/sessions` `/session` 或 `/ss` 可查看当前已添加的会话
139
- - `/ss <agent> -d <path>` 新建会话,会自动按目录名推导并创建或复用 workspace,再创建或复用 session
140
- - `/ss new <agent> -d <path>` 强制新建会话
141
- - `/ss new <alias> -a <name> --ws <name>` 强制新建会话,并指定 agent 和 workspace
142
- - `/ss attach <alias> -a <name> --ws <name> --name <transport-session>` 恢复已存在的会话
143
- - `/use <alias>` 切换当前会话
144
- - `/status` 查看当前会话状态
145
- - `/cancel` 取消当前会话
146
- - `/stop` 停止当前会话
147
+ | 命令 | 说明 |
148
+ |------|------|
149
+ | `/sessions` / `/session` / `/ss` | 查看当前已添加的会话 |
150
+ | `/ss <agent> -d <path>` | 新建会话(自动按目录名推导并创建或复用 workspace,再创建或复用 session) |
151
+ | `/ss new <agent> -d <path>` | 强制新建会话 |
152
+ | `/ss new <alias> -a <name> --ws <name>` | 强制新建会话,并指定 agent 和 workspace |
153
+ | `/ss attach <alias> -a <name> --ws <name> --name <transport-session>` | 恢复已存在的会话 |
154
+ | `/use <alias>` | 切换当前会话 |
155
+ | `/status` | 查看当前会话状态 |
156
+ | `/cancel` | 取消当前会话 |
157
+ | `/stop` | 停止当前会话 |
147
158
 
148
159
  说明:
149
160
 
@@ -28,6 +28,21 @@ var __export = (target, all) => {
28
28
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
30
 
31
+ // src/process/spawn-command.ts
32
+ function resolveSpawnCommand(command, args) {
33
+ if (SCRIPT_FILE_PATTERN.test(command)) {
34
+ return {
35
+ command: process.execPath,
36
+ args: [command, ...args]
37
+ };
38
+ }
39
+ return { command, args };
40
+ }
41
+ var SCRIPT_FILE_PATTERN;
42
+ var init_spawn_command = __esm(() => {
43
+ SCRIPT_FILE_PATTERN = /\.(c|m)?js$/i;
44
+ });
45
+
31
46
  // src/bridge/bridge-main.ts
32
47
  import { createInterface } from "node:readline";
33
48
 
@@ -108,6 +123,7 @@ function asOptionalString(value) {
108
123
  }
109
124
 
110
125
  // src/bridge/bridge-runtime.ts
126
+ init_spawn_command();
111
127
  import { spawn } from "node:child_process";
112
128
  import { fileURLToPath } from "node:url";
113
129
 
@@ -121,46 +137,57 @@ class BridgeRuntime {
121
137
  this.runSessionCreate = runSessionCreate;
122
138
  }
123
139
  async hasSession(input) {
124
- const result = await this.run(this.command, this.buildSessionArgs(input, [
140
+ const spawnSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, [
125
141
  "sessions",
126
142
  "show",
127
143
  input.name
128
144
  ]));
145
+ const result = await this.run(spawnSpec.command, spawnSpec.args);
129
146
  return { exists: result.code === 0 };
130
147
  }
131
148
  async ensureSession(input) {
132
- const ensured = await this.run(this.command, this.buildSessionArgs(input, ["sessions", "ensure", "--name", input.name]));
149
+ const ensuredSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, [
150
+ "sessions",
151
+ "ensure",
152
+ "--name",
153
+ input.name
154
+ ]));
155
+ const ensured = await this.run(ensuredSpec.command, ensuredSpec.args);
133
156
  if (ensured.code === 0) {
134
157
  return {};
135
158
  }
136
- const existing = await this.run(this.command, this.buildSessionArgs(input, ["sessions", "show", input.name]));
159
+ const existingSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, ["sessions", "show", input.name]));
160
+ const existing = await this.run(existingSpec.command, existingSpec.args);
137
161
  if (existing.code === 0) {
138
162
  return {};
139
163
  }
140
- const createdWithHelper = await this.runSessionCreate(this.command, this.buildSessionArgs(input, ["sessions", "new", "--name", input.name]), input.cwd);
164
+ const createSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, ["sessions", "new", "--name", input.name]));
165
+ const createdWithHelper = await this.runSessionCreate(createSpec.command, createSpec.args, input.cwd);
141
166
  if (createdWithHelper.code !== 0) {
142
167
  throw new Error(createdWithHelper.stderr || createdWithHelper.stdout || ensured.stderr || ensured.stdout || "failed to create session");
143
168
  }
144
169
  return {};
145
170
  }
146
171
  async prompt(input) {
147
- const result = await this.run(this.command, this.buildSessionArgs(input, [
172
+ const spawnSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, [
148
173
  "prompt",
149
174
  "-s",
150
175
  input.name,
151
176
  input.text
152
177
  ]));
178
+ const result = await this.run(spawnSpec.command, spawnSpec.args);
153
179
  if (result.code !== 0) {
154
180
  throw new Error(result.stderr || result.stdout || "prompt failed");
155
181
  }
156
182
  return { text: result.stdout.trim() };
157
183
  }
158
184
  async cancel(input) {
159
- const result = await this.run(this.command, this.buildSessionArgs(input, [
185
+ const spawnSpec = resolveSpawnCommand(this.command, this.buildSessionArgs(input, [
160
186
  "cancel",
161
187
  "-s",
162
188
  input.name
163
189
  ]));
190
+ const result = await this.run(spawnSpec.command, spawnSpec.args);
164
191
  if (result.code !== 0) {
165
192
  throw new Error(result.stderr || result.stdout || "cancel failed");
166
193
  }
package/dist/cli.js CHANGED
@@ -2108,7 +2108,7 @@ var init_ensure_config = __esm(() => {
2108
2108
 
2109
2109
  // src/config/resolve-acpx-command.ts
2110
2110
  import { readFileSync } from "node:fs";
2111
- import { dirname as dirname6, resolve } from "node:path";
2111
+ import { posix, win32 } from "node:path";
2112
2112
  import { createRequire as createRequire2 } from "node:module";
2113
2113
  function resolveAcpxCommand(options = {}) {
2114
2114
  if (options.configuredCommand) {
@@ -2120,12 +2120,11 @@ function resolveAcpxCommand(options = {}) {
2120
2120
  try {
2121
2121
  const packageJsonPath = resolvePackageJson("acpx/package.json");
2122
2122
  const pkg = readPackageJson(packageJsonPath);
2123
+ const pathApi = platform === "win32" ? win32 : posix;
2124
+ const packageDir = pathApi.dirname(packageJsonPath);
2123
2125
  const binPath = typeof pkg.bin === "string" ? pkg.bin : pkg.bin && typeof pkg.bin.acpx === "string" ? pkg.bin.acpx : null;
2124
2126
  if (binPath) {
2125
- if (platform === "win32") {
2126
- return resolve(dirname6(packageJsonPath), "../.bin/acpx.exe");
2127
- }
2128
- return resolve(dirname6(packageJsonPath), binPath);
2127
+ return pathApi.resolve(packageDir, binPath);
2129
2128
  }
2130
2129
  } catch {}
2131
2130
  return "acpx";
@@ -2275,7 +2274,7 @@ function createEmptyState() {
2275
2274
 
2276
2275
  // src/state/state-store.ts
2277
2276
  import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
2278
- import { dirname as dirname7 } from "node:path";
2277
+ import { dirname as dirname6 } from "node:path";
2279
2278
 
2280
2279
  class StateStore {
2281
2280
  path;
@@ -2297,7 +2296,7 @@ class StateStore {
2297
2296
  }
2298
2297
  }
2299
2298
  async save(state) {
2300
- await mkdir7(dirname7(this.path), { recursive: true });
2299
+ await mkdir7(dirname6(this.path), { recursive: true });
2301
2300
  await writeFile5(this.path, JSON.stringify(state, null, 2));
2302
2301
  }
2303
2302
  }
@@ -2355,8 +2354,8 @@ class AcpxBridgeClient {
2355
2354
  request(method, params) {
2356
2355
  const id = String(this.nextId);
2357
2356
  this.nextId += 1;
2358
- return awaitable((resolve2, reject) => {
2359
- this.pending.set(id, { resolve: resolve2, reject });
2357
+ return awaitable((resolve, reject) => {
2358
+ this.pending.set(id, { resolve, reject });
2360
2359
  this.writeLine(encodeBridgeRequest({
2361
2360
  id,
2362
2361
  method,
@@ -2432,8 +2431,8 @@ async function spawnAcpxBridgeClient(options = {}) {
2432
2431
  return client;
2433
2432
  }
2434
2433
  function awaitable(executor) {
2435
- return new Promise((resolve2, reject) => {
2436
- executor(resolve2, reject);
2434
+ return new Promise((resolve, reject) => {
2435
+ executor(resolve, reject);
2437
2436
  });
2438
2437
  }
2439
2438
  var init_acpx_bridge_client = () => {};
@@ -2476,14 +2475,29 @@ class AcpxBridgeTransport {
2476
2475
  }
2477
2476
  }
2478
2477
 
2478
+ // src/process/spawn-command.ts
2479
+ function resolveSpawnCommand(command, args) {
2480
+ if (SCRIPT_FILE_PATTERN.test(command)) {
2481
+ return {
2482
+ command: process.execPath,
2483
+ args: [command, ...args]
2484
+ };
2485
+ }
2486
+ return { command, args };
2487
+ }
2488
+ var SCRIPT_FILE_PATTERN;
2489
+ var init_spawn_command = __esm(() => {
2490
+ SCRIPT_FILE_PATTERN = /\.(c|m)?js$/i;
2491
+ });
2492
+
2479
2493
  // src/transport/acpx-cli/node-pty-helper.ts
2480
2494
  import { chmod as chmodFs } from "node:fs/promises";
2481
- import { dirname as dirname8, join as join3 } from "node:path";
2495
+ import { dirname as dirname7, join as join3 } from "node:path";
2482
2496
  function resolveNodePtyHelperPath(packageJsonPath, platform, arch) {
2483
2497
  if (platform === "win32") {
2484
2498
  return null;
2485
2499
  }
2486
- return join3(dirname8(packageJsonPath), "prebuilds", `${platform}-${arch}`, "spawn-helper");
2500
+ return join3(dirname7(packageJsonPath), "prebuilds", `${platform}-${arch}`, "spawn-helper");
2487
2501
  }
2488
2502
  async function ensureNodePtyHelperExecutable(helperPath, chmod = chmodFs) {
2489
2503
  if (!helperPath) {
@@ -2505,8 +2519,9 @@ import { createRequire as createRequire3 } from "node:module";
2505
2519
  import { spawn as spawn3 } from "node:child_process";
2506
2520
  import { spawn as spawnPty } from "node-pty";
2507
2521
  async function defaultRunner(command, args, options) {
2508
- return await new Promise((resolve2, reject) => {
2509
- const child = spawn3(command, args, { stdio: ["ignore", "pipe", "pipe"] });
2522
+ return await new Promise((resolve, reject) => {
2523
+ const spawnSpec = resolveSpawnCommand(command, args);
2524
+ const child = spawn3(spawnSpec.command, spawnSpec.args, { stdio: ["ignore", "pipe", "pipe"] });
2510
2525
  let stdout = "";
2511
2526
  let stderr = "";
2512
2527
  const timeoutId = options?.timeoutMs ? setTimeout(() => {
@@ -2527,15 +2542,16 @@ async function defaultRunner(command, args, options) {
2527
2542
  child.on("close", (code) => {
2528
2543
  if (timeoutId)
2529
2544
  clearTimeout(timeoutId);
2530
- resolve2({ code: code ?? 1, stdout, stderr });
2545
+ resolve({ code: code ?? 1, stdout, stderr });
2531
2546
  });
2532
2547
  });
2533
2548
  }
2534
2549
  async function defaultPtyRunner(command, args, options) {
2535
2550
  const helperPath = resolveNodePtyHelperPath(require3.resolve("node-pty/package.json"), process.platform, process.arch);
2536
2551
  await ensureNodePtyHelperExecutable(helperPath);
2537
- return await new Promise((resolve2, reject) => {
2538
- const child = spawnPty(command, args, {
2552
+ return await new Promise((resolve, reject) => {
2553
+ const spawnSpec = resolveSpawnCommand(command, args);
2554
+ const child = spawnPty(spawnSpec.command, spawnSpec.args, {
2539
2555
  name: "xterm-color",
2540
2556
  cols: 80,
2541
2557
  rows: 24,
@@ -2553,7 +2569,7 @@ async function defaultPtyRunner(command, args, options) {
2553
2569
  child.onExit(({ exitCode }) => {
2554
2570
  if (timeoutId)
2555
2571
  clearTimeout(timeoutId);
2556
- resolve2({ code: exitCode, stdout: output, stderr: "" });
2572
+ resolve({ code: exitCode, stdout: output, stderr: "" });
2557
2573
  });
2558
2574
  });
2559
2575
  }
@@ -2624,12 +2640,13 @@ class AcpxCliTransport {
2624
2640
  return result.stdout;
2625
2641
  }
2626
2642
  async runCommandWithTimeout(runner, args, options) {
2643
+ const spawnSpec = resolveSpawnCommand(this.command, args);
2627
2644
  if (!options?.timeoutMs) {
2628
- return await runner(this.command, args, undefined);
2645
+ return await runner(spawnSpec.command, spawnSpec.args, undefined);
2629
2646
  }
2630
2647
  let timeoutId;
2631
2648
  return await Promise.race([
2632
- runner(this.command, args, options).finally(() => {
2649
+ runner(spawnSpec.command, spawnSpec.args, options).finally(() => {
2633
2650
  if (timeoutId)
2634
2651
  clearTimeout(timeoutId);
2635
2652
  }),
@@ -2754,6 +2771,7 @@ function extractJsonRpcErrorMessages(output) {
2754
2771
  }
2755
2772
  var require3;
2756
2773
  var init_acpx_cli_transport = __esm(() => {
2774
+ init_spawn_command();
2757
2775
  init_node_pty_helper();
2758
2776
  require3 = createRequire3(import.meta.url);
2759
2777
  });
@@ -2766,7 +2784,7 @@ __export(exports_main, {
2766
2784
  buildApp: () => buildApp
2767
2785
  });
2768
2786
  import { homedir } from "node:os";
2769
- import { dirname as dirname9, join as join4 } from "node:path";
2787
+ import { dirname as dirname8, join as join4 } from "node:path";
2770
2788
  import { fileURLToPath as fileURLToPath2 } from "node:url";
2771
2789
  async function buildApp(paths, deps = {}) {
2772
2790
  await ensureConfigExists(paths.configPath);
@@ -2842,7 +2860,7 @@ function resolveBridgeEntryPath() {
2842
2860
  return fileURLToPath2(new URL("./bridge/bridge-main.ts", import.meta.url));
2843
2861
  }
2844
2862
  function resolveAppLogPath(configPath) {
2845
- const rootDir = dirname9(configPath);
2863
+ const rootDir = dirname8(configPath);
2846
2864
  const runtimeDir = join4(rootDir, "runtime");
2847
2865
  return join4(runtimeDir, "app.log");
2848
2866
  }
@@ -2911,18 +2929,10 @@ class DaemonController {
2911
2929
  paths;
2912
2930
  deps;
2913
2931
  statusStore;
2914
- startupPollIntervalMs;
2915
- startupTimeoutMs;
2916
- onStartupPoll;
2917
2932
  constructor(paths, deps) {
2918
2933
  this.paths = paths;
2919
2934
  this.deps = deps;
2920
2935
  this.statusStore = new DaemonStatusStore(paths.statusFile);
2921
- this.startupPollIntervalMs = deps.startupPollIntervalMs ?? 50;
2922
- this.startupTimeoutMs = deps.startupTimeoutMs ?? 5000;
2923
- this.onStartupPoll = deps.onStartupPoll ?? (async () => {
2924
- await new Promise((resolve) => setTimeout(resolve, this.startupPollIntervalMs));
2925
- });
2926
2936
  }
2927
2937
  async getStatus() {
2928
2938
  const pid = await this.loadPid();
@@ -2948,10 +2958,8 @@ class DaemonController {
2948
2958
  if (current.state === "running") {
2949
2959
  return { state: "already-running", pid: current.pid };
2950
2960
  }
2951
- await this.statusStore.clear();
2952
2961
  const pid = await this.deps.spawnDetached();
2953
2962
  await this.writePid(pid);
2954
- await this.waitForStartupMetadata(pid);
2955
2963
  return { state: "started", pid };
2956
2964
  }
2957
2965
  async stop() {
@@ -2986,21 +2994,6 @@ class DaemonController {
2986
2994
  await rm2(this.paths.pidFile, { force: true });
2987
2995
  await this.statusStore.clear();
2988
2996
  }
2989
- async waitForStartupMetadata(pid) {
2990
- const deadline = Date.now() + this.startupTimeoutMs;
2991
- while (Date.now() < deadline) {
2992
- const status = await this.statusStore.load();
2993
- if (status?.pid === pid) {
2994
- return;
2995
- }
2996
- if (!this.deps.isProcessRunning(pid)) {
2997
- await this.clearRuntimeFiles();
2998
- throw new Error(`weacpx daemon exited before reporting ready state (pid ${pid})`);
2999
- }
3000
- await this.onStartupPoll();
3001
- }
3002
- throw new Error(`weacpx daemon did not report ready state within ${this.startupTimeoutMs}ms (pid ${pid})`);
3003
- }
3004
2997
  }
3005
2998
 
3006
2999
  // src/daemon/create-daemon-controller.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weacpx",
3
3
  "description": "用微信远程控制 `acpx` 会话的控制台, 底层基于 `weixin-agent-sdk` 与 `acpx`",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "main": "index.js",
6
6
  "directories": {
7
7
  "doc": "docs",