@hasna/testers 0.0.40 → 0.0.41
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 +54 -8
- package/dist/index.js +18 -6
- package/dist/lib/persona-auth.d.ts +1 -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 +60 -14
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/server/index.js +19 -7
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16940,17 +16940,29 @@ var init_secrets_resolver = () => {};
|
|
|
16940
16940
|
function isSessionCookie(cookieName) {
|
|
16941
16941
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
16942
16942
|
}
|
|
16943
|
-
function
|
|
16943
|
+
function getCookieExpires(cookie) {
|
|
16944
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
16945
|
+
return cookie.expires;
|
|
16946
|
+
}
|
|
16947
|
+
if (typeof cookie.expires === "string") {
|
|
16948
|
+
const parsed = Number(cookie.expires);
|
|
16949
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
16950
|
+
}
|
|
16951
|
+
return null;
|
|
16952
|
+
}
|
|
16953
|
+
function hasFreshAuthCookies(persona) {
|
|
16944
16954
|
if (!persona.auth?.cookies?.length)
|
|
16945
16955
|
return false;
|
|
16946
16956
|
const cookies = persona.auth.cookies;
|
|
16947
|
-
|
|
16957
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isSessionCookie(String(cookie.name)));
|
|
16958
|
+
if (sessionCookies.length === 0) {
|
|
16948
16959
|
return false;
|
|
16949
16960
|
}
|
|
16950
16961
|
const now2 = Date.now() / 1000;
|
|
16951
|
-
const
|
|
16952
|
-
if (
|
|
16953
|
-
return
|
|
16962
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
16963
|
+
if (expiringSessionCookies.length > 0) {
|
|
16964
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
16965
|
+
}
|
|
16954
16966
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
16955
16967
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
16956
16968
|
}
|
|
@@ -17140,7 +17152,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
17140
17152
|
if (!persona.auth) {
|
|
17141
17153
|
return { success: true, method: "none" };
|
|
17142
17154
|
}
|
|
17143
|
-
if (
|
|
17155
|
+
if (hasFreshAuthCookies(persona)) {
|
|
17144
17156
|
const restored = await restoreCookies(page, persona);
|
|
17145
17157
|
if (restored) {
|
|
17146
17158
|
return { success: true, method: "cookies" };
|
|
@@ -94025,7 +94037,7 @@ import chalk6 from "chalk";
|
|
|
94025
94037
|
// package.json
|
|
94026
94038
|
var package_default = {
|
|
94027
94039
|
name: "@hasna/testers",
|
|
94028
|
-
version: "0.0.
|
|
94040
|
+
version: "0.0.41",
|
|
94029
94041
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
94030
94042
|
type: "module",
|
|
94031
94043
|
main: "dist/index.js",
|
|
@@ -95752,6 +95764,40 @@ function formatProdDebugPlan(plan) {
|
|
|
95752
95764
|
`);
|
|
95753
95765
|
}
|
|
95754
95766
|
|
|
95767
|
+
// src/lib/persona-redaction.ts
|
|
95768
|
+
function stringKeys(value) {
|
|
95769
|
+
return value ? Object.keys(value).sort() : [];
|
|
95770
|
+
}
|
|
95771
|
+
function cookieNames(cookies) {
|
|
95772
|
+
if (!cookies)
|
|
95773
|
+
return [];
|
|
95774
|
+
return cookies.map((cookie) => cookie.name).filter((name) => typeof name === "string" && name.length > 0);
|
|
95775
|
+
}
|
|
95776
|
+
function redactPersona(persona) {
|
|
95777
|
+
if (!persona.auth)
|
|
95778
|
+
return { ...persona, auth: null };
|
|
95779
|
+
const names = cookieNames(persona.auth.cookies);
|
|
95780
|
+
const headerNames = stringKeys(persona.auth.headers);
|
|
95781
|
+
return {
|
|
95782
|
+
...persona,
|
|
95783
|
+
auth: {
|
|
95784
|
+
emailConfigured: Boolean(persona.auth.email),
|
|
95785
|
+
passwordConfigured: Boolean(persona.auth.password),
|
|
95786
|
+
loginPath: persona.auth.loginPath,
|
|
95787
|
+
strategy: persona.auth.strategy,
|
|
95788
|
+
cookiesConfigured: names.length > 0,
|
|
95789
|
+
cookieCount: names.length,
|
|
95790
|
+
cookieNames: names,
|
|
95791
|
+
headersConfigured: headerNames.length > 0,
|
|
95792
|
+
headerNames,
|
|
95793
|
+
customScriptConfigured: Boolean(persona.auth.customScript)
|
|
95794
|
+
}
|
|
95795
|
+
};
|
|
95796
|
+
}
|
|
95797
|
+
function redactPersonas(personas) {
|
|
95798
|
+
return personas.map(redactPersona);
|
|
95799
|
+
}
|
|
95800
|
+
|
|
95755
95801
|
// src/cli/index.tsx
|
|
95756
95802
|
init_projects();
|
|
95757
95803
|
init_personas();
|
|
@@ -100783,7 +100829,7 @@ personaCmd.command("list").description("List personas").option("--project <id>",
|
|
|
100783
100829
|
globalOnly: opts.global ? true : undefined
|
|
100784
100830
|
});
|
|
100785
100831
|
if (opts.json) {
|
|
100786
|
-
log(JSON.stringify(personas, null, 2));
|
|
100832
|
+
log(JSON.stringify(redactPersonas(personas), null, 2));
|
|
100787
100833
|
return;
|
|
100788
100834
|
}
|
|
100789
100835
|
if (personas.length === 0) {
|
package/dist/index.js
CHANGED
|
@@ -15499,17 +15499,29 @@ 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 getCookieExpires(cookie) {
|
|
15503
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
15504
|
+
return cookie.expires;
|
|
15505
|
+
}
|
|
15506
|
+
if (typeof cookie.expires === "string") {
|
|
15507
|
+
const parsed = Number(cookie.expires);
|
|
15508
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
15509
|
+
}
|
|
15510
|
+
return null;
|
|
15511
|
+
}
|
|
15512
|
+
function hasFreshAuthCookies(persona) {
|
|
15503
15513
|
if (!persona.auth?.cookies?.length)
|
|
15504
15514
|
return false;
|
|
15505
15515
|
const cookies = persona.auth.cookies;
|
|
15506
|
-
|
|
15516
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isSessionCookie(String(cookie.name)));
|
|
15517
|
+
if (sessionCookies.length === 0) {
|
|
15507
15518
|
return false;
|
|
15508
15519
|
}
|
|
15509
15520
|
const now2 = Date.now() / 1000;
|
|
15510
|
-
const
|
|
15511
|
-
if (
|
|
15512
|
-
return
|
|
15521
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
15522
|
+
if (expiringSessionCookies.length > 0) {
|
|
15523
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
15524
|
+
}
|
|
15513
15525
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
15514
15526
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
15515
15527
|
}
|
|
@@ -15699,7 +15711,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
15699
15711
|
if (!persona.auth) {
|
|
15700
15712
|
return { success: true, method: "none" };
|
|
15701
15713
|
}
|
|
15702
|
-
if (
|
|
15714
|
+
if (hasFreshAuthCookies(persona)) {
|
|
15703
15715
|
const restored = await restoreCookies(page, persona);
|
|
15704
15716
|
if (restored) {
|
|
15705
15717
|
return { success: true, method: "cookies" };
|
|
@@ -6,6 +6,7 @@ export interface LoginResult {
|
|
|
6
6
|
method: "cookies" | "login" | "none";
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
|
+
export declare function hasFreshAuthCookies(persona: Persona): boolean;
|
|
9
10
|
/**
|
|
10
11
|
* Perform login using a raw AuthConfig (e.g. from scenario.authConfig or an auth preset).
|
|
11
12
|
* 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,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.41",
|
|
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,29 @@ var init_secrets_resolver = () => {};
|
|
|
20048
20048
|
function isSessionCookie(cookieName) {
|
|
20049
20049
|
return !/(?:csrf|xsrf)/i.test(cookieName);
|
|
20050
20050
|
}
|
|
20051
|
-
function
|
|
20051
|
+
function getCookieExpires(cookie) {
|
|
20052
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
20053
|
+
return cookie.expires;
|
|
20054
|
+
}
|
|
20055
|
+
if (typeof cookie.expires === "string") {
|
|
20056
|
+
const parsed = Number(cookie.expires);
|
|
20057
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
20058
|
+
}
|
|
20059
|
+
return null;
|
|
20060
|
+
}
|
|
20061
|
+
function hasFreshAuthCookies(persona) {
|
|
20052
20062
|
if (!persona.auth?.cookies?.length)
|
|
20053
20063
|
return false;
|
|
20054
20064
|
const cookies = persona.auth.cookies;
|
|
20055
|
-
|
|
20065
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isSessionCookie(String(cookie.name)));
|
|
20066
|
+
if (sessionCookies.length === 0) {
|
|
20056
20067
|
return false;
|
|
20057
20068
|
}
|
|
20058
20069
|
const now2 = Date.now() / 1000;
|
|
20059
|
-
const
|
|
20060
|
-
if (
|
|
20061
|
-
return
|
|
20070
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
20071
|
+
if (expiringSessionCookies.length > 0) {
|
|
20072
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
20073
|
+
}
|
|
20062
20074
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
20063
20075
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
20064
20076
|
}
|
|
@@ -20248,7 +20260,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
20248
20260
|
if (!persona.auth) {
|
|
20249
20261
|
return { success: true, method: "none" };
|
|
20250
20262
|
}
|
|
20251
|
-
if (
|
|
20263
|
+
if (hasFreshAuthCookies(persona)) {
|
|
20252
20264
|
const restored = await restoreCookies(page, persona);
|
|
20253
20265
|
if (restored) {
|
|
20254
20266
|
return { success: true, method: "cookies" };
|
|
@@ -53463,6 +53475,40 @@ var init_workflow_agent = __esm(() => {
|
|
|
53463
53475
|
init_runner();
|
|
53464
53476
|
});
|
|
53465
53477
|
|
|
53478
|
+
// src/lib/persona-redaction.ts
|
|
53479
|
+
function stringKeys(value) {
|
|
53480
|
+
return value ? Object.keys(value).sort() : [];
|
|
53481
|
+
}
|
|
53482
|
+
function cookieNames(cookies) {
|
|
53483
|
+
if (!cookies)
|
|
53484
|
+
return [];
|
|
53485
|
+
return cookies.map((cookie) => cookie.name).filter((name21) => typeof name21 === "string" && name21.length > 0);
|
|
53486
|
+
}
|
|
53487
|
+
function redactPersona(persona) {
|
|
53488
|
+
if (!persona.auth)
|
|
53489
|
+
return { ...persona, auth: null };
|
|
53490
|
+
const names = cookieNames(persona.auth.cookies);
|
|
53491
|
+
const headerNames = stringKeys(persona.auth.headers);
|
|
53492
|
+
return {
|
|
53493
|
+
...persona,
|
|
53494
|
+
auth: {
|
|
53495
|
+
emailConfigured: Boolean(persona.auth.email),
|
|
53496
|
+
passwordConfigured: Boolean(persona.auth.password),
|
|
53497
|
+
loginPath: persona.auth.loginPath,
|
|
53498
|
+
strategy: persona.auth.strategy,
|
|
53499
|
+
cookiesConfigured: names.length > 0,
|
|
53500
|
+
cookieCount: names.length,
|
|
53501
|
+
cookieNames: names,
|
|
53502
|
+
headersConfigured: headerNames.length > 0,
|
|
53503
|
+
headerNames,
|
|
53504
|
+
customScriptConfigured: Boolean(persona.auth.customScript)
|
|
53505
|
+
}
|
|
53506
|
+
};
|
|
53507
|
+
}
|
|
53508
|
+
function redactPersonas(personas) {
|
|
53509
|
+
return personas.map(redactPersona);
|
|
53510
|
+
}
|
|
53511
|
+
|
|
53466
53512
|
// src/db/environments.ts
|
|
53467
53513
|
var exports_environments = {};
|
|
53468
53514
|
__export(exports_environments, {
|
|
@@ -86939,7 +86985,7 @@ function buildServer() {
|
|
|
86939
86985
|
authPassword,
|
|
86940
86986
|
authLoginPath
|
|
86941
86987
|
});
|
|
86942
|
-
return json3(persona);
|
|
86988
|
+
return json3(redactPersona(persona));
|
|
86943
86989
|
} catch (error40) {
|
|
86944
86990
|
return errorResponse(error40);
|
|
86945
86991
|
}
|
|
@@ -86951,7 +86997,7 @@ function buildServer() {
|
|
|
86951
86997
|
}, async ({ projectId, enabled, globalOnly }) => {
|
|
86952
86998
|
try {
|
|
86953
86999
|
const personas = listPersonas({ projectId, enabled, globalOnly });
|
|
86954
|
-
return json3({ items: personas, total: personas.length });
|
|
87000
|
+
return json3({ items: redactPersonas(personas), total: personas.length });
|
|
86955
87001
|
} catch (error40) {
|
|
86956
87002
|
return errorResponse(error40);
|
|
86957
87003
|
}
|
|
@@ -86966,7 +87012,7 @@ function buildServer() {
|
|
|
86966
87012
|
const db2 = getDatabase();
|
|
86967
87013
|
const scenarioRows = db2.query("SELECT id, short_id, name FROM scenarios WHERE persona_id = ?").all(persona.id);
|
|
86968
87014
|
return json3({
|
|
86969
|
-
...persona,
|
|
87015
|
+
...redactPersona(persona),
|
|
86970
87016
|
usedByScenarios: scenarioRows.map((r2) => ({ id: r2.id, shortId: r2.short_id, name: r2.name }))
|
|
86971
87017
|
});
|
|
86972
87018
|
} catch (error40) {
|
|
@@ -86989,7 +87035,7 @@ function buildServer() {
|
|
|
86989
87035
|
}, async ({ id, version: version2, ...updates }) => {
|
|
86990
87036
|
try {
|
|
86991
87037
|
const persona = updatePersona(id, updates, version2);
|
|
86992
|
-
return json3(persona);
|
|
87038
|
+
return json3(redactPersona(persona));
|
|
86993
87039
|
} catch (error40) {
|
|
86994
87040
|
return errorResponse(error40, {
|
|
86995
87041
|
fetchCurrent: () => getPersona(id)
|
|
@@ -87020,7 +87066,7 @@ function buildServer() {
|
|
|
87020
87066
|
if (!scenario)
|
|
87021
87067
|
return errorResponse(notFoundErr(scenarioId, "Scenario"));
|
|
87022
87068
|
const updated = updateScenario(scenario.id, { personaId: persona.id }, scenario.version);
|
|
87023
|
-
return json3({ ...updated, attachedPersona: persona });
|
|
87069
|
+
return json3({ ...updated, attachedPersona: redactPersona(persona) });
|
|
87024
87070
|
} catch (error40) {
|
|
87025
87071
|
return errorResponse(error40);
|
|
87026
87072
|
}
|
|
@@ -87418,7 +87464,7 @@ function buildServer() {
|
|
|
87418
87464
|
projectId: scenario.projectId ?? undefined,
|
|
87419
87465
|
personaId: persona.id
|
|
87420
87466
|
});
|
|
87421
|
-
return json3({ ...clone2, attachedPersona: persona, clonedFrom: scenario.id });
|
|
87467
|
+
return json3({ ...clone2, attachedPersona: redactPersona(persona), clonedFrom: scenario.id });
|
|
87422
87468
|
} catch (e2) {
|
|
87423
87469
|
return errorResponse(e2);
|
|
87424
87470
|
}
|
|
@@ -87683,7 +87729,7 @@ Context: ${context2}` : ""}`,
|
|
|
87683
87729
|
const updated = syncPersonaFromContact2(persona.id);
|
|
87684
87730
|
if (!updated)
|
|
87685
87731
|
return json3({ synced: false, message: "No linked contact found or no changes needed" });
|
|
87686
|
-
return json3({ synced: true, persona: updated });
|
|
87732
|
+
return json3({ synced: true, persona: redactPersona(updated) });
|
|
87687
87733
|
} catch (e2) {
|
|
87688
87734
|
return errorResponse(e2);
|
|
87689
87735
|
}
|
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.41",
|
|
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,29 @@ 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 getCookieExpires(cookie) {
|
|
48547
|
+
if (typeof cookie.expires === "number" && Number.isFinite(cookie.expires)) {
|
|
48548
|
+
return cookie.expires;
|
|
48549
|
+
}
|
|
48550
|
+
if (typeof cookie.expires === "string") {
|
|
48551
|
+
const parsed = Number(cookie.expires);
|
|
48552
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
48553
|
+
}
|
|
48554
|
+
return null;
|
|
48555
|
+
}
|
|
48556
|
+
function hasFreshAuthCookies(persona) {
|
|
48547
48557
|
if (!persona.auth?.cookies?.length)
|
|
48548
48558
|
return false;
|
|
48549
48559
|
const cookies = persona.auth.cookies;
|
|
48550
|
-
|
|
48560
|
+
const sessionCookies = cookies.filter((cookie) => ("name" in cookie) && isSessionCookie(String(cookie.name)));
|
|
48561
|
+
if (sessionCookies.length === 0) {
|
|
48551
48562
|
return false;
|
|
48552
48563
|
}
|
|
48553
48564
|
const now2 = Date.now() / 1000;
|
|
48554
|
-
const
|
|
48555
|
-
if (
|
|
48556
|
-
return
|
|
48565
|
+
const expiringSessionCookies = sessionCookies.map(getCookieExpires).filter((expires) => expires !== null && expires > 0);
|
|
48566
|
+
if (expiringSessionCookies.length > 0) {
|
|
48567
|
+
return expiringSessionCookies.some((expires) => expires > now2 + 60);
|
|
48568
|
+
}
|
|
48557
48569
|
const updatedAt = new Date(persona.updatedAt).getTime();
|
|
48558
48570
|
return Date.now() - updatedAt < COOKIE_MAX_AGE_MS;
|
|
48559
48571
|
}
|
|
@@ -48743,7 +48755,7 @@ async function ensurePersonaAuthenticated(page, persona, baseUrl) {
|
|
|
48743
48755
|
if (!persona.auth) {
|
|
48744
48756
|
return { success: true, method: "none" };
|
|
48745
48757
|
}
|
|
48746
|
-
if (
|
|
48758
|
+
if (hasFreshAuthCookies(persona)) {
|
|
48747
48759
|
const restored = await restoreCookies(page, persona);
|
|
48748
48760
|
if (restored) {
|
|
48749
48761
|
return { success: true, method: "cookies" };
|