@ait-co/devtools 0.1.132 → 0.1.134

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 (85) hide show
  1. package/dist/{attach-orchestrator-ca34r46y.js → attach-orchestrator-CE0S09YU.js} +110 -5
  2. package/dist/attach-orchestrator-CE0S09YU.js.map +1 -0
  3. package/dist/{attach-orchestrator-BiaYiNOr.js → attach-orchestrator-CMoDuG2A.js} +110 -5
  4. package/dist/attach-orchestrator-CMoDuG2A.js.map +1 -0
  5. package/dist/{cdp-connection-D7AYQck2.d.ts → cdp-connection-BYE9meXe.d.ts} +12 -2
  6. package/dist/{cdp-connection-D7AYQck2.d.ts.map → cdp-connection-BYE9meXe.d.ts.map} +1 -1
  7. package/dist/cell-BIdSQb9T.js +201 -0
  8. package/dist/cell-BIdSQb9T.js.map +1 -0
  9. package/dist/{cell-Cw4fVOl2.js → cell-D1y4shoV.js} +1 -21
  10. package/dist/cell-D1y4shoV.js.map +1 -0
  11. package/dist/cell-DHA578lX.js +200 -0
  12. package/dist/cell-DHA578lX.js.map +1 -0
  13. package/dist/{debug-server-Ch5p0ryv.js → debug-server-BcSBrajf.js} +19 -9
  14. package/dist/debug-server-BcSBrajf.js.map +1 -0
  15. package/dist/{debug-server-DoWAtTNj.js → debug-server-D9SmprUI.js} +7 -8
  16. package/dist/{debug-server-DoWAtTNj.js.map → debug-server-D9SmprUI.js.map} +1 -1
  17. package/dist/{debug-server-BBUzxZSf.js → debug-server-DnNCoNiR.js} +7 -7
  18. package/dist/{debug-server-BBUzxZSf.js.map → debug-server-DnNCoNiR.js.map} +1 -1
  19. package/dist/mcp/cli.js +149 -16
  20. package/dist/mcp/cli.js.map +1 -1
  21. package/dist/mcp/server.js +1 -1
  22. package/dist/panel/index.js +1 -1
  23. package/dist/{pool-BtLh7U1y.d.ts → pool-C6TgrcyW.d.ts} +3 -3
  24. package/dist/{pool-BtLh7U1y.d.ts.map → pool-C6TgrcyW.d.ts.map} +1 -1
  25. package/dist/{qr-http-server-KB147M-S.js → qr-http-server-C_DTp9WU.js} +1 -1
  26. package/dist/{qr-http-server-KB147M-S.js.map → qr-http-server-C_DTp9WU.js.map} +1 -1
  27. package/dist/{relay-factory-cNgPfrWg.js → relay-factory-CsVO9o25.js} +6 -6
  28. package/dist/{relay-factory-cNgPfrWg.js.map → relay-factory-CsVO9o25.js.map} +1 -1
  29. package/dist/{relay-secret-store-CFc9n0OA.js → relay-secret-store-CLEGyHou.js} +2 -2
  30. package/dist/{relay-secret-store-CFc9n0OA.js.map → relay-secret-store-CLEGyHou.js.map} +1 -1
  31. package/dist/{relay-secret-store-DzxDsK6S.js → relay-secret-store-DGduVJhs.js} +2 -2
  32. package/dist/{relay-secret-store-DzxDsK6S.js.map → relay-secret-store-DGduVJhs.js.map} +1 -1
  33. package/dist/{relay-url-store-D3rY-GJJ.js → relay-url-store-B0X8TsGr.js} +2 -2
  34. package/dist/{relay-url-store-D3rY-GJJ.js.map → relay-url-store-B0X8TsGr.js.map} +1 -1
  35. package/dist/{relay-url-store-DGQ-HPQC.js → relay-url-store-CKW8RQzf.js} +2 -2
  36. package/dist/{relay-url-store-DGQ-HPQC.js.map → relay-url-store-CKW8RQzf.js.map} +1 -1
  37. package/dist/{relay-worker-BMSnlyls.d.ts → relay-worker-Dw3aIzIK.d.ts} +15 -3
  38. package/dist/relay-worker-Dw3aIzIK.d.ts.map +1 -0
  39. package/dist/{relay-worker-l34xNuci.js → relay-worker-UK0nBfDX.js} +25 -11
  40. package/dist/relay-worker-UK0nBfDX.js.map +1 -0
  41. package/dist/rolldown-runtime-DGkTqVfb.js +15 -0
  42. package/dist/rolldown-runtime-DUslC3ob.js +14 -0
  43. package/dist/{runtime-9xhN9pr8.d.ts → runtime-DfHHZms2.d.ts} +34 -5
  44. package/dist/runtime-DfHHZms2.d.ts.map +1 -0
  45. package/dist/test-runner/bin.js +47 -112
  46. package/dist/test-runner/bin.js.map +1 -1
  47. package/dist/test-runner/config.d.ts +1 -1
  48. package/dist/test-runner/config.js +1 -1
  49. package/dist/test-runner/pool.d.ts +1 -1
  50. package/dist/test-runner/pool.js +1 -1
  51. package/dist/test-runner/relay-factory.d.ts +12 -2
  52. package/dist/test-runner/relay-factory.d.ts.map +1 -1
  53. package/dist/test-runner/relay-factory.js +3 -3
  54. package/dist/test-runner/relay-worker.d.ts +1 -1
  55. package/dist/test-runner/relay-worker.js +1 -1
  56. package/dist/test-runner/report.d.ts +11 -2
  57. package/dist/test-runner/report.d.ts.map +1 -1
  58. package/dist/test-runner/report.js +1 -0
  59. package/dist/test-runner/report.js.map +1 -1
  60. package/dist/test-runner/rpc.d.ts +8 -5
  61. package/dist/test-runner/rpc.d.ts.map +1 -1
  62. package/dist/test-runner/rpc.js +15 -4
  63. package/dist/test-runner/rpc.js.map +1 -1
  64. package/dist/test-runner/runtime.d.ts +2 -2
  65. package/dist/test-runner/runtime.js +30 -4
  66. package/dist/test-runner/runtime.js.map +1 -1
  67. package/dist/test-runner/task-graph.d.ts +1 -1
  68. package/dist/{totp-DvOYkYim.js → totp-CZLLKfOC.js} +2 -14
  69. package/dist/{totp-DvOYkYim.js.map → totp-CZLLKfOC.js.map} +1 -1
  70. package/dist/totp-DAxys-r0.js +199 -0
  71. package/dist/totp-DAxys-r0.js.map +1 -0
  72. package/package.json +1 -1
  73. package/dist/attach-orchestrator-BiaYiNOr.js.map +0 -1
  74. package/dist/attach-orchestrator-ca34r46y.js.map +0 -1
  75. package/dist/cell-Bi8MAPA8.js +0 -88
  76. package/dist/cell-Bi8MAPA8.js.map +0 -1
  77. package/dist/cell-Cw4fVOl2.js.map +0 -1
  78. package/dist/cell-rr6gL9AT.js +0 -89
  79. package/dist/cell-rr6gL9AT.js.map +0 -1
  80. package/dist/debug-server-Ch5p0ryv.js.map +0 -1
  81. package/dist/log-CUik_tHp.js +0 -95
  82. package/dist/log-CUik_tHp.js.map +0 -1
  83. package/dist/relay-worker-BMSnlyls.d.ts.map +0 -1
  84. package/dist/relay-worker-l34xNuci.js.map +0 -1
  85. package/dist/runtime-9xhN9pr8.d.ts.map +0 -1
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { r as generateTotp } from "../totp-DvOYkYim.js";
2
+ import { m as logInfo } from "../attach-orchestrator-CE0S09YU.js";
3
+ import { r as generateTotp } from "../totp-CZLLKfOC.js";
4
+ import { n as runPermissionPreflight } from "../cell-BIdSQb9T.js";
3
5
  import * as path$1 from "node:path";
4
6
  import path, { basename, isAbsolute, resolve } from "node:path";
5
7
  import { parseArgs } from "node:util";
@@ -117,10 +119,10 @@ function createRelayConnectionFactory(opts) {
117
119
  let manualPrompt = null;
118
120
  return {
119
121
  async open() {
120
- const { prepareAttach, renderAndMaybeWait, mintAttachUrl } = await import("../attach-orchestrator-ca34r46y.js");
121
- const { injectDebugIndicator, injectGlobals } = await import("../cell-rr6gL9AT.js");
122
- const { loadRelaySecretReadOnly } = await import("../relay-secret-store-CFc9n0OA.js");
123
- const { bootRelayFamily, buildRelayVerifyAuth } = await import("../debug-server-BBUzxZSf.js");
122
+ const { prepareAttach, renderAndMaybeWait, mintAttachUrl } = await import("../attach-orchestrator-CE0S09YU.js").then((n) => n.i);
123
+ const { injectDebugIndicator, injectGlobals } = await import("../cell-BIdSQb9T.js").then((n) => n.t);
124
+ const { loadRelaySecretReadOnly } = await import("../relay-secret-store-CLEGyHou.js");
125
+ const { bootRelayFamily, buildRelayVerifyAuth } = await import("../debug-server-DnNCoNiR.js");
124
126
  await loadRelaySecretReadOnly({ projectRoot });
125
127
  let resolveTunnelUp;
126
128
  const tunnelReady = new Promise((resolve) => {
@@ -150,7 +152,7 @@ function createRelayConnectionFactory(opts) {
150
152
  canOpenBrowser: () => !headless
151
153
  };
152
154
  try {
153
- const { startQrHttpServer } = await import("../qr-http-server-KB147M-S.js");
155
+ const { startQrHttpServer } = await import("../qr-http-server-C_DTp9WU.js");
154
156
  const getDashboardState = () => ({
155
157
  tunnel: attachDeps.getTunnelStatus(),
156
158
  pages: null,
@@ -224,7 +226,7 @@ function createRelayConnectionFactory(opts) {
224
226
  qrServer?.notifyStateChange();
225
227
  }
226
228
  try {
227
- const { injectDebugIndicator } = await import("../cell-rr6gL9AT.js");
229
+ const { injectDebugIndicator } = await import("../cell-BIdSQb9T.js").then((n) => n.t);
228
230
  await injectDebugIndicator(connection, { state: "disconnected" });
229
231
  } catch {}
230
232
  family?.stop();
@@ -276,98 +278,6 @@ const RELAY_AUTH_REJECT_CLOSE_CODE = 4401;
276
278
  */
277
279
  const RELAY_AUTH_REJECT_REASON = "totp-rejected";
278
280
  //#endregion
279
- //#region src/mcp/log.ts
280
- /**
281
- * Allowed field keys that may pass through to a log line.
282
- * Unknown keys are dropped. Values are still redact-scanned.
283
- */
284
- const ALLOWED_KEYS = new Set([
285
- "ts",
286
- "level",
287
- "event",
288
- "msg",
289
- "port",
290
- "totpEnabled",
291
- "env",
292
- "tool",
293
- "deploymentId",
294
- "errorKind",
295
- "reason",
296
- "prevTargetId",
297
- "mode",
298
- "fileCount",
299
- "passed",
300
- "failed",
301
- "skipped"
302
- ]);
303
- /**
304
- * Patterns that match secret values.
305
- * Match order matters — more-specific patterns first.
306
- *
307
- * #268 redact script covers: relay=wss://…, at=<TOTP>, _deploymentId=<uuid>.
308
- * Here we extend to in-process value-level patterns used in server logs.
309
- */
310
- const SECRET_PATTERNS = [
311
- /^\d{6}$/,
312
- /^(aitcc_|AITCC_)/i,
313
- /^[A-Za-z0-9_-]+=.{4,}/,
314
- /^wss:\/\//,
315
- /(?:^|[?&])at=[A-Z0-9]{6}/i
316
- ];
317
- /**
318
- * Returns `true` when the string value matches any known-secret pattern.
319
- * Only string values are tested — numbers/booleans are always safe.
320
- */
321
- function isSecretValue(value) {
322
- return SECRET_PATTERNS.some((re) => re.test(value));
323
- }
324
- /**
325
- * Redacts a single scalar value.
326
- * - strings: return "***" if the value matches a secret pattern.
327
- * - other: return as-is.
328
- */
329
- function redactValue(value) {
330
- if (typeof value === "string" && isSecretValue(value)) return "***";
331
- return value;
332
- }
333
- /**
334
- * Builds a safe log payload from raw fields.
335
- *
336
- * - Only keys in `ALLOWED_KEYS` are included.
337
- * - String values are scanned for secret patterns and replaced with "***".
338
- * - `ts` and `level` and `event` are always included (they are injected by the
339
- * logger functions below, not by callers).
340
- */
341
- function buildPayload(level, event, fields) {
342
- const out = {
343
- ts: (/* @__PURE__ */ new Date()).toISOString(),
344
- level,
345
- event
346
- };
347
- for (const [key, value] of Object.entries(fields)) {
348
- if (!ALLOWED_KEYS.has(key)) continue;
349
- if (key === "ts" || key === "level" || key === "event") continue;
350
- out[key] = redactValue(value);
351
- }
352
- return out;
353
- }
354
- /**
355
- * Writes a single JSON log line to stderr.
356
- * MCP stdio transport uses stdout; all diagnostics go to stderr.
357
- */
358
- function writeLog(level, event, fields = {}) {
359
- const payload = buildPayload(level, event, fields);
360
- process.stderr.write(`${JSON.stringify(payload)}\n`);
361
- }
362
- /** Log an informational structured event. */
363
- function logInfo(event, fields = {}) {
364
- writeLog("info", event, fields);
365
- }
366
- /** Log an error structured event. */
367
- function logError(event, fields = {}) {
368
- writeLog("error", event, fields);
369
- }
370
- //#endregion
371
281
  //#region src/mcp/chii-connection.ts
372
282
  /**
373
283
  * Production `CdpConnection` backed by the local Chii relay.
@@ -682,9 +592,13 @@ var ChiiCdpConnection = class {
682
592
  /**
683
593
  * Issue a CDP command and resolve with its result (Phase 2). Rejects on a CDP
684
594
  * error frame or when no websocket is open (no page attached yet).
595
+ *
596
+ * @param opts.timeoutMs - Per-call override for this connection's command
597
+ * watchdog (devtools#747) — see the `CdpConnection.send` docblock for the
598
+ * contract callers racing their own longer timeout must follow.
685
599
  */
686
- send(method, params) {
687
- return this.sendCommand(method, params ?? {});
600
+ send(method, params, opts) {
601
+ return this.sendCommand(method, params ?? {}, opts);
688
602
  }
689
603
  /**
690
604
  * Issue an arbitrary request→response command over the relay and resolve with
@@ -695,16 +609,22 @@ var ChiiCdpConnection = class {
695
609
  * auto-reconnect). Caller should re-run `list_pages` or `enableDomains` to
696
610
  * reattach.
697
611
  *
698
- * Times out after `commandTimeoutMs` (default 30s, env
699
- * `AIT_CDP_COMMAND_TIMEOUT_MS`). On timeout the pending entry is cleaned up
700
- * and the promise rejects with a descriptive Korean error.
612
+ * Times out after `opts.timeoutMs` when given, else `commandTimeoutMs`
613
+ * (default 30s, env `AIT_CDP_COMMAND_TIMEOUT_MS`) see devtools#747: the
614
+ * default 30s watchdog used to undercut the test-runner's own longer
615
+ * file-evaluate race no matter what `--timeout` the caller asked for. On
616
+ * timeout the pending entry is cleaned up and the promise rejects with a
617
+ * descriptive Korean error. `Number.isFinite` guards against a non-finite
618
+ * override (e.g. `Infinity`, mirroring `waitForFirstTarget`'s convention)
619
+ * so an intentional "no watchdog" override doesn't get clamped by
620
+ * `setTimeout`.
701
621
  */
702
- sendCommand(method, params = {}) {
622
+ sendCommand(method, params = {}, opts) {
703
623
  if (this.connectionState === "disconnected") return Promise.reject(/* @__PURE__ */ new Error(`relay에 연결되어 있지 않습니다 (${method}). list_pages로 attach 상태를 확인하고 enableDomains()로 재연결하세요.`));
704
624
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return Promise.reject(/* @__PURE__ */ new Error("No mini-app page attached to the Chii relay yet. Call enableDomains() first."));
705
625
  const id = this.nextCommandId++;
706
626
  const ws = this.ws;
707
- const timeoutMs = this.commandTimeoutMs;
627
+ const timeoutMs = opts?.timeoutMs !== void 0 && Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0 ? opts.timeoutMs : this.commandTimeoutMs;
708
628
  return new Promise((resolve, reject) => {
709
629
  const handle = setTimeout(() => {
710
630
  this.pending.delete(id);
@@ -1289,6 +1209,14 @@ function parseCaptureLines(raw) {
1289
1209
  /** Maximum milliseconds to wait for a single evaluate round-trip. */
1290
1210
  const DEFAULT_TIMEOUT_MS = 6e4;
1291
1211
  /**
1212
+ * Extra headroom (ms) added on top of the rpc-level `timeoutMs` when telling
1213
+ * the underlying `CdpConnection` its per-command watchdog budget (devtools#747).
1214
+ * The rpc-level race above is the authoritative file timeout — this margin
1215
+ * only ensures the connection's own (shorter-by-default) watchdog never fires
1216
+ * first and masks the rpc-level timeout error with a connection-level one.
1217
+ */
1218
+ const CONNECTION_TIMEOUT_MARGIN_MS = 5e3;
1219
+ /**
1292
1220
  * Wraps bundle code in a self-executing IIFE that:
1293
1221
  * 1. Evaluates the bundle (registering describe/it/test).
1294
1222
  * 2. Calls `__testBundle.runTestModule(...)` — the entry the runtime exports.
@@ -1335,12 +1263,15 @@ function parseRunTestsResult(rawValue) {
1335
1263
  * Injects `bundleCode` into the attached page and awaits test execution.
1336
1264
  *
1337
1265
  * Uses `Runtime.evaluate` with `awaitPromise: true` to wait for the
1338
- * async IIFE to settle. The 30-second CDP command timeout covers even
1339
- * long-running test suites; split into smaller files if you hit it.
1266
+ * async IIFE to settle. `timeoutMs` (default 60s) is the authoritative file
1267
+ * timeout this function races it against the evaluate call AND (devtools#747)
1268
+ * threads it down to the underlying `CdpConnection`'s own per-command watchdog
1269
+ * (plus a small margin) so that watchdog can never undercut this race. Split
1270
+ * into smaller files if you hit the timeout.
1340
1271
  *
1341
1272
  * @param connection - Active CDP connection (relay or local).
1342
1273
  * @param bundleCode - IIFE bundle string from `bundleTestFile`.
1343
- * @param timeoutMs - Override the default 30 s timeout.
1274
+ * @param timeoutMs - Override the default 60 s timeout.
1344
1275
  *
1345
1276
  * SECRET-HANDLING: `bundleCode` and the raw CDP result value are never logged.
1346
1277
  */
@@ -1352,7 +1283,7 @@ async function injectAndRunBundle(connection, bundleCode, timeoutMs = DEFAULT_TI
1352
1283
  expression,
1353
1284
  returnByValue: true,
1354
1285
  awaitPromise: true
1355
- });
1286
+ }, { timeoutMs: timeoutMs + CONNECTION_TIMEOUT_MARGIN_MS });
1356
1287
  const raceResult = await Promise.race([evalPromise.then((v) => ({
1357
1288
  tag: "eval",
1358
1289
  v
@@ -1451,6 +1382,8 @@ async function runTestFilesOverRelay(connection, files, opts) {
1451
1382
  const manualFiles = opts?.manualFiles;
1452
1383
  const manualTotal = manualFiles?.size ?? 0;
1453
1384
  let manualIndex = 0;
1385
+ let preflightPermissions;
1386
+ if (files.length > 0) preflightPermissions = await runPermissionPreflight(connection);
1454
1387
  try {
1455
1388
  for (const file of files) {
1456
1389
  if (pendingReconnectCheck) {
@@ -1553,7 +1486,8 @@ async function runTestFilesOverRelay(connection, files, opts) {
1553
1486
  duration: Date.now() - wallStart,
1554
1487
  files: fileResults,
1555
1488
  totals,
1556
- captures
1489
+ captures,
1490
+ ...preflightPermissions ? { preflight: { permissions: preflightPermissions } } : {}
1557
1491
  };
1558
1492
  }
1559
1493
  /**
@@ -1636,6 +1570,7 @@ function serializeRelayReport(report, meta) {
1636
1570
  startedAt: report.startedAt,
1637
1571
  duration: report.duration,
1638
1572
  totals: report.totals,
1573
+ ...report.preflight ? { preflight: report.preflight } : {},
1639
1574
  files: report.files.map((f) => {
1640
1575
  const file = relativise(meta.projectRoot, f.file);
1641
1576
  const modeField = f.mode === "manual" ? { mode: "manual" } : {};
@@ -2106,6 +2041,6 @@ main().catch((e) => {
2106
2041
  process.exitCode = 1;
2107
2042
  });
2108
2043
  //#endregion
2109
- export { RELAY_AUTH_REJECT_REASON as a, RELAY_AUTH_REJECT_CLOSE_CODE as i, logError as n, logInfo as r, ChiiCdpConnection as t };
2044
+ export { RELAY_AUTH_REJECT_CLOSE_CODE as n, RELAY_AUTH_REJECT_REASON as r, ChiiCdpConnection as t };
2110
2045
 
2111
2046
  //# sourceMappingURL=bin.js.map