@ait-co/devtools 0.1.131 → 0.1.133
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/dist/{attach-orchestrator-ca34r46y.js → attach-orchestrator-CE0S09YU.js} +110 -5
- package/dist/attach-orchestrator-CE0S09YU.js.map +1 -0
- package/dist/{attach-orchestrator-BiaYiNOr.js → attach-orchestrator-CMoDuG2A.js} +110 -5
- package/dist/attach-orchestrator-CMoDuG2A.js.map +1 -0
- package/dist/cell-BIdSQb9T.js +201 -0
- package/dist/cell-BIdSQb9T.js.map +1 -0
- package/dist/{cell-Cw4fVOl2.js → cell-D1y4shoV.js} +1 -21
- package/dist/cell-D1y4shoV.js.map +1 -0
- package/dist/cell-DHA578lX.js +200 -0
- package/dist/cell-DHA578lX.js.map +1 -0
- package/dist/{debug-server-qRSRG7YZ.js → debug-server-CS1BS2BX.js} +21 -3
- package/dist/debug-server-CS1BS2BX.js.map +1 -0
- package/dist/{debug-server-BSbfnFR5.js → debug-server-DmzuK2c6.js} +26 -9
- package/dist/debug-server-DmzuK2c6.js.map +1 -0
- package/dist/{debug-server-CD4zYBq4.js → debug-server-DnNCoNiR.js} +7 -7
- package/dist/{debug-server-CD4zYBq4.js.map → debug-server-DnNCoNiR.js.map} +1 -1
- package/dist/mcp/cli.js +180 -8
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/panel/index.js +1 -1
- package/dist/{pool-BaSCZALv.d.ts → pool-x28Wv1ty.d.ts} +16 -2
- package/dist/{pool-BaSCZALv.d.ts.map → pool-x28Wv1ty.d.ts.map} +1 -1
- package/dist/{qr-http-server-DCbjORFa.js → qr-http-server-C_DTp9WU.js} +3 -2
- package/dist/{qr-http-server-DCbjORFa.js.map → qr-http-server-C_DTp9WU.js.map} +1 -1
- package/dist/{qr-http-server-BxoRp2w7.cjs → qr-http-server-DX_9UA-p.cjs} +3 -2
- package/dist/qr-http-server-DX_9UA-p.cjs.map +1 -0
- package/dist/{qr-http-server-BdNGPRoL.js → qr-http-server-DeRrKp_R.js} +3 -2
- package/dist/{qr-http-server-BdNGPRoL.js.map → qr-http-server-DeRrKp_R.js.map} +1 -1
- package/dist/{qr-http-server-cKbciY5k.js → qr-http-server-FVn61xAq.js} +3 -2
- package/dist/{qr-http-server-Bq9zR7-z.js.map → qr-http-server-FVn61xAq.js.map} +1 -1
- package/dist/{qr-http-server-Bq9zR7-z.js → qr-http-server-V0xuU5TJ.js} +3 -2
- package/dist/{qr-http-server-cKbciY5k.js.map → qr-http-server-V0xuU5TJ.js.map} +1 -1
- package/dist/{qr-http-server-CV6TA9ZN.cjs → qr-http-server-iH_Hh_si.cjs} +3 -2
- package/dist/qr-http-server-iH_Hh_si.cjs.map +1 -0
- package/dist/{relay-factory-Cloog1jb.js → relay-factory-BQfmK7RP.js} +14 -8
- package/dist/relay-factory-BQfmK7RP.js.map +1 -0
- package/dist/{relay-secret-store-CFc9n0OA.js → relay-secret-store-CLEGyHou.js} +2 -2
- package/dist/{relay-secret-store-CFc9n0OA.js.map → relay-secret-store-CLEGyHou.js.map} +1 -1
- package/dist/{relay-secret-store-DzxDsK6S.js → relay-secret-store-DGduVJhs.js} +2 -2
- package/dist/{relay-secret-store-DzxDsK6S.js.map → relay-secret-store-DGduVJhs.js.map} +1 -1
- package/dist/{relay-url-store-D3rY-GJJ.js → relay-url-store-B0X8TsGr.js} +2 -2
- package/dist/{relay-url-store-D3rY-GJJ.js.map → relay-url-store-B0X8TsGr.js.map} +1 -1
- package/dist/{relay-url-store-DGQ-HPQC.js → relay-url-store-CKW8RQzf.js} +2 -2
- package/dist/{relay-url-store-DGQ-HPQC.js.map → relay-url-store-CKW8RQzf.js.map} +1 -1
- package/dist/{relay-worker-o0M2ndyJ.d.ts → relay-worker-DtX_eszH.d.ts} +51 -2
- package/dist/relay-worker-DtX_eszH.d.ts.map +1 -0
- package/dist/{relay-worker-CCAHLC4a.js → relay-worker-MZq4fLv8.js} +27 -6
- package/dist/{relay-worker-CCAHLC4a.js.map → relay-worker-MZq4fLv8.js.map} +1 -1
- package/dist/rolldown-runtime-DGkTqVfb.js +15 -0
- package/dist/rolldown-runtime-DUslC3ob.js +14 -0
- package/dist/test-runner/bin.js +173 -119
- package/dist/test-runner/bin.js.map +1 -1
- package/dist/test-runner/config.d.ts +1 -1
- package/dist/test-runner/config.js +1 -1
- package/dist/test-runner/pool.d.ts +1 -1
- package/dist/test-runner/pool.js +1 -1
- package/dist/test-runner/pool.js.map +1 -1
- package/dist/test-runner/relay-factory.d.ts +14 -0
- package/dist/test-runner/relay-factory.d.ts.map +1 -1
- package/dist/test-runner/relay-factory.js +11 -5
- package/dist/test-runner/relay-factory.js.map +1 -1
- package/dist/test-runner/relay-worker.d.ts +2 -2
- package/dist/test-runner/relay-worker.js +2 -2
- package/dist/test-runner/report.d.ts +35 -4
- package/dist/test-runner/report.d.ts.map +1 -1
- package/dist/test-runner/report.js +42 -7
- package/dist/test-runner/report.js.map +1 -1
- package/dist/{totp-DvOYkYim.js → totp-CZLLKfOC.js} +2 -14
- package/dist/{totp-DvOYkYim.js.map → totp-CZLLKfOC.js.map} +1 -1
- package/dist/totp-DAxys-r0.js +199 -0
- package/dist/totp-DAxys-r0.js.map +1 -0
- package/dist/{tunnel-B2UCKAc7.cjs → tunnel-DP453L4e.cjs} +2 -2
- package/dist/{tunnel-B2UCKAc7.cjs.map → tunnel-DP453L4e.cjs.map} +1 -1
- package/dist/{tunnel-C-rQ34dM.js → tunnel-Djf-zmjJ.js} +2 -2
- package/dist/{tunnel-C-rQ34dM.js.map → tunnel-Djf-zmjJ.js.map} +1 -1
- package/dist/unplugin/index.cjs +1 -1
- package/dist/unplugin/index.js +1 -1
- package/dist/unplugin/tunnel.cjs +1 -1
- package/dist/unplugin/tunnel.js +1 -1
- package/package.json +1 -1
- package/dist/attach-orchestrator-BiaYiNOr.js.map +0 -1
- package/dist/attach-orchestrator-ca34r46y.js.map +0 -1
- package/dist/cell-Bi8MAPA8.js +0 -88
- package/dist/cell-Bi8MAPA8.js.map +0 -1
- package/dist/cell-Cw4fVOl2.js.map +0 -1
- package/dist/cell-rr6gL9AT.js +0 -89
- package/dist/cell-rr6gL9AT.js.map +0 -1
- package/dist/debug-server-BSbfnFR5.js.map +0 -1
- package/dist/debug-server-qRSRG7YZ.js.map +0 -1
- package/dist/log-CUik_tHp.js +0 -95
- package/dist/log-CUik_tHp.js.map +0 -1
- package/dist/qr-http-server-BxoRp2w7.cjs.map +0 -1
- package/dist/qr-http-server-CV6TA9ZN.cjs.map +0 -1
- package/dist/relay-factory-Cloog1jb.js.map +0 -1
- package/dist/relay-worker-o0M2ndyJ.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.
|
|
2027
|
+
return "0.1.133";
|
|
2028
2028
|
}
|
|
2029
2029
|
/**
|
|
2030
2030
|
* Derives the next recommended action from a completed diagnostics snapshot.
|
|
@@ -2932,6 +2932,110 @@ function buildIndicatorExpression(opts) {
|
|
|
2932
2932
|
* Node-only. react-free. CdpConnection only.
|
|
2933
2933
|
*/
|
|
2934
2934
|
/**
|
|
2935
|
+
* `__AIT_PERMS__` key → SDK function name whose `.getPermission()` is probed
|
|
2936
|
+
* (devtools#739). This is the exact contract sdk-example#265 consumes — do
|
|
2937
|
+
* not rename keys without a coordinated sdk-example update.
|
|
2938
|
+
*
|
|
2939
|
+
* Each SDK function is reached via `window.__sdk` — the SAME page-global
|
|
2940
|
+
* bridge `src/in-app/auto.ts` installs for `call_sdk`/`__sdkCall` (see
|
|
2941
|
+
* `src/test-runner/bundle.ts`'s `sdkRedirectPlugin`, which redirects bundled
|
|
2942
|
+
* `@apps-in-toss/web-framework` imports to this same object at runtime). The
|
|
2943
|
+
* test-runner bundle owns no independent SDK import — `window.__sdk` is a
|
|
2944
|
+
* page global regardless of whether a bundle has been injected yet, so this
|
|
2945
|
+
* preflight runs standalone via `injectGlobals`'s `Runtime.evaluate`
|
|
2946
|
+
* mechanism BEFORE the first bundle, rather than being prepended into
|
|
2947
|
+
* `rpc.ts#buildRunTestsExpression`. (Design choice documented in PR #739 —
|
|
2948
|
+
* bundle-prepend was the fallback plan if the SDK were only reachable from
|
|
2949
|
+
* inside bundle scope, which reality ruled out.)
|
|
2950
|
+
*/
|
|
2951
|
+
const PERMISSION_PROBE_MAP = {
|
|
2952
|
+
clipboardRead: "getClipboardText",
|
|
2953
|
+
clipboardWrite: "setClipboardText",
|
|
2954
|
+
album: "fetchAlbumPhotos",
|
|
2955
|
+
camera: "openCamera",
|
|
2956
|
+
contacts: "fetchContacts",
|
|
2957
|
+
location: "getCurrentLocation"
|
|
2958
|
+
};
|
|
2959
|
+
/** Non-fatal bound for the permission preflight `Runtime.evaluate` round-trip. */
|
|
2960
|
+
const PERMISSION_PREFLIGHT_TIMEOUT_MS = 1e4;
|
|
2961
|
+
/**
|
|
2962
|
+
* Builds the `Runtime.evaluate` expression for the permission-state preflight
|
|
2963
|
+
* (devtools#739). Evaluated ONCE per relay session, before the first test
|
|
2964
|
+
* bundle is injected (see `relay-worker.ts#runTestFilesOverRelay`).
|
|
2965
|
+
*
|
|
2966
|
+
* For each entry in {@link PERMISSION_PROBE_MAP}, probes
|
|
2967
|
+
* `window.__sdk.<fn>.getPermission()` — a NON-blocking query (never
|
|
2968
|
+
* `openPermissionDialog`/`requestPermission`, which open native UI) — and
|
|
2969
|
+
* assigns the resolved `'allowed'|'denied'|'notDetermined'` status to
|
|
2970
|
+
* `globalThis.__AIT_PERMS__[<key>]`. A probe that is absent, throws, or
|
|
2971
|
+
* rejects resolves to `'unavailable'` — this expression never throws to its
|
|
2972
|
+
* caller, and a single slow/broken permission must not fail the others (each
|
|
2973
|
+
* probe is awaited independently, not short-circuited).
|
|
2974
|
+
*
|
|
2975
|
+
* Tests (sdk-example#265) read `globalThis.__AIT_PERMS__` to branch
|
|
2976
|
+
* deterministically per permission state instead of blanket outcome-branching.
|
|
2977
|
+
*
|
|
2978
|
+
* Returns a JSON-serialised string (the same double-serialisation pattern
|
|
2979
|
+
* `rpc.ts#buildRunTestsExpression` uses) rather than relying on CDP
|
|
2980
|
+
* `returnByValue` structural fidelity for a plain object across the Chii
|
|
2981
|
+
* relay — the Node side re-parses via `JSON.parse`.
|
|
2982
|
+
*
|
|
2983
|
+
* Pure function — no I/O, no CDP call. Callers pass the returned string to
|
|
2984
|
+
* `Runtime.evaluate`.
|
|
2985
|
+
*/
|
|
2986
|
+
function buildPermissionPreflightExpression() {
|
|
2987
|
+
return `(async () => { const probe = async (fnName) => { try { const fn = globalThis.__sdk && globalThis.__sdk[fnName]; if (!fn || typeof fn.getPermission !== 'function') return 'unavailable'; const status = await fn.getPermission(); if (status === 'allowed' || status === 'denied' || status === 'notDetermined') return status; return 'unavailable'; } catch (e) { return 'unavailable'; } }; const result = {};${Object.entries(PERMISSION_PROBE_MAP).map(([key, fnName]) => ` result[${JSON.stringify(key)}] = await probe(${JSON.stringify(fnName)});`).join("\n")}\n globalThis.__AIT_PERMS__ = result; return JSON.stringify(result);})()`;
|
|
2988
|
+
}
|
|
2989
|
+
/**
|
|
2990
|
+
* Runs the permission-state preflight (devtools#739) via `Runtime.evaluate`
|
|
2991
|
+
* and returns the collected `__AIT_PERMS__` map, or `undefined` when the
|
|
2992
|
+
* preflight itself failed or timed out.
|
|
2993
|
+
*
|
|
2994
|
+
* NON-FATAL by design: any failure (CDP exception, timeout, page-side throw)
|
|
2995
|
+
* is caught here, logged as ONE stderr line, and swallowed — the whole test
|
|
2996
|
+
* run must proceed even when the preflight cannot complete (e.g. `window.__sdk`
|
|
2997
|
+
* not yet installed, or a page navigation mid-attach). Callers that want the
|
|
2998
|
+
* result for report provenance (`RelayRunReport.preflight`) get `undefined`
|
|
2999
|
+
* in that case, which downstream code treats the same as "not run".
|
|
3000
|
+
*
|
|
3001
|
+
* SECRET-HANDLING: no relay/wss/secret values are read or logged; only
|
|
3002
|
+
* permission-state strings cross this boundary.
|
|
3003
|
+
*
|
|
3004
|
+
* @param conn - The live CDP connection (relay-attached page).
|
|
3005
|
+
* @param timeoutMs - Round-trip bound. Defaults to {@link PERMISSION_PREFLIGHT_TIMEOUT_MS}.
|
|
3006
|
+
*/
|
|
3007
|
+
async function runPermissionPreflight(conn, timeoutMs = PERMISSION_PREFLIGHT_TIMEOUT_MS) {
|
|
3008
|
+
const TIMEOUT_SENTINEL = Symbol("permission-preflight-timeout");
|
|
3009
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve(TIMEOUT_SENTINEL), timeoutMs));
|
|
3010
|
+
try {
|
|
3011
|
+
const evalPromise = conn.send("Runtime.evaluate", {
|
|
3012
|
+
expression: buildPermissionPreflightExpression(),
|
|
3013
|
+
returnByValue: true,
|
|
3014
|
+
awaitPromise: true
|
|
3015
|
+
});
|
|
3016
|
+
const raceResult = await Promise.race([evalPromise.then((v) => ({
|
|
3017
|
+
tag: "eval",
|
|
3018
|
+
v
|
|
3019
|
+
})), timeoutPromise.then(() => ({ tag: "timeout" }))]);
|
|
3020
|
+
if (raceResult.tag === "timeout") {
|
|
3021
|
+
process.stderr.write(`test-runner: permission preflight timed out after ${timeoutMs}ms — proceeding with __AIT_PERMS__ unset\n`);
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
if (raceResult.v.exceptionDetails) {
|
|
3025
|
+
process.stderr.write("test-runner: permission preflight threw — proceeding with __AIT_PERMS__ unset\n");
|
|
3026
|
+
return;
|
|
3027
|
+
}
|
|
3028
|
+
const rawValue = raceResult.v.result.value;
|
|
3029
|
+
if (typeof rawValue !== "string") return void 0;
|
|
3030
|
+
const parsed = JSON.parse(rawValue);
|
|
3031
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
3032
|
+
return parsed;
|
|
3033
|
+
} catch (e) {
|
|
3034
|
+
process.stderr.write(`test-runner: permission preflight failed (${e instanceof Error ? e.message : String(e)}) — proceeding with __AIT_PERMS__ unset\n`);
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
/**
|
|
2935
3039
|
* Injects each key of `globals` into `globalThis` in the page via a single
|
|
2936
3040
|
* `Runtime.evaluate` call. Must be called BEFORE the first `bundleTestFile`
|
|
2937
3041
|
* inject — the cell is session-global and applies to all subsequent files.
|
|
@@ -3007,6 +3111,23 @@ async function injectDebugIndicator(conn, opts) {
|
|
|
3007
3111
|
* safe to import from the MCP daemon graph.
|
|
3008
3112
|
*/
|
|
3009
3113
|
/**
|
|
3114
|
+
* Filename suffix that opts a test file into manual-variant scheduling
|
|
3115
|
+
* (devtools#741). A file named `<name>.manual.ait.test.ts` is EXCLUDED from
|
|
3116
|
+
* `discoverTestFiles`'s default output (so existing unattended runs are
|
|
3117
|
+
* unaffected — the zero-diff-when-off constraint) and is only surfaced when
|
|
3118
|
+
* the caller explicitly asks for manual files via {@link partitionManualTests}
|
|
3119
|
+
* (wired from the CLI's `--manual-blocking` flag).
|
|
3120
|
+
*
|
|
3121
|
+
* This is the entire tagging contract for v1 — no separate manifest/config,
|
|
3122
|
+
* just a filename convention. Documented here + in the CLI `--help` text
|
|
3123
|
+
* (cli.ts USAGE) and the test-runner README.
|
|
3124
|
+
*/
|
|
3125
|
+
const MANUAL_TEST_SUFFIX = ".manual.ait.test.ts";
|
|
3126
|
+
/** True when `file`'s basename ends with {@link MANUAL_TEST_SUFFIX}. */
|
|
3127
|
+
function isManualTestFile(file) {
|
|
3128
|
+
return basename(file).endsWith(MANUAL_TEST_SUFFIX);
|
|
3129
|
+
}
|
|
3130
|
+
/**
|
|
3010
3131
|
* Expands `patterns` (globs or plain paths) into a sorted, de-duplicated list of
|
|
3011
3132
|
* ABSOLUTE test file paths, resolved relative to `cwd`.
|
|
3012
3133
|
*
|
|
@@ -3015,14 +3136,26 @@ async function injectDebugIndicator(conn, opts) {
|
|
|
3015
3136
|
* resolved against `cwd`. `bundleTestFile` requires an absolute path, so the
|
|
3016
3137
|
* absolute output feeds it directly.
|
|
3017
3138
|
*
|
|
3139
|
+
* By default, files matching {@link MANUAL_TEST_SUFFIX} are EXCLUDED from the
|
|
3140
|
+
* result (devtools#741) — blocking-UI tests opt in via that filename
|
|
3141
|
+
* convention and must never appear in an unattended run unless the caller
|
|
3142
|
+
* explicitly asks for them via `includeManual: true`. This keeps the
|
|
3143
|
+
* default (flag-off) discovery path byte-for-byte identical to before this
|
|
3144
|
+
* option existed.
|
|
3145
|
+
*
|
|
3018
3146
|
* @param patterns Glob patterns or file paths (e.g. `['src/**\/*.ait.test.ts']`).
|
|
3019
3147
|
* @param cwd Base directory for relative patterns/results.
|
|
3148
|
+
* @param opts `{ includeManual }` — when true, manual-tagged files are kept
|
|
3149
|
+
* in the (still-sorted) output instead of being filtered out.
|
|
3150
|
+
* Use {@link partitionManualTests} to separate + reorder them.
|
|
3020
3151
|
* @returns Sorted, de-duplicated absolute file paths. Empty when nothing matches.
|
|
3021
3152
|
*/
|
|
3022
|
-
async function discoverTestFiles(patterns, cwd) {
|
|
3153
|
+
async function discoverTestFiles(patterns, cwd, opts) {
|
|
3023
3154
|
const out = /* @__PURE__ */ new Set();
|
|
3024
3155
|
for await (const match of glob(patterns, { cwd })) out.add(isAbsolute(match) ? match : resolve(cwd, match));
|
|
3025
|
-
|
|
3156
|
+
const sorted = [...out].sort();
|
|
3157
|
+
if (opts?.includeManual) return sorted;
|
|
3158
|
+
return sorted.filter((f) => !isManualTestFile(f));
|
|
3026
3159
|
}
|
|
3027
3160
|
//#endregion
|
|
3028
3161
|
//#region src/shared/relay-auth-close.ts
|
|
@@ -4069,6 +4202,13 @@ async function injectAndRunBundle(connection, bundleCode, timeoutMs = DEFAULT_TI
|
|
|
4069
4202
|
//#endregion
|
|
4070
4203
|
//#region src/test-runner/relay-worker.ts
|
|
4071
4204
|
/**
|
|
4205
|
+
* Per-file evaluate timeout (ms) for manual-variant files (devtools#741) — a
|
|
4206
|
+
* human is expected to be tapping through a native sheet, so the timeout must
|
|
4207
|
+
* be far longer than the unattended default (60s, rpc.ts DEFAULT_TIMEOUT_MS).
|
|
4208
|
+
* Fixed constant (not configurable in v1) — documented here + CLI `--help`.
|
|
4209
|
+
*/
|
|
4210
|
+
const MANUAL_FILE_TIMEOUT_MS = 5 * 6e4;
|
|
4211
|
+
/**
|
|
4072
4212
|
* Sentinel string embedded in the error message by `injectAndRunBundle` when
|
|
4073
4213
|
* the per-file evaluate race hits the timeout. Used by the retry guard so only
|
|
4074
4214
|
* genuine timeouts get a second attempt — not bundle errors or parse failures.
|
|
@@ -4139,12 +4279,23 @@ async function runTestFilesOverRelay(connection, files, opts) {
|
|
|
4139
4279
|
process.stderr.write(`relay-worker: reconnect failed (${e instanceof Error ? e.message : String(e)}) — continuing, remaining files may fail\n`);
|
|
4140
4280
|
}
|
|
4141
4281
|
};
|
|
4282
|
+
const manualFiles = opts?.manualFiles;
|
|
4283
|
+
const manualTotal = manualFiles?.size ?? 0;
|
|
4284
|
+
let manualIndex = 0;
|
|
4285
|
+
let preflightPermissions;
|
|
4286
|
+
if (files.length > 0) preflightPermissions = await runPermissionPreflight(connection);
|
|
4142
4287
|
try {
|
|
4143
4288
|
for (const file of files) {
|
|
4144
4289
|
if (pendingReconnectCheck) {
|
|
4145
4290
|
await attemptReconnect("next-file");
|
|
4146
4291
|
pendingReconnectCheck = false;
|
|
4147
4292
|
}
|
|
4293
|
+
const isManual = manualFiles?.has(file) === true;
|
|
4294
|
+
if (isManual) {
|
|
4295
|
+
manualIndex += 1;
|
|
4296
|
+
opts?.onManualFile?.(file, manualIndex, manualTotal);
|
|
4297
|
+
}
|
|
4298
|
+
const fileTimeoutMs = isManual ? MANUAL_FILE_TIMEOUT_MS : opts?.timeoutMs;
|
|
4148
4299
|
let fileEntry;
|
|
4149
4300
|
try {
|
|
4150
4301
|
const { code } = await bundleTestFile(file, opts?.bundleOptions);
|
|
@@ -4170,7 +4321,7 @@ async function runTestFilesOverRelay(connection, files, opts) {
|
|
|
4170
4321
|
const attempt = async () => {
|
|
4171
4322
|
let rpcResult;
|
|
4172
4323
|
try {
|
|
4173
|
-
rpcResult = await injectAndRunBundle(connection, code,
|
|
4324
|
+
rpcResult = await injectAndRunBundle(connection, code, fileTimeoutMs);
|
|
4174
4325
|
} catch (e) {
|
|
4175
4326
|
return {
|
|
4176
4327
|
file,
|
|
@@ -4206,6 +4357,7 @@ async function runTestFilesOverRelay(connection, files, opts) {
|
|
|
4206
4357
|
};
|
|
4207
4358
|
}
|
|
4208
4359
|
if ("error" in fileEntry.result && isRelayDisconnectMessage(fileEntry.result.error)) pendingReconnectCheck = true;
|
|
4360
|
+
if (isManual) fileEntry.mode = "manual";
|
|
4209
4361
|
fileResults.push(fileEntry);
|
|
4210
4362
|
}
|
|
4211
4363
|
} finally {
|
|
@@ -4234,7 +4386,8 @@ async function runTestFilesOverRelay(connection, files, opts) {
|
|
|
4234
4386
|
duration: Date.now() - wallStart,
|
|
4235
4387
|
files: fileResults,
|
|
4236
4388
|
totals,
|
|
4237
|
-
captures
|
|
4389
|
+
captures,
|
|
4390
|
+
...preflightPermissions ? { preflight: { permissions: preflightPermissions } } : {}
|
|
4238
4391
|
};
|
|
4239
4392
|
}
|
|
4240
4393
|
/**
|
|
@@ -4293,6 +4446,24 @@ OPTIONS
|
|
|
4293
4446
|
--headless Disable browser auto-open (text QR only)
|
|
4294
4447
|
--project-root <dir> Project root for .ait_relay secret lookup
|
|
4295
4448
|
(default: current working directory)
|
|
4449
|
+
--manual-blocking Run manual-tagged test files (*.manual.ait.test.ts)
|
|
4450
|
+
LAST, after all regular files, with a human present.
|
|
4451
|
+
Before each manual file, the QR dashboard is pushed
|
|
4452
|
+
a step-by-step Korean prompt naming the file + its
|
|
4453
|
+
progress (k/n), and the same line is printed to
|
|
4454
|
+
stdout. Manual files get a 5-minute per-file evaluate
|
|
4455
|
+
timeout (vs. --timeout for everything else) since a
|
|
4456
|
+
human is expected to tap through a native sheet
|
|
4457
|
+
(photo picker, permission dialog, fullscreen ad).
|
|
4458
|
+
Without this flag (default off), *.manual.ait.test.ts
|
|
4459
|
+
files are EXCLUDED from the glob expansion entirely —
|
|
4460
|
+
existing unattended runs are byte-for-byte unaffected.
|
|
4461
|
+
With --report-dir, a run that included manual files
|
|
4462
|
+
ALSO writes <sdkLine>.<platform>.manual.json
|
|
4463
|
+
alongside (never replacing) the standard report, and
|
|
4464
|
+
each manual file's report entry is stamped
|
|
4465
|
+
mode: 'manual' — never diff a manual run against an
|
|
4466
|
+
unattended baseline as if they were equivalent.
|
|
4296
4467
|
--help, -h Show this help message
|
|
4297
4468
|
|
|
4298
4469
|
DESCRIPTION
|
|
@@ -6638,7 +6809,8 @@ async function startQrHttpServer(getDashboardState, options) {
|
|
|
6638
6809
|
pages: state.pages,
|
|
6639
6810
|
attachUrl: state.attachUrl,
|
|
6640
6811
|
inspectorUrl: state.inspectorUrl ?? null,
|
|
6641
|
-
phase: state.phase ?? "active"
|
|
6812
|
+
phase: state.phase ?? "active",
|
|
6813
|
+
manualPrompt: state.manualPrompt ?? null
|
|
6642
6814
|
});
|
|
6643
6815
|
res.write(`data: ${payload}\n\n`);
|
|
6644
6816
|
}
|
|
@@ -6947,7 +7119,7 @@ function createDebugServer(deps) {
|
|
|
6947
7119
|
};
|
|
6948
7120
|
const server = new Server({
|
|
6949
7121
|
name: "ait-debug",
|
|
6950
|
-
version: "0.1.
|
|
7122
|
+
version: "0.1.133"
|
|
6951
7123
|
}, { capabilities: { tools: { listChanged: true } } });
|
|
6952
7124
|
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
6953
7125
|
const conn = router.active;
|
|
@@ -8931,7 +9103,7 @@ function createDevServer(deps = {}) {
|
|
|
8931
9103
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
8932
9104
|
const server = new Server({
|
|
8933
9105
|
name: "ait-devtools",
|
|
8934
|
-
version: "0.1.
|
|
9106
|
+
version: "0.1.133"
|
|
8935
9107
|
}, { capabilities: { tools: {} } });
|
|
8936
9108
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
8937
9109
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|