@ait-co/devtools 0.1.136 → 0.1.137

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 (45) hide show
  1. package/dist/bundle-BKqyhEK9.d.ts.map +1 -1
  2. package/dist/{debug-server-DApo0o3t.js → debug-server-BQplCzf8.js} +21 -3
  3. package/dist/debug-server-BQplCzf8.js.map +1 -0
  4. package/dist/{debug-server-BZtH2Z5b.js → debug-server-CBK7dn8O.js} +19 -1
  5. package/dist/debug-server-CBK7dn8O.js.map +1 -0
  6. package/dist/mcp/cli.js +70 -19
  7. package/dist/mcp/cli.js.map +1 -1
  8. package/dist/mcp/server.js +1 -1
  9. package/dist/panel/index.js +1 -1
  10. package/dist/{pool-C6TgrcyW.d.ts → pool-CmfvXnwh.d.ts} +2 -2
  11. package/dist/{pool-C6TgrcyW.d.ts.map → pool-CmfvXnwh.d.ts.map} +1 -1
  12. package/dist/{relay-factory-DnuTH4v-.js → relay-factory-DVzpBRxz.js} +3 -2
  13. package/dist/relay-factory-DVzpBRxz.js.map +1 -0
  14. package/dist/{relay-worker-UK0nBfDX.js → relay-worker-6fy1eaIo.js} +6 -3
  15. package/dist/{relay-worker-UK0nBfDX.js.map → relay-worker-6fy1eaIo.js.map} +1 -1
  16. package/dist/{relay-worker-Dw3aIzIK.d.ts → relay-worker-DJnZkXza.d.ts} +41 -7
  17. package/dist/relay-worker-DJnZkXza.d.ts.map +1 -0
  18. package/dist/test-runner/bin.js +108 -27
  19. package/dist/test-runner/bin.js.map +1 -1
  20. package/dist/test-runner/bridge-stub.d.ts +125 -0
  21. package/dist/test-runner/bridge-stub.d.ts.map +1 -0
  22. package/dist/test-runner/bridge-stub.js +92 -0
  23. package/dist/test-runner/bridge-stub.js.map +1 -0
  24. package/dist/test-runner/bundle.js +44 -14
  25. package/dist/test-runner/bundle.js.map +1 -1
  26. package/dist/test-runner/config.d.ts +11 -1
  27. package/dist/test-runner/config.d.ts.map +1 -1
  28. package/dist/test-runner/config.js +1 -1
  29. package/dist/test-runner/pool.d.ts +1 -1
  30. package/dist/test-runner/pool.js +1 -1
  31. package/dist/test-runner/relay-factory.d.ts +10 -0
  32. package/dist/test-runner/relay-factory.d.ts.map +1 -1
  33. package/dist/test-runner/relay-factory.js +2 -1
  34. package/dist/test-runner/relay-factory.js.map +1 -1
  35. package/dist/test-runner/relay-worker.d.ts +1 -1
  36. package/dist/test-runner/relay-worker.js +1 -1
  37. package/dist/test-runner/report.d.ts +41 -15
  38. package/dist/test-runner/report.d.ts.map +1 -1
  39. package/dist/test-runner/report.js +33 -9
  40. package/dist/test-runner/report.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/debug-server-BZtH2Z5b.js.map +0 -1
  43. package/dist/debug-server-DApo0o3t.js.map +0 -1
  44. package/dist/relay-factory-DnuTH4v-.js.map +0 -1
  45. package/dist/relay-worker-Dw3aIzIK.d.ts.map +0 -1
package/dist/mcp/cli.js CHANGED
@@ -2024,7 +2024,7 @@ async function readMcpSdkVersion() {
2024
2024
  * some test environments that skip the build step).
2025
2025
  */
2026
2026
  function readDevtoolsVersion() {
2027
- return "0.1.136";
2027
+ return "0.1.137";
2028
2028
  }
2029
2029
  /**
2030
2030
  * Derives the next recommended action from a completed diagnostics snapshot.
@@ -3827,6 +3827,16 @@ const SDK_IMPORT_FILTER = new RegExp(`^${SDK_PACKAGE.replace(/[.*+?^${}()|[\]\\]
3827
3827
  *
3828
3828
  * If `window.__sdk` is absent (non-dog-food build), every access throws a
3829
3829
  * descriptive error rather than returning `undefined` silently.
3830
+ *
3831
+ * Bridge-stub interception (devtools#740, DT-2): the virtual module runs the
3832
+ * resolved `window.__sdk` object through `wrapSdkWithStub` before exporting
3833
+ * it. `wrapSdkWithStub` is a pass-through (returns the same object,
3834
+ * unwrapped) unless `isStubBlockingEnabled()` reads `true` off
3835
+ * `globalThis.__AIT_STUB_BLOCKING__` — an opt-in flag injected the same way
3836
+ * `__AIT_CELL__` is (`cell.ts#injectGlobals`, wired from the CLI's
3837
+ * `--stub-blocking` flag). Default off => zero behavior change: every existing
3838
+ * (non-stub) test run resolves the exact same `window.__sdk` reference it did
3839
+ * before this plugin learned about stubbing.
3830
3840
  */
3831
3841
  function sdkRedirectPlugin() {
3832
3842
  return {
@@ -3841,16 +3851,19 @@ function sdkRedirectPlugin() {
3841
3851
  namespace: "sdk-redirect"
3842
3852
  }, () => ({
3843
3853
  contents: `
3844
- var __proxy = (typeof window !== 'undefined' && window.__sdk)
3854
+ import { wrapSdkWithStub, isStubBlockingEnabled } from ${JSON.stringify(getBridgeStubPath())};
3855
+ var __rawSdk = (typeof window !== 'undefined' && window.__sdk)
3845
3856
  ? window.__sdk
3846
3857
  : new Proxy({}, {
3847
3858
  get: function(_t, p) {
3848
3859
  throw new Error('window.__sdk is not installed — run in a dog-food build. Missing: ' + String(p));
3849
3860
  }
3850
3861
  });
3862
+ var __proxy = wrapSdkWithStub(__rawSdk, isStubBlockingEnabled());
3851
3863
  module.exports = __proxy;
3852
3864
  `,
3853
- loader: "js"
3865
+ loader: "js",
3866
+ resolveDir: process.cwd()
3854
3867
  }));
3855
3868
  }
3856
3869
  };
@@ -3984,8 +3997,9 @@ function userFactoryPlugin(absPath) {
3984
3997
  };
3985
3998
  }
3986
3999
  /**
3987
- * Returns the absolute filesystem path to the test-runner runtime module
3988
- * (dist/test-runner/runtime.js — a fully self-contained page-side bundle).
4000
+ * Returns the absolute filesystem path to a page-side leaf module shipped
4001
+ * alongside `bundle.ts` in dist (e.g. `runtime.js`, `bridge-stub.js`) — a
4002
+ * fully self-contained module with no further page-side deps of its own.
3989
4003
  *
3990
4004
  * Rolldown code-splitting duplicates this bundling logic into shared chunks
3991
4005
  * emitted at ARBITRARY dist depths: the `devtools-test` CLI pulls it from
@@ -3995,26 +4009,30 @@ function userFactoryPlugin(absPath) {
3995
4009
  * is therefore wrong from at least one chunk — the live #697 regression.
3996
4010
  *
3997
4011
  * This resolves WITHOUT assuming chunk depth: from `import.meta.url`'s dir it
3998
- * probes the co-located `runtime.js` and the nested `test-runner/runtime.js`,
4012
+ * probes the co-located `<name>.js` and the nested `test-runner/<name>.js`,
3999
4013
  * then ascends one directory at a time (bounded) repeating both probes. The
4000
- * nested probe catches dist/test-runner/runtime.js from the dist/ root level no
4014
+ * nested probe catches dist/test-runner/<name>.js from the dist/ root level no
4001
4015
  * matter which depth the chunk was hoisted to (root, dist/mcp/, or a future
4002
- * relocation). The build always emits dist/test-runner/runtime.js (tsdown entry
4003
- * `'test-runner/runtime'`; guarded by scripts/check-test-runner-dist.sh).
4016
+ * relocation). The build always emits dist/test-runner/<name>.js (tsdown entry
4017
+ * `'test-runner/<name>'`; guarded by scripts/check-test-runner-dist.sh for
4018
+ * `runtime`).
4004
4019
  *
4005
4020
  * An ABSOLUTE path is returned deliberately: esbuild loads it as a literal file
4006
4021
  * read, bypassing Node module resolution entirely, so this works identically in
4007
4022
  * the npx-daemon context (its own dist tree) and the consumer-CLI context
4008
4023
  * (the mini-app's installed @ait-co/devtools dist) — neither needs the package
4009
4024
  * to be node-resolvable from the caller.
4025
+ *
4026
+ * @param moduleName - The leaf module's basename without extension, e.g.
4027
+ * `'runtime'` or `'bridge-stub'`.
4010
4028
  */
4011
- function getRuntimePath() {
4029
+ function getPageSideModulePath(moduleName) {
4012
4030
  const startDir = path.dirname(fileURLToPath(import.meta.url));
4013
4031
  const RELATIVE_PROBES = [
4014
- ["runtime.js"],
4015
- ["test-runner", "runtime.js"],
4016
- ["runtime.ts"],
4017
- ["test-runner", "runtime.ts"]
4032
+ [`${moduleName}.js`],
4033
+ ["test-runner", `${moduleName}.js`],
4034
+ [`${moduleName}.ts`],
4035
+ ["test-runner", `${moduleName}.ts`]
4018
4036
  ];
4019
4037
  let dir = startDir;
4020
4038
  for (let i = 0; i < 12; i++) {
@@ -4029,7 +4047,19 @@ function getRuntimePath() {
4029
4047
  if (parent === dir) break;
4030
4048
  dir = parent;
4031
4049
  }
4032
- return path.join(startDir, "runtime.js");
4050
+ return path.join(startDir, `${moduleName}.js`);
4051
+ }
4052
+ /** Absolute path to the test-runner page-side runtime (describe/it/test/expect). */
4053
+ function getRuntimePath() {
4054
+ return getPageSideModulePath("runtime");
4055
+ }
4056
+ /**
4057
+ * Absolute path to the bridge-stub interceptor (devtools#740, DT-2) —
4058
+ * `wrapSdkWithStub`/`isStubBlockingEnabled`, statically imported by the
4059
+ * `sdk-redirect` virtual module.
4060
+ */
4061
+ function getBridgeStubPath() {
4062
+ return getPageSideModulePath("bridge-stub");
4033
4063
  }
4034
4064
  /**
4035
4065
  * Bundles `absPath` into a single IIFE string suitable for `Runtime.evaluate`.
@@ -4303,6 +4333,7 @@ async function runTestFilesOverRelay(connection, files, opts) {
4303
4333
  const manualFiles = opts?.manualFiles;
4304
4334
  const manualTotal = manualFiles?.size ?? 0;
4305
4335
  let manualIndex = 0;
4336
+ const stubBlockingFiles = opts?.stubBlockingFiles;
4306
4337
  let preflightPermissions;
4307
4338
  if (files.length > 0) preflightPermissions = await runPermissionPreflight(connection);
4308
4339
  try {
@@ -4311,7 +4342,8 @@ async function runTestFilesOverRelay(connection, files, opts) {
4311
4342
  await attemptReconnect("next-file");
4312
4343
  pendingReconnectCheck = false;
4313
4344
  }
4314
- const isManual = manualFiles?.has(file) === true;
4345
+ const isStubbed = stubBlockingFiles?.has(file) === true;
4346
+ const isManual = !isStubbed && manualFiles?.has(file) === true;
4315
4347
  if (isManual) {
4316
4348
  manualIndex += 1;
4317
4349
  opts?.onManualFile?.(file, manualIndex, manualTotal);
@@ -4378,7 +4410,8 @@ async function runTestFilesOverRelay(connection, files, opts) {
4378
4410
  };
4379
4411
  }
4380
4412
  if ("error" in fileEntry.result && isRelayDisconnectMessage(fileEntry.result.error)) pendingReconnectCheck = true;
4381
- if (isManual) fileEntry.mode = "manual";
4413
+ if (isStubbed) fileEntry.mode = "stubbed";
4414
+ else if (isManual) fileEntry.mode = "manual";
4382
4415
  fileResults.push(fileEntry);
4383
4416
  }
4384
4417
  } finally {
@@ -4490,6 +4523,24 @@ OPTIONS
4490
4523
  each manual file's report entry is stamped
4491
4524
  mode: 'manual' — never diff a manual run against an
4492
4525
  unattended baseline as if they were equivalent.
4526
+ --stub-blocking Run manual-tagged test files (*.manual.ait.test.ts)
4527
+ UNATTENDED (devtools#740, DT-2) by intercepting a
4528
+ fixed allowlist of blocking-UI SDK calls (ads
4529
+ show*, openPermissionDialog/requestPermission,
4530
+ saveBase64Data) in the page and answering them from
4531
+ fixtures captured by a real --manual-blocking run,
4532
+ instead of forwarding them to native UI. Implies
4533
+ --manual-blocking (manual files are included in the
4534
+ run); no human presence or QR-dashboard prompt is
4535
+ needed for them. HYBRID cell, not pure env3 — every
4536
+ other SDK call in the same run still hits the real
4537
+ native bridge. With --report-dir, files that ran
4538
+ under the stub are written to a SEPARATE
4539
+ <sdkLine>.<platform>.stubbed.json artifact (never
4540
+ merged into the standard or .manual.json report) and
4541
+ the report body is stamped cell.bridgeStub: true —
4542
+ never diff a stubbed run against a real device
4543
+ baseline (manual or unattended) as if equivalent.
4493
4544
  --help, -h Show this help message
4494
4545
 
4495
4546
  DESCRIPTION
@@ -7205,7 +7256,7 @@ function createDebugServer(deps) {
7205
7256
  };
7206
7257
  const server = new Server({
7207
7258
  name: "ait-debug",
7208
- version: "0.1.136"
7259
+ version: "0.1.137"
7209
7260
  }, { capabilities: { tools: { listChanged: true } } });
7210
7261
  server.setRequestHandler(ListToolsRequestSchema, () => {
7211
7262
  const conn = router.active;
@@ -9189,7 +9240,7 @@ function createDevServer(deps = {}) {
9189
9240
  const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
9190
9241
  const server = new Server({
9191
9242
  name: "ait-devtools",
9192
- version: "0.1.136"
9243
+ version: "0.1.137"
9193
9244
  }, { capabilities: { tools: {} } });
9194
9245
  server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
9195
9246
  server.setRequestHandler(CallToolRequestSchema, async (request) => {