@vostride/agent-qa-dashboard 0.1.13 → 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 +206 -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 +209 -21
- package/dist/index.js.map +1 -1
- package/dist/server/index.cjs +205 -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 +207 -19
- package/dist/server/index.js.map +1 -1
- package/package.json +7 -7
package/dist/server/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { f as createRouter, r as readJsonBody, s as startServer } from '../index-
|
|
1
|
+
export { f as createRouter, r as readJsonBody, s as startServer } from '../index-ygQLgXzT.cjs';
|
|
2
2
|
import 'node:http';
|
|
3
3
|
import '@vostride/agent-qa-core';
|
|
4
4
|
import '@vostride/agent-qa-mcp';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { f as createRouter, r as readJsonBody, s as startServer } from '../index-
|
|
1
|
+
export { f as createRouter, r as readJsonBody, s as startServer } from '../index-ygQLgXzT.js';
|
|
2
2
|
import 'node:http';
|
|
3
3
|
import '@vostride/agent-qa-core';
|
|
4
4
|
import '@vostride/agent-qa-mcp';
|
package/dist/server/index.js
CHANGED
|
@@ -1572,7 +1572,7 @@ function readJsonBody(req, maxBytes = DEFAULT_MAX_BYTES) {
|
|
|
1572
1572
|
}
|
|
1573
1573
|
|
|
1574
1574
|
// src/server/routes.ts
|
|
1575
|
-
import { buildAnalyticsEvent, buildInternalRunAttributes, captureAnalytics, mergeRunAttributes, readAuth, writeAuth, removeAuth, getProviderOptions, getLLMAuthProviderPlugin, listLLMAuthProviderPlugins, ModelConfigSchema, NamedLLMConfigSchema, WorkspaceSchema, ServicesSchema, RegistrySchema, UseSchema, MobileAppStateSchema, hashStepInstruction, TimeoutConfigSchema, CacheConfigSchema, HealingConfigSchema, PlannerConfigSchema, LoggingConfigSchema, LogCaptureConfigSchema, AccessibilityConfigSchema, DashboardConfigSchema, McpConfigSchema, RecordingConfigSchema, BrowserConfigSchema, AnalyticsSchema, AgentQaConfigSchema as AgentQaConfigSchema3, TestDefinitionSchema, SuiteDefinitionSchema, parseEnvFile, serializeEnvFile, runHookInSandbox, RUNTIME_IMAGE_MAP, SecretStore, SecretRedactor, validateUserRunAttributes, discoverWorkspaceFiles as discoverWorkspaceFiles4, isWorkspacePathMatch, resolveAnalyticsStandardProperties, resolveMemoryRoot as resolveMemoryRoot2, resolveWorkspaceFileTarget as resolveWorkspaceFileTarget2 } from "@vostride/agent-qa-core";
|
|
1575
|
+
import { AuthStateNameSchema, buildAnalyticsEvent, buildInternalRunAttributes, captureAnalytics, mergeRunAttributes, readAuth, writeAuth, removeAuth, getAgentQaVersion, getProviderOptions, getLLMAuthProviderPlugin, listAuthStateMetadata, listLLMAuthProviderPlugins, ModelConfigSchema, NamedLLMConfigSchema, WorkspaceSchema, ServicesSchema, RegistrySchema, UseSchema, MobileAppStateSchema, hashStepInstruction, TimeoutConfigSchema, CacheConfigSchema, HealingConfigSchema, PlannerConfigSchema, LoggingConfigSchema, LogCaptureConfigSchema, AccessibilityConfigSchema, DashboardConfigSchema, McpConfigSchema, RecordingConfigSchema, BrowserConfigSchema, AnalyticsSchema, AgentQaConfigSchema as AgentQaConfigSchema3, TestDefinitionSchema, SuiteDefinitionSchema, parseEnvFile, serializeEnvFile, runHookInSandbox, RUNTIME_IMAGE_MAP, SecretStore, SecretRedactor, redactAuthStateValue, validateUserRunAttributes, discoverWorkspaceFiles as discoverWorkspaceFiles4, isWorkspacePathMatch, resolveAnalyticsStandardProperties, resolveMemoryRoot as resolveMemoryRoot2, resolveWorkspaceFileTarget as resolveWorkspaceFileTarget2 } from "@vostride/agent-qa-core";
|
|
1576
1576
|
import { parse as parseYaml5 } from "yaml";
|
|
1577
1577
|
var LLM_PROVIDER_MODES = /* @__PURE__ */ new Set([
|
|
1578
1578
|
"openai-compatible",
|
|
@@ -1862,6 +1862,41 @@ function cors(res) {
|
|
|
1862
1862
|
function isPlainRecord(value) {
|
|
1863
1863
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1864
1864
|
}
|
|
1865
|
+
function getConfiguredAuthStateDir(config) {
|
|
1866
|
+
const services = isPlainRecord(config.services) ? config.services : void 0;
|
|
1867
|
+
const authState = services && isPlainRecord(services.authState) ? services.authState : void 0;
|
|
1868
|
+
return typeof authState?.dir === "string" ? authState.dir : void 0;
|
|
1869
|
+
}
|
|
1870
|
+
function getSessionTargetNameForAuthState(session) {
|
|
1871
|
+
if (!session || typeof session.getState !== "function") return "selected target";
|
|
1872
|
+
try {
|
|
1873
|
+
const state = session.getState();
|
|
1874
|
+
if (isPlainRecord(state) && typeof state.targetName === "string" && state.targetName.trim().length > 0) {
|
|
1875
|
+
return state.targetName.trim();
|
|
1876
|
+
}
|
|
1877
|
+
} catch {
|
|
1878
|
+
}
|
|
1879
|
+
return "selected target";
|
|
1880
|
+
}
|
|
1881
|
+
function buildAuthStateSaveErrorMessage(stateName, targetName, error) {
|
|
1882
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
1883
|
+
if (/already exists/i.test(raw)) {
|
|
1884
|
+
return {
|
|
1885
|
+
status: 409,
|
|
1886
|
+
message: `Auth state "${stateName}" for target "${targetName}" already exists. Use replace=true to replace it.`
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1889
|
+
if (/web Live Mode|not ready|executing|busy/i.test(raw)) {
|
|
1890
|
+
return {
|
|
1891
|
+
status: 409,
|
|
1892
|
+
message: `Could not save auth state "${stateName}" for target "${targetName}".`
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
return {
|
|
1896
|
+
status: 500,
|
|
1897
|
+
message: `Could not save auth state "${stateName}" for target "${targetName}".`
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1865
1900
|
function isDashboardProductEventName(value) {
|
|
1866
1901
|
return typeof value === "string" && DASHBOARD_PRODUCT_EVENT_NAME_SET.has(value);
|
|
1867
1902
|
}
|
|
@@ -2261,7 +2296,7 @@ function sanitizeSecretsFileMetadata(value) {
|
|
|
2261
2296
|
};
|
|
2262
2297
|
}
|
|
2263
2298
|
function sanitizeArtifactPayloadForResponse(payload) {
|
|
2264
|
-
const sanitized = sanitizeSecretTemplates(payload);
|
|
2299
|
+
const sanitized = redactAuthStateValue(sanitizeSecretTemplates(payload));
|
|
2265
2300
|
if (!isRecord(sanitized)) return payload;
|
|
2266
2301
|
const config = sanitized.config;
|
|
2267
2302
|
if (!isRecord(config) || !("secretsFile" in config)) return sanitized;
|
|
@@ -2280,6 +2315,9 @@ function sanitizeArtifactForResponse(artifact) {
|
|
|
2280
2315
|
payload: sanitizeArtifactPayloadForResponse(artifact.payload)
|
|
2281
2316
|
};
|
|
2282
2317
|
}
|
|
2318
|
+
function sanitizeAuthStateForResponse(value) {
|
|
2319
|
+
return redactAuthStateValue(value);
|
|
2320
|
+
}
|
|
2283
2321
|
async function normalizeDashboardWorkspacePath(filePath, workspacePaths, kind, requireExisting = true) {
|
|
2284
2322
|
if (!workspacePaths) {
|
|
2285
2323
|
throw new Error("Workspace path resolution is required for dashboard-triggered runs");
|
|
@@ -2504,6 +2542,28 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2504
2542
|
}
|
|
2505
2543
|
const url = parseUrl(req);
|
|
2506
2544
|
const path = url.pathname;
|
|
2545
|
+
if (path === "/api/auth-states" && req.method === "GET") {
|
|
2546
|
+
if (!configManager || !deps.configPath) {
|
|
2547
|
+
json(res, { error: "Auth-state metadata not available" }, 503);
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
;
|
|
2551
|
+
(async () => {
|
|
2552
|
+
try {
|
|
2553
|
+
const config = await configManager.read();
|
|
2554
|
+
const targetName = url.searchParams.get("target") ?? void 0;
|
|
2555
|
+
const authStates = await listAuthStateMetadata({
|
|
2556
|
+
configDir: dirname4(resolve3(deps.configPath)),
|
|
2557
|
+
authStateDir: getConfiguredAuthStateDir(config),
|
|
2558
|
+
targetName
|
|
2559
|
+
});
|
|
2560
|
+
json(res, { authStates });
|
|
2561
|
+
} catch {
|
|
2562
|
+
json(res, { error: "Could not list auth states." }, 500);
|
|
2563
|
+
}
|
|
2564
|
+
})();
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2507
2567
|
if (path === "/api/analytics/events" && req.method === "POST") {
|
|
2508
2568
|
readJsonBody(req).then((body) => {
|
|
2509
2569
|
if (!isPlainRecord(body) || !isDashboardProductEventName(body.name) || Object.prototype.hasOwnProperty.call(body, "properties") && body.properties !== void 0 && !isPlainRecord(body.properties)) {
|
|
@@ -2617,7 +2677,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2617
2677
|
return;
|
|
2618
2678
|
}
|
|
2619
2679
|
const bundle = db.getRunArtifactBundle(runId);
|
|
2620
|
-
json(res, {
|
|
2680
|
+
json(res, sanitizeAuthStateForResponse({
|
|
2621
2681
|
run,
|
|
2622
2682
|
artifact: sanitizeArtifactForResponse(bundle.artifact),
|
|
2623
2683
|
children: bundle.children.map((child) => ({
|
|
@@ -2625,7 +2685,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2625
2685
|
artifact: sanitizeArtifactForResponse(child.artifact)
|
|
2626
2686
|
})),
|
|
2627
2687
|
missingSections: getArtifactMissingSections(bundle.artifact)
|
|
2628
|
-
});
|
|
2688
|
+
}));
|
|
2629
2689
|
return;
|
|
2630
2690
|
}
|
|
2631
2691
|
if (path.startsWith("/api/runs/") && path.endsWith("/accessibility") && req.method === "GET") {
|
|
@@ -2651,7 +2711,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2651
2711
|
const stepOrder = parseInt(stepOrderStr, 10);
|
|
2652
2712
|
const trace = db.getReasoningTrace(runId, stepOrder);
|
|
2653
2713
|
if (trace) {
|
|
2654
|
-
json(res, { trace });
|
|
2714
|
+
json(res, sanitizeAuthStateForResponse({ trace }));
|
|
2655
2715
|
return;
|
|
2656
2716
|
}
|
|
2657
2717
|
const steps = db.getSteps(runId);
|
|
@@ -2660,7 +2720,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2660
2720
|
notFound(res, "Step not found");
|
|
2661
2721
|
return;
|
|
2662
2722
|
}
|
|
2663
|
-
json(res, {
|
|
2723
|
+
json(res, sanitizeAuthStateForResponse({
|
|
2664
2724
|
trace: {
|
|
2665
2725
|
id: null,
|
|
2666
2726
|
stepId: step.id,
|
|
@@ -2681,7 +2741,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2681
2741
|
screenStateAfter: null,
|
|
2682
2742
|
createdAt: step.createdAt
|
|
2683
2743
|
}
|
|
2684
|
-
});
|
|
2744
|
+
}));
|
|
2685
2745
|
return;
|
|
2686
2746
|
}
|
|
2687
2747
|
if (path.startsWith("/api/runs/") && path.endsWith("/execution-logs") && req.method === "GET") {
|
|
@@ -2701,11 +2761,11 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2701
2761
|
for (const rid of allRunIds) {
|
|
2702
2762
|
allLogs.push(...db.getExecutionLogs({ runId: rid, stepId, type }));
|
|
2703
2763
|
}
|
|
2704
|
-
json(res, { logs: allLogs });
|
|
2764
|
+
json(res, sanitizeAuthStateForResponse({ logs: allLogs }));
|
|
2705
2765
|
return;
|
|
2706
2766
|
}
|
|
2707
2767
|
const logs = db.getExecutionLogs({ runId: id, stepId, type });
|
|
2708
|
-
json(res, { logs });
|
|
2768
|
+
json(res, sanitizeAuthStateForResponse({ logs }));
|
|
2709
2769
|
return;
|
|
2710
2770
|
}
|
|
2711
2771
|
if (path.startsWith("/api/runs/") && path.endsWith("/logs") && req.method === "GET") {
|
|
@@ -2722,7 +2782,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2722
2782
|
const limit = url.searchParams.has("limit") ? parseInt(url.searchParams.get("limit"), 10) : 500;
|
|
2723
2783
|
const offset = url.searchParams.has("offset") ? parseInt(url.searchParams.get("offset"), 10) : 0;
|
|
2724
2784
|
const logs = db.getLogs({ runId: id, stepId, level, source, limit, offset });
|
|
2725
|
-
json(res, { logs, total: logs.length });
|
|
2785
|
+
json(res, sanitizeAuthStateForResponse({ logs, total: logs.length }));
|
|
2726
2786
|
return;
|
|
2727
2787
|
}
|
|
2728
2788
|
if (path.startsWith("/api/runs/") && path.endsWith("/steps") && req.method === "GET") {
|
|
@@ -2734,7 +2794,7 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2734
2794
|
return;
|
|
2735
2795
|
}
|
|
2736
2796
|
const steps = db.getSteps(id);
|
|
2737
|
-
json(res, { steps });
|
|
2797
|
+
json(res, sanitizeAuthStateForResponse({ steps }));
|
|
2738
2798
|
return;
|
|
2739
2799
|
}
|
|
2740
2800
|
if (path.startsWith("/api/runs/") && path.endsWith("/cancel") && req.method === "POST") {
|
|
@@ -2808,9 +2868,9 @@ function createRouter(dbOrDeps, artifactsDir) {
|
|
|
2808
2868
|
const attempts = db.getRunsByParent(id);
|
|
2809
2869
|
if (run.suiteId && !run.parentRunId) {
|
|
2810
2870
|
const tests = db.getRunsByParent(id);
|
|
2811
|
-
json(res, { run, steps, attempts, tests });
|
|
2871
|
+
json(res, sanitizeAuthStateForResponse({ run, steps, attempts, tests }));
|
|
2812
2872
|
} else {
|
|
2813
|
-
json(res, { run, steps, attempts });
|
|
2873
|
+
json(res, sanitizeAuthStateForResponse({ run, steps, attempts }));
|
|
2814
2874
|
}
|
|
2815
2875
|
return;
|
|
2816
2876
|
}
|
|
@@ -3600,6 +3660,11 @@ data: ${JSON.stringify(event)}
|
|
|
3600
3660
|
});
|
|
3601
3661
|
return;
|
|
3602
3662
|
}
|
|
3663
|
+
if (path === "/api/app-metadata" && req.method === "GET") {
|
|
3664
|
+
const version = getAgentQaVersion().trim() || "0.0.0";
|
|
3665
|
+
json(res, { version });
|
|
3666
|
+
return;
|
|
3667
|
+
}
|
|
3603
3668
|
if (path === "/api/config/targets" && req.method === "GET") {
|
|
3604
3669
|
if (!configManager) {
|
|
3605
3670
|
json(res, { error: "Config management not available" }, 501);
|
|
@@ -4418,7 +4483,7 @@ data: ${JSON.stringify(event)}
|
|
|
4418
4483
|
const networkLogs = summarizeHookNetworkLogs(
|
|
4419
4484
|
result.networkLogs
|
|
4420
4485
|
);
|
|
4421
|
-
json(res, {
|
|
4486
|
+
json(res, sanitizeAuthStateForResponse({
|
|
4422
4487
|
success: result.success,
|
|
4423
4488
|
status: result.success ? "passed" : "failed",
|
|
4424
4489
|
executedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4436,9 +4501,9 @@ data: ${JSON.stringify(event)}
|
|
|
4436
4501
|
networkLogsAvailable: networkLogs.length > 0,
|
|
4437
4502
|
networkLogs
|
|
4438
4503
|
}
|
|
4439
|
-
});
|
|
4504
|
+
}));
|
|
4440
4505
|
} catch (err) {
|
|
4441
|
-
json(res, { error: err instanceof Error ? err.message : "Failed to run hook" }, 500);
|
|
4506
|
+
json(res, sanitizeAuthStateForResponse({ error: err instanceof Error ? err.message : "Failed to run hook" }), 500);
|
|
4442
4507
|
}
|
|
4443
4508
|
}).catch(() => json(res, { error: "Invalid request body" }, 400));
|
|
4444
4509
|
return;
|
|
@@ -4687,6 +4752,45 @@ data: ${JSON.stringify(event)}
|
|
|
4687
4752
|
})();
|
|
4688
4753
|
return;
|
|
4689
4754
|
}
|
|
4755
|
+
const liveEditorAuthStateMatch = path.match(/^\/api\/live-editor\/sessions\/([^/]+)\/auth-state$/);
|
|
4756
|
+
if (liveEditorAuthStateMatch && req.method === "POST") {
|
|
4757
|
+
if (!sessionManager) {
|
|
4758
|
+
json(res, { error: "Live editor not available" }, 503);
|
|
4759
|
+
return;
|
|
4760
|
+
}
|
|
4761
|
+
;
|
|
4762
|
+
(async () => {
|
|
4763
|
+
let stateName = "";
|
|
4764
|
+
let session;
|
|
4765
|
+
try {
|
|
4766
|
+
const body = await readJsonBody(req);
|
|
4767
|
+
const parsedName = AuthStateNameSchema.safeParse(typeof body?.name === "string" ? body.name : "");
|
|
4768
|
+
if (!parsedName.success) {
|
|
4769
|
+
json(res, { error: "Auth state name must be a lowercase slug." }, 400);
|
|
4770
|
+
return;
|
|
4771
|
+
}
|
|
4772
|
+
stateName = parsedName.data;
|
|
4773
|
+
session = sessionManager.getSession(decodeURIComponent(liveEditorAuthStateMatch[1]));
|
|
4774
|
+
if (!session) {
|
|
4775
|
+
notFound(res, "Session not found");
|
|
4776
|
+
return;
|
|
4777
|
+
}
|
|
4778
|
+
if (typeof session.captureWebAuthState !== "function") {
|
|
4779
|
+
json(res, {
|
|
4780
|
+
error: `Could not save auth state "${stateName}" for target "${getSessionTargetNameForAuthState(session)}".`
|
|
4781
|
+
}, 500);
|
|
4782
|
+
return;
|
|
4783
|
+
}
|
|
4784
|
+
const authState = await session.captureWebAuthState(stateName, { replace: body?.replace === true });
|
|
4785
|
+
json(res, { authState });
|
|
4786
|
+
} catch (err) {
|
|
4787
|
+
const targetName = getSessionTargetNameForAuthState(session);
|
|
4788
|
+
const response = buildAuthStateSaveErrorMessage(stateName || "unknown", targetName, err);
|
|
4789
|
+
json(res, { error: response.message }, response.status);
|
|
4790
|
+
}
|
|
4791
|
+
})();
|
|
4792
|
+
return;
|
|
4793
|
+
}
|
|
4690
4794
|
if (path === "/api/live-editor/sessions" && req.method === "POST") {
|
|
4691
4795
|
if (!sessionManager) {
|
|
4692
4796
|
json(res, { error: "Live editor not available" }, 503);
|
|
@@ -5894,7 +5998,9 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
5894
5998
|
|
|
5895
5999
|
// src/live-editor/live-session.ts
|
|
5896
6000
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
6001
|
+
import { dirname as dirname8, resolve as resolvePath } from "path";
|
|
5897
6002
|
import {
|
|
6003
|
+
AUTH_STATE_SCHEMA_VERSION,
|
|
5898
6004
|
executeStep,
|
|
5899
6005
|
createModel,
|
|
5900
6006
|
getProviderOptions as getProviderOptions2,
|
|
@@ -5908,8 +6014,11 @@ import {
|
|
|
5908
6014
|
runHooks,
|
|
5909
6015
|
runHookInSandbox as runHookInSandbox2,
|
|
5910
6016
|
MobileSetupError as MobileSetupError2,
|
|
5911
|
-
|
|
5912
|
-
|
|
6017
|
+
readAuthStateMetadata,
|
|
6018
|
+
redactAuthStateValue as redactAuthStateValue2,
|
|
6019
|
+
resolveAuthStatePaths,
|
|
6020
|
+
resolveSecretTemplatesInValue,
|
|
6021
|
+
writeAuthStateFiles
|
|
5913
6022
|
} from "@vostride/agent-qa-core";
|
|
5914
6023
|
|
|
5915
6024
|
// src/live-editor/mobile-bootstrap.ts
|
|
@@ -6064,6 +6173,26 @@ function coerceRunJSResult(value) {
|
|
|
6064
6173
|
}
|
|
6065
6174
|
return JSON.stringify(value);
|
|
6066
6175
|
}
|
|
6176
|
+
function getWebStorageStateContext(adapter) {
|
|
6177
|
+
if (!adapter || !("getPage" in adapter)) return null;
|
|
6178
|
+
const page = adapter.getPage?.();
|
|
6179
|
+
if (!page || typeof page !== "object") return null;
|
|
6180
|
+
const contextFactory = page.context;
|
|
6181
|
+
if (typeof contextFactory !== "function") return null;
|
|
6182
|
+
const context = contextFactory.call(page);
|
|
6183
|
+
if (!context || typeof context !== "object") return null;
|
|
6184
|
+
const storageState = context.storageState;
|
|
6185
|
+
if (typeof storageState !== "function") return null;
|
|
6186
|
+
return context;
|
|
6187
|
+
}
|
|
6188
|
+
function getConfiguredAuthStateDir2(config) {
|
|
6189
|
+
const services = config.services;
|
|
6190
|
+
if (!services || typeof services !== "object") return void 0;
|
|
6191
|
+
const authState = services.authState;
|
|
6192
|
+
if (!authState || typeof authState !== "object") return void 0;
|
|
6193
|
+
const dir = authState.dir;
|
|
6194
|
+
return typeof dir === "string" ? dir : void 0;
|
|
6195
|
+
}
|
|
6067
6196
|
function toLiveSubActionData(result) {
|
|
6068
6197
|
return result.trace?.subActions?.map((subAction) => ({
|
|
6069
6198
|
index: subAction.index,
|
|
@@ -6141,6 +6270,7 @@ var LiveSession = class {
|
|
|
6141
6270
|
previousSteps = [];
|
|
6142
6271
|
currentStep = null;
|
|
6143
6272
|
platform = "web";
|
|
6273
|
+
targetName = null;
|
|
6144
6274
|
currentUrl = null;
|
|
6145
6275
|
executing = false;
|
|
6146
6276
|
idleTimer = null;
|
|
@@ -6178,7 +6308,7 @@ var LiveSession = class {
|
|
|
6178
6308
|
this.pendingMessages.push(message);
|
|
6179
6309
|
}
|
|
6180
6310
|
redact(value) {
|
|
6181
|
-
return
|
|
6311
|
+
return redactAuthStateValue2(value, { secretRedactor: this.secretRedactor });
|
|
6182
6312
|
}
|
|
6183
6313
|
resolveSecrets(value) {
|
|
6184
6314
|
return resolveSecretTemplatesInValue(value, this.secretStore);
|
|
@@ -6408,6 +6538,7 @@ var LiveSession = class {
|
|
|
6408
6538
|
}
|
|
6409
6539
|
async initialize(config) {
|
|
6410
6540
|
this.platform = config.platform;
|
|
6541
|
+
this.targetName = typeof config.targetName === "string" && config.targetName.trim().length > 0 ? config.targetName.trim() : null;
|
|
6411
6542
|
this._modelName = config.llmConfig.model ?? "unknown";
|
|
6412
6543
|
this.variableStore = new VariableStore();
|
|
6413
6544
|
this.secretStore = config.secretStore;
|
|
@@ -6898,6 +7029,62 @@ ${errorLines.join("\n")}`;
|
|
|
6898
7029
|
this.messageSink = originalSink;
|
|
6899
7030
|
}
|
|
6900
7031
|
}
|
|
7032
|
+
async captureWebAuthState(name, options = {}) {
|
|
7033
|
+
if (this.platform !== "web") {
|
|
7034
|
+
throw new Error("Auth-state capture is only available for web Live Mode sessions.");
|
|
7035
|
+
}
|
|
7036
|
+
if (!this.readyForInteraction || !this.adapter) {
|
|
7037
|
+
throw new Error(this.terminalError ?? "Live session is not ready for auth-state capture.");
|
|
7038
|
+
}
|
|
7039
|
+
if (this.adapter.platform !== "web") {
|
|
7040
|
+
throw new Error("Auth-state capture is only available for web Live Mode sessions.");
|
|
7041
|
+
}
|
|
7042
|
+
if (this.executing) {
|
|
7043
|
+
throw new Error("Cannot save auth state while the Live Mode session is executing.");
|
|
7044
|
+
}
|
|
7045
|
+
if (!this.targetName) {
|
|
7046
|
+
throw new Error("Cannot save auth state because this Live Mode session has no configured target.");
|
|
7047
|
+
}
|
|
7048
|
+
if (!this.deps.configManager || !this.deps.configPath) {
|
|
7049
|
+
throw new Error("Cannot save auth state because workspace config is unavailable.");
|
|
7050
|
+
}
|
|
7051
|
+
const context = getWebStorageStateContext(this.adapter);
|
|
7052
|
+
if (!context) {
|
|
7053
|
+
throw new Error("Cannot save auth state because the active browser context is unavailable.");
|
|
7054
|
+
}
|
|
7055
|
+
const config = await this.deps.configManager.read();
|
|
7056
|
+
const authStateDir = getConfiguredAuthStateDir2(config);
|
|
7057
|
+
const paths = resolveAuthStatePaths({
|
|
7058
|
+
configDir: dirname8(resolvePath(this.deps.configPath)),
|
|
7059
|
+
authStateDir,
|
|
7060
|
+
targetName: this.targetName,
|
|
7061
|
+
stateName: name,
|
|
7062
|
+
target: { platform: "web" }
|
|
7063
|
+
});
|
|
7064
|
+
let existing = null;
|
|
7065
|
+
try {
|
|
7066
|
+
existing = await readAuthStateMetadata(paths);
|
|
7067
|
+
} catch {
|
|
7068
|
+
existing = null;
|
|
7069
|
+
}
|
|
7070
|
+
if (existing && options.replace !== true) {
|
|
7071
|
+
throw new Error(`Auth state "${paths.stateName}" for target "${paths.targetName}" already exists. Use replace=true to replace it.`);
|
|
7072
|
+
}
|
|
7073
|
+
const payload = await context.storageState({ indexedDB: true });
|
|
7074
|
+
const metadata = {
|
|
7075
|
+
version: AUTH_STATE_SCHEMA_VERSION,
|
|
7076
|
+
kind: "web",
|
|
7077
|
+
target: paths.targetName,
|
|
7078
|
+
name: paths.stateName,
|
|
7079
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7080
|
+
};
|
|
7081
|
+
try {
|
|
7082
|
+
await writeAuthStateFiles(paths, { payload, metadata });
|
|
7083
|
+
} catch {
|
|
7084
|
+
throw new Error(`Could not save auth state "${paths.stateName}" for target "${paths.targetName}".`);
|
|
7085
|
+
}
|
|
7086
|
+
return metadata;
|
|
7087
|
+
}
|
|
6901
7088
|
cancelStep() {
|
|
6902
7089
|
this.abortController?.abort();
|
|
6903
7090
|
}
|
|
@@ -6958,6 +7145,7 @@ ${errorLines.join("\n")}`;
|
|
|
6958
7145
|
return {
|
|
6959
7146
|
sessionId: this.sessionId,
|
|
6960
7147
|
platform: this.adapter?.platform ?? this.platform,
|
|
7148
|
+
targetName: this.targetName,
|
|
6961
7149
|
status: this.status === "terminated" ? "idle" : this.status === "executing" ? "executing" : this.status,
|
|
6962
7150
|
currentStep: this.currentStep,
|
|
6963
7151
|
currentUrl: this.currentUrl,
|