@vostride/agent-qa-dashboard 0.1.14 → 0.1.15
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/{index-BL7OautO.d.cts → index-ygQLgXzT.d.cts} +6 -1
- package/dist/{index-BL7OautO.d.ts → index-ygQLgXzT.d.ts} +6 -1
- package/dist/index.cjs +201 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +204 -21
- package/dist/index.js.map +1 -1
- package/dist/server/index.cjs +200 -21
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +202 -19
- package/dist/server/index.js.map +1 -1
- package/package.json +7 -7
package/dist/server/index.cjs
CHANGED
|
@@ -39,7 +39,7 @@ module.exports = __toCommonJS(server_exports);
|
|
|
39
39
|
// src/server/server.ts
|
|
40
40
|
var import_node_http2 = require("http");
|
|
41
41
|
var import_promises9 = require("fs/promises");
|
|
42
|
-
var
|
|
42
|
+
var import_node_path10 = require("path");
|
|
43
43
|
var import_node_os2 = require("os");
|
|
44
44
|
|
|
45
45
|
// src/server/routes.ts
|
|
@@ -1885,6 +1885,41 @@ function cors(res) {
|
|
|
1885
1885
|
function isPlainRecord(value) {
|
|
1886
1886
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1887
1887
|
}
|
|
1888
|
+
function getConfiguredAuthStateDir(config) {
|
|
1889
|
+
const services = isPlainRecord(config.services) ? config.services : void 0;
|
|
1890
|
+
const authState = services && isPlainRecord(services.authState) ? services.authState : void 0;
|
|
1891
|
+
return typeof authState?.dir === "string" ? authState.dir : void 0;
|
|
1892
|
+
}
|
|
1893
|
+
function getSessionTargetNameForAuthState(session) {
|
|
1894
|
+
if (!session || typeof session.getState !== "function") return "selected target";
|
|
1895
|
+
try {
|
|
1896
|
+
const state = session.getState();
|
|
1897
|
+
if (isPlainRecord(state) && typeof state.targetName === "string" && state.targetName.trim().length > 0) {
|
|
1898
|
+
return state.targetName.trim();
|
|
1899
|
+
}
|
|
1900
|
+
} catch {
|
|
1901
|
+
}
|
|
1902
|
+
return "selected target";
|
|
1903
|
+
}
|
|
1904
|
+
function buildAuthStateSaveErrorMessage(stateName, targetName, error) {
|
|
1905
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
1906
|
+
if (/already exists/i.test(raw)) {
|
|
1907
|
+
return {
|
|
1908
|
+
status: 409,
|
|
1909
|
+
message: `Auth state "${stateName}" for target "${targetName}" already exists. Use replace=true to replace it.`
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
if (/web Live Mode|not ready|executing|busy/i.test(raw)) {
|
|
1913
|
+
return {
|
|
1914
|
+
status: 409,
|
|
1915
|
+
message: `Could not save auth state "${stateName}" for target "${targetName}".`
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
return {
|
|
1919
|
+
status: 500,
|
|
1920
|
+
message: `Could not save auth state "${stateName}" for target "${targetName}".`
|
|
1921
|
+
};
|
|
1922
|
+
}
|
|
1888
1923
|
function isDashboardProductEventName(value) {
|
|
1889
1924
|
return typeof value === "string" && DASHBOARD_PRODUCT_EVENT_NAME_SET.has(value);
|
|
1890
1925
|
}
|
|
@@ -2284,7 +2319,7 @@ function sanitizeSecretsFileMetadata(value) {
|
|
|
2284
2319
|
};
|
|
2285
2320
|
}
|
|
2286
2321
|
function sanitizeArtifactPayloadForResponse(payload) {
|
|
2287
|
-
const sanitized = sanitizeSecretTemplates(payload);
|
|
2322
|
+
const sanitized = (0, import_agent_qa_core5.redactAuthStateValue)(sanitizeSecretTemplates(payload));
|
|
2288
2323
|
if (!isRecord(sanitized)) return payload;
|
|
2289
2324
|
const config = sanitized.config;
|
|
2290
2325
|
if (!isRecord(config) || !("secretsFile" in config)) return sanitized;
|
|
@@ -2303,6 +2338,9 @@ function sanitizeArtifactForResponse(artifact) {
|
|
|
2303
2338
|
payload: sanitizeArtifactPayloadForResponse(artifact.payload)
|
|
2304
2339
|
};
|
|
2305
2340
|
}
|
|
2341
|
+
function sanitizeAuthStateForResponse(value) {
|
|
2342
|
+
return (0, import_agent_qa_core5.redactAuthStateValue)(value);
|
|
2343
|
+
}
|
|
2306
2344
|
async function normalizeDashboardWorkspacePath(filePath, workspacePaths, kind, requireExisting = true) {
|
|
2307
2345
|
if (!workspacePaths) {
|
|
2308
2346
|
throw new Error("Workspace path resolution is required for dashboard-triggered runs");
|
|
@@ -2527,6 +2565,28 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2527
2565
|
}
|
|
2528
2566
|
const url = parseUrl(req);
|
|
2529
2567
|
const path = url.pathname;
|
|
2568
|
+
if (path === "/api/auth-states" && req.method === "GET") {
|
|
2569
|
+
if (!configManager || !deps.configPath) {
|
|
2570
|
+
json(res, { error: "Auth-state metadata not available" }, 503);
|
|
2571
|
+
return;
|
|
2572
|
+
}
|
|
2573
|
+
;
|
|
2574
|
+
(async () => {
|
|
2575
|
+
try {
|
|
2576
|
+
const config = await configManager.read();
|
|
2577
|
+
const targetName = url.searchParams.get("target") ?? void 0;
|
|
2578
|
+
const authStates = await (0, import_agent_qa_core5.listAuthStateMetadata)({
|
|
2579
|
+
configDir: (0, import_node_path5.dirname)((0, import_node_path5.resolve)(deps.configPath)),
|
|
2580
|
+
authStateDir: getConfiguredAuthStateDir(config),
|
|
2581
|
+
targetName
|
|
2582
|
+
});
|
|
2583
|
+
json(res, { authStates });
|
|
2584
|
+
} catch {
|
|
2585
|
+
json(res, { error: "Could not list auth states." }, 500);
|
|
2586
|
+
}
|
|
2587
|
+
})();
|
|
2588
|
+
return;
|
|
2589
|
+
}
|
|
2530
2590
|
if (path === "/api/analytics/events" && req.method === "POST") {
|
|
2531
2591
|
readJsonBody(req).then((body) => {
|
|
2532
2592
|
if (!isPlainRecord(body) || !isDashboardProductEventName(body.name) || Object.prototype.hasOwnProperty.call(body, "properties") && body.properties !== void 0 && !isPlainRecord(body.properties)) {
|
|
@@ -2640,7 +2700,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2640
2700
|
return;
|
|
2641
2701
|
}
|
|
2642
2702
|
const bundle = db.getRunArtifactBundle(runId);
|
|
2643
|
-
json(res, {
|
|
2703
|
+
json(res, sanitizeAuthStateForResponse({
|
|
2644
2704
|
run,
|
|
2645
2705
|
artifact: sanitizeArtifactForResponse(bundle.artifact),
|
|
2646
2706
|
children: bundle.children.map((child) => ({
|
|
@@ -2648,7 +2708,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2648
2708
|
artifact: sanitizeArtifactForResponse(child.artifact)
|
|
2649
2709
|
})),
|
|
2650
2710
|
missingSections: getArtifactMissingSections(bundle.artifact)
|
|
2651
|
-
});
|
|
2711
|
+
}));
|
|
2652
2712
|
return;
|
|
2653
2713
|
}
|
|
2654
2714
|
if (path.startsWith("/api/runs/") && path.endsWith("/accessibility") && req.method === "GET") {
|
|
@@ -2674,7 +2734,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2674
2734
|
const stepOrder = parseInt(stepOrderStr, 10);
|
|
2675
2735
|
const trace = db.getReasoningTrace(runId, stepOrder);
|
|
2676
2736
|
if (trace) {
|
|
2677
|
-
json(res, { trace });
|
|
2737
|
+
json(res, sanitizeAuthStateForResponse({ trace }));
|
|
2678
2738
|
return;
|
|
2679
2739
|
}
|
|
2680
2740
|
const steps = db.getSteps(runId);
|
|
@@ -2683,7 +2743,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2683
2743
|
notFound(res, "Step not found");
|
|
2684
2744
|
return;
|
|
2685
2745
|
}
|
|
2686
|
-
json(res, {
|
|
2746
|
+
json(res, sanitizeAuthStateForResponse({
|
|
2687
2747
|
trace: {
|
|
2688
2748
|
id: null,
|
|
2689
2749
|
stepId: step.id,
|
|
@@ -2704,7 +2764,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2704
2764
|
screenStateAfter: null,
|
|
2705
2765
|
createdAt: step.createdAt
|
|
2706
2766
|
}
|
|
2707
|
-
});
|
|
2767
|
+
}));
|
|
2708
2768
|
return;
|
|
2709
2769
|
}
|
|
2710
2770
|
if (path.startsWith("/api/runs/") && path.endsWith("/execution-logs") && req.method === "GET") {
|
|
@@ -2724,11 +2784,11 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2724
2784
|
for (const rid of allRunIds) {
|
|
2725
2785
|
allLogs.push(...db.getExecutionLogs({ runId: rid, stepId, type }));
|
|
2726
2786
|
}
|
|
2727
|
-
json(res, { logs: allLogs });
|
|
2787
|
+
json(res, sanitizeAuthStateForResponse({ logs: allLogs }));
|
|
2728
2788
|
return;
|
|
2729
2789
|
}
|
|
2730
2790
|
const logs = db.getExecutionLogs({ runId: id, stepId, type });
|
|
2731
|
-
json(res, { logs });
|
|
2791
|
+
json(res, sanitizeAuthStateForResponse({ logs }));
|
|
2732
2792
|
return;
|
|
2733
2793
|
}
|
|
2734
2794
|
if (path.startsWith("/api/runs/") && path.endsWith("/logs") && req.method === "GET") {
|
|
@@ -2745,7 +2805,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2745
2805
|
const limit = url.searchParams.has("limit") ? parseInt(url.searchParams.get("limit"), 10) : 500;
|
|
2746
2806
|
const offset = url.searchParams.has("offset") ? parseInt(url.searchParams.get("offset"), 10) : 0;
|
|
2747
2807
|
const logs = db.getLogs({ runId: id, stepId, level, source, limit, offset });
|
|
2748
|
-
json(res, { logs, total: logs.length });
|
|
2808
|
+
json(res, sanitizeAuthStateForResponse({ logs, total: logs.length }));
|
|
2749
2809
|
return;
|
|
2750
2810
|
}
|
|
2751
2811
|
if (path.startsWith("/api/runs/") && path.endsWith("/steps") && req.method === "GET") {
|
|
@@ -2757,7 +2817,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2757
2817
|
return;
|
|
2758
2818
|
}
|
|
2759
2819
|
const steps = db.getSteps(id);
|
|
2760
|
-
json(res, { steps });
|
|
2820
|
+
json(res, sanitizeAuthStateForResponse({ steps }));
|
|
2761
2821
|
return;
|
|
2762
2822
|
}
|
|
2763
2823
|
if (path.startsWith("/api/runs/") && path.endsWith("/cancel") && req.method === "POST") {
|
|
@@ -2831,9 +2891,9 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2831
2891
|
const attempts = db.getRunsByParent(id);
|
|
2832
2892
|
if (run.suiteId && !run.parentRunId) {
|
|
2833
2893
|
const tests = db.getRunsByParent(id);
|
|
2834
|
-
json(res, { run, steps, attempts, tests });
|
|
2894
|
+
json(res, sanitizeAuthStateForResponse({ run, steps, attempts, tests }));
|
|
2835
2895
|
} else {
|
|
2836
|
-
json(res, { run, steps, attempts });
|
|
2896
|
+
json(res, sanitizeAuthStateForResponse({ run, steps, attempts }));
|
|
2837
2897
|
}
|
|
2838
2898
|
return;
|
|
2839
2899
|
}
|
|
@@ -4446,7 +4506,7 @@ data: ${JSON.stringify(event)}
|
|
|
4446
4506
|
const networkLogs = summarizeHookNetworkLogs(
|
|
4447
4507
|
result.networkLogs
|
|
4448
4508
|
);
|
|
4449
|
-
json(res, {
|
|
4509
|
+
json(res, sanitizeAuthStateForResponse({
|
|
4450
4510
|
success: result.success,
|
|
4451
4511
|
status: result.success ? "passed" : "failed",
|
|
4452
4512
|
executedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4464,9 +4524,9 @@ data: ${JSON.stringify(event)}
|
|
|
4464
4524
|
networkLogsAvailable: networkLogs.length > 0,
|
|
4465
4525
|
networkLogs
|
|
4466
4526
|
}
|
|
4467
|
-
});
|
|
4527
|
+
}));
|
|
4468
4528
|
} catch (err) {
|
|
4469
|
-
json(res, { error: err instanceof Error ? err.message : "Failed to run hook" }, 500);
|
|
4529
|
+
json(res, sanitizeAuthStateForResponse({ error: err instanceof Error ? err.message : "Failed to run hook" }), 500);
|
|
4470
4530
|
}
|
|
4471
4531
|
}).catch(() => json(res, { error: "Invalid request body" }, 400));
|
|
4472
4532
|
return;
|
|
@@ -4715,6 +4775,45 @@ data: ${JSON.stringify(event)}
|
|
|
4715
4775
|
})();
|
|
4716
4776
|
return;
|
|
4717
4777
|
}
|
|
4778
|
+
const liveEditorAuthStateMatch = path.match(/^\/api\/live-editor\/sessions\/([^/]+)\/auth-state$/);
|
|
4779
|
+
if (liveEditorAuthStateMatch && req.method === "POST") {
|
|
4780
|
+
if (!sessionManager) {
|
|
4781
|
+
json(res, { error: "Live editor not available" }, 503);
|
|
4782
|
+
return;
|
|
4783
|
+
}
|
|
4784
|
+
;
|
|
4785
|
+
(async () => {
|
|
4786
|
+
let stateName = "";
|
|
4787
|
+
let session;
|
|
4788
|
+
try {
|
|
4789
|
+
const body = await readJsonBody(req);
|
|
4790
|
+
const parsedName = import_agent_qa_core5.AuthStateNameSchema.safeParse(typeof body?.name === "string" ? body.name : "");
|
|
4791
|
+
if (!parsedName.success) {
|
|
4792
|
+
json(res, { error: "Auth state name must be a lowercase slug." }, 400);
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4795
|
+
stateName = parsedName.data;
|
|
4796
|
+
session = sessionManager.getSession(decodeURIComponent(liveEditorAuthStateMatch[1]));
|
|
4797
|
+
if (!session) {
|
|
4798
|
+
notFound(res, "Session not found");
|
|
4799
|
+
return;
|
|
4800
|
+
}
|
|
4801
|
+
if (typeof session.captureWebAuthState !== "function") {
|
|
4802
|
+
json(res, {
|
|
4803
|
+
error: `Could not save auth state "${stateName}" for target "${getSessionTargetNameForAuthState(session)}".`
|
|
4804
|
+
}, 500);
|
|
4805
|
+
return;
|
|
4806
|
+
}
|
|
4807
|
+
const authState = await session.captureWebAuthState(stateName, { replace: body?.replace === true });
|
|
4808
|
+
json(res, { authState });
|
|
4809
|
+
} catch (err) {
|
|
4810
|
+
const targetName = getSessionTargetNameForAuthState(session);
|
|
4811
|
+
const response = buildAuthStateSaveErrorMessage(stateName || "unknown", targetName, err);
|
|
4812
|
+
json(res, { error: response.message }, response.status);
|
|
4813
|
+
}
|
|
4814
|
+
})();
|
|
4815
|
+
return;
|
|
4816
|
+
}
|
|
4718
4817
|
if (path === "/api/live-editor/sessions" && req.method === "POST") {
|
|
4719
4818
|
if (!sessionManager) {
|
|
4720
4819
|
json(res, { error: "Live editor not available" }, 503);
|
|
@@ -5919,6 +6018,7 @@ var import_node_crypto3 = require("crypto");
|
|
|
5919
6018
|
|
|
5920
6019
|
// src/live-editor/live-session.ts
|
|
5921
6020
|
var import_node_crypto2 = require("crypto");
|
|
6021
|
+
var import_node_path9 = require("path");
|
|
5922
6022
|
var import_agent_qa_core9 = require("@vostride/agent-qa-core");
|
|
5923
6023
|
|
|
5924
6024
|
// src/live-editor/mobile-bootstrap.ts
|
|
@@ -6070,6 +6170,26 @@ function coerceRunJSResult(value) {
|
|
|
6070
6170
|
}
|
|
6071
6171
|
return JSON.stringify(value);
|
|
6072
6172
|
}
|
|
6173
|
+
function getWebStorageStateContext(adapter) {
|
|
6174
|
+
if (!adapter || !("getPage" in adapter)) return null;
|
|
6175
|
+
const page = adapter.getPage?.();
|
|
6176
|
+
if (!page || typeof page !== "object") return null;
|
|
6177
|
+
const contextFactory = page.context;
|
|
6178
|
+
if (typeof contextFactory !== "function") return null;
|
|
6179
|
+
const context = contextFactory.call(page);
|
|
6180
|
+
if (!context || typeof context !== "object") return null;
|
|
6181
|
+
const storageState = context.storageState;
|
|
6182
|
+
if (typeof storageState !== "function") return null;
|
|
6183
|
+
return context;
|
|
6184
|
+
}
|
|
6185
|
+
function getConfiguredAuthStateDir2(config) {
|
|
6186
|
+
const services = config.services;
|
|
6187
|
+
if (!services || typeof services !== "object") return void 0;
|
|
6188
|
+
const authState = services.authState;
|
|
6189
|
+
if (!authState || typeof authState !== "object") return void 0;
|
|
6190
|
+
const dir = authState.dir;
|
|
6191
|
+
return typeof dir === "string" ? dir : void 0;
|
|
6192
|
+
}
|
|
6073
6193
|
function toLiveSubActionData(result) {
|
|
6074
6194
|
return result.trace?.subActions?.map((subAction) => ({
|
|
6075
6195
|
index: subAction.index,
|
|
@@ -6147,6 +6267,7 @@ var LiveSession = class {
|
|
|
6147
6267
|
previousSteps = [];
|
|
6148
6268
|
currentStep = null;
|
|
6149
6269
|
platform = "web";
|
|
6270
|
+
targetName = null;
|
|
6150
6271
|
currentUrl = null;
|
|
6151
6272
|
executing = false;
|
|
6152
6273
|
idleTimer = null;
|
|
@@ -6184,7 +6305,7 @@ var LiveSession = class {
|
|
|
6184
6305
|
this.pendingMessages.push(message);
|
|
6185
6306
|
}
|
|
6186
6307
|
redact(value) {
|
|
6187
|
-
return (0, import_agent_qa_core9.
|
|
6308
|
+
return (0, import_agent_qa_core9.redactAuthStateValue)(value, { secretRedactor: this.secretRedactor });
|
|
6188
6309
|
}
|
|
6189
6310
|
resolveSecrets(value) {
|
|
6190
6311
|
return (0, import_agent_qa_core9.resolveSecretTemplatesInValue)(value, this.secretStore);
|
|
@@ -6414,6 +6535,7 @@ var LiveSession = class {
|
|
|
6414
6535
|
}
|
|
6415
6536
|
async initialize(config) {
|
|
6416
6537
|
this.platform = config.platform;
|
|
6538
|
+
this.targetName = typeof config.targetName === "string" && config.targetName.trim().length > 0 ? config.targetName.trim() : null;
|
|
6417
6539
|
this._modelName = config.llmConfig.model ?? "unknown";
|
|
6418
6540
|
this.variableStore = new import_agent_qa_core9.VariableStore();
|
|
6419
6541
|
this.secretStore = config.secretStore;
|
|
@@ -6904,6 +7026,62 @@ ${errorLines.join("\n")}`;
|
|
|
6904
7026
|
this.messageSink = originalSink;
|
|
6905
7027
|
}
|
|
6906
7028
|
}
|
|
7029
|
+
async captureWebAuthState(name, options = {}) {
|
|
7030
|
+
if (this.platform !== "web") {
|
|
7031
|
+
throw new Error("Auth-state capture is only available for web Live Mode sessions.");
|
|
7032
|
+
}
|
|
7033
|
+
if (!this.readyForInteraction || !this.adapter) {
|
|
7034
|
+
throw new Error(this.terminalError ?? "Live session is not ready for auth-state capture.");
|
|
7035
|
+
}
|
|
7036
|
+
if (this.adapter.platform !== "web") {
|
|
7037
|
+
throw new Error("Auth-state capture is only available for web Live Mode sessions.");
|
|
7038
|
+
}
|
|
7039
|
+
if (this.executing) {
|
|
7040
|
+
throw new Error("Cannot save auth state while the Live Mode session is executing.");
|
|
7041
|
+
}
|
|
7042
|
+
if (!this.targetName) {
|
|
7043
|
+
throw new Error("Cannot save auth state because this Live Mode session has no configured target.");
|
|
7044
|
+
}
|
|
7045
|
+
if (!this.deps.configManager || !this.deps.configPath) {
|
|
7046
|
+
throw new Error("Cannot save auth state because workspace config is unavailable.");
|
|
7047
|
+
}
|
|
7048
|
+
const context = getWebStorageStateContext(this.adapter);
|
|
7049
|
+
if (!context) {
|
|
7050
|
+
throw new Error("Cannot save auth state because the active browser context is unavailable.");
|
|
7051
|
+
}
|
|
7052
|
+
const config = await this.deps.configManager.read();
|
|
7053
|
+
const authStateDir = getConfiguredAuthStateDir2(config);
|
|
7054
|
+
const paths = (0, import_agent_qa_core9.resolveAuthStatePaths)({
|
|
7055
|
+
configDir: (0, import_node_path9.dirname)((0, import_node_path9.resolve)(this.deps.configPath)),
|
|
7056
|
+
authStateDir,
|
|
7057
|
+
targetName: this.targetName,
|
|
7058
|
+
stateName: name,
|
|
7059
|
+
target: { platform: "web" }
|
|
7060
|
+
});
|
|
7061
|
+
let existing = null;
|
|
7062
|
+
try {
|
|
7063
|
+
existing = await (0, import_agent_qa_core9.readAuthStateMetadata)(paths);
|
|
7064
|
+
} catch {
|
|
7065
|
+
existing = null;
|
|
7066
|
+
}
|
|
7067
|
+
if (existing && options.replace !== true) {
|
|
7068
|
+
throw new Error(`Auth state "${paths.stateName}" for target "${paths.targetName}" already exists. Use replace=true to replace it.`);
|
|
7069
|
+
}
|
|
7070
|
+
const payload = await context.storageState({ indexedDB: true });
|
|
7071
|
+
const metadata = {
|
|
7072
|
+
version: import_agent_qa_core9.AUTH_STATE_SCHEMA_VERSION,
|
|
7073
|
+
kind: "web",
|
|
7074
|
+
target: paths.targetName,
|
|
7075
|
+
name: paths.stateName,
|
|
7076
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7077
|
+
};
|
|
7078
|
+
try {
|
|
7079
|
+
await (0, import_agent_qa_core9.writeAuthStateFiles)(paths, { payload, metadata });
|
|
7080
|
+
} catch {
|
|
7081
|
+
throw new Error(`Could not save auth state "${paths.stateName}" for target "${paths.targetName}".`);
|
|
7082
|
+
}
|
|
7083
|
+
return metadata;
|
|
7084
|
+
}
|
|
6907
7085
|
cancelStep() {
|
|
6908
7086
|
this.abortController?.abort();
|
|
6909
7087
|
}
|
|
@@ -6964,6 +7142,7 @@ ${errorLines.join("\n")}`;
|
|
|
6964
7142
|
return {
|
|
6965
7143
|
sessionId: this.sessionId,
|
|
6966
7144
|
platform: this.adapter?.platform ?? this.platform,
|
|
7145
|
+
targetName: this.targetName,
|
|
6967
7146
|
status: this.status === "terminated" ? "idle" : this.status === "executing" ? "executing" : this.status,
|
|
6968
7147
|
currentStep: this.currentStep,
|
|
6969
7148
|
currentUrl: this.currentUrl,
|
|
@@ -7442,7 +7621,7 @@ function isAnalyticsPrivacyEnabled(config) {
|
|
|
7442
7621
|
}
|
|
7443
7622
|
async function startServer(opts) {
|
|
7444
7623
|
const { db, port = 3470, uiDir, artifactsDir, workspacePaths, configPath, mcp, llmConfig, authFetch } = opts;
|
|
7445
|
-
const resolvedConfigPath = configPath ?? (0,
|
|
7624
|
+
const resolvedConfigPath = configPath ?? (0, import_node_path10.resolve)("agent-qa.config.yaml");
|
|
7446
7625
|
const configManager = new ConfigManager(resolvedConfigPath);
|
|
7447
7626
|
const config = await configManager.read().catch(() => ({}));
|
|
7448
7627
|
const concurrency = typeof config.concurrency === "number" ? config.concurrency : (0, import_node_os2.cpus)().length;
|
|
@@ -7762,12 +7941,12 @@ async function startServer(opts) {
|
|
|
7762
7941
|
return;
|
|
7763
7942
|
}
|
|
7764
7943
|
if (uiDir) {
|
|
7765
|
-
const filePath = path === "/" ? (0,
|
|
7944
|
+
const filePath = path === "/" ? (0, import_node_path10.join)(uiDir, "index.html") : (0, import_node_path10.join)(uiDir, path);
|
|
7766
7945
|
try {
|
|
7767
7946
|
const fileStat = await (0, import_promises9.stat)(filePath);
|
|
7768
7947
|
if (fileStat.isFile()) {
|
|
7769
7948
|
const content = await (0, import_promises9.readFile)(filePath);
|
|
7770
|
-
const ext = (0,
|
|
7949
|
+
const ext = (0, import_node_path10.extname)(filePath);
|
|
7771
7950
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
7772
7951
|
res.writeHead(200, {
|
|
7773
7952
|
"Content-Type": contentType,
|
|
@@ -7780,7 +7959,7 @@ async function startServer(opts) {
|
|
|
7780
7959
|
} catch {
|
|
7781
7960
|
}
|
|
7782
7961
|
try {
|
|
7783
|
-
const indexPath = (0,
|
|
7962
|
+
const indexPath = (0, import_node_path10.join)(uiDir, "index.html");
|
|
7784
7963
|
const content = await (0, import_promises9.readFile)(indexPath);
|
|
7785
7964
|
res.writeHead(200, {
|
|
7786
7965
|
"Content-Type": "text/html",
|