weapp-ide-cli 5.4.6 → 5.4.8

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.
@@ -1268,6 +1268,7 @@ async function connectMiniProgram(options) {
1268
1268
  };
1269
1269
  } catch (error) {
1270
1270
  const normalizedOpenSessionError = normalizeMiniProgramConnectionError(error);
1271
+ if (options.openedOnly) throw normalizedOpenSessionError;
1271
1272
  if (normalizedOpenSessionError instanceof Error && normalizedOpenSessionError.message === "DEVTOOLS_PROTOCOL_TIMEOUT") throw normalizedOpenSessionError;
1272
1273
  try {
1273
1274
  return {
@@ -1,6 +1,6 @@
1
- import { $ as overwriteCustomConfig, C as configureLocaleFromArgv, H as resolveDevtoolsAutomationDefaults, J as logger_default, Q as createLocaleConfig, T as validateLocaleOption, V as getConfiguredLocale, X as createAutoTrustProjectConfig, Y as createAutoBootstrapDevtoolsConfig, Z as createCustomConfig, et as readCustomConfig, q as colors, r as connectMiniProgram, rt as defaultCustomConfigFilePath, tt as removeCustomConfigKey, w as i18nText, z as resolveCliPath } from "./automator-session-JEM5q8tK.js";
2
- import { A as isWechatIdeLoggedIn, B as runWechatCliCommand, C as clearWechatIdeCache, F as quitWechatIde, G as transformArgv, H as execute, K as promptForCliPath, L as resetWechatIdeFileUtils, M as openWechatIde, N as openWechatIdeOtherProject, P as previewWechatIde, Q as startWechatIdeEngineBuildByHttp, S as buildWechatIdeNpm, T as closeWechatIdeProject, U as createAlias, W as createPathCompat, Y as pollWechatIdeEngineBuildResultByHttp, _ as autoPreviewWechatIde, a as navigateBack, b as buildWechatIdeApk, c as pageStack, d as remote, f as scrollTo, g as tap, i as input, it as removeOption, j as loginWechatIde, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, nt as readBooleanOption, o as navigateTo, p as switchTab, r as currentPage, rt as readOptionValue, s as pageData, t as audit, tt as parseAutomatorArgs, u as redirectTo, v as autoReplayWechatIde, x as buildWechatIdeIpa, y as autoWechatIde, z as uploadWechatIde } from "./commands-8Wamgvv0.js";
3
- import "./run-mcp-L4shbBPP.js";
1
+ import { $ as overwriteCustomConfig, C as configureLocaleFromArgv, H as resolveDevtoolsAutomationDefaults, J as logger_default, Q as createLocaleConfig, T as validateLocaleOption, V as getConfiguredLocale, X as createAutoTrustProjectConfig, Y as createAutoBootstrapDevtoolsConfig, Z as createCustomConfig, a as releaseSharedMiniProgram, et as readCustomConfig, q as colors, r as connectMiniProgram, rt as defaultCustomConfigFilePath, t as acquireSharedMiniProgram, tt as removeCustomConfigKey, w as i18nText, z as resolveCliPath } from "./automator-session-C8JdS2rx.js";
2
+ import { A as isWechatIdeLoggedIn, B as runWechatCliCommand, C as clearWechatIdeCache, F as quitWechatIde, G as transformArgv, H as execute, K as promptForCliPath, L as resetWechatIdeFileUtils, M as openWechatIde, N as openWechatIdeOtherProject, P as previewWechatIde, Q as startWechatIdeEngineBuildByHttp, S as buildWechatIdeNpm, T as closeWechatIdeProject, U as createAlias, W as createPathCompat, Y as pollWechatIdeEngineBuildResultByHttp, _ as autoPreviewWechatIde, a as navigateBack, b as buildWechatIdeApk, c as pageStack, d as remote, f as scrollTo, g as tap, i as input, it as removeOption, j as loginWechatIde, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, nt as readBooleanOption, o as navigateTo, p as switchTab, r as currentPage, rt as readOptionValue, s as pageData, t as audit, tt as parseAutomatorArgs, u as redirectTo, v as autoReplayWechatIde, x as buildWechatIdeIpa, y as autoWechatIde, z as uploadWechatIde } from "./commands-C6ATyJuz.js";
3
+ import "./run-mcp-X00XjC8Z.js";
4
4
  import fs from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { fs as fs$1 } from "@weapp-core/shared/fs";
@@ -313,7 +313,7 @@ async function runScreenshot(argv) {
313
313
  }
314
314
  const options = parseScreenshotArgs(argv);
315
315
  const isJsonOutput = argv.includes("--json");
316
- const { takeScreenshot } = await import("./commands-BIKOtazW.js");
316
+ const { takeScreenshot } = await import("./commands-CEJ6rVma.js");
317
317
  const result = await takeScreenshot(options);
318
318
  if (isJsonOutput) {
319
319
  console.log(JSON.stringify(result, null, 2));
@@ -324,7 +324,7 @@ async function runScreenshot(argv) {
324
324
  //#endregion
325
325
  //#region src/cli/runtime-service.ts
326
326
  const DEFAULT_RUNTIME_SERVICE_URL = "http://127.0.0.1:3088/api/weapp/devtools";
327
- const SERVICE_UNAVAILABLE_CODES = new Set([
327
+ const SERVICE_UNAVAILABLE_CODES = /* @__PURE__ */ new Set([
328
328
  "ECONNREFUSED",
329
329
  "ECONNRESET",
330
330
  "ENOTFOUND",
@@ -500,7 +500,7 @@ const COMMON_OPTION_DEFINITIONS = [
500
500
  }
501
501
  }
502
502
  ];
503
- const COMMON_ALLOWED_OPTIONS = new Set([
503
+ const COMMON_ALLOWED_OPTIONS = /* @__PURE__ */ new Set([
504
504
  "-p",
505
505
  "--project",
506
506
  "-t",
@@ -517,7 +517,7 @@ function createDefinition(input) {
517
517
  description: input.description,
518
518
  usage: input.usage,
519
519
  options: input.options ?? [],
520
- allowedOptions: new Set([...COMMON_ALLOWED_OPTIONS, ...input.allowedOptions ?? []]),
520
+ allowedOptions: /* @__PURE__ */ new Set([...COMMON_ALLOWED_OPTIONS, ...input.allowedOptions ?? []]),
521
521
  handler: input.handler
522
522
  };
523
523
  }
@@ -1010,7 +1010,7 @@ const ENGINE_BUILD_ENDPOINT_MISSING_PATTERNS = [/Cannot GET \/engine\/build\b/i,
1010
1010
  const ENGINE_BUILD_ENDPOINT_MISSING_MESSAGE = "当前微信开发者工具未提供 engine build 接口,已跳过自动 engine build 刷新。";
1011
1011
  const ENGINE_BUILD_CLI_OPENED_PATTERN = /打开项目成功|project\s+opened|open\s+project\s+success|(?:^|\n)\s*✔\s*open(?:\n|$)/i;
1012
1012
  const COMPACT_WHITESPACE_PATTERN = /\s+/g;
1013
- function sleep(ms) {
1013
+ function sleep$1(ms) {
1014
1014
  return new Promise((resolve) => setTimeout(resolve, ms));
1015
1015
  }
1016
1016
  function createEngineBuildLogFilename() {
@@ -1089,7 +1089,7 @@ async function runWechatIdeEngineBuildByHttp(projectPath, options = {}) {
1089
1089
  options.onProgress?.(result);
1090
1090
  if (result.failed) throw createEngineBuildError(result.msg || result.body || "WECHAT_DEVTOOLS_ENGINE_BUILD_FAILED", "WECHAT_DEVTOOLS_ENGINE_BUILD_FAILED");
1091
1091
  if (result.done) return result;
1092
- await sleep(options.pollIntervalMs ?? 1e3);
1092
+ await sleep$1(options.pollIntervalMs ?? 1e3);
1093
1093
  }
1094
1094
  }
1095
1095
  /**
@@ -1129,39 +1129,43 @@ const DEFAULT_FORWARD_CONSOLE_LEVELS = [
1129
1129
  "warn",
1130
1130
  "error"
1131
1131
  ];
1132
- /**
1133
- * @description 启动小程序控制台日志转发,并保持 automator 会话常驻。
1134
- */
1135
- async function startForwardConsole(options) {
1136
- const miniProgram = await connectMiniProgram(options);
1137
- const logLevels = new Set(options.logLevels?.length ? options.logLevels : DEFAULT_FORWARD_CONSOLE_LEVELS);
1138
- const logHandler = options.onLog ?? printForwardConsoleEvent;
1139
- const onConsole = (payload) => {
1140
- const event = normalizeConsoleEvent(payload);
1141
- if (!logLevels.has(event.level)) return;
1142
- logHandler(event);
1143
- };
1144
- const onException = (payload) => {
1145
- if (options.unhandledErrors === false) return;
1146
- logHandler(normalizeExceptionEvent(payload));
1147
- };
1148
- miniProgram.on("console", onConsole);
1149
- miniProgram.on("exception", onException);
1150
- options.onReady?.();
1151
- let closed = false;
1152
- return { async close() {
1153
- if (closed) return;
1154
- closed = true;
1155
- detachMiniProgramListener(miniProgram, "console", onConsole);
1156
- detachMiniProgramListener(miniProgram, "exception", onException);
1157
- await miniProgram.close();
1158
- } };
1132
+ const ENABLE_LOG_RETRY_DELAY_MS = 500;
1133
+ const ENABLE_LOG_RETRY_TIMES = 5;
1134
+ const ENABLE_LOG_REFRESH_INTERVAL_MS = 2e3;
1135
+ const AUXILIARY_FORWARD_CONSOLE_DELAY_MS = 2500;
1136
+ const DUPLICATE_LOG_SUPPRESS_MS = 800;
1137
+ function getStringValue(value) {
1138
+ return typeof value === "string" && value.trim() ? value : void 0;
1139
+ }
1140
+ function toPlainObject(value) {
1141
+ if (!value || typeof value !== "object") return {};
1142
+ return value;
1143
+ }
1144
+ function normalizeLogLevel(value) {
1145
+ const normalized = String(value ?? "log").toLowerCase();
1146
+ if (normalized === "warning") return "warn";
1147
+ if (normalized === "debug" || normalized === "info" || normalized === "warn" || normalized === "error") return normalized;
1148
+ return "log";
1159
1149
  }
1160
1150
  function detachMiniProgramListener(miniProgram, event, listener) {
1161
1151
  if (typeof miniProgram.off === "function") miniProgram.off(event, listener);
1162
1152
  }
1153
+ function formatForwardConsolePrefix(level) {
1154
+ const label = `[mini:${level.padEnd(5)}]`;
1155
+ if (level === "error") return colors.bold(colors.red(label));
1156
+ if (level === "warn") return colors.bold(colors.yellow(label));
1157
+ if (level === "info") return colors.bold(colors.cyan(label));
1158
+ if (level === "debug") return colors.dim(label);
1159
+ return colors.bold(colors.green(label));
1160
+ }
1161
+ function formatForwardConsoleMessage(event) {
1162
+ if (event.level === "debug") return colors.dim(event.message);
1163
+ if (event.level === "error") return colors.red(event.message);
1164
+ if (event.level === "warn") return colors.yellow(event.message);
1165
+ return event.message;
1166
+ }
1163
1167
  function printForwardConsoleEvent(event) {
1164
- const line = `${colors.dim(`[mini:${event.level}]`)} ${event.message}`;
1168
+ const line = `${formatForwardConsolePrefix(event.level)} ${formatForwardConsoleMessage(event)}`;
1165
1169
  switch (event.level) {
1166
1170
  case "error":
1167
1171
  logger_default.error(line);
@@ -1175,6 +1179,35 @@ function printForwardConsoleEvent(event) {
1175
1179
  default: logger_default.log(line);
1176
1180
  }
1177
1181
  }
1182
+ function formatConsoleArgument(value) {
1183
+ const record = toPlainObject(value);
1184
+ const rawValue = record.value;
1185
+ const description = getStringValue(record.description);
1186
+ if (typeof rawValue === "string" || typeof rawValue === "number" || typeof rawValue === "boolean") return String(rawValue);
1187
+ if (rawValue !== void 0) return inspect(rawValue, {
1188
+ depth: 4,
1189
+ colors: false,
1190
+ compact: true
1191
+ });
1192
+ if (description) return description;
1193
+ if (typeof value === "string") return value;
1194
+ return inspect(value, {
1195
+ depth: 4,
1196
+ colors: false,
1197
+ compact: true
1198
+ });
1199
+ }
1200
+ function resolveLogMessage(record, payload) {
1201
+ const text = getStringValue(record.text) ?? getStringValue(record.message);
1202
+ if (text) return text;
1203
+ if (Array.isArray(record.args) && record.args.length > 0) return record.args.map(formatConsoleArgument).join(" ");
1204
+ if (typeof payload === "string") return payload;
1205
+ return inspect(payload, {
1206
+ depth: 4,
1207
+ colors: false,
1208
+ compact: true
1209
+ });
1210
+ }
1178
1211
  function normalizeConsoleEvent(payload) {
1179
1212
  const record = toPlainObject(payload);
1180
1213
  return {
@@ -1196,47 +1229,116 @@ function normalizeExceptionEvent(payload) {
1196
1229
  raw: payload
1197
1230
  };
1198
1231
  }
1199
- function normalizeLogLevel(value) {
1200
- const normalized = String(value ?? "log").toLowerCase();
1201
- if (normalized === "warning") return "warn";
1202
- if (normalized === "debug" || normalized === "info" || normalized === "warn" || normalized === "error") return normalized;
1203
- return "log";
1232
+ function sleep(ms) {
1233
+ return new Promise((resolve) => setTimeout(resolve, ms));
1204
1234
  }
1205
- function resolveLogMessage(record, payload) {
1206
- const text = getStringValue(record.text) ?? getStringValue(record.message);
1207
- if (text) return text;
1208
- if (Array.isArray(record.args) && record.args.length > 0) return record.args.map(formatConsoleArgument).join(" ");
1209
- if (typeof payload === "string") return payload;
1210
- return inspect(payload, {
1211
- depth: 4,
1212
- colors: false,
1213
- compact: true
1214
- });
1235
+ async function enableMiniProgramConsoleLog(miniProgram) {
1236
+ if (typeof miniProgram.enableLog !== "function") return;
1237
+ let lastError;
1238
+ for (let attempt = 0; attempt <= ENABLE_LOG_RETRY_TIMES; attempt += 1) try {
1239
+ await miniProgram.enableLog();
1240
+ return;
1241
+ } catch (error) {
1242
+ lastError = error;
1243
+ if (attempt < ENABLE_LOG_RETRY_TIMES) await sleep(ENABLE_LOG_RETRY_DELAY_MS);
1244
+ }
1245
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
1215
1246
  }
1216
- function formatConsoleArgument(value) {
1217
- const record = toPlainObject(value);
1218
- const rawValue = record.value;
1219
- const description = getStringValue(record.description);
1220
- if (typeof rawValue === "string" || typeof rawValue === "number" || typeof rawValue === "boolean") return String(rawValue);
1221
- if (rawValue !== void 0) return inspect(rawValue, {
1222
- depth: 4,
1223
- colors: false,
1224
- compact: true
1225
- });
1226
- if (description) return description;
1227
- if (typeof value === "string") return value;
1228
- return inspect(value, {
1229
- depth: 4,
1230
- colors: false,
1231
- compact: true
1247
+ async function refreshOpenedMiniProgramConsoleLog(options) {
1248
+ const miniProgram = await connectMiniProgram({
1249
+ ...options,
1250
+ openedOnly: true
1232
1251
  });
1252
+ try {
1253
+ await enableMiniProgramConsoleLog(miniProgram);
1254
+ } finally {
1255
+ miniProgram.disconnect();
1256
+ }
1233
1257
  }
1234
- function getStringValue(value) {
1235
- return typeof value === "string" && value.trim() ? value : void 0;
1258
+ function startEnableLogRefresh(miniProgram, options) {
1259
+ if (typeof miniProgram.enableLog !== "function") return;
1260
+ const timer = setInterval(() => {
1261
+ miniProgram.enableLog().catch(() => {});
1262
+ refreshOpenedMiniProgramConsoleLog(options).catch(() => {});
1263
+ }, ENABLE_LOG_REFRESH_INTERVAL_MS);
1264
+ return () => {
1265
+ clearInterval(timer);
1266
+ };
1236
1267
  }
1237
- function toPlainObject(value) {
1238
- if (!value || typeof value !== "object") return {};
1239
- return value;
1268
+ /**
1269
+ * @description 启动小程序控制台日志转发,并保持 automator 会话常驻。
1270
+ */
1271
+ async function startForwardConsole(options) {
1272
+ const miniProgram = await acquireSharedMiniProgram(options);
1273
+ const logLevels = new Set(options.logLevels?.length ? options.logLevels : DEFAULT_FORWARD_CONSOLE_LEVELS);
1274
+ const logHandler = options.onLog ?? printForwardConsoleEvent;
1275
+ const recentLogTimes = /* @__PURE__ */ new Map();
1276
+ const emitLog = (event) => {
1277
+ const key = `${event.level}\0${event.message}`;
1278
+ const now = Date.now();
1279
+ if (now - (recentLogTimes.get(key) ?? 0) < DUPLICATE_LOG_SUPPRESS_MS) return;
1280
+ recentLogTimes.set(key, now);
1281
+ logHandler(event);
1282
+ };
1283
+ const onConsole = (payload) => {
1284
+ const event = normalizeConsoleEvent(payload);
1285
+ if (!logLevels.has(event.level)) return;
1286
+ emitLog(event);
1287
+ };
1288
+ const onException = (payload) => {
1289
+ if (options.unhandledErrors === false) return;
1290
+ emitLog(normalizeExceptionEvent(payload));
1291
+ };
1292
+ let closed = false;
1293
+ let stopEnableLogRefresh;
1294
+ let auxiliaryMiniProgram;
1295
+ let auxiliaryTimer;
1296
+ const closeSession = async () => {
1297
+ if (closed) return;
1298
+ closed = true;
1299
+ if (auxiliaryTimer) {
1300
+ clearTimeout(auxiliaryTimer);
1301
+ auxiliaryTimer = void 0;
1302
+ }
1303
+ stopEnableLogRefresh?.();
1304
+ stopEnableLogRefresh = void 0;
1305
+ detachMiniProgramListener(miniProgram, "console", onConsole);
1306
+ detachMiniProgramListener(miniProgram, "exception", onException);
1307
+ if (auxiliaryMiniProgram) {
1308
+ detachMiniProgramListener(auxiliaryMiniProgram, "console", onConsole);
1309
+ detachMiniProgramListener(auxiliaryMiniProgram, "exception", onException);
1310
+ auxiliaryMiniProgram.disconnect();
1311
+ auxiliaryMiniProgram = void 0;
1312
+ }
1313
+ releaseSharedMiniProgram(options.projectPath, options.sessionId || options.port);
1314
+ };
1315
+ try {
1316
+ await enableMiniProgramConsoleLog(miniProgram);
1317
+ } catch (error) {
1318
+ await closeSession();
1319
+ throw error;
1320
+ }
1321
+ miniProgram.on("console", onConsole);
1322
+ miniProgram.on("exception", onException);
1323
+ stopEnableLogRefresh = startEnableLogRefresh(miniProgram, options);
1324
+ auxiliaryTimer = setTimeout(() => {
1325
+ (async () => {
1326
+ const openedMiniProgram = await connectMiniProgram({
1327
+ ...options,
1328
+ openedOnly: true
1329
+ });
1330
+ if (closed) {
1331
+ openedMiniProgram.disconnect();
1332
+ return;
1333
+ }
1334
+ auxiliaryMiniProgram = openedMiniProgram;
1335
+ await enableMiniProgramConsoleLog(openedMiniProgram);
1336
+ openedMiniProgram.on("console", onConsole);
1337
+ openedMiniProgram.on("exception", onException);
1338
+ })().catch(() => {});
1339
+ }, AUXILIARY_FORWARD_CONSOLE_DELAY_MS);
1340
+ options.onReady?.();
1341
+ return { close: closeSession };
1240
1342
  }
1241
1343
  //#endregion
1242
1344
  //#region src/cli/minidev.ts
@@ -1623,7 +1725,7 @@ async function parse(argv) {
1623
1725
  return;
1624
1726
  }
1625
1727
  if (matchedCommand === "mcp") {
1626
- const { runMcpCommand } = await import("./run-mcp-C0yaUdqC.js");
1728
+ const { runMcpCommand } = await import("./run-mcp-B5RshzSs.js");
1627
1729
  await runMcpCommand(argv.slice(1));
1628
1730
  return;
1629
1731
  }
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
- import { J as logger_default } from "./automator-session-JEM5q8tK.js";
2
- import { n as parse } from "./cli-Cy53rG5o.js";
1
+ import { J as logger_default } from "./automator-session-C8JdS2rx.js";
2
+ import { n as parse } from "./cli-BUx9wWVK.js";
3
3
  import process from "node:process";
4
4
  //#region src/cli.ts
5
5
  const argv = process.argv.slice(2);
@@ -1,4 +1,4 @@
1
- import { G as isOperatingSystemSupported, J as logger_default, K as operatingSystemName, L as bootstrapWechatDevtoolsSettings, R as detectWechatDevtoolsServicePort, Z as createCustomConfig, d as createWechatIdeLoginRequiredExitError, et as readCustomConfig, h as isWechatIdeLoginRequiredError, it as resolvePath, n as closeSharedMiniProgram, o as withMiniProgram, q as colors, rt as defaultCustomConfigFilePath, s as runRetryableCommand, v as promptWechatIdeLoginRetry, w as i18nText, x as runWithSuspendedSharedInput, z as resolveCliPath } from "./automator-session-JEM5q8tK.js";
1
+ import { G as isOperatingSystemSupported, J as logger_default, K as operatingSystemName, L as bootstrapWechatDevtoolsSettings, R as detectWechatDevtoolsServicePort, Z as createCustomConfig, d as createWechatIdeLoginRequiredExitError, et as readCustomConfig, h as isWechatIdeLoginRequiredError, it as resolvePath, n as closeSharedMiniProgram, o as withMiniProgram, q as colors, rt as defaultCustomConfigFilePath, s as runRetryableCommand, v as promptWechatIdeLoginRetry, w as i18nText, x as runWithSuspendedSharedInput, z as resolveCliPath } from "./automator-session-C8JdS2rx.js";
2
2
  import { Buffer } from "node:buffer";
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
@@ -167,6 +167,7 @@ function removeOption(argv, optionName) {
167
167
  //#endregion
168
168
  //#region src/cli/fullPageScreenshot.ts
169
169
  function decodeScreenshotBuffer(raw) {
170
+ if (raw === void 0) throw new Error("Failed to capture screenshot");
170
171
  const buffer = typeof raw === "string" ? Buffer.from(raw, "base64") : Buffer.from(raw);
171
172
  if (buffer.length === 0) throw new Error("Failed to capture screenshot");
172
173
  return buffer;
@@ -210,7 +211,7 @@ async function captureFullPageScreenshotBuffer(options) {
210
211
  const initialScrollTop = typeof page.scrollTop === "function" ? await page.scrollTop() : 0;
211
212
  const pageHeight = toPositiveNumber(pageSize.height);
212
213
  const viewportHeight = toPositiveNumber(systemInfo.windowHeight);
213
- if (!pageHeight || !viewportHeight) return decodeScreenshotBuffer(await runWithTimeout(miniProgram.screenshot(), timeoutMs, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT"));
214
+ if (!pageHeight || !viewportHeight) return decodeScreenshotBuffer(await runWithTimeout(miniProgram.screenshot({ timeout: timeoutMs }), timeoutMs, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT"));
214
215
  const segments = [];
215
216
  const positions = createScrollPositions(pageHeight, viewportHeight);
216
217
  let coveredUntil = 0;
@@ -219,7 +220,7 @@ async function captureFullPageScreenshotBuffer(options) {
219
220
  for (const scrollTop of positions) {
220
221
  await miniProgram.pageScrollTo(scrollTop);
221
222
  await page.waitFor(150);
222
- const rawScreenshot = await runWithTimeout(miniProgram.screenshot(), timeoutMs, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT");
223
+ const rawScreenshot = await runWithTimeout(miniProgram.screenshot({ timeout: timeoutMs }), timeoutMs, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT");
223
224
  const png = PNG.sync.read(decodeScreenshotBuffer(rawScreenshot));
224
225
  if (viewportHeight > 0) scale = png.height / viewportHeight;
225
226
  const visibleEnd = Math.min(scrollTop + viewportHeight, pageHeight);
@@ -937,6 +938,14 @@ function isDevtoolsProtocolTimeoutError(error) {
937
938
  function isScreenshotNavigationTimeoutError(error) {
938
939
  return error instanceof Error && Reflect.get(error, "code") === "DEVTOOLS_SCREENSHOT_NAVIGATION_TIMEOUT";
939
940
  }
941
+ function isScreenshotRequestTimeoutError(error) {
942
+ if (!(error instanceof Error)) return false;
943
+ return error.message === "DEVTOOLS_SCREENSHOT_TIMEOUT" || Reflect.get(error, "code") === "DEVTOOLS_SCREENSHOT_TIMEOUT";
944
+ }
945
+ function toScreenshotBuffer(screenshot) {
946
+ if (screenshot === void 0) return Buffer.alloc(0);
947
+ return typeof screenshot === "string" ? Buffer.from(screenshot, "base64") : Buffer.from(screenshot);
948
+ }
940
949
  async function reLaunchForScreenshot(miniProgram, page) {
941
950
  const routeOptions = { url: page };
942
951
  if (typeof miniProgram.callWxMethod === "function") await miniProgram.callWxMethod("reLaunch", routeOptions);
@@ -1119,8 +1128,7 @@ async function captureScreenshotBuffer(options) {
1119
1128
  });
1120
1129
  }
1121
1130
  logger_default.info(i18nText("正在截图...", "Taking screenshot..."));
1122
- const screenshot = await withCommandTimeout(miniProgram.screenshot(), commandTimeout, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT");
1123
- const buffer = typeof screenshot === "string" ? Buffer.from(screenshot, "base64") : Buffer.from(screenshot);
1131
+ const buffer = toScreenshotBuffer(await withCommandTimeout(miniProgram.screenshot({ timeout: commandTimeout }), commandTimeout, screenshotTimeoutMessage, "DEVTOOLS_SCREENSHOT_TIMEOUT"));
1124
1132
  if (buffer.length === 0) throw new Error(i18nText("截图失败", "Failed to capture screenshot"));
1125
1133
  return buffer;
1126
1134
  });
@@ -1138,7 +1146,8 @@ async function takeScreenshot(options) {
1138
1146
  } catch (error) {
1139
1147
  const isProtocolTimeout = error instanceof Error && error.message === "DEVTOOLS_PROTOCOL_TIMEOUT";
1140
1148
  const isNavigationTimeout = isScreenshotNavigationTimeoutError(error);
1141
- if (!Boolean(!nextOptions.miniProgram && (isProtocolTimeout || isNavigationTimeout) && !hasRetriedWithFreshSession)) throw error;
1149
+ const isScreenshotTimeout = isScreenshotRequestTimeoutError(error);
1150
+ if (!Boolean(!nextOptions.miniProgram && (isProtocolTimeout || isNavigationTimeout || isScreenshotTimeout) && !hasRetriedWithFreshSession)) throw error;
1142
1151
  hasRetriedWithFreshSession = true;
1143
1152
  await closeWechatIdeProject().catch((closeError) => {
1144
1153
  logger_default.warn(i18nText(`关闭当前微信开发者工具项目窗口失败:${closeError instanceof Error ? closeError.message : String(closeError)},仍将继续尝试重建自动化会话。`, `Failed to close the current Wechat DevTools project window: ${closeError instanceof Error ? closeError.message : String(closeError)}. Continuing to rebuild the automation session.`));
@@ -0,0 +1,2 @@
1
+ import { h as takeScreenshot } from "./commands-C6ATyJuz.js";
2
+ export { takeScreenshot };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as overwriteCustomConfig, A as isAutomatorProtocolTimeoutError, B as getConfig, D as formatAutomatorLoginError, E as connectOpenedAutomator, F as launchAutomator, G as isOperatingSystemSupported, H as resolveDevtoolsAutomationDefaults, I as resolveProjectAutomatorPort, K as operatingSystemName, L as bootstrapWechatDevtoolsSettings, M as isDevtoolsExtensionContextInvalidatedError, N as isDevtoolsHttpPortError, O as getAutomatorProtocolTimeoutMethod, P as isRetryableAutomatorLaunchError, Q as createLocaleConfig, R as detectWechatDevtoolsServicePort, S as waitForExclusiveKeypress, U as SupportedPlatformsMap, V as getConfiguredLocale, W as getDefaultCliPath, X as createAutoTrustProjectConfig, Y as createAutoBootstrapDevtoolsConfig, Z as createCustomConfig, _ as promptRetryKeypress, a as releaseSharedMiniProgram, b as createSharedInputSession, c as RETRY_CANCEL_KEYS, d as createWechatIdeLoginRequiredExitError, et as readCustomConfig, f as extractExecutionErrorText, g as isWechatIdeLoginRequiredExitError, h as isWechatIdeLoginRequiredError, i as getSharedMiniProgramSessionCount, it as resolvePath, j as isAutomatorWsConnectError, k as isAutomatorLoginError, l as RETRY_CONFIRM_KEYS, m as formatWechatIdeLoginRequiredError, n as closeSharedMiniProgram, nt as defaultCustomConfigDirPath, o as withMiniProgram, p as formatRetryHotkeyPrompt, r as connectMiniProgram, rt as defaultCustomConfigFilePath, s as runRetryableCommand, t as acquireSharedMiniProgram, tt as removeCustomConfigKey, u as RETRY_PROMPT_INITIAL_IGNORE_MS, v as promptWechatIdeLoginRetry, x as runWithSuspendedSharedInput, y as waitForRetryKeypress, z as resolveCliPath } from "./automator-session-JEM5q8tK.js";
2
- import { $ as getRuntimeWechatDevtoolsServicePort, A as isWechatIdeLoggedIn, C as clearWechatIdeCache, D as getWechatIdeTestAccounts, E as compileWechatIdeByAutomator, F as quitWechatIde, G as transformArgv, H as execute, I as refreshWechatIdeTicket, J as openWechatIdeProjectByHttp, K as promptForCliPath, L as resetWechatIdeFileUtils, M as openWechatIde, N as openWechatIdeOtherProject, O as getWechatIdeTicket, P as previewWechatIde, Q as startWechatIdeEngineBuildByHttp, R as setWechatIdeTicket, S as buildWechatIdeNpm, T as closeWechatIdeProject, U as createAlias, V as runWechatCliWithRetry, W as createPathCompat, X as requestWechatDevtoolsHttp, Y as pollWechatIdeEngineBuildResultByHttp, Z as resetWechatIdeFileUtilsByHttp, _ as autoPreviewWechatIde, a as navigateBack, b as buildWechatIdeApk, c as pageStack, d as remote, et as setRuntimeWechatDevtoolsServicePort, f as scrollTo, g as tap, h as takeScreenshot, i as input, it as removeOption, j as loginWechatIde, k as getWechatIdeToolInfo, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, nt as readBooleanOption, o as navigateTo, p as switchTab, q as WECHAT_DEVTOOLS_ENGINE_BUILD_STATUSES, r as currentPage, rt as readOptionValue, s as pageData, t as audit, tt as parseAutomatorArgs, u as redirectTo, v as autoReplayWechatIde, w as clearWechatIdeCacheByAutomator, x as buildWechatIdeIpa, y as autoWechatIde, z as uploadWechatIde } from "./commands-8Wamgvv0.js";
3
- import { C as parseCompareArgs, S as printScreenshotHelp, _ as AUTOMATOR_COMMAND_NAMES, a as runMinidev, b as runAutomatorCommand, c as runWechatIdeEngineBuild, d as CONFIG_COMMAND_NAME, f as MCP_COMMAND_NAME, g as isWeappIdeTopLevelCommand, h as WECHAT_CLI_COMMAND_NAMES, i as validateWechatCliCommandArgs, l as runWechatIdeEngineBuildByHttp, m as WEAPP_IDE_TOP_LEVEL_COMMAND_NAMES, n as parse, o as startForwardConsole, p as MINIDEV_NAMESPACE_COMMAND_NAMES, r as dispatchWechatCliCommand, s as isWechatIdeEngineBuildEndpointMissingError, t as createCli, u as handleConfigCommand, v as getAutomatorCommandHelp, w as printCompareHelp, x as parseScreenshotArgs, y as isAutomatorCommand } from "./cli-Cy53rG5o.js";
4
- import { a as readElementSnapshot, i as registerWeappIdeMcpTools, n as startWeappIdeMcpServer, o as resolveProjectPath, r as createWeappIdeMcpServer, s as toSerializableValue, t as runMcpCommand } from "./run-mcp-L4shbBPP.js";
1
+ import { $ as overwriteCustomConfig, A as isAutomatorProtocolTimeoutError, B as getConfig, D as formatAutomatorLoginError, E as connectOpenedAutomator, F as launchAutomator, G as isOperatingSystemSupported, H as resolveDevtoolsAutomationDefaults, I as resolveProjectAutomatorPort, K as operatingSystemName, L as bootstrapWechatDevtoolsSettings, M as isDevtoolsExtensionContextInvalidatedError, N as isDevtoolsHttpPortError, O as getAutomatorProtocolTimeoutMethod, P as isRetryableAutomatorLaunchError, Q as createLocaleConfig, R as detectWechatDevtoolsServicePort, S as waitForExclusiveKeypress, U as SupportedPlatformsMap, V as getConfiguredLocale, W as getDefaultCliPath, X as createAutoTrustProjectConfig, Y as createAutoBootstrapDevtoolsConfig, Z as createCustomConfig, _ as promptRetryKeypress, a as releaseSharedMiniProgram, b as createSharedInputSession, c as RETRY_CANCEL_KEYS, d as createWechatIdeLoginRequiredExitError, et as readCustomConfig, f as extractExecutionErrorText, g as isWechatIdeLoginRequiredExitError, h as isWechatIdeLoginRequiredError, i as getSharedMiniProgramSessionCount, it as resolvePath, j as isAutomatorWsConnectError, k as isAutomatorLoginError, l as RETRY_CONFIRM_KEYS, m as formatWechatIdeLoginRequiredError, n as closeSharedMiniProgram, nt as defaultCustomConfigDirPath, o as withMiniProgram, p as formatRetryHotkeyPrompt, r as connectMiniProgram, rt as defaultCustomConfigFilePath, s as runRetryableCommand, t as acquireSharedMiniProgram, tt as removeCustomConfigKey, u as RETRY_PROMPT_INITIAL_IGNORE_MS, v as promptWechatIdeLoginRetry, x as runWithSuspendedSharedInput, y as waitForRetryKeypress, z as resolveCliPath } from "./automator-session-C8JdS2rx.js";
2
+ import { $ as getRuntimeWechatDevtoolsServicePort, A as isWechatIdeLoggedIn, C as clearWechatIdeCache, D as getWechatIdeTestAccounts, E as compileWechatIdeByAutomator, F as quitWechatIde, G as transformArgv, H as execute, I as refreshWechatIdeTicket, J as openWechatIdeProjectByHttp, K as promptForCliPath, L as resetWechatIdeFileUtils, M as openWechatIde, N as openWechatIdeOtherProject, O as getWechatIdeTicket, P as previewWechatIde, Q as startWechatIdeEngineBuildByHttp, R as setWechatIdeTicket, S as buildWechatIdeNpm, T as closeWechatIdeProject, U as createAlias, V as runWechatCliWithRetry, W as createPathCompat, X as requestWechatDevtoolsHttp, Y as pollWechatIdeEngineBuildResultByHttp, Z as resetWechatIdeFileUtilsByHttp, _ as autoPreviewWechatIde, a as navigateBack, b as buildWechatIdeApk, c as pageStack, d as remote, et as setRuntimeWechatDevtoolsServicePort, f as scrollTo, g as tap, h as takeScreenshot, i as input, it as removeOption, j as loginWechatIde, k as getWechatIdeToolInfo, l as reLaunch, m as systemInfo, n as captureScreenshotBuffer, nt as readBooleanOption, o as navigateTo, p as switchTab, q as WECHAT_DEVTOOLS_ENGINE_BUILD_STATUSES, r as currentPage, rt as readOptionValue, s as pageData, t as audit, tt as parseAutomatorArgs, u as redirectTo, v as autoReplayWechatIde, w as clearWechatIdeCacheByAutomator, x as buildWechatIdeIpa, y as autoWechatIde, z as uploadWechatIde } from "./commands-C6ATyJuz.js";
3
+ import { C as parseCompareArgs, S as printScreenshotHelp, _ as AUTOMATOR_COMMAND_NAMES, a as runMinidev, b as runAutomatorCommand, c as runWechatIdeEngineBuild, d as CONFIG_COMMAND_NAME, f as MCP_COMMAND_NAME, g as isWeappIdeTopLevelCommand, h as WECHAT_CLI_COMMAND_NAMES, i as validateWechatCliCommandArgs, l as runWechatIdeEngineBuildByHttp, m as WEAPP_IDE_TOP_LEVEL_COMMAND_NAMES, n as parse, o as startForwardConsole, p as MINIDEV_NAMESPACE_COMMAND_NAMES, r as dispatchWechatCliCommand, s as isWechatIdeEngineBuildEndpointMissingError, t as createCli, u as handleConfigCommand, v as getAutomatorCommandHelp, w as printCompareHelp, x as parseScreenshotArgs, y as isAutomatorCommand } from "./cli-BUx9wWVK.js";
4
+ import { a as readElementSnapshot, i as registerWeappIdeMcpTools, n as startWeappIdeMcpServer, o as resolveProjectPath, r as createWeappIdeMcpServer, s as toSerializableValue, t as runMcpCommand } from "./run-mcp-X00XjC8Z.js";
5
5
  export { AUTOMATOR_COMMAND_NAMES, CONFIG_COMMAND_NAME, MCP_COMMAND_NAME, MINIDEV_NAMESPACE_COMMAND_NAMES, RETRY_CANCEL_KEYS, RETRY_CONFIRM_KEYS, RETRY_PROMPT_INITIAL_IGNORE_MS, SupportedPlatformsMap, WEAPP_IDE_TOP_LEVEL_COMMAND_NAMES, WECHAT_CLI_COMMAND_NAMES, WECHAT_DEVTOOLS_ENGINE_BUILD_STATUSES, acquireSharedMiniProgram, audit, autoPreviewWechatIde, autoReplayWechatIde, autoWechatIde, bootstrapWechatDevtoolsSettings, buildWechatIdeApk, buildWechatIdeIpa, buildWechatIdeNpm, captureScreenshotBuffer, clearWechatIdeCache, clearWechatIdeCacheByAutomator, closeSharedMiniProgram, closeWechatIdeProject, compileWechatIdeByAutomator, connectMiniProgram, connectOpenedAutomator, createAlias, createAutoBootstrapDevtoolsConfig, createAutoTrustProjectConfig, createCli, createCustomConfig, createLocaleConfig, createPathCompat, createSharedInputSession, createWeappIdeMcpServer, createWechatIdeLoginRequiredExitError, currentPage, defaultCustomConfigDirPath, defaultCustomConfigFilePath, detectWechatDevtoolsServicePort, dispatchWechatCliCommand, execute, extractExecutionErrorText, formatAutomatorLoginError, formatRetryHotkeyPrompt, formatWechatIdeLoginRequiredError, getAutomatorCommandHelp, getAutomatorProtocolTimeoutMethod, getConfig, getConfiguredLocale, getDefaultCliPath, getRuntimeWechatDevtoolsServicePort, getSharedMiniProgramSessionCount, getWechatIdeTestAccounts, getWechatIdeTicket, getWechatIdeToolInfo, handleConfigCommand, input, isAutomatorCommand, isAutomatorLoginError, isAutomatorProtocolTimeoutError, isAutomatorWsConnectError, isDevtoolsExtensionContextInvalidatedError, isDevtoolsHttpPortError, isOperatingSystemSupported, isRetryableAutomatorLaunchError, isWeappIdeTopLevelCommand, isWechatIdeEngineBuildEndpointMissingError, isWechatIdeLoggedIn, isWechatIdeLoginRequiredError, isWechatIdeLoginRequiredExitError, launchAutomator, loginWechatIde, navigateBack, navigateTo, openWechatIde, openWechatIdeOtherProject, openWechatIdeProjectByHttp, operatingSystemName, overwriteCustomConfig, pageData, pageStack, parse, parseAutomatorArgs, parseCompareArgs, parseScreenshotArgs, pollWechatIdeEngineBuildResultByHttp, previewWechatIde, printCompareHelp, printScreenshotHelp, promptForCliPath, promptRetryKeypress, promptWechatIdeLoginRetry, quitWechatIde, reLaunch, readBooleanOption, readCustomConfig, readElementSnapshot, readOptionValue, redirectTo, refreshWechatIdeTicket, registerWeappIdeMcpTools, releaseSharedMiniProgram, remote, removeCustomConfigKey, removeOption, requestWechatDevtoolsHttp, resetWechatIdeFileUtils, resetWechatIdeFileUtilsByHttp, resolveCliPath, resolveDevtoolsAutomationDefaults, resolvePath, resolveProjectAutomatorPort, resolveProjectPath, runAutomatorCommand, runMcpCommand, runMinidev, runRetryableCommand, runWechatCliWithRetry, runWechatIdeEngineBuild, runWechatIdeEngineBuildByHttp, runWithSuspendedSharedInput, scrollTo, setRuntimeWechatDevtoolsServicePort, setWechatIdeTicket, startForwardConsole, startWeappIdeMcpServer, startWechatIdeEngineBuildByHttp, switchTab, systemInfo, takeScreenshot, tap, toSerializableValue, transformArgv, uploadWechatIde, validateWechatCliCommandArgs, waitForExclusiveKeypress, waitForRetryKeypress, withMiniProgram };
@@ -0,0 +1,2 @@
1
+ import { t as runMcpCommand } from "./run-mcp-X00XjC8Z.js";
2
+ export { runMcpCommand };
@@ -1,4 +1,4 @@
1
- import { o as withMiniProgram$1 } from "./automator-session-JEM5q8tK.js";
1
+ import { o as withMiniProgram$1 } from "./automator-session-C8JdS2rx.js";
2
2
  import { Buffer } from "node:buffer";
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
@@ -298,7 +298,7 @@ function registerWeappIdeMcpTools(server, options) {
298
298
  try {
299
299
  const result = await withConnectedMiniProgram(options.runtimeHooks, workspaceRoot, input, async (miniProgram) => {
300
300
  const screenshot = await miniProgram.screenshot();
301
- const base64 = typeof screenshot === "string" ? screenshot : Buffer.from(screenshot).toString("base64");
301
+ const base64 = typeof screenshot === "string" ? screenshot : Buffer.from(screenshot ?? "").toString("base64");
302
302
  const buffer = Buffer.from(base64, "base64");
303
303
  if (input.outputPath) {
304
304
  const resolvedOutputPath = createResolvedOutputPath(workspaceRoot, input.outputPath);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weapp-ide-cli",
3
3
  "type": "module",
4
- "version": "5.4.6",
4
+ "version": "5.4.8",
5
5
  "description": "让微信开发者工具,用起来更加方便!",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -71,8 +71,8 @@
71
71
  "zod": "^4.4.3",
72
72
  "@weapp-core/logger": "3.1.1",
73
73
  "@weapp-core/shared": "3.0.4",
74
- "@weapp-vite/devtools-runtime": "0.4.4",
75
- "@weapp-vite/miniprogram-automator": "1.2.3"
74
+ "@weapp-vite/miniprogram-automator": "1.2.5",
75
+ "@weapp-vite/devtools-runtime": "0.4.6"
76
76
  },
77
77
  "scripts": {
78
78
  "dev": "tsdown -w --sourcemap",
@@ -1,2 +0,0 @@
1
- import { h as takeScreenshot } from "./commands-8Wamgvv0.js";
2
- export { takeScreenshot };
@@ -1,2 +0,0 @@
1
- import { t as runMcpCommand } from "./run-mcp-L4shbBPP.js";
2
- export { runMcpCommand };