weapp-ide-cli 5.0.3 → 5.1.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.
@@ -1,568 +0,0 @@
1
- // src/logger.ts
2
- import logger, { colors } from "@weapp-core/logger";
3
- var logger_default = logger;
4
-
5
- // src/utils/path.ts
6
- import process from "process";
7
- import path from "pathe";
8
- function resolvePath(filePath) {
9
- if (path.isAbsolute(filePath)) {
10
- return filePath;
11
- }
12
- return path.resolve(process.cwd(), filePath);
13
- }
14
-
15
- // src/utils/argv.ts
16
- import process2 from "process";
17
- function ensurePathArgument(argv, optionIndex) {
18
- const paramIdx = optionIndex + 1;
19
- const param = argv[paramIdx];
20
- if (param && !param.startsWith("-")) {
21
- argv[paramIdx] = resolvePath(param);
22
- } else {
23
- argv.splice(paramIdx, 0, process2.cwd());
24
- }
25
- return argv;
26
- }
27
- function transformArgv(argv, transforms) {
28
- return transforms.reduce((current, transform) => transform(current), [
29
- ...argv
30
- ]);
31
- }
32
- function createAlias(entry) {
33
- return (input2) => {
34
- const argv = [...input2];
35
- let optionIndex = argv.indexOf(entry.find);
36
- if (optionIndex > -1) {
37
- argv.splice(optionIndex, 1, entry.replacement);
38
- } else {
39
- optionIndex = argv.indexOf(entry.replacement);
40
- }
41
- if (optionIndex === -1) {
42
- return argv;
43
- }
44
- return ensurePathArgument(argv, optionIndex);
45
- };
46
- }
47
- function createPathCompat(option) {
48
- return (input2) => {
49
- const argv = [...input2];
50
- const optionIndex = argv.indexOf(option);
51
- if (optionIndex === -1) {
52
- return argv;
53
- }
54
- return ensurePathArgument(argv, optionIndex);
55
- };
56
- }
57
-
58
- // src/utils/exec.ts
59
- import process3 from "process";
60
- async function execute(cliPath, argv, options = {}) {
61
- const {
62
- pipeStdout = true,
63
- pipeStderr = true
64
- } = options;
65
- const { execa } = await import("execa");
66
- const task = execa(cliPath, argv);
67
- if (pipeStdout) {
68
- task?.stdout?.pipe(process3.stdout);
69
- }
70
- if (pipeStderr) {
71
- task?.stderr?.pipe(process3.stderr);
72
- }
73
- return await task;
74
- }
75
-
76
- // src/cli/minidev.ts
77
- var MINIDEV_COMMAND = "minidev";
78
- function isCommandNotFound(error) {
79
- return Boolean(
80
- error && typeof error === "object" && "code" in error && error.code === "ENOENT"
81
- );
82
- }
83
- async function runMinidev(argv) {
84
- try {
85
- await execute(MINIDEV_COMMAND, [...argv]);
86
- } catch (error) {
87
- if (isCommandNotFound(error)) {
88
- logger_default.error("\u672A\u68C0\u6D4B\u5230\u652F\u4ED8\u5B9D\u5C0F\u7A0B\u5E8F CLI\uFF1Aminidev");
89
- logger_default.warn("\u8BF7\u5148\u5B89\u88C5 minidev\uFF0C\u53EF\u4F7F\u7528\u4EE5\u4E0B\u4EFB\u4E00\u547D\u4EE4\uFF1A");
90
- logger_default.info(`- ${colors.green("pnpm add -g minidev")}`);
91
- logger_default.info(`- ${colors.green("npm install -g minidev")}`);
92
- logger_default.info(`- ${colors.green("yarn global add minidev")}`);
93
- return;
94
- }
95
- throw error;
96
- }
97
- }
98
-
99
- // src/config/paths.ts
100
- import os from "os";
101
- import path2 from "pathe";
102
- var homedir = os.homedir();
103
- var defaultCustomConfigDirPath = path2.join(homedir, ".weapp-ide-cli");
104
- var defaultCustomConfigFilePath = path2.join(
105
- defaultCustomConfigDirPath,
106
- "config.json"
107
- );
108
-
109
- // src/config/custom.ts
110
- import fs from "fs-extra";
111
- var JSON_OPTIONS = {
112
- encoding: "utf8",
113
- spaces: 2
114
- };
115
- async function createCustomConfig(params) {
116
- const trimmedCliPath = params.cliPath.trim();
117
- if (!trimmedCliPath) {
118
- throw new Error("cliPath cannot be empty");
119
- }
120
- const normalizedCliPath = resolvePath(trimmedCliPath);
121
- await fs.ensureDir(defaultCustomConfigDirPath);
122
- await fs.writeJSON(
123
- defaultCustomConfigFilePath,
124
- {
125
- cliPath: normalizedCliPath
126
- },
127
- JSON_OPTIONS
128
- );
129
- return normalizedCliPath;
130
- }
131
-
132
- // src/cli/prompt.ts
133
- import { stdin as input, stdout as output } from "process";
134
- import { createInterface } from "readline/promises";
135
- import fs2 from "fs-extra";
136
- async function promptForCliPath() {
137
- const rl = createInterface({ input, output });
138
- try {
139
- logger_default.info(`\u8BF7\u8BBE\u7F6E ${colors.bold("\u5FAE\u4FE1web\u5F00\u53D1\u8005\u5DE5\u5177 CLI")} \u7684\u8DEF\u5F84`);
140
- logger_default.info("\u63D0\u793A\uFF1A\u547D\u4EE4\u884C\u5DE5\u5177\u9ED8\u8BA4\u6240\u5728\u4F4D\u7F6E\uFF1A");
141
- logger_default.info(`- MacOS: ${colors.green("<\u5B89\u88C5\u8DEF\u5F84>/Contents/MacOS/cli")}`);
142
- logger_default.info(`- Windows: ${colors.green("<\u5B89\u88C5\u8DEF\u5F84>/cli.bat")}`);
143
- logger_default.info(`- Linux: ${colors.green("<\u5B89\u88C5\u8DEF\u5F84>/files/bin/bin/wechat-devtools-cli")}`);
144
- const cliPath = (await rl.question("\u8BF7\u8F93\u5165\u5FAE\u4FE1web\u5F00\u53D1\u8005\u5DE5\u5177 CLI \u8DEF\u5F84\uFF1A")).trim();
145
- if (!cliPath) {
146
- logger_default.error("\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u5DF2\u53D6\u6D88\u672C\u6B21\u914D\u7F6E\u3002");
147
- return null;
148
- }
149
- try {
150
- const normalizedPath = await createCustomConfig({ cliPath });
151
- logger_default.info(`\u5168\u5C40\u914D\u7F6E\u5B58\u50A8\u4F4D\u7F6E\uFF1A${colors.green(defaultCustomConfigFilePath)}`);
152
- if (!await fs2.pathExists(normalizedPath)) {
153
- logger_default.warn("\u5728\u5F53\u524D\u8DEF\u5F84\u672A\u627E\u5230\u5FAE\u4FE1web\u5F00\u53D1\u8005\u547D\u4EE4\u884C\u5DE5\u5177\uFF0C\u8BF7\u786E\u8BA4\u8DEF\u5F84\u662F\u5426\u6B63\u786E\u3002");
154
- }
155
- return normalizedPath;
156
- } catch (error) {
157
- const reason = error instanceof Error ? error.message : String(error);
158
- logger_default.error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25\uFF1A${reason}`);
159
- return null;
160
- }
161
- } finally {
162
- rl.close();
163
- }
164
- }
165
-
166
- // src/runtime/platform.ts
167
- import os2 from "os";
168
- import process4 from "process";
169
- import fs3 from "fs-extra";
170
- import path3 from "pathe";
171
- var SupportedPlatformsMap = {
172
- Windows_NT: "Windows_NT",
173
- Darwin: "Darwin",
174
- Linux: "Linux"
175
- };
176
- function isOperatingSystemSupported(osName = os2.type()) {
177
- return osName === SupportedPlatformsMap.Windows_NT || osName === SupportedPlatformsMap.Darwin || osName === SupportedPlatformsMap.Linux;
178
- }
179
- var operatingSystemName = os2.type();
180
- function createLinuxCliResolver() {
181
- let resolvedPath;
182
- let attempted = false;
183
- let pending = null;
184
- return async () => {
185
- if (attempted) {
186
- return resolvedPath;
187
- }
188
- if (!pending) {
189
- pending = (async () => {
190
- try {
191
- const envPath = await getFirstBinaryPath("wechat-devtools-cli");
192
- if (envPath) {
193
- resolvedPath = envPath;
194
- }
195
- } catch (error) {
196
- const reason = error instanceof Error ? error.message : String(error);
197
- logger_default.warn(`\u83B7\u53D6 Linux wechat-devtools-cli \u8DEF\u5F84\u5931\u8D25\uFF1A${reason}`);
198
- } finally {
199
- attempted = true;
200
- }
201
- return resolvedPath;
202
- })();
203
- }
204
- return pending;
205
- };
206
- }
207
- var linuxCliResolver = createLinuxCliResolver();
208
- var WINDOWS_DEFAULT_CLI = "C:\\Program Files (x86)\\Tencent\\\u5FAE\u4FE1web\u5F00\u53D1\u8005\u5DE5\u5177\\cli.bat";
209
- var DARWIN_DEFAULT_CLI = "/Applications/wechatwebdevtools.app/Contents/MacOS/cli";
210
- var cliPathResolvers = {
211
- [SupportedPlatformsMap.Windows_NT]: async () => WINDOWS_DEFAULT_CLI,
212
- [SupportedPlatformsMap.Darwin]: async () => DARWIN_DEFAULT_CLI,
213
- [SupportedPlatformsMap.Linux]: linuxCliResolver
214
- };
215
- async function getDefaultCliPath(targetOs = operatingSystemName) {
216
- if (!isOperatingSystemSupported(targetOs)) {
217
- return void 0;
218
- }
219
- const resolver = cliPathResolvers[targetOs];
220
- const resolvedPath = await resolver();
221
- return resolvedPath;
222
- }
223
- async function getFirstBinaryPath(command) {
224
- const envPath = process4.env.PATH || "";
225
- const pathDirs = envPath.split(path3.delimiter);
226
- for (const dir of pathDirs) {
227
- const fullPath = path3.join(dir, command);
228
- try {
229
- await fs3.access(fullPath, fs3.constants.X_OK);
230
- return fullPath;
231
- } catch {
232
- continue;
233
- }
234
- }
235
- return void 0;
236
- }
237
-
238
- // src/config/resolver.ts
239
- import fs4 from "fs-extra";
240
- async function getConfig() {
241
- if (await fs4.pathExists(defaultCustomConfigFilePath)) {
242
- try {
243
- const config = await fs4.readJSON(defaultCustomConfigFilePath);
244
- const cliPath = typeof config.cliPath === "string" ? config.cliPath.trim() : "";
245
- if (cliPath) {
246
- logger_default.info(`\u5168\u5C40\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF1A${colors.green(defaultCustomConfigFilePath)}`);
247
- logger_default.info(`\u81EA\u5B9A\u4E49 CLI \u8DEF\u5F84\uFF1A${colors.green(cliPath)}`);
248
- return {
249
- cliPath,
250
- source: "custom"
251
- };
252
- }
253
- logger_default.warn("\u81EA\u5B9A\u4E49\u914D\u7F6E\u6587\u4EF6\u7F3A\u5C11\u6709\u6548\u7684 CLI \u8DEF\u5F84\uFF0C\u5C06\u5C1D\u8BD5\u4F7F\u7528\u9ED8\u8BA4\u8DEF\u5F84\u3002");
254
- } catch (error) {
255
- const reason = error instanceof Error ? error.message : String(error);
256
- logger_default.warn(`\u89E3\u6790\u81EA\u5B9A\u4E49\u914D\u7F6E\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4F7F\u7528\u9ED8\u8BA4\u8DEF\u5F84\u3002\u539F\u56E0\uFF1A${reason}`);
257
- }
258
- }
259
- const fallbackPath = await getDefaultCliPath();
260
- if (fallbackPath) {
261
- return {
262
- cliPath: fallbackPath,
263
- source: "default"
264
- };
265
- }
266
- return {
267
- cliPath: "",
268
- source: "missing"
269
- };
270
- }
271
-
272
- // src/cli/resolver.ts
273
- import fs5 from "fs-extra";
274
- async function resolveCliPath() {
275
- const config = await getConfig();
276
- if (!config.cliPath) {
277
- return { cliPath: null, source: config.source };
278
- }
279
- const exists = await fs5.pathExists(config.cliPath);
280
- return {
281
- cliPath: exists ? config.cliPath : null,
282
- source: config.source
283
- };
284
- }
285
-
286
- // src/cli/retry.ts
287
- import process5 from "process";
288
- import { emitKeypressEvents } from "readline";
289
- var LOGIN_REQUIRED_PATTERNS = [
290
- /code\s*[:=]\s*10/i,
291
- /需要重新登录/,
292
- /need\s+re-?login/i,
293
- /re-?login/i
294
- ];
295
- function isWechatIdeLoginRequiredError(error) {
296
- const text = extractExecutionErrorText(error);
297
- if (!text) {
298
- return false;
299
- }
300
- return LOGIN_REQUIRED_PATTERNS.some((pattern) => pattern.test(text));
301
- }
302
- function extractExecutionErrorText(error) {
303
- if (!error || typeof error !== "object") {
304
- return "";
305
- }
306
- const parts = [];
307
- const candidate = error;
308
- for (const field of [candidate.message, candidate.shortMessage, candidate.stderr, candidate.stdout]) {
309
- if (typeof field === "string" && field.trim()) {
310
- parts.push(field);
311
- }
312
- }
313
- return parts.join("\n");
314
- }
315
- function formatWechatIdeLoginRequiredError(error) {
316
- const text = extractExecutionErrorText(error);
317
- const code = text.match(/code\s*[:=]\s*(\d+)/i)?.[1];
318
- const message = extractLoginRequiredMessage(text);
319
- const lines = ["\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u8FD4\u56DE\u767B\u5F55\u9519\u8BEF\uFF1A"];
320
- if (code) {
321
- lines.push(`- code: ${code}`);
322
- }
323
- if (message) {
324
- lines.push(`- message: ${message}`);
325
- }
326
- if (!code && !message) {
327
- lines.push("- message: \u9700\u8981\u91CD\u65B0\u767B\u5F55");
328
- }
329
- return lines.join("\n");
330
- }
331
- function extractLoginRequiredMessage(text) {
332
- if (!text) {
333
- return "";
334
- }
335
- if (/需要重新登录/.test(text)) {
336
- return "\u9700\u8981\u91CD\u65B0\u767B\u5F55";
337
- }
338
- const englishMatch = text.match(/need\s+re-?login|re-?login/i);
339
- if (englishMatch?.[0]) {
340
- return englishMatch[0].toLowerCase();
341
- }
342
- const firstLine = text.split(/\r?\n/).map((line) => line.trim()).find((line) => Boolean(line) && !line.startsWith("at "));
343
- if (!firstLine) {
344
- return "";
345
- }
346
- return firstLine.replace(/^\[error\]\s*/i, "").replace(/^error\s*:\s*/i, "").slice(0, 120);
347
- }
348
- async function waitForRetryKeypress() {
349
- if (!process5.stdin.isTTY) {
350
- return false;
351
- }
352
- emitKeypressEvents(process5.stdin);
353
- const hasSetRawMode = typeof process5.stdin.setRawMode === "function";
354
- if (hasSetRawMode) {
355
- process5.stdin.setRawMode(true);
356
- }
357
- process5.stdin.resume();
358
- return new Promise((resolve) => {
359
- const cleanup = () => {
360
- process5.stdin.off("keypress", onKeypress);
361
- if (hasSetRawMode) {
362
- process5.stdin.setRawMode(false);
363
- }
364
- process5.stdin.pause();
365
- };
366
- const done = (value) => {
367
- cleanup();
368
- resolve(value);
369
- };
370
- const onKeypress = (_str, key) => {
371
- if (!key) {
372
- return;
373
- }
374
- if (key.ctrl && key.name === "c") {
375
- done(false);
376
- return;
377
- }
378
- if (key.name === "r") {
379
- done(true);
380
- return;
381
- }
382
- if (key.name === "q" || key.name === "escape") {
383
- done(false);
384
- }
385
- };
386
- process5.stdin.on("keypress", onKeypress);
387
- });
388
- }
389
- function formatRetryHotkeyPrompt() {
390
- const highlight = (key) => highlightHotkey(key);
391
- return `\u6309 ${highlight("r")} \u91CD\u8BD5\uFF0C\u6309 ${highlight("q")} / ${highlight("Esc")} / ${highlight("Ctrl+C")} \u9000\u51FA\u3002`;
392
- }
393
- function highlightHotkey(key) {
394
- return colors.bold(colors.green(key));
395
- }
396
-
397
- // src/cli/run.ts
398
- import process6 from "process";
399
- var MINIDEV_NAMESPACE = /* @__PURE__ */ new Set(["alipay", "ali", "minidev"]);
400
- var ALIPAY_PLATFORM_ALIASES = /* @__PURE__ */ new Set(["alipay", "ali", "minidev"]);
401
- var ARG_TRANSFORMS = [
402
- createAlias({ find: "-p", replacement: "--project" }),
403
- createPathCompat("--result-output"),
404
- createPathCompat("-r"),
405
- createPathCompat("--qr-output"),
406
- createPathCompat("-o"),
407
- createPathCompat("--info-output"),
408
- createPathCompat("-i")
409
- ];
410
- async function parse(argv) {
411
- const head = argv[0];
412
- if (head && MINIDEV_NAMESPACE.has(head)) {
413
- await runMinidev(argv.slice(1));
414
- return;
415
- }
416
- const formattedArgv = transformArgv(argv, ARG_TRANSFORMS);
417
- if (shouldDelegateOpenToMinidev(formattedArgv)) {
418
- await runMinidev(createMinidevOpenArgv(formattedArgv));
419
- return;
420
- }
421
- if (!isOperatingSystemSupported(operatingSystemName)) {
422
- logger_default.warn(`\u5FAE\u4FE1web\u5F00\u53D1\u8005\u5DE5\u5177\u4E0D\u652F\u6301\u5F53\u524D\u5E73\u53F0\uFF1A${operatingSystemName} !`);
423
- return;
424
- }
425
- if (head === "config") {
426
- await promptForCliPath();
427
- return;
428
- }
429
- const { cliPath, source } = await resolveCliPath();
430
- if (!cliPath) {
431
- const message = source === "custom" ? "\u5728\u5F53\u524D\u81EA\u5B9A\u4E49\u8DEF\u5F84\u4E2D\u672A\u627E\u5230\u5FAE\u4FE1web\u5F00\u53D1\u8005\u547D\u4EE4\u884C\u5DE5\u5177\uFF0C\u8BF7\u91CD\u65B0\u6307\u5B9A\u8DEF\u5F84\u3002" : `\u672A\u68C0\u6D4B\u5230\u5FAE\u4FE1web\u5F00\u53D1\u8005\u547D\u4EE4\u884C\u5DE5\u5177\uFF0C\u8BF7\u6267\u884C ${colors.bold(colors.green("weapp-ide-cli config"))} \u6307\u5B9A\u8DEF\u5F84\u3002`;
432
- logger_default.warn(message);
433
- await promptForCliPath();
434
- return;
435
- }
436
- await runWechatCliWithRetry(cliPath, formattedArgv);
437
- }
438
- async function runWechatCliWithRetry(cliPath, argv) {
439
- let retrying = true;
440
- while (retrying) {
441
- try {
442
- const result = await execute(cliPath, argv, {
443
- pipeStdout: false,
444
- pipeStderr: false
445
- });
446
- if (!isWechatIdeLoginRequiredError(result)) {
447
- flushExecutionOutput(result);
448
- return;
449
- }
450
- retrying = await promptLoginRetry(result);
451
- if (retrying) {
452
- logger_default.info("\u6B63\u5728\u91CD\u8BD5\u8FDE\u63A5\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177...");
453
- }
454
- } catch (error) {
455
- if (!isWechatIdeLoginRequiredError(error)) {
456
- throw error;
457
- }
458
- retrying = await promptLoginRetry(error);
459
- if (retrying) {
460
- logger_default.info("\u6B63\u5728\u91CD\u8BD5\u8FDE\u63A5\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177...");
461
- }
462
- }
463
- }
464
- }
465
- async function promptLoginRetry(errorLike) {
466
- logger_default.error("\u68C0\u6D4B\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u767B\u5F55\u72B6\u6001\u5931\u6548\uFF0C\u8BF7\u5148\u767B\u5F55\u540E\u91CD\u8BD5\u3002");
467
- logger_default.warn("\u8BF7\u5148\u6253\u5F00\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u5B8C\u6210\u767B\u5F55\u3002");
468
- logger_default.warn(formatWechatIdeLoginRequiredError(errorLike));
469
- logger_default.info(formatRetryHotkeyPrompt());
470
- const shouldRetry = await waitForRetryKeypress();
471
- if (!shouldRetry) {
472
- logger_default.info("\u5DF2\u53D6\u6D88\u91CD\u8BD5\u3002\u5B8C\u6210\u767B\u5F55\u540E\u8BF7\u91CD\u65B0\u6267\u884C\u5F53\u524D\u547D\u4EE4\u3002");
473
- }
474
- return shouldRetry;
475
- }
476
- function shouldDelegateOpenToMinidev(argv) {
477
- if (argv[0] !== "open") {
478
- return false;
479
- }
480
- const platform = readOptionValue(argv, "--platform");
481
- if (!platform) {
482
- return false;
483
- }
484
- return ALIPAY_PLATFORM_ALIASES.has(platform);
485
- }
486
- function createMinidevOpenArgv(argv) {
487
- const nextArgv = [...argv];
488
- nextArgv[0] = "ide";
489
- return removeOption(nextArgv, "--platform");
490
- }
491
- function readOptionValue(argv, optionName) {
492
- const optionWithEqual = `${optionName}=`;
493
- for (let index = 0; index < argv.length; index += 1) {
494
- const token = argv[index];
495
- if (!token) {
496
- continue;
497
- }
498
- if (token === optionName) {
499
- const value = argv[index + 1];
500
- return typeof value === "string" ? value.trim().toLowerCase() : void 0;
501
- }
502
- if (token.startsWith(optionWithEqual)) {
503
- const value = token.slice(optionWithEqual.length);
504
- return value.trim().toLowerCase();
505
- }
506
- }
507
- return void 0;
508
- }
509
- function removeOption(argv, optionName) {
510
- const optionWithEqual = `${optionName}=`;
511
- const nextArgv = [];
512
- for (let index = 0; index < argv.length; index += 1) {
513
- const token = argv[index];
514
- if (!token) {
515
- continue;
516
- }
517
- if (token === optionName) {
518
- const nextToken = argv[index + 1];
519
- if (nextToken && !nextToken.startsWith("-")) {
520
- index += 1;
521
- }
522
- continue;
523
- }
524
- if (token.startsWith(optionWithEqual)) {
525
- continue;
526
- }
527
- nextArgv.push(token);
528
- }
529
- return nextArgv;
530
- }
531
- function flushExecutionOutput(result) {
532
- if (!result || typeof result !== "object") {
533
- return;
534
- }
535
- const candidate = result;
536
- if (typeof candidate.stdout === "string" && candidate.stdout) {
537
- process6.stdout.write(candidate.stdout);
538
- }
539
- if (typeof candidate.stderr === "string" && candidate.stderr) {
540
- process6.stderr.write(candidate.stderr);
541
- }
542
- }
543
-
544
- export {
545
- logger_default,
546
- resolvePath,
547
- transformArgv,
548
- createAlias,
549
- createPathCompat,
550
- execute,
551
- runMinidev,
552
- defaultCustomConfigDirPath,
553
- defaultCustomConfigFilePath,
554
- createCustomConfig,
555
- promptForCliPath,
556
- SupportedPlatformsMap,
557
- isOperatingSystemSupported,
558
- operatingSystemName,
559
- getDefaultCliPath,
560
- getConfig,
561
- resolveCliPath,
562
- isWechatIdeLoginRequiredError,
563
- extractExecutionErrorText,
564
- formatWechatIdeLoginRequiredError,
565
- waitForRetryKeypress,
566
- formatRetryHotkeyPrompt,
567
- parse
568
- };