@vostride/agent-qa-dashboard 0.1.14 → 0.1.16
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.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, getAgentQaVersion, 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
|
}
|
|
@@ -4423,7 +4483,7 @@ data: ${JSON.stringify(event)}
|
|
|
4423
4483
|
const networkLogs = summarizeHookNetworkLogs(
|
|
4424
4484
|
result.networkLogs
|
|
4425
4485
|
);
|
|
4426
|
-
json(res, {
|
|
4486
|
+
json(res, sanitizeAuthStateForResponse({
|
|
4427
4487
|
success: result.success,
|
|
4428
4488
|
status: result.success ? "passed" : "failed",
|
|
4429
4489
|
executedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4441,9 +4501,9 @@ data: ${JSON.stringify(event)}
|
|
|
4441
4501
|
networkLogsAvailable: networkLogs.length > 0,
|
|
4442
4502
|
networkLogs
|
|
4443
4503
|
}
|
|
4444
|
-
});
|
|
4504
|
+
}));
|
|
4445
4505
|
} catch (err) {
|
|
4446
|
-
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);
|
|
4447
4507
|
}
|
|
4448
4508
|
}).catch(() => json(res, { error: "Invalid request body" }, 400));
|
|
4449
4509
|
return;
|
|
@@ -4692,6 +4752,45 @@ data: ${JSON.stringify(event)}
|
|
|
4692
4752
|
})();
|
|
4693
4753
|
return;
|
|
4694
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
|
+
}
|
|
4695
4794
|
if (path === "/api/live-editor/sessions" && req.method === "POST") {
|
|
4696
4795
|
if (!sessionManager) {
|
|
4697
4796
|
json(res, { error: "Live editor not available" }, 503);
|
|
@@ -5899,7 +5998,9 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
5899
5998
|
|
|
5900
5999
|
// src/live-editor/live-session.ts
|
|
5901
6000
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
6001
|
+
import { dirname as dirname8, resolve as resolvePath } from "path";
|
|
5902
6002
|
import {
|
|
6003
|
+
AUTH_STATE_SCHEMA_VERSION,
|
|
5903
6004
|
executeStep,
|
|
5904
6005
|
createModel,
|
|
5905
6006
|
getProviderOptions as getProviderOptions2,
|
|
@@ -5913,8 +6014,11 @@ import {
|
|
|
5913
6014
|
runHooks,
|
|
5914
6015
|
runHookInSandbox as runHookInSandbox2,
|
|
5915
6016
|
MobileSetupError as MobileSetupError2,
|
|
5916
|
-
|
|
5917
|
-
|
|
6017
|
+
readAuthStateMetadata,
|
|
6018
|
+
redactAuthStateValue as redactAuthStateValue2,
|
|
6019
|
+
resolveAuthStatePaths,
|
|
6020
|
+
resolveSecretTemplatesInValue,
|
|
6021
|
+
writeAuthStateFiles
|
|
5918
6022
|
} from "@vostride/agent-qa-core";
|
|
5919
6023
|
|
|
5920
6024
|
// src/live-editor/mobile-bootstrap.ts
|
|
@@ -6069,6 +6173,26 @@ function coerceRunJSResult(value) {
|
|
|
6069
6173
|
}
|
|
6070
6174
|
return JSON.stringify(value);
|
|
6071
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
|
+
}
|
|
6072
6196
|
function toLiveSubActionData(result) {
|
|
6073
6197
|
return result.trace?.subActions?.map((subAction) => ({
|
|
6074
6198
|
index: subAction.index,
|
|
@@ -6146,6 +6270,7 @@ var LiveSession = class {
|
|
|
6146
6270
|
previousSteps = [];
|
|
6147
6271
|
currentStep = null;
|
|
6148
6272
|
platform = "web";
|
|
6273
|
+
targetName = null;
|
|
6149
6274
|
currentUrl = null;
|
|
6150
6275
|
executing = false;
|
|
6151
6276
|
idleTimer = null;
|
|
@@ -6183,7 +6308,7 @@ var LiveSession = class {
|
|
|
6183
6308
|
this.pendingMessages.push(message);
|
|
6184
6309
|
}
|
|
6185
6310
|
redact(value) {
|
|
6186
|
-
return
|
|
6311
|
+
return redactAuthStateValue2(value, { secretRedactor: this.secretRedactor });
|
|
6187
6312
|
}
|
|
6188
6313
|
resolveSecrets(value) {
|
|
6189
6314
|
return resolveSecretTemplatesInValue(value, this.secretStore);
|
|
@@ -6413,6 +6538,7 @@ var LiveSession = class {
|
|
|
6413
6538
|
}
|
|
6414
6539
|
async initialize(config) {
|
|
6415
6540
|
this.platform = config.platform;
|
|
6541
|
+
this.targetName = typeof config.targetName === "string" && config.targetName.trim().length > 0 ? config.targetName.trim() : null;
|
|
6416
6542
|
this._modelName = config.llmConfig.model ?? "unknown";
|
|
6417
6543
|
this.variableStore = new VariableStore();
|
|
6418
6544
|
this.secretStore = config.secretStore;
|
|
@@ -6903,6 +7029,62 @@ ${errorLines.join("\n")}`;
|
|
|
6903
7029
|
this.messageSink = originalSink;
|
|
6904
7030
|
}
|
|
6905
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
|
+
}
|
|
6906
7088
|
cancelStep() {
|
|
6907
7089
|
this.abortController?.abort();
|
|
6908
7090
|
}
|
|
@@ -6963,6 +7145,7 @@ ${errorLines.join("\n")}`;
|
|
|
6963
7145
|
return {
|
|
6964
7146
|
sessionId: this.sessionId,
|
|
6965
7147
|
platform: this.adapter?.platform ?? this.platform,
|
|
7148
|
+
targetName: this.targetName,
|
|
6966
7149
|
status: this.status === "terminated" ? "idle" : this.status === "executing" ? "executing" : this.status,
|
|
6967
7150
|
currentStep: this.currentStep,
|
|
6968
7151
|
currentUrl: this.currentUrl,
|