@validate.qa/runner 1.0.92 → 1.0.94
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/cli.js +319 -34
- package/dist/cli.mjs +319 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8555,6 +8555,162 @@ var require_scrub_credentials = __commonJS({
|
|
|
8555
8555
|
}
|
|
8556
8556
|
});
|
|
8557
8557
|
|
|
8558
|
+
// ../runner-core/dist/services/google-signin.js
|
|
8559
|
+
var require_google_signin = __commonJS({
|
|
8560
|
+
"../runner-core/dist/services/google-signin.js"(exports2) {
|
|
8561
|
+
"use strict";
|
|
8562
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
8563
|
+
exports2.GOOGLE_SIGNIN_ENV_KEYS = exports2.GOOGLE_SIGNIN_PASSWORD_KEY = void 0;
|
|
8564
|
+
exports2.loadGoogleSignInConfig = loadGoogleSignInConfig;
|
|
8565
|
+
exports2.mergeGoogleSignInSecrets = mergeGoogleSignInSecrets;
|
|
8566
|
+
exports2.googleSignInGuidanceOpts = googleSignInGuidanceOpts;
|
|
8567
|
+
exports2.googleSignInAllowedEmails = googleSignInAllowedEmails;
|
|
8568
|
+
exports2.collectGoogleSignInEnv = collectGoogleSignInEnv;
|
|
8569
|
+
exports2.isGoogleAccountsUrl = isGoogleAccountsUrl;
|
|
8570
|
+
exports2.googleSignInCredentialMismatch = googleSignInCredentialMismatch;
|
|
8571
|
+
exports2.generateTotp = generateTotp;
|
|
8572
|
+
exports2.buildGoogleSignInPromptSection = buildGoogleSignInPromptSection;
|
|
8573
|
+
var node_crypto_1 = require("crypto");
|
|
8574
|
+
exports2.GOOGLE_SIGNIN_PASSWORD_KEY = "GOOGLE_SIGNIN_PASSWORD";
|
|
8575
|
+
var APP_REGISTER_CREDENTIAL_KEYS = /^(TEST_|E2E_|QA_)?(USER_?EMAIL|USER_?PASSWORD|USER_?NAME|USERNAME)$/i;
|
|
8576
|
+
exports2.GOOGLE_SIGNIN_ENV_KEYS = [
|
|
8577
|
+
"GOOGLE_SIGNIN_PASSWORD",
|
|
8578
|
+
"GOOGLE_SIGNIN_EMAIL",
|
|
8579
|
+
"GOOGLE_SIGNIN_TOTP_SECRET"
|
|
8580
|
+
];
|
|
8581
|
+
function trimEnv(env, name) {
|
|
8582
|
+
const value = env[name]?.trim();
|
|
8583
|
+
return value ? value : void 0;
|
|
8584
|
+
}
|
|
8585
|
+
function loadGoogleSignInConfig(env = process.env) {
|
|
8586
|
+
const password = trimEnv(env, "GOOGLE_SIGNIN_PASSWORD");
|
|
8587
|
+
if (!password)
|
|
8588
|
+
return null;
|
|
8589
|
+
const email = (trimEnv(env, "GOOGLE_SIGNIN_EMAIL") ?? trimEnv(env, "VERIFICATION_INBOX_ADDRESS"))?.toLowerCase();
|
|
8590
|
+
if (!email || !email.includes("@"))
|
|
8591
|
+
return null;
|
|
8592
|
+
const totpSecret = trimEnv(env, "GOOGLE_SIGNIN_TOTP_SECRET");
|
|
8593
|
+
return {
|
|
8594
|
+
email,
|
|
8595
|
+
password,
|
|
8596
|
+
passwordKey: exports2.GOOGLE_SIGNIN_PASSWORD_KEY,
|
|
8597
|
+
totpSecret,
|
|
8598
|
+
totpAvailable: !!totpSecret
|
|
8599
|
+
};
|
|
8600
|
+
}
|
|
8601
|
+
function mergeGoogleSignInSecrets(credentials, env = process.env) {
|
|
8602
|
+
const cfg = loadGoogleSignInConfig(env);
|
|
8603
|
+
if (!cfg)
|
|
8604
|
+
return credentials;
|
|
8605
|
+
if (credentials[exports2.GOOGLE_SIGNIN_PASSWORD_KEY])
|
|
8606
|
+
return credentials;
|
|
8607
|
+
return { ...credentials, [exports2.GOOGLE_SIGNIN_PASSWORD_KEY]: cfg.password };
|
|
8608
|
+
}
|
|
8609
|
+
function googleSignInGuidanceOpts(env = process.env) {
|
|
8610
|
+
const cfg = loadGoogleSignInConfig(env);
|
|
8611
|
+
if (!cfg)
|
|
8612
|
+
return void 0;
|
|
8613
|
+
return {
|
|
8614
|
+
googleEmail: cfg.email,
|
|
8615
|
+
googlePasswordKey: cfg.passwordKey,
|
|
8616
|
+
googleTotpAvailable: cfg.totpAvailable
|
|
8617
|
+
};
|
|
8618
|
+
}
|
|
8619
|
+
function googleSignInAllowedEmails(env = process.env) {
|
|
8620
|
+
const cfg = loadGoogleSignInConfig(env);
|
|
8621
|
+
return cfg ? [cfg.email] : [];
|
|
8622
|
+
}
|
|
8623
|
+
function collectGoogleSignInEnv(env = process.env) {
|
|
8624
|
+
const out = {};
|
|
8625
|
+
for (const key of exports2.GOOGLE_SIGNIN_ENV_KEYS) {
|
|
8626
|
+
const value = env[key]?.trim();
|
|
8627
|
+
if (value)
|
|
8628
|
+
out[key] = value;
|
|
8629
|
+
}
|
|
8630
|
+
return out;
|
|
8631
|
+
}
|
|
8632
|
+
function isGoogleAccountsUrl(url) {
|
|
8633
|
+
if (!url)
|
|
8634
|
+
return false;
|
|
8635
|
+
try {
|
|
8636
|
+
const host = new URL(url).hostname.toLowerCase();
|
|
8637
|
+
return host === "accounts.google.com" || host.endsWith(".google.com") && host.includes("accounts");
|
|
8638
|
+
} catch {
|
|
8639
|
+
return /accounts\.google\.com/i.test(url);
|
|
8640
|
+
}
|
|
8641
|
+
}
|
|
8642
|
+
function googleSignInCredentialMismatch(pageUrl, credentialKey, opts) {
|
|
8643
|
+
const configured = opts?.configured ?? !!loadGoogleSignInConfig(opts?.env);
|
|
8644
|
+
if (!configured)
|
|
8645
|
+
return null;
|
|
8646
|
+
const onGoogle = isGoogleAccountsUrl(pageUrl);
|
|
8647
|
+
if (onGoogle) {
|
|
8648
|
+
if (credentialKey === exports2.GOOGLE_SIGNIN_PASSWORD_KEY)
|
|
8649
|
+
return null;
|
|
8650
|
+
if (APP_REGISTER_CREDENTIAL_KEYS.test(credentialKey)) {
|
|
8651
|
+
return `fill_credential: this is Google account login (accounts.google.com), not app email signup. Do not use ${credentialKey}. Type the BARE Google email with browser_type, then fill_credential with credentialKey ${exports2.GOOGLE_SIGNIN_PASSWORD_KEY}. Do not click Continue with phone / SMS OTP when Continue with Google is available.`;
|
|
8652
|
+
}
|
|
8653
|
+
return null;
|
|
8654
|
+
}
|
|
8655
|
+
if (credentialKey === exports2.GOOGLE_SIGNIN_PASSWORD_KEY) {
|
|
8656
|
+
return `fill_credential: ${exports2.GOOGLE_SIGNIN_PASSWORD_KEY} is only for accounts.google.com. Click Continue with Google first (not Continue with phone). Phone / "Mobile or email" is not app email signup.`;
|
|
8657
|
+
}
|
|
8658
|
+
return null;
|
|
8659
|
+
}
|
|
8660
|
+
function generateTotp(secret, atMs = Date.now(), stepSeconds = 30, digits = 6) {
|
|
8661
|
+
const key = decodeBase32(secret);
|
|
8662
|
+
const counter = Math.floor(atMs / 1e3 / stepSeconds);
|
|
8663
|
+
const buf = Buffer.alloc(8);
|
|
8664
|
+
buf.writeUInt32BE(Math.floor(counter / 4294967296), 0);
|
|
8665
|
+
buf.writeUInt32BE(counter >>> 0, 4);
|
|
8666
|
+
const hmac = (0, node_crypto_1.createHmac)("sha1", key).update(buf).digest();
|
|
8667
|
+
const offset = hmac[hmac.length - 1] & 15;
|
|
8668
|
+
const bin = (hmac[offset] & 127) << 24 | hmac[offset + 1] << 16 | hmac[offset + 2] << 8 | hmac[offset + 3];
|
|
8669
|
+
const otp = bin % 10 ** digits;
|
|
8670
|
+
return String(otp).padStart(digits, "0");
|
|
8671
|
+
}
|
|
8672
|
+
function decodeBase32(input) {
|
|
8673
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
8674
|
+
const cleaned = input.toUpperCase().replace(/[\s=-]+/g, "");
|
|
8675
|
+
let bits = 0;
|
|
8676
|
+
let value = 0;
|
|
8677
|
+
const out = [];
|
|
8678
|
+
for (const ch of cleaned) {
|
|
8679
|
+
const idx = alphabet.indexOf(ch);
|
|
8680
|
+
if (idx < 0)
|
|
8681
|
+
continue;
|
|
8682
|
+
value = value << 5 | idx;
|
|
8683
|
+
bits += 5;
|
|
8684
|
+
if (bits >= 8) {
|
|
8685
|
+
bits -= 8;
|
|
8686
|
+
out.push(value >>> bits & 255);
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8689
|
+
return Buffer.from(out);
|
|
8690
|
+
}
|
|
8691
|
+
function buildGoogleSignInPromptSection(opts, variant) {
|
|
8692
|
+
const totpNative = opts.googleTotpAvailable ? " If Google asks for a 2-step / Authenticator code, call `provision_google_totp` and type the 6-digit `code` it returns (do not invent a code)." : " If Google asks for 2-step verification and you have no authenticator code tool, STOP and report Google SSO as BLOCKED (2FA not configured on this runner).";
|
|
8693
|
+
const totpCli = opts.googleTotpAvailable ? " If Google asks for a 2-step / Authenticator code, call `inbox_google_totp` and type the 6-digit `code` it returns." : " If Google asks for 2-step verification, STOP and report Google SSO as BLOCKED (2FA not configured on this runner).";
|
|
8694
|
+
const totp = variant === "cli" ? totpCli : totpNative;
|
|
8695
|
+
const fill = variant === "cli" ? `fill_credential with credentialKey \`${opts.googlePasswordKey}\`` : `\`fill_credential\` (credentialKey \`${opts.googlePasswordKey}\`)`;
|
|
8696
|
+
const plainProvision = variant === "cli" ? "`inbox_provision_identity` with `plain: true`" : "`provision_identity` with `plain: true`";
|
|
8697
|
+
return `
|
|
8698
|
+
Google / Gmail SSO (use this when the APP has no Create-account email form):
|
|
8699
|
+
- App email+password SIGNUP means a form ON THIS APP to create an account (Sign up / Create account / Register, including after "Sign up with email"). That is FIRST. Do not use Google if that form exists.
|
|
8700
|
+
- These are NOT app email signup \u2014 do not treat them as the email playbook, and do not fill TEST_USER_EMAIL / TEST_USER_PASSWORD into them when Continue with Google is available:
|
|
8701
|
+
- "Continue with phone" / SMS / OTP
|
|
8702
|
+
- "Mobile or email" / phone-number identity on a Sign in page
|
|
8703
|
+
- Google's own email and password fields on accounts.google.com
|
|
8704
|
+
- If Sign in offers Continue with Google (and there is no app Create-account email form): click Continue with Google. Do NOT click Continue with phone for this registration.
|
|
8705
|
+
- If a Google popup or tab opens, switch to it. On accounts.google.com, type the BARE Google account email \`${opts.googleEmail}\` (no plus-tag) with browser_type, click Next, then fill the Google password with ${fill}. NEVER type the Google password as text, NEVER use TEST_USER_PASSWORD here, NEVER use the IMAP app password.
|
|
8706
|
+
- Click Next.${totp}
|
|
8707
|
+
- Click Continue / Allow on any consent screen, then return to the app tab.
|
|
8708
|
+
- If the app then emails a verification code/link, first call ${plainProvision} (Google SSO uses the bare inbox address, not the +tag), then complete it with the inbox tools as usual.
|
|
8709
|
+
- Register / Google-sign-in ONCE per run. If Google says the account is already used on this app, that is success \u2014 continue as the logged-in user.`;
|
|
8710
|
+
}
|
|
8711
|
+
}
|
|
8712
|
+
});
|
|
8713
|
+
|
|
8558
8714
|
// ../runner-core/dist/services/credential-tools.js
|
|
8559
8715
|
var require_credential_tools = __commonJS({
|
|
8560
8716
|
"../runner-core/dist/services/credential-tools.js"(exports2) {
|
|
@@ -8573,17 +8729,18 @@ var require_credential_tools = __commonJS({
|
|
|
8573
8729
|
exports2.mcpResultIsError = mcpResultIsError;
|
|
8574
8730
|
exports2.aggressiveScrubCredentials = aggressiveScrubCredentials;
|
|
8575
8731
|
var scrub_credentials_js_1 = require_scrub_credentials();
|
|
8732
|
+
var google_signin_js_1 = require_google_signin();
|
|
8576
8733
|
exports2.FILL_CREDENTIAL_TOOL = {
|
|
8577
8734
|
type: "function",
|
|
8578
8735
|
function: {
|
|
8579
8736
|
name: "fill_credential",
|
|
8580
|
-
description: 'Fill a stored credential VALUE into a form field. ALWAYS use this instead of `browser_type` for ANY email/password/token/auth field. You pass the variable KEY (e.g. "TEST_USER_EMAIL") and the runner injects the real value server-side \u2014 you never see the secret. The list of available credential keys is in the system prompt.',
|
|
8737
|
+
description: 'Fill a stored credential VALUE into a form field. ALWAYS use this instead of `browser_type` for ANY email/password/token/auth field. You pass the variable KEY (e.g. "TEST_USER_EMAIL") and the runner injects the real value server-side \u2014 you never see the secret. On accounts.google.com use GOOGLE_SIGNIN_PASSWORD (never TEST_USER_PASSWORD). The list of available credential keys is in the system prompt.',
|
|
8581
8738
|
parameters: {
|
|
8582
8739
|
type: "object",
|
|
8583
8740
|
properties: {
|
|
8584
8741
|
credentialKey: {
|
|
8585
8742
|
type: "string",
|
|
8586
|
-
description: 'The credential variable name (e.g. "TEST_USER_EMAIL", "TEST_USER_PASSWORD", "
|
|
8743
|
+
description: 'The credential variable name (e.g. "TEST_USER_EMAIL", "TEST_USER_PASSWORD", "GOOGLE_SIGNIN_PASSWORD"). Must be one of the keys listed in the Test Credentials section of the prompt.'
|
|
8587
8744
|
},
|
|
8588
8745
|
element: {
|
|
8589
8746
|
type: "string",
|
|
@@ -8739,6 +8896,22 @@ CREDENTIAL ROTATION (required when the STORED user's secret changes \u2014 read
|
|
|
8739
8896
|
return entries.map(([k, v]) => `- **${k}**: \`${v}\``).join("\n");
|
|
8740
8897
|
}
|
|
8741
8898
|
var DEFAULT_MAX_RESULT_CHARS = 15e3;
|
|
8899
|
+
var PAGE_URL_RE = /Page URL:\s*(\S+)/i;
|
|
8900
|
+
async function peekPageUrl(mcpClient) {
|
|
8901
|
+
try {
|
|
8902
|
+
const mcpResult = await mcpClient.callTool({ name: "browser_snapshot", arguments: {} });
|
|
8903
|
+
const { text } = parseMcpContent(mcpResult);
|
|
8904
|
+
const match = text.match(PAGE_URL_RE);
|
|
8905
|
+
return match?.[1]?.replace(/[),.;]+$/, "");
|
|
8906
|
+
} catch {
|
|
8907
|
+
return void 0;
|
|
8908
|
+
}
|
|
8909
|
+
}
|
|
8910
|
+
function googleFillBlocked(pageUrl, credentialKey, credentials) {
|
|
8911
|
+
return (0, google_signin_js_1.googleSignInCredentialMismatch)(pageUrl, credentialKey, {
|
|
8912
|
+
configured: !!credentials[google_signin_js_1.GOOGLE_SIGNIN_PASSWORD_KEY]
|
|
8913
|
+
});
|
|
8914
|
+
}
|
|
8742
8915
|
async function handleFillCredential(toolArgs, ctx) {
|
|
8743
8916
|
const key = typeof toolArgs.credentialKey === "string" ? toolArgs.credentialKey : "";
|
|
8744
8917
|
const element = typeof toolArgs.element === "string" ? toolArgs.element : "";
|
|
@@ -8760,6 +8933,13 @@ CREDENTIAL ROTATION (required when the STORED user's secret changes \u2014 read
|
|
|
8760
8933
|
didMutate: false
|
|
8761
8934
|
};
|
|
8762
8935
|
}
|
|
8936
|
+
if (ctx.credentials[google_signin_js_1.GOOGLE_SIGNIN_PASSWORD_KEY]) {
|
|
8937
|
+
const pageUrl = await peekPageUrl(ctx.mcpClient);
|
|
8938
|
+
const blocked = googleFillBlocked(pageUrl, key, ctx.credentials);
|
|
8939
|
+
if (blocked) {
|
|
8940
|
+
return { content: JSON.stringify({ error: blocked }), didMutate: false };
|
|
8941
|
+
}
|
|
8942
|
+
}
|
|
8763
8943
|
const underlyingArgs = { element, ref, text: value, submit };
|
|
8764
8944
|
const mcpResult = await ctx.mcpClient.callTool({ name: "browser_type", arguments: underlyingArgs });
|
|
8765
8945
|
const mcpFailed = mcpResultIsError(mcpResult);
|
|
@@ -8798,6 +8978,16 @@ CREDENTIAL ROTATION (required when the STORED user's secret changes \u2014 read
|
|
|
8798
8978
|
}
|
|
8799
8979
|
resolved.push({ field, value });
|
|
8800
8980
|
}
|
|
8981
|
+
if (ctx.credentials[google_signin_js_1.GOOGLE_SIGNIN_PASSWORD_KEY]) {
|
|
8982
|
+
const pageUrl = await peekPageUrl(ctx.mcpClient);
|
|
8983
|
+
for (const f of fields) {
|
|
8984
|
+
const key = typeof f.credentialKey === "string" ? f.credentialKey : typeof f.key === "string" ? f.key : "";
|
|
8985
|
+
const blocked = googleFillBlocked(pageUrl, key, ctx.credentials);
|
|
8986
|
+
if (blocked) {
|
|
8987
|
+
return { content: JSON.stringify({ error: blocked }), didMutate: false };
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
8990
|
+
}
|
|
8801
8991
|
if (missing.length > 0) {
|
|
8802
8992
|
const available = Object.keys(ctx.credentials).filter((k) => ctx.credentials[k]).join(", ") || "(none configured)";
|
|
8803
8993
|
return {
|
|
@@ -8849,6 +9039,14 @@ CREDENTIAL ROTATION (required when the STORED user's secret changes \u2014 read
|
|
|
8849
9039
|
didMutate: false
|
|
8850
9040
|
};
|
|
8851
9041
|
}
|
|
9042
|
+
if (key === google_signin_js_1.GOOGLE_SIGNIN_PASSWORD_KEY) {
|
|
9043
|
+
return {
|
|
9044
|
+
content: JSON.stringify({
|
|
9045
|
+
error: "set_credential: GOOGLE_SIGNIN_PASSWORD is a runner-operator secret and cannot be persisted to project Test Data"
|
|
9046
|
+
}),
|
|
9047
|
+
didMutate: false
|
|
9048
|
+
};
|
|
9049
|
+
}
|
|
8852
9050
|
if (!(key in ctx.credentials)) {
|
|
8853
9051
|
const available = Object.keys(ctx.credentials).filter((k) => ctx.credentials[k]).join(", ") || "(none configured)";
|
|
8854
9052
|
return {
|
|
@@ -74110,7 +74308,7 @@ var require_inbox_tools = __commonJS({
|
|
|
74110
74308
|
"../runner-core/dist/services/inbox-tools.js"(exports2) {
|
|
74111
74309
|
"use strict";
|
|
74112
74310
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74113
|
-
exports2.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK = exports2.INBOX_TOOL_NAMES = exports2.INBOX_TOOLS = exports2.OPEN_VERIFICATION_LINK_TOOL = exports2.GET_VERIFICATION_LINK_TOOL = exports2.EXTRACT_VERIFICATION_CODE_TOOL = exports2.READ_VERIFICATION_EMAIL_TOOL = exports2.WAIT_FOR_VERIFICATION_TOOL = exports2.CHECK_INBOX_TOOL = exports2.PROVISION_IDENTITY_TOOL = void 0;
|
|
74311
|
+
exports2.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK = exports2.INBOX_TOOL_NAMES = exports2.INBOX_TOOLS = exports2.PROVISION_GOOGLE_TOTP_TOOL = exports2.OPEN_VERIFICATION_LINK_TOOL = exports2.GET_VERIFICATION_LINK_TOOL = exports2.EXTRACT_VERIFICATION_CODE_TOOL = exports2.READ_VERIFICATION_EMAIL_TOOL = exports2.WAIT_FOR_VERIFICATION_TOOL = exports2.CHECK_INBOX_TOOL = exports2.PROVISION_IDENTITY_TOOL = void 0;
|
|
74114
74312
|
exports2.createInboxRunState = createInboxRunState;
|
|
74115
74313
|
exports2.dispatchInboxTool = dispatchInboxTool;
|
|
74116
74314
|
exports2.isPublicHttpUrl = isPublicHttpUrl;
|
|
@@ -74125,6 +74323,7 @@ var require_inbox_tools = __commonJS({
|
|
|
74125
74323
|
exports2.clearThrowawayRegisterSeed = clearThrowawayRegisterSeed;
|
|
74126
74324
|
exports2.buildInboxAgentsGuidance = buildInboxAgentsGuidance;
|
|
74127
74325
|
var verification_inbox_js_1 = require_verification_inbox();
|
|
74326
|
+
var google_signin_js_1 = require_google_signin();
|
|
74128
74327
|
function createInboxRunState(config, opts = {}) {
|
|
74129
74328
|
const baseEmail = config.address;
|
|
74130
74329
|
const tag = opts.tag !== void 0 ? opts.tag : opts.tagSeed ? (0, verification_inbox_js_1.deriveProjectInboxTag)(opts.tagSeed, opts.projectScope) : null;
|
|
@@ -74246,6 +74445,14 @@ var require_inbox_tools = __commonJS({
|
|
|
74246
74445
|
}
|
|
74247
74446
|
}
|
|
74248
74447
|
};
|
|
74448
|
+
exports2.PROVISION_GOOGLE_TOTP_TOOL = {
|
|
74449
|
+
type: "function",
|
|
74450
|
+
function: {
|
|
74451
|
+
name: "provision_google_totp",
|
|
74452
|
+
description: "Return a one-time 6-digit Authenticator code for the operator Google account. Call this ONLY when Google Sign-In shows a 2-step / Authenticator challenge after you submitted the Google password. Type the returned code into the Google prompt. Do not invent a code.",
|
|
74453
|
+
parameters: { type: "object", properties: {} }
|
|
74454
|
+
}
|
|
74455
|
+
};
|
|
74249
74456
|
exports2.INBOX_TOOLS = [
|
|
74250
74457
|
exports2.PROVISION_IDENTITY_TOOL,
|
|
74251
74458
|
exports2.CHECK_INBOX_TOOL,
|
|
@@ -74253,7 +74460,8 @@ var require_inbox_tools = __commonJS({
|
|
|
74253
74460
|
exports2.READ_VERIFICATION_EMAIL_TOOL,
|
|
74254
74461
|
exports2.EXTRACT_VERIFICATION_CODE_TOOL,
|
|
74255
74462
|
exports2.GET_VERIFICATION_LINK_TOOL,
|
|
74256
|
-
exports2.OPEN_VERIFICATION_LINK_TOOL
|
|
74463
|
+
exports2.OPEN_VERIFICATION_LINK_TOOL,
|
|
74464
|
+
exports2.PROVISION_GOOGLE_TOTP_TOOL
|
|
74257
74465
|
];
|
|
74258
74466
|
exports2.INBOX_TOOL_NAMES = new Set(exports2.INBOX_TOOLS.map((t) => t.function.name));
|
|
74259
74467
|
var DEFAULT_MAX_RESULT_CHARS = 8e3;
|
|
@@ -74265,7 +74473,7 @@ var require_inbox_tools = __commonJS({
|
|
|
74265
74473
|
}
|
|
74266
74474
|
var INBOX_AUTH_DEAD_GUIDANCE = "the inbox authentication is PERMANENTLY rejected (revoked/wrong app password) \u2014 STOP calling inbox tools; none of them can succeed this run. Treat email verification as UNAVAILABLE: hard-stop at any emailed code/link wall, NEVER type a guessed code, and report verification-gated flows as BLOCKED (blockedReason: inbox authentication failed). Continue with publicly reachable coverage.";
|
|
74267
74475
|
async function dispatchInboxTool(toolName, toolArgs, ctx) {
|
|
74268
|
-
if (ctx.state.authDead) {
|
|
74476
|
+
if (ctx.state.authDead && toolName !== "provision_google_totp") {
|
|
74269
74477
|
return err(`${toolName} skipped: ${INBOX_AUTH_DEAD_GUIDANCE}`);
|
|
74270
74478
|
}
|
|
74271
74479
|
try {
|
|
@@ -74284,6 +74492,8 @@ var require_inbox_tools = __commonJS({
|
|
|
74284
74492
|
return await handleGetLink(toolArgs, ctx);
|
|
74285
74493
|
case "open_verification_link":
|
|
74286
74494
|
return await handleOpenLink(toolArgs, ctx);
|
|
74495
|
+
case "provision_google_totp":
|
|
74496
|
+
return handleProvisionGoogleTotp();
|
|
74287
74497
|
default:
|
|
74288
74498
|
return err(`inbox dispatch: unknown tool "${toolName}"`);
|
|
74289
74499
|
}
|
|
@@ -74459,6 +74669,20 @@ var require_inbox_tools = __commonJS({
|
|
|
74459
74669
|
didMutate: !failed
|
|
74460
74670
|
};
|
|
74461
74671
|
}
|
|
74672
|
+
function handleProvisionGoogleTotp(env = process.env) {
|
|
74673
|
+
const cfg = (0, google_signin_js_1.loadGoogleSignInConfig)(env);
|
|
74674
|
+
if (!cfg) {
|
|
74675
|
+
return err("Google SSO is not configured on this runner (GOOGLE_SIGNIN_PASSWORD unset). Prefer email-field signup, or report Google SSO as BLOCKED.");
|
|
74676
|
+
}
|
|
74677
|
+
if (!cfg.totpSecret) {
|
|
74678
|
+
return err("Google Authenticator 2FA is not configured on this runner (GOOGLE_SIGNIN_TOTP_SECRET unset). STOP and report Google SSO as BLOCKED (2FA not configured).");
|
|
74679
|
+
}
|
|
74680
|
+
return ok({
|
|
74681
|
+
code: (0, google_signin_js_1.generateTotp)(cfg.totpSecret),
|
|
74682
|
+
digits: 6,
|
|
74683
|
+
instructions: "Type this 6-digit code into the Google 2-step / Authenticator prompt. Do not reuse it later \u2014 call this tool again if Google asks for another code."
|
|
74684
|
+
});
|
|
74685
|
+
}
|
|
74462
74686
|
function requireProvisioned(ctx) {
|
|
74463
74687
|
if (ctx.state.provisioned)
|
|
74464
74688
|
return null;
|
|
@@ -74593,7 +74817,7 @@ var require_inbox_tools = __commonJS({
|
|
|
74593
74817
|
${where} You register using ONE real, monitored email (\`${opts.email}\`) and can complete email-verification (OTP code or confirmation link) end-to-end. This OVERRIDES the general "do not submit forms" rule for the signup/registration form ONLY.
|
|
74594
74818
|
|
|
74595
74819
|
Steps:
|
|
74596
|
-
1. Navigate to the Sign Up / Register page (click the link in the UI).
|
|
74820
|
+
1. Navigate to the Sign Up / Register / Sign in page (click the link in the UI). FIRST look for an app Create-account email+password form (including after "Sign up with email").${opts.googleEmail && opts.googlePasswordKey ? ' "Continue with phone", SMS OTP, and "Mobile or email" on a Sign in page are NOT that form \u2014 if Continue with Google is offered and there is no app Create-account email form, use the Google / Gmail SSO playbook below (do not click Continue with phone).' : ""}
|
|
74597
74821
|
2. Call \`provision_identity\` \u2192 it returns the email to register with (\`${opts.email}\`). The \`+\` part is a normal sub-address that still lands in our inbox.
|
|
74598
74822
|
3. Fill the signup form: type that email into the email field with \`browser_type\` (this generated inbox email is intentionally visible and is allowed for registration); fill the password field with single-field \`fill_credential\` (credentialKey \`${opts.passwordKey}\`); fill any name/other required fields with simple test values. Do NOT use \`fill_credential_form\` for registration.
|
|
74599
74823
|
- If the form REJECTS the email (says "invalid email" / will not accept the "+"), call \`provision_identity\` again with \`plain: true\` and use the bare address it returns instead.
|
|
@@ -74611,6 +74835,11 @@ Rules:
|
|
|
74611
74835
|
- The provisioned email is reused for this project; if signup says it is ALREADY registered, the account already exists \u2014 log in with that email + the \`${opts.passwordKey}\` password instead of registering again.
|
|
74612
74836
|
- You register ONCE per run. After you submit the signup form in step 4, NEVER submit it again and NEVER create a second account \u2014 even if verification is slow, even if a later login attempt fails. Recover by re-polling \`wait_for_verification\` (and at most one "Resend"), not by re-registering.
|
|
74613
74837
|
- Only call the verification tools AFTER submitting the signup form, and pass the site as \`senderMatch\` so you read YOUR verification email (the inbox is shared).
|
|
74838
|
+
${opts.googleEmail && opts.googlePasswordKey ? (0, google_signin_js_1.buildGoogleSignInPromptSection)({
|
|
74839
|
+
googleEmail: opts.googleEmail,
|
|
74840
|
+
googlePasswordKey: opts.googlePasswordKey,
|
|
74841
|
+
googleTotpAvailable: opts.googleTotpAvailable
|
|
74842
|
+
}, "native") : ""}
|
|
74614
74843
|
`;
|
|
74615
74844
|
}
|
|
74616
74845
|
exports2.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK = `## EMAIL VERIFICATION UNAVAILABLE \u2014 FINAL OVERRIDE (supersedes any instruction above)
|
|
@@ -74765,11 +74994,12 @@ This project asked to REGISTER a new account, but this runner CANNOT receive ema
|
|
|
74765
74994
|
}
|
|
74766
74995
|
return false;
|
|
74767
74996
|
}
|
|
74768
|
-
function buildInboxAgentsGuidance(email, passwordKey) {
|
|
74997
|
+
function buildInboxAgentsGuidance(email, passwordKey, google) {
|
|
74998
|
+
const googleBlock = google ? (0, google_signin_js_1.buildGoogleSignInPromptSection)(google, "cli") : "";
|
|
74769
74999
|
return `## Account registration & email verification (ENABLED)
|
|
74770
75000
|
This run registers a new account using our ONE real, monitored inbox (the address \`${email}\` \u2014 the "+" part is a normal sub-address that still lands in our inbox) and can complete email verification end-to-end. This overrides any "do not submit forms" guidance for the signup form only.
|
|
74771
75001
|
|
|
74772
|
-
1. Go to the Sign Up / Register page.
|
|
75002
|
+
1. Go to the Sign Up / Register / Sign in page. FIRST look for an app Create-account email+password form (including after "Sign up with email").${google ? ' "Continue with phone", SMS OTP, and "Mobile or email" on a Sign in page are NOT that form \u2014 if Continue with Google is offered and there is no app Create-account email form, use the Google / Gmail SSO playbook below (do not click Continue with phone).' : ""}
|
|
74773
75003
|
2. Call \`inbox_provision_identity\` \u2192 it returns the email to register with (\`${email}\`). Type that email into the email field.
|
|
74774
75004
|
- If the form REJECTS the email (says "invalid email" / will not accept the "+"), call \`inbox_provision_identity\` with \`plain: true\` and use the bare address it returns instead.
|
|
74775
75005
|
3. Fill the password with the \`${passwordKey}\` credential (use fill_credential). Submit the signup form.
|
|
@@ -74780,6 +75010,7 @@ This run registers a new account using our ONE real, monitored inbox (the addres
|
|
|
74780
75010
|
- If it returns BOTH, try the code first; if the app insists on the link, open it, then enter the code if the page it lands on asks for one.
|
|
74781
75011
|
- Otherwise call \`inbox_read_email\` to read the body.
|
|
74782
75012
|
5. NEVER invent an email address \u2014 always use exactly what \`inbox_provision_identity\` returns. The address is reused for this project; if signup says it is already registered, log in with it + \`${passwordKey}\` instead. Register ONCE per run \u2014 never submit signup twice or make a second account; if verification is slow, re-poll \`inbox_wait_for_verification\` (at most one Resend) instead of re-registering.
|
|
75013
|
+
${googleBlock}
|
|
74783
75014
|
`;
|
|
74784
75015
|
}
|
|
74785
75016
|
}
|
|
@@ -88614,6 +88845,7 @@ var require_browser_config = __commonJS({
|
|
|
88614
88845
|
var path_1 = require("path");
|
|
88615
88846
|
var os_1 = require("os");
|
|
88616
88847
|
var shared_1 = (init_dist(), __toCommonJS(dist_exports));
|
|
88848
|
+
var google_signin_js_1 = require_google_signin();
|
|
88617
88849
|
exports2.IS_CLOUD = (0, shared_1.parseBoolFlag)(process.env.RUNNER_CLOUD);
|
|
88618
88850
|
exports2.CLOUD_ARGS = [
|
|
88619
88851
|
"--no-sandbox",
|
|
@@ -88719,6 +88951,10 @@ var require_browser_config = __commonJS({
|
|
|
88719
88951
|
(document.head || document.documentElement).appendChild(style);
|
|
88720
88952
|
|
|
88721
88953
|
// Layer 2: Web Animations API - make instant (preserves completion callbacks)
|
|
88954
|
+
try {
|
|
88955
|
+
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
|
88956
|
+
} catch {}
|
|
88957
|
+
|
|
88722
88958
|
const origAnimate = Element.prototype.animate;
|
|
88723
88959
|
Element.prototype.animate = function(keyframes, options) {
|
|
88724
88960
|
if (typeof options === 'object' && options !== null) {
|
|
@@ -88825,6 +89061,20 @@ var require_browser_config = __commonJS({
|
|
|
88825
89061
|
return null;
|
|
88826
89062
|
}
|
|
88827
89063
|
}
|
|
89064
|
+
function googleSsoCloudLaunch(env = process.env) {
|
|
89065
|
+
if (!(0, shared_1.parseBoolFlag)(env.RUNNER_CLOUD))
|
|
89066
|
+
return null;
|
|
89067
|
+
if (!(0, google_signin_js_1.loadGoogleSignInConfig)(env))
|
|
89068
|
+
return null;
|
|
89069
|
+
const executablePath = getFullChromiumPath();
|
|
89070
|
+
if (!executablePath)
|
|
89071
|
+
return null;
|
|
89072
|
+
return {
|
|
89073
|
+
executablePath,
|
|
89074
|
+
extraArgs: ["--headless=new"],
|
|
89075
|
+
ignoreDefaultArgs: ["--enable-automation"]
|
|
89076
|
+
};
|
|
89077
|
+
}
|
|
88828
89078
|
function getMCPBrowserConfig2(opts) {
|
|
88829
89079
|
const userDataDir = opts?.forceIsolated ? null : getTestUserDataDir2();
|
|
88830
89080
|
const headless = isHeadless2();
|
|
@@ -88848,15 +89098,21 @@ var require_browser_config = __commonJS({
|
|
|
88848
89098
|
};
|
|
88849
89099
|
}
|
|
88850
89100
|
const headlessShellPath = getHeadlessShellPath();
|
|
88851
|
-
const
|
|
89101
|
+
const googleLaunch = googleSsoCloudLaunch();
|
|
89102
|
+
const useHeadlessShell = headless && headlessShellPath && !opts?.harPath && !googleLaunch;
|
|
89103
|
+
const cloud = (0, shared_1.parseBoolFlag)(process.env.RUNNER_CLOUD);
|
|
89104
|
+
const args = [
|
|
89105
|
+
...cloud ? exports2.CLOUD_ARGS : ["--disable-blink-features=AutomationControlled"],
|
|
89106
|
+
...googleLaunch?.extraArgs ?? []
|
|
89107
|
+
];
|
|
88852
89108
|
return {
|
|
88853
89109
|
browserName: "chromium",
|
|
88854
89110
|
isolated: true,
|
|
88855
89111
|
launchOptions: {
|
|
88856
|
-
headless,
|
|
88857
|
-
...useHeadlessShell ? { executablePath: headlessShellPath } : {},
|
|
89112
|
+
headless: googleLaunch ? false : headless,
|
|
89113
|
+
...googleLaunch ? { executablePath: googleLaunch.executablePath, ignoreDefaultArgs: googleLaunch.ignoreDefaultArgs } : useHeadlessShell ? { executablePath: headlessShellPath } : {},
|
|
88858
89114
|
channel: "",
|
|
88859
|
-
args
|
|
89115
|
+
args,
|
|
88860
89116
|
...slowMo > 0 ? { slowMo } : {}
|
|
88861
89117
|
},
|
|
88862
89118
|
contextOptions: {
|
|
@@ -88869,15 +89125,21 @@ var require_browser_config = __commonJS({
|
|
|
88869
89125
|
function getPlaywrightLaunchOptions2(withProfile = false, extraArgs) {
|
|
88870
89126
|
const headless = isHeadless2();
|
|
88871
89127
|
const slowMo = getSlowMoMs();
|
|
89128
|
+
const googleLaunch = googleSsoCloudLaunch();
|
|
88872
89129
|
const baseArgs = exports2.IS_CLOUD ? exports2.CLOUD_ARGS : [
|
|
88873
89130
|
"--disable-blink-features=AutomationControlled"
|
|
88874
89131
|
];
|
|
88875
|
-
const mergedArgs =
|
|
89132
|
+
const mergedArgs = [
|
|
89133
|
+
...baseArgs,
|
|
89134
|
+
...googleLaunch?.extraArgs ?? [],
|
|
89135
|
+
...extraArgs && extraArgs.length > 0 ? extraArgs : []
|
|
89136
|
+
];
|
|
88876
89137
|
return {
|
|
88877
|
-
headless,
|
|
89138
|
+
headless: googleLaunch ? false : headless,
|
|
88878
89139
|
// Use Chrome channel only when a real Chrome user profile is being loaded.
|
|
88879
89140
|
// In isolated mode, bundled Chromium avoids hard dependency on Chrome installation.
|
|
88880
89141
|
...exports2.IS_CLOUD || !withProfile ? {} : { channel: "chrome" },
|
|
89142
|
+
...googleLaunch ? { executablePath: googleLaunch.executablePath, ignoreDefaultArgs: googleLaunch.ignoreDefaultArgs } : {},
|
|
88881
89143
|
args: mergedArgs,
|
|
88882
89144
|
...slowMo > 0 ? { slowMo } : {}
|
|
88883
89145
|
};
|
|
@@ -320219,6 +320481,7 @@ var require_playwright_mcp_config = __commonJS({
|
|
|
320219
320481
|
var promises_1 = require("fs/promises");
|
|
320220
320482
|
var node_path_1 = require("path");
|
|
320221
320483
|
var browser_config_js_1 = require_browser_config();
|
|
320484
|
+
var google_signin_js_1 = require_google_signin();
|
|
320222
320485
|
var PLAYWRIGHT_MCP_VERSION = "0.0.68";
|
|
320223
320486
|
var INBOX_SECRET_ENV_KEYS = [
|
|
320224
320487
|
"VERIFICATION_INBOX_HOST",
|
|
@@ -320228,7 +320491,10 @@ var require_playwright_mcp_config = __commonJS({
|
|
|
320228
320491
|
"VERIFICATION_INBOX_PASSWORD",
|
|
320229
320492
|
"VERIFICATION_INBOX_ADDRESS",
|
|
320230
320493
|
"VERIFICATION_INBOX_MAILBOX",
|
|
320231
|
-
"VERIFICATION_INBOX_EXTRA_MAILBOXES"
|
|
320494
|
+
"VERIFICATION_INBOX_EXTRA_MAILBOXES",
|
|
320495
|
+
"GOOGLE_SIGNIN_PASSWORD",
|
|
320496
|
+
"GOOGLE_SIGNIN_EMAIL",
|
|
320497
|
+
"GOOGLE_SIGNIN_TOTP_SECRET"
|
|
320232
320498
|
];
|
|
320233
320499
|
function collectInboxSecretEnv() {
|
|
320234
320500
|
const out = {};
|
|
@@ -320269,12 +320535,13 @@ var require_playwright_mcp_config = __commonJS({
|
|
|
320269
320535
|
const body = cfg.format === "json" ? buildJsonConfig(cfg) : buildTomlConfig(cfg);
|
|
320270
320536
|
await (0, promises_1.writeFile)(cfg.configPath, body, { encoding: "utf8", mode: 384 });
|
|
320271
320537
|
if (!cfg.cdpEndpoint && browser_config_js_1.IS_CLOUD) {
|
|
320538
|
+
const launchOptions = (0, browser_config_js_1.getMCPBrowserConfig)({ forceIsolated: true }).launchOptions ?? {
|
|
320539
|
+
headless: true,
|
|
320540
|
+
args: [...browser_config_js_1.CLOUD_ARGS]
|
|
320541
|
+
};
|
|
320272
320542
|
const browserConfig = {
|
|
320273
320543
|
browser: {
|
|
320274
|
-
launchOptions
|
|
320275
|
-
headless: true,
|
|
320276
|
-
args: [...browser_config_js_1.CLOUD_ARGS]
|
|
320277
|
-
}
|
|
320544
|
+
launchOptions
|
|
320278
320545
|
}
|
|
320279
320546
|
};
|
|
320280
320547
|
await (0, promises_1.writeFile)(mcpBrowserConfigPath(cfg.configPath), JSON.stringify(browserConfig, null, 2) + "\n", { encoding: "utf8", mode: 384 });
|
|
@@ -320298,7 +320565,11 @@ var require_playwright_mcp_config = __commonJS({
|
|
|
320298
320565
|
];
|
|
320299
320566
|
if (cfg.includeCredentialServer && cfg.cdpEndpoint) {
|
|
320300
320567
|
const serverJs = (0, node_path_1.join)(__dirname, "credential-mcp-server.js");
|
|
320301
|
-
blocks.push("[mcp_servers.validateqa_credentials]", 'command = "node"', `args = ["${tomlEscape(serverJs)}"]`, "enabled = true", "startup_timeout_sec = 30", "tool_timeout_sec = 60", "", "[mcp_servers.validateqa_credentials.env]", `CDP_ENDPOINT = "${tomlEscape(cfg.cdpEndpoint)}"
|
|
320568
|
+
blocks.push("[mcp_servers.validateqa_credentials]", 'command = "node"', `args = ["${tomlEscape(serverJs)}"]`, "enabled = true", "startup_timeout_sec = 30", "tool_timeout_sec = 60", "", "[mcp_servers.validateqa_credentials.env]", `CDP_ENDPOINT = "${tomlEscape(cfg.cdpEndpoint)}"`);
|
|
320569
|
+
for (const [k, v] of Object.entries((0, google_signin_js_1.collectGoogleSignInEnv)())) {
|
|
320570
|
+
blocks.push(`${k} = "${tomlEscape(v)}"`);
|
|
320571
|
+
}
|
|
320572
|
+
blocks.push("");
|
|
320302
320573
|
}
|
|
320303
320574
|
if (cfg.includeDiscoveryServer) {
|
|
320304
320575
|
if (!cfg.runDir) {
|
|
@@ -320346,7 +320617,7 @@ var require_playwright_mcp_config = __commonJS({
|
|
|
320346
320617
|
type: "stdio",
|
|
320347
320618
|
command: "node",
|
|
320348
320619
|
args: [serverJs],
|
|
320349
|
-
env: { CDP_ENDPOINT: cfg.cdpEndpoint }
|
|
320620
|
+
env: { CDP_ENDPOINT: cfg.cdpEndpoint, ...(0, google_signin_js_1.collectGoogleSignInEnv)() }
|
|
320350
320621
|
};
|
|
320351
320622
|
}
|
|
320352
320623
|
if (cfg.includeDiscoveryServer) {
|
|
@@ -328553,6 +328824,7 @@ var require_discover_explorer = __commonJS({
|
|
|
328553
328824
|
var credential_tools_js_1 = require_credential_tools();
|
|
328554
328825
|
var inbox_tools_js_1 = require_inbox_tools();
|
|
328555
328826
|
var verification_inbox_js_1 = require_verification_inbox();
|
|
328827
|
+
var google_signin_js_1 = require_google_signin();
|
|
328556
328828
|
var discover_planner_js_1 = require_discover_planner();
|
|
328557
328829
|
var exploration_prompt_builder_js_1 = require_exploration_prompt_builder();
|
|
328558
328830
|
var ai_queue_js_1 = require_ai_queue();
|
|
@@ -328957,7 +329229,8 @@ NEVER assert: user-specific text (names, emails), counts/numbers, timestamps, ma
|
|
|
328957
329229
|
};
|
|
328958
329230
|
function buildSystemPrompt(baseUrl, variableContext, existingSiteMap, existingTestNames, options) {
|
|
328959
329231
|
const browserCredentials = variableContext.allTestVariables ?? variableContext.publicTestVariables;
|
|
328960
|
-
const { secrets:
|
|
329232
|
+
const { secrets: explorerSecretVarsRaw, publics: explorerPublicVarsRaw } = (0, credential_tools_js_1.partitionTestVariables)(browserCredentials);
|
|
329233
|
+
const explorerSecretVars = options?.inboxPrompt ? (0, google_signin_js_1.mergeGoogleSignInSecrets)(explorerSecretVarsRaw) : explorerSecretVarsRaw;
|
|
328961
329234
|
const hasCredentials = Object.keys(explorerSecretVars).length > 0;
|
|
328962
329235
|
const { DISCOVERY_SHOULD_REGISTER: _omitRegisterFlag, ...explorerPublicVars } = explorerPublicVarsRaw;
|
|
328963
329236
|
const explorerPublicLines = (0, credential_tools_js_1.renderPublicVariablesBlock)(explorerPublicVars);
|
|
@@ -329574,10 +329847,12 @@ ${inbox_tools_js_1.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK}` : ""}`;
|
|
|
329574
329847
|
if (emailVerificationUnavailable) {
|
|
329575
329848
|
logs2.push("Email verification unavailable \u2014 the agent will ATTEMPT registration once; any flow requiring an emailed code/link will be reported BLOCKED.");
|
|
329576
329849
|
}
|
|
329850
|
+
const googleGuidance = (0, google_signin_js_1.googleSignInGuidanceOpts)();
|
|
329577
329851
|
const inboxPromptBlock = inboxState ? (0, inbox_tools_js_1.buildInboxPromptBlock)({
|
|
329578
329852
|
email: inboxState.email,
|
|
329579
329853
|
passwordKey: inboxState.passwordKey ?? "TEST_USER_PASSWORD",
|
|
329580
|
-
context: options?.mode
|
|
329854
|
+
context: options?.mode,
|
|
329855
|
+
...googleGuidance
|
|
329581
329856
|
}) : "";
|
|
329582
329857
|
try {
|
|
329583
329858
|
const { tools: mcpTools } = await mcpClient.listTools();
|
|
@@ -329598,7 +329873,8 @@ ${inbox_tools_js_1.EMAIL_VERIFICATION_UNAVAILABLE_OVERRIDE_BLOCK}` : ""}`;
|
|
|
329598
329873
|
}
|
|
329599
329874
|
const browserCredsForTools = variableContext.allTestVariables ?? variableContext.publicTestVariables;
|
|
329600
329875
|
const { secrets: explorerToolSecrets } = (0, credential_tools_js_1.partitionTestVariables)(browserCredsForTools);
|
|
329601
|
-
|
|
329876
|
+
const explorerToolSecretsWithGoogle = inboxState ? (0, google_signin_js_1.mergeGoogleSignInSecrets)(explorerToolSecrets) : explorerToolSecrets;
|
|
329877
|
+
if (Object.keys(explorerToolSecretsWithGoogle).length > 0) {
|
|
329602
329878
|
openaiTools.push(credential_tools_js_1.FILL_CREDENTIAL_TOOL, credential_tools_js_1.FILL_CREDENTIAL_FORM_TOOL);
|
|
329603
329879
|
if (options?.onCredentialUpdate) {
|
|
329604
329880
|
openaiTools.push(credential_tools_js_1.SET_CREDENTIAL_TOOL);
|
|
@@ -330238,8 +330514,12 @@ ${currentSummary}`;
|
|
|
330238
330514
|
let finishBouncedThisBatch = false;
|
|
330239
330515
|
let finishStreakCountedThisBatch = false;
|
|
330240
330516
|
const fullVarMapForGuard = variableContext.allTestVariables ?? variableContext.publicTestVariables;
|
|
330241
|
-
const { secrets:
|
|
330242
|
-
const
|
|
330517
|
+
const { secrets: partitionedSecretsForGuard } = (0, credential_tools_js_1.partitionTestVariables)(fullVarMapForGuard);
|
|
330518
|
+
const secretsOnlyForGuard = inboxState ? (0, google_signin_js_1.mergeGoogleSignInSecrets)(partitionedSecretsForGuard) : partitionedSecretsForGuard;
|
|
330519
|
+
const allowedCredentialValues = [...new Set([
|
|
330520
|
+
...inboxState ? [inboxState.email, inboxState.baseEmail] : [],
|
|
330521
|
+
...inboxState ? (0, google_signin_js_1.googleSignInAllowedEmails)() : []
|
|
330522
|
+
].filter((value) => !!value))];
|
|
330243
330523
|
const secretsForLogging = Object.fromEntries(Object.entries(secretsOnlyForGuard).filter(([, value]) => !allowedCredentialValues.includes(value)));
|
|
330244
330524
|
for (const toolCall of assistantMessage.tool_calls) {
|
|
330245
330525
|
const toolName = toolCall.function.name;
|
|
@@ -331090,8 +331370,9 @@ Exploration complete: ${summary}`);
|
|
|
331090
331370
|
}
|
|
331091
331371
|
const fullVarMap = variableContext.allTestVariables ?? variableContext.publicTestVariables;
|
|
331092
331372
|
const { secrets: dispatchSecrets } = (0, credential_tools_js_1.partitionTestVariables)(fullVarMap);
|
|
331373
|
+
const fillSecrets = inboxState ? (0, google_signin_js_1.mergeGoogleSignInSecrets)(dispatchSecrets) : dispatchSecrets;
|
|
331093
331374
|
try {
|
|
331094
|
-
const result = toolName === "fill_credential" ? await (0, credential_tools_js_1.handleFillCredential)(toolArgs, { mcpClient, credentials:
|
|
331375
|
+
const result = toolName === "fill_credential" ? await (0, credential_tools_js_1.handleFillCredential)(toolArgs, { mcpClient, credentials: fillSecrets, maxResultChars: MAX_TOOL_RESULT_CHARS }) : await (0, credential_tools_js_1.handleFillCredentialForm)(toolArgs, { mcpClient, credentials: fillSecrets, maxResultChars: MAX_TOOL_RESULT_CHARS });
|
|
331095
331376
|
if (result.didMutate) {
|
|
331096
331377
|
lastSnapshotText = null;
|
|
331097
331378
|
const codeLines = (0, exploration_parser_js_1.extractCodeLines)(result.content);
|
|
@@ -333131,7 +333412,7 @@ ${keyLines || "- (none provided)"}
|
|
|
333131
333412
|
## EXACTLY what to do
|
|
333132
333413
|
1. Navigate to ${baseUrl} and take a \`browser_snapshot\`.
|
|
333133
333414
|
2. Find the Sign Up / Register / Create account affordance (match by PURPOSE, in the app's own language) and open the signup form. If a reveal button hides the fields ("Sign up with Email"), click it first.
|
|
333134
|
-
3. Follow the "Account Registration (verification inbox is ENABLED)" steps below EXACTLY: call \`provision_identity\` for the email, type that email, fill the password with \`fill_credential\`, fill any other required fields with simple test values, and submit.
|
|
333415
|
+
3. Follow the "Account Registration (verification inbox is ENABLED)" steps below EXACTLY: call \`provision_identity\` for the email, type that email, fill the password with \`fill_credential\`, fill any other required fields with simple test values, and submit. If there is no app Create-account email form (phone / "Mobile or email" / SMS do not count) and Sign in offers "Continue with Google", follow the Google / Gmail SSO playbook (bare Google account email, \`fill_credential\` with \`GOOGLE_SIGNIN_PASSWORD\` on accounts.google.com, never TEST_USER_PASSWORD, never Continue with phone).
|
|
333135
333416
|
4. Complete email verification using the inbox tools (\`wait_for_verification\` \u2192 enter the code or \`open_verification_link\`). Re-poll if the email is slow; resend AT MOST once; NEVER register a second account.
|
|
333136
333417
|
5. Confirm you are signed in \u2014 a redirect to an authenticated route, or an in-place change to authenticated content. Take a \`browser_snapshot\`.
|
|
333137
333418
|
6. \`capture_page\` the authenticated landing page in its DEFAULT state, then call \`finish_exploration\`. Do this the MOMENT the account is verified and you are signed in.
|
|
@@ -333685,6 +333966,7 @@ var require_grok_survey_runner = __commonJS({
|
|
|
333685
333966
|
var grok_cli_js_1 = require_grok_cli();
|
|
333686
333967
|
var playwright_mcp_config_js_1 = require_playwright_mcp_config();
|
|
333687
333968
|
var inbox_tools_js_1 = require_inbox_tools();
|
|
333969
|
+
var google_signin_js_1 = require_google_signin();
|
|
333688
333970
|
var exploration_parser_js_1 = require_exploration_parser();
|
|
333689
333971
|
var scrub_credentials_js_1 = require_scrub_credentials();
|
|
333690
333972
|
var agentic_survey_prompts_js_1 = require_agentic_survey_prompts();
|
|
@@ -334209,7 +334491,7 @@ var require_grok_survey_runner = __commonJS({
|
|
|
334209
334491
|
};
|
|
334210
334492
|
const surveyAgentsMd = inboxReg ? `${(0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)()}
|
|
334211
334493
|
|
|
334212
|
-
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey)}` : (0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)();
|
|
334494
|
+
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey, (0, google_signin_js_1.googleSignInGuidanceOpts)())}` : (0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)();
|
|
334213
334495
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "AGENTS.md"), surveyAgentsMd, "utf8");
|
|
334214
334496
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "BRIEF.md"), (0, agentic_survey_prompts_js_1.buildSurveyBriefMd)(briefInput), "utf8");
|
|
334215
334497
|
log2("Wrote AGENTS.md + BRIEF.md");
|
|
@@ -335616,6 +335898,7 @@ var require_grok_discovery_runner = __commonJS({
|
|
|
335616
335898
|
var playwright_native_js_1 = require_playwright_native();
|
|
335617
335899
|
var playwright_mcp_config_js_1 = require_playwright_mcp_config();
|
|
335618
335900
|
var inbox_tools_js_1 = require_inbox_tools();
|
|
335901
|
+
var google_signin_js_1 = require_google_signin();
|
|
335619
335902
|
var scrub_credentials_js_1 = require_scrub_credentials();
|
|
335620
335903
|
var grok_survey_runner_js_1 = require_grok_survey_runner();
|
|
335621
335904
|
var agentic_discovery_prompts_js_1 = require_agentic_discovery_prompts();
|
|
@@ -335909,7 +336192,7 @@ var require_grok_discovery_runner = __commonJS({
|
|
|
335909
336192
|
};
|
|
335910
336193
|
const discoveryAgentsMd = inboxReg ? `${(0, agentic_discovery_prompts_js_1.buildDiscoveryAgentsMd)()}
|
|
335911
336194
|
|
|
335912
|
-
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey)}` : (0, agentic_discovery_prompts_js_1.buildDiscoveryAgentsMd)();
|
|
336195
|
+
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey, (0, google_signin_js_1.googleSignInGuidanceOpts)())}` : (0, agentic_discovery_prompts_js_1.buildDiscoveryAgentsMd)();
|
|
335913
336196
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "AGENTS.md"), discoveryAgentsMd, "utf8");
|
|
335914
336197
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "BRIEF.md"), (0, agentic_discovery_prompts_js_1.buildDiscoveryBriefMd)(briefInput), "utf8");
|
|
335915
336198
|
await (0, promises_1.mkdir)(testsDirPath, { recursive: true });
|
|
@@ -336862,7 +337145,7 @@ ${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwo
|
|
|
336862
337145
|
|
|
336863
337146
|
---
|
|
336864
337147
|
|
|
336865
|
-
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxRegV2.email, inboxRegV2.passwordKey)}` : "");
|
|
337148
|
+
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxRegV2.email, inboxRegV2.passwordKey, (0, google_signin_js_1.googleSignInGuidanceOpts)())}` : "");
|
|
336866
337149
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "AGENTS.md"), agentsMd, "utf8");
|
|
336867
337150
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "BRIEF.md"), (0, agentic_discovery_prompts_js_1.buildDiscoveryBriefMd)(briefInput), "utf8");
|
|
336868
337151
|
await (0, promises_1.mkdir)(testsDirPath, { recursive: true });
|
|
@@ -337834,6 +338117,7 @@ var require_claude_survey_runner = __commonJS({
|
|
|
337834
338117
|
var claude_stream_parser_js_1 = require_claude_stream_parser();
|
|
337835
338118
|
var playwright_mcp_config_js_1 = require_playwright_mcp_config();
|
|
337836
338119
|
var inbox_tools_js_1 = require_inbox_tools();
|
|
338120
|
+
var google_signin_js_1 = require_google_signin();
|
|
337837
338121
|
var scrub_credentials_js_1 = require_scrub_credentials();
|
|
337838
338122
|
var agentic_cli_constants_js_1 = require_agentic_cli_constants();
|
|
337839
338123
|
var grok_survey_runner_js_1 = require_grok_survey_runner();
|
|
@@ -337934,7 +338218,7 @@ ${preview}`);
|
|
|
337934
338218
|
};
|
|
337935
338219
|
const surveyAgentsMd = inboxReg ? `${(0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)({ canvasMode })}
|
|
337936
338220
|
|
|
337937
|
-
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey)}` : (0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)({ canvasMode });
|
|
338221
|
+
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey, (0, google_signin_js_1.googleSignInGuidanceOpts)())}` : (0, agentic_survey_prompts_js_1.buildSurveyAgentsMd)({ canvasMode });
|
|
337938
338222
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "AGENTS.md"), surveyAgentsMd, "utf8");
|
|
337939
338223
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "BRIEF.md"), (0, agentic_survey_prompts_js_1.buildSurveyBriefMd)(briefInput), "utf8");
|
|
337940
338224
|
log2("Wrote AGENTS.md + BRIEF.md");
|
|
@@ -338644,6 +338928,7 @@ var require_claude_discovery_runner = __commonJS({
|
|
|
338644
338928
|
var claude_cli_js_1 = require_claude_cli();
|
|
338645
338929
|
var playwright_mcp_config_js_1 = require_playwright_mcp_config();
|
|
338646
338930
|
var inbox_tools_js_1 = require_inbox_tools();
|
|
338931
|
+
var google_signin_js_1 = require_google_signin();
|
|
338647
338932
|
var coverage_examples_content_js_1 = require_coverage_examples_content();
|
|
338648
338933
|
var scrub_credentials_js_1 = require_scrub_credentials();
|
|
338649
338934
|
var agentic_cli_constants_js_1 = require_agentic_cli_constants();
|
|
@@ -338812,7 +339097,7 @@ var require_claude_discovery_runner = __commonJS({
|
|
|
338812
339097
|
};
|
|
338813
339098
|
const explorerContractMd = inboxReg ? `${(0, agentic_discovery_prompts_js_1.buildExplorerContractMd)(contractInput)}
|
|
338814
339099
|
|
|
338815
|
-
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey)}` : (0, agentic_discovery_prompts_js_1.buildExplorerContractMd)(contractInput);
|
|
339100
|
+
${(0, inbox_tools_js_1.buildInboxAgentsGuidance)(inboxReg.email, inboxReg.passwordKey, (0, google_signin_js_1.googleSignInGuidanceOpts)())}` : (0, agentic_discovery_prompts_js_1.buildExplorerContractMd)(contractInput);
|
|
338816
339101
|
await (0, promises_1.writeFile)(claudeMdPath, explorerContractMd, "utf8");
|
|
338817
339102
|
await (0, promises_1.writeFile)((0, node_path_1.join)(runDir, "BRIEF.md"), (0, agentic_discovery_prompts_js_1.buildDiscoveryBriefMd)(briefInput), "utf8");
|
|
338818
339103
|
await (0, promises_1.mkdir)(testsDirPath, { recursive: true });
|
|
@@ -356069,7 +356354,7 @@ var require_package4 = __commonJS({
|
|
|
356069
356354
|
"package.json"(exports2, module2) {
|
|
356070
356355
|
module2.exports = {
|
|
356071
356356
|
name: "@validate.qa/runner",
|
|
356072
|
-
version: "1.0.
|
|
356357
|
+
version: "1.0.94",
|
|
356073
356358
|
description: "validate local test runner - execute Playwright tests on your machine, connected to validate.qa cloud.",
|
|
356074
356359
|
bin: {
|
|
356075
356360
|
"validate-runner": "dist/cli.js"
|