@hasna/testers 0.0.40 → 0.0.42
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/index.js +57 -8
- package/dist/index.js +21 -6
- package/dist/lib/persona-auth.d.ts +2 -0
- package/dist/lib/persona-auth.d.ts.map +1 -1
- package/dist/lib/persona-redaction.d.ts +19 -0
- package/dist/lib/persona-redaction.d.ts.map +1 -0
- package/dist/mcp/index.js +63 -14
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/server/index.js +22 -7
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16940,17 +16940,32 @@ var init_secrets_resolver = () => {};
|
|
|
16940
16940
|
function isSessionCookie(cookieName) {
|
|
16941
16941
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
16942
16942
|
}
|
|
16943
|
-
function
|
|
16943
|
+
function isPrimarySessionCookie(cookieName) {
|
|
16944
|
+
return isSessionCookie(cookieName) && !/refresh/i.test(cookieName);
|
|
16945
|
+
}
|
|
16946
|
+
function getCookieExpires(cookie) {
|
|
16947
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
16948
|
+
return cookie.expires;
|
|
16949
|
+
}
|
|
16950
|
+
if (typeof cookie.expires === "string") {
|
|
16951
|
+
const parsed = Number(cookie.expires);
|
|
16952
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
16953
|
+
}
|
|
16954
|
+
return null;
|
|
16955
|
+
}
|
|
16956
|
+
function hasFreshAuthCookies(persona) {
|
|
16944
16957
|
if (!persona.auth?.cookies?.length)
|
|
16945
16958
|
return false;
|
|
16946
16959
|
const cookies = persona.auth.cookies;
|
|
16947
|
-
|
|
16960
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isPrimarySessionCookie(String(cookie.name)));
|
|
16961
|
+
if (sessionCookies.length === 0) {
|
|
16948
16962
|
return false;
|
|
16949
16963
|
}
|
|
16950
16964
|
const now2 = Date.now() / 1000;
|
|
16951
|
-
const
|
|
16952
|
-
if (
|
|
16953
|
-
return
|
|
16965
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
16966
|
+
if (expiringSessionCookies.length > 0) {
|
|
16967
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
16968
|
+
}
|
|
16954
16969
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
16955
16970
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
16956
16971
|
}
|
|
@@ -17140,7 +17155,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
17140
17155
|
if (!persona.auth) {
|
|
17141
17156
|
return { success: true, method: "none" };
|
|
17142
17157
|
}
|
|
17143
|
-
if (
|
|
17158
|
+
if (hasFreshAuthCookies(persona)) {
|
|
17144
17159
|
const restored = await restoreCookies(page, persona);
|
|
17145
17160
|
if (restored) {
|
|
17146
17161
|
return { success: true, method: "cookies" };
|
|
@@ -94025,7 +94040,7 @@ import chalk6 from "chalk";
|
|
|
94025
94040
|
// package.json
|
|
94026
94041
|
var package_default = {
|
|
94027
94042
|
name: "@hasna/testers",
|
|
94028
|
-
version: "0.0.
|
|
94043
|
+
version: "0.0.42",
|
|
94029
94044
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
94030
94045
|
type: "module",
|
|
94031
94046
|
main: "dist/index.js",
|
|
@@ -95752,6 +95767,40 @@ function formatProdDebugPlan(plan) {
|
|
|
95752
95767
|
`);
|
|
95753
95768
|
}
|
|
95754
95769
|
|
|
95770
|
+
// src/lib/persona-redaction.ts
|
|
95771
|
+
function stringKeys(value) {
|
|
95772
|
+
return value ? Object.keys(value).sort() : [];
|
|
95773
|
+
}
|
|
95774
|
+
function cookieNames(cookies) {
|
|
95775
|
+
if (!cookies)
|
|
95776
|
+
return [];
|
|
95777
|
+
return cookies.map((cookie) => cookie.name).filter((name) => typeof name === "string" && name.length > 0);
|
|
95778
|
+
}
|
|
95779
|
+
function redactPersona(persona) {
|
|
95780
|
+
if (!persona.auth)
|
|
95781
|
+
return { ...persona, auth: null };
|
|
95782
|
+
const names = cookieNames(persona.auth.cookies);
|
|
95783
|
+
const headerNames = stringKeys(persona.auth.headers);
|
|
95784
|
+
return {
|
|
95785
|
+
...persona,
|
|
95786
|
+
auth: {
|
|
95787
|
+
emailConfigured: Boolean(persona.auth.email),
|
|
95788
|
+
passwordConfigured: Boolean(persona.auth.password),
|
|
95789
|
+
loginPath: persona.auth.loginPath,
|
|
95790
|
+
strategy: persona.auth.strategy,
|
|
95791
|
+
cookiesConfigured: names.length > 0,
|
|
95792
|
+
cookieCount: names.length,
|
|
95793
|
+
cookieNames: names,
|
|
95794
|
+
headersConfigured: headerNames.length > 0,
|
|
95795
|
+
headerNames,
|
|
95796
|
+
customScriptConfigured: Boolean(persona.auth.customScript)
|
|
95797
|
+
}
|
|
95798
|
+
};
|
|
95799
|
+
}
|
|
95800
|
+
function redactPersonas(personas) {
|
|
95801
|
+
return personas.map(redactPersona);
|
|
95802
|
+
}
|
|
95803
|
+
|
|
95755
95804
|
// src/cli/index.tsx
|
|
95756
95805
|
init_projects();
|
|
95757
95806
|
init_personas();
|
|
@@ -100783,7 +100832,7 @@ personaCmd.command("list").description("List personas").option("--project <id>",
|
|
|
100783
100832
|
globalOnly: opts.global ? true : undefined
|
|
100784
100833
|
});
|
|
100785
100834
|
if (opts.json) {
|
|
100786
|
-
log(JSON.stringify(personas, null, 2));
|
|
100835
|
+
log(JSON.stringify(redactPersonas(personas), null, 2));
|
|
100787
100836
|
return;
|
|
100788
100837
|
}
|
|
100789
100838
|
if (personas.length === 0) {
|
package/dist/index.js
CHANGED
|
@@ -15499,17 +15499,32 @@ var COOKIE_MAX_AGE_MS = 60 * 60 * 1000;
|
|
|
15499
15499
|
function isSessionCookie(cookieName) {
|
|
15500
15500
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
15501
15501
|
}
|
|
15502
|
-
function
|
|
15502
|
+
function isPrimarySessionCookie(cookieName) {
|
|
15503
|
+
return isSessionCookie(cookieName) && !/refresh/i.test(cookieName);
|
|
15504
|
+
}
|
|
15505
|
+
function getCookieExpires(cookie) {
|
|
15506
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
15507
|
+
return cookie.expires;
|
|
15508
|
+
}
|
|
15509
|
+
if (typeof cookie.expires === "string") {
|
|
15510
|
+
const parsed = Number(cookie.expires);
|
|
15511
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
15512
|
+
}
|
|
15513
|
+
return null;
|
|
15514
|
+
}
|
|
15515
|
+
function hasFreshAuthCookies(persona) {
|
|
15503
15516
|
if (!persona.auth?.cookies?.length)
|
|
15504
15517
|
return false;
|
|
15505
15518
|
const cookies = persona.auth.cookies;
|
|
15506
|
-
|
|
15519
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isPrimarySessionCookie(String(cookie.name)));
|
|
15520
|
+
if (sessionCookies.length === 0) {
|
|
15507
15521
|
return false;
|
|
15508
15522
|
}
|
|
15509
15523
|
const now2 = Date.now() / 1000;
|
|
15510
|
-
const
|
|
15511
|
-
if (
|
|
15512
|
-
return
|
|
15524
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
15525
|
+
if (expiringSessionCookies.length > 0) {
|
|
15526
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
15527
|
+
}
|
|
15513
15528
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
15514
15529
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
15515
15530
|
}
|
|
@@ -15699,7 +15714,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
15699
15714
|
if (!persona.auth) {
|
|
15700
15715
|
return { success: true, method: "none" };
|
|
15701
15716
|
}
|
|
15702
|
-
if (
|
|
15717
|
+
if (hasFreshAuthCookies(persona)) {
|
|
15703
15718
|
const restored = await restoreCookies(page, persona);
|
|
15704
15719
|
if (restored) {
|
|
15705
15720
|
return { success: true, method: "cookies" };
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { Page } from "playwright";
|
|
2
2
|
import type { Persona } from "../types/index.js";
|
|
3
3
|
export declare function isSessionCookie(cookieName: string): boolean;
|
|
4
|
+
export declare function isPrimarySessionCookie(cookieName: string): boolean;
|
|
4
5
|
export interface LoginResult {
|
|
5
6
|
success: boolean;
|
|
6
7
|
method: "cookies" | "login" | "none";
|
|
7
8
|
error?: string;
|
|
8
9
|
}
|
|
10
|
+
export declare function hasFreshAuthCookies(persona: Persona): boolean;
|
|
9
11
|
/**
|
|
10
12
|
* Perform login using a raw AuthConfig (e.g. from scenario.authConfig or an auth preset).
|
|
11
13
|
* Resolves credentials via resolveCredential() supporting @secrets: and $ENV references.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persona-auth.d.ts","sourceRoot":"","sources":["../../src/lib/persona-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAMjD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"persona-auth.d.ts","sourceRoot":"","sources":["../../src/lib/persona-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAMjD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkBD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAsB7D;AA2ND;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EACvG,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAsBtB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Persona } from "../types/index.js";
|
|
2
|
+
export interface RedactedPersonaAuth {
|
|
3
|
+
emailConfigured: boolean;
|
|
4
|
+
passwordConfigured: boolean;
|
|
5
|
+
loginPath: string;
|
|
6
|
+
strategy: string;
|
|
7
|
+
cookiesConfigured: boolean;
|
|
8
|
+
cookieCount: number;
|
|
9
|
+
cookieNames: string[];
|
|
10
|
+
headersConfigured: boolean;
|
|
11
|
+
headerNames: string[];
|
|
12
|
+
customScriptConfigured: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type RedactedPersona = Omit<Persona, "auth"> & {
|
|
15
|
+
auth: RedactedPersonaAuth | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function redactPersona(persona: Persona): RedactedPersona;
|
|
18
|
+
export declare function redactPersonas(personas: Persona[]): RedactedPersona[];
|
|
19
|
+
//# sourceMappingURL=persona-redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-redaction.d.ts","sourceRoot":"","sources":["../../src/lib/persona-redaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IACpD,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAClC,CAAC;AAaF,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAoB/D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,eAAe,EAAE,CAErE"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.42",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
|
@@ -20048,17 +20048,32 @@ var init_secrets_resolver = () => {};
|
|
|
20048
20048
|
function isSessionCookie(cookieName) {
|
|
20049
20049
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
20050
20050
|
}
|
|
20051
|
-
function
|
|
20051
|
+
function isPrimarySessionCookie(cookieName) {
|
|
20052
|
+
return isSessionCookie(cookieName) && !/refresh/i.test(cookieName);
|
|
20053
|
+
}
|
|
20054
|
+
function getCookieExpires(cookie) {
|
|
20055
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
20056
|
+
return cookie.expires;
|
|
20057
|
+
}
|
|
20058
|
+
if (typeof cookie.expires === "string") {
|
|
20059
|
+
const parsed = Number(cookie.expires);
|
|
20060
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
20061
|
+
}
|
|
20062
|
+
return null;
|
|
20063
|
+
}
|
|
20064
|
+
function hasFreshAuthCookies(persona) {
|
|
20052
20065
|
if (!persona.auth?.cookies?.length)
|
|
20053
20066
|
return false;
|
|
20054
20067
|
const cookies = persona.auth.cookies;
|
|
20055
|
-
|
|
20068
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isPrimarySessionCookie(String(cookie.name)));
|
|
20069
|
+
if (sessionCookies.length === 0) {
|
|
20056
20070
|
return false;
|
|
20057
20071
|
}
|
|
20058
20072
|
const now2 = Date.now() / 1000;
|
|
20059
|
-
const
|
|
20060
|
-
if (
|
|
20061
|
-
return
|
|
20073
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
20074
|
+
if (expiringSessionCookies.length > 0) {
|
|
20075
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
20076
|
+
}
|
|
20062
20077
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
20063
20078
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
20064
20079
|
}
|
|
@@ -20248,7 +20263,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
20248
20263
|
if (!persona.auth) {
|
|
20249
20264
|
return { success: true, method: "none" };
|
|
20250
20265
|
}
|
|
20251
|
-
if (
|
|
20266
|
+
if (hasFreshAuthCookies(persona)) {
|
|
20252
20267
|
const restored = await restoreCookies(page, persona);
|
|
20253
20268
|
if (restored) {
|
|
20254
20269
|
return { success: true, method: "cookies" };
|
|
@@ -53463,6 +53478,40 @@ var init_workflow_agent = __esm(() => {
|
|
|
53463
53478
|
init_runner();
|
|
53464
53479
|
});
|
|
53465
53480
|
|
|
53481
|
+
// src/lib/persona-redaction.ts
|
|
53482
|
+
function stringKeys(value) {
|
|
53483
|
+
return value ? Object.keys(value).sort() : [];
|
|
53484
|
+
}
|
|
53485
|
+
function cookieNames(cookies) {
|
|
53486
|
+
if (!cookies)
|
|
53487
|
+
return [];
|
|
53488
|
+
return cookies.map((cookie) => cookie.name).filter((name21) => typeof name21 === "string" && name21.length > 0);
|
|
53489
|
+
}
|
|
53490
|
+
function redactPersona(persona) {
|
|
53491
|
+
if (!persona.auth)
|
|
53492
|
+
return { ...persona, auth: null };
|
|
53493
|
+
const names = cookieNames(persona.auth.cookies);
|
|
53494
|
+
const headerNames = stringKeys(persona.auth.headers);
|
|
53495
|
+
return {
|
|
53496
|
+
...persona,
|
|
53497
|
+
auth: {
|
|
53498
|
+
emailConfigured: Boolean(persona.auth.email),
|
|
53499
|
+
passwordConfigured: Boolean(persona.auth.password),
|
|
53500
|
+
loginPath: persona.auth.loginPath,
|
|
53501
|
+
strategy: persona.auth.strategy,
|
|
53502
|
+
cookiesConfigured: names.length > 0,
|
|
53503
|
+
cookieCount: names.length,
|
|
53504
|
+
cookieNames: names,
|
|
53505
|
+
headersConfigured: headerNames.length > 0,
|
|
53506
|
+
headerNames,
|
|
53507
|
+
customScriptConfigured: Boolean(persona.auth.customScript)
|
|
53508
|
+
}
|
|
53509
|
+
};
|
|
53510
|
+
}
|
|
53511
|
+
function redactPersonas(personas) {
|
|
53512
|
+
return personas.map(redactPersona);
|
|
53513
|
+
}
|
|
53514
|
+
|
|
53466
53515
|
// src/db/environments.ts
|
|
53467
53516
|
var exports_environments = {};
|
|
53468
53517
|
__export(exports_environments, {
|
|
@@ -86939,7 +86988,7 @@ function buildServer() {
|
|
|
86939
86988
|
authPassword,
|
|
86940
86989
|
authLoginPath
|
|
86941
86990
|
});
|
|
86942
|
-
return json3(persona);
|
|
86991
|
+
return json3(redactPersona(persona));
|
|
86943
86992
|
} catch (error40) {
|
|
86944
86993
|
return errorResponse(error40);
|
|
86945
86994
|
}
|
|
@@ -86951,7 +87000,7 @@ function buildServer() {
|
|
|
86951
87000
|
}, async ({ projectId, enabled, globalOnly }) => {
|
|
86952
87001
|
try {
|
|
86953
87002
|
const personas = listPersonas({ projectId, enabled, globalOnly });
|
|
86954
|
-
return json3({ items: personas, total: personas.length });
|
|
87003
|
+
return json3({ items: redactPersonas(personas), total: personas.length });
|
|
86955
87004
|
} catch (error40) {
|
|
86956
87005
|
return errorResponse(error40);
|
|
86957
87006
|
}
|
|
@@ -86966,7 +87015,7 @@ function buildServer() {
|
|
|
86966
87015
|
const db2 = getDatabase();
|
|
86967
87016
|
const scenarioRows = db2.query("SELECT id, short_id, name FROM scenarios WHERE persona_id = ?").all(persona.id);
|
|
86968
87017
|
return json3({
|
|
86969
|
-
...persona,
|
|
87018
|
+
...redactPersona(persona),
|
|
86970
87019
|
usedByScenarios: scenarioRows.map((r2) => ({ id: r2.id, shortId: r2.short_id, name: r2.name }))
|
|
86971
87020
|
});
|
|
86972
87021
|
} catch (error40) {
|
|
@@ -86989,7 +87038,7 @@ function buildServer() {
|
|
|
86989
87038
|
}, async ({ id, version: version2, ...updates }) => {
|
|
86990
87039
|
try {
|
|
86991
87040
|
const persona = updatePersona(id, updates, version2);
|
|
86992
|
-
return json3(persona);
|
|
87041
|
+
return json3(redactPersona(persona));
|
|
86993
87042
|
} catch (error40) {
|
|
86994
87043
|
return errorResponse(error40, {
|
|
86995
87044
|
fetchCurrent: () => getPersona(id)
|
|
@@ -87020,7 +87069,7 @@ function buildServer() {
|
|
|
87020
87069
|
if (!scenario)
|
|
87021
87070
|
return errorResponse(notFoundErr(scenarioId, "Scenario"));
|
|
87022
87071
|
const updated = updateScenario(scenario.id, { personaId: persona.id }, scenario.version);
|
|
87023
|
-
return json3({ ...updated, attachedPersona: persona });
|
|
87072
|
+
return json3({ ...updated, attachedPersona: redactPersona(persona) });
|
|
87024
87073
|
} catch (error40) {
|
|
87025
87074
|
return errorResponse(error40);
|
|
87026
87075
|
}
|
|
@@ -87418,7 +87467,7 @@ function buildServer() {
|
|
|
87418
87467
|
projectId: scenario.projectId ?? undefined,
|
|
87419
87468
|
personaId: persona.id
|
|
87420
87469
|
});
|
|
87421
|
-
return json3({ ...clone2, attachedPersona: persona, clonedFrom: scenario.id });
|
|
87470
|
+
return json3({ ...clone2, attachedPersona: redactPersona(persona), clonedFrom: scenario.id });
|
|
87422
87471
|
} catch (e2) {
|
|
87423
87472
|
return errorResponse(e2);
|
|
87424
87473
|
}
|
|
@@ -87683,7 +87732,7 @@ Context: ${context2}` : ""}`,
|
|
|
87683
87732
|
const updated = syncPersonaFromContact2(persona.id);
|
|
87684
87733
|
if (!updated)
|
|
87685
87734
|
return json3({ synced: false, message: "No linked contact found or no changes needed" });
|
|
87686
|
-
return json3({ synced: true, persona: updated });
|
|
87735
|
+
return json3({ synced: true, persona: redactPersona(updated) });
|
|
87687
87736
|
} catch (e2) {
|
|
87688
87737
|
return errorResponse(e2);
|
|
87689
87738
|
}
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiHpE,wBAAgB,WAAW,IAAI,SAAS,CA2+EvC"}
|
package/dist/server/index.js
CHANGED
|
@@ -46910,7 +46910,7 @@ import { join as join14 } from "path";
|
|
|
46910
46910
|
// package.json
|
|
46911
46911
|
var package_default = {
|
|
46912
46912
|
name: "@hasna/testers",
|
|
46913
|
-
version: "0.0.
|
|
46913
|
+
version: "0.0.42",
|
|
46914
46914
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
46915
46915
|
type: "module",
|
|
46916
46916
|
main: "dist/index.js",
|
|
@@ -48543,17 +48543,32 @@ var COOKIE_MAX_AGE_MS = 60 * 60 * 1000;
|
|
|
48543
48543
|
function isSessionCookie(cookieName) {
|
|
48544
48544
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
48545
48545
|
}
|
|
48546
|
-
function
|
|
48546
|
+
function isPrimarySessionCookie(cookieName) {
|
|
48547
|
+
return isSessionCookie(cookieName) && !/refresh/i.test(cookieName);
|
|
48548
|
+
}
|
|
48549
|
+
function getCookieExpires(cookie) {
|
|
48550
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
48551
|
+
return cookie.expires;
|
|
48552
|
+
}
|
|
48553
|
+
if (typeof cookie.expires === "string") {
|
|
48554
|
+
const parsed = Number(cookie.expires);
|
|
48555
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
48556
|
+
}
|
|
48557
|
+
return null;
|
|
48558
|
+
}
|
|
48559
|
+
function hasFreshAuthCookies(persona) {
|
|
48547
48560
|
if (!persona.auth?.cookies?.length)
|
|
48548
48561
|
return false;
|
|
48549
48562
|
const cookies = persona.auth.cookies;
|
|
48550
|
-
|
|
48563
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isPrimarySessionCookie(String(cookie.name)));
|
|
48564
|
+
if (sessionCookies.length === 0) {
|
|
48551
48565
|
return false;
|
|
48552
48566
|
}
|
|
48553
48567
|
const now2 = Date.now() / 1000;
|
|
48554
|
-
const
|
|
48555
|
-
if (
|
|
48556
|
-
return
|
|
48568
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
48569
|
+
if (expiringSessionCookies.length > 0) {
|
|
48570
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
48571
|
+
}
|
|
48557
48572
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
48558
48573
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
48559
48574
|
}
|
|
@@ -48743,7 +48758,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
48743
48758
|
if (!persona.auth) {
|
|
48744
48759
|
return { success: true, method: "none" };
|
|
48745
48760
|
}
|
|
48746
|
-
if (
|
|
48761
|
+
if (hasFreshAuthCookies(persona)) {
|
|
48747
48762
|
const restored = await restoreCookies(page, persona);
|
|
48748
48763
|
if (restored) {
|
|
48749
48764
|
return { success: true, method: "cookies" };
|