@vostride/agent-qa-dashboard 0.1.8 → 0.1.10
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-CmNQ5PbF.d.cts → index-qDoSzi3O.d.cts} +3 -1
- package/dist/{index-CmNQ5PbF.d.ts → index-qDoSzi3O.d.ts} +3 -1
- package/dist/index.cjs +36 -32
- 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 +9 -2
- package/dist/index.js.map +1 -1
- package/dist/server/index.cjs +36 -32
- 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 +9 -2
- package/dist/server/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Server, IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { RunAttributes, RunArtifactKind, RunArtifactStageInput, RunArtifactPayload, RunArtifactFinalizeInput, LogEntry, ResolvedWorkspacePaths, ModelConfig, SecretStore, SecretRedactor, HookDefinition, ConsoleLogEntry, NetworkLogEntry, StepAnnotation, StepPhaseEvent, StepResult, buildAnalyticsEvent, captureAnalytics, resolveAnalyticsStandardProperties } from '@vostride/agent-qa-core';
|
|
2
|
+
import { RunAttributes, RunArtifactKind, RunArtifactStageInput, RunArtifactPayload, RunArtifactFinalizeInput, LogEntry, ResolvedWorkspacePaths, ModelConfig, ResolvedAppiumExecutable, SecretStore, SecretRedactor, HookDefinition, ConsoleLogEntry, NetworkLogEntry, StepAnnotation, StepPhaseEvent, StepResult, buildAnalyticsEvent, captureAnalytics, resolveAnalyticsStandardProperties } from '@vostride/agent-qa-core';
|
|
3
3
|
import { LocalMcpEndpointConfig, LocalMcpTransport } from '@vostride/agent-qa-mcp';
|
|
4
4
|
import { Document } from 'yaml';
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
@@ -548,11 +548,13 @@ declare class AppiumManager {
|
|
|
548
548
|
private anonymousRefCount;
|
|
549
549
|
private leases;
|
|
550
550
|
private logLevel;
|
|
551
|
+
private appiumResolver;
|
|
551
552
|
constructor(opts?: {
|
|
552
553
|
port?: number;
|
|
553
554
|
startupTimeoutMs?: number;
|
|
554
555
|
pollIntervalMs?: number;
|
|
555
556
|
logLevel?: 'normal' | 'debug';
|
|
557
|
+
appiumResolver?: () => ResolvedAppiumExecutable;
|
|
556
558
|
});
|
|
557
559
|
acquire(): Promise<void>;
|
|
558
560
|
release(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Server, IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { RunAttributes, RunArtifactKind, RunArtifactStageInput, RunArtifactPayload, RunArtifactFinalizeInput, LogEntry, ResolvedWorkspacePaths, ModelConfig, SecretStore, SecretRedactor, HookDefinition, ConsoleLogEntry, NetworkLogEntry, StepAnnotation, StepPhaseEvent, StepResult, buildAnalyticsEvent, captureAnalytics, resolveAnalyticsStandardProperties } from '@vostride/agent-qa-core';
|
|
2
|
+
import { RunAttributes, RunArtifactKind, RunArtifactStageInput, RunArtifactPayload, RunArtifactFinalizeInput, LogEntry, ResolvedWorkspacePaths, ModelConfig, ResolvedAppiumExecutable, SecretStore, SecretRedactor, HookDefinition, ConsoleLogEntry, NetworkLogEntry, StepAnnotation, StepPhaseEvent, StepResult, buildAnalyticsEvent, captureAnalytics, resolveAnalyticsStandardProperties } from '@vostride/agent-qa-core';
|
|
3
3
|
import { LocalMcpEndpointConfig, LocalMcpTransport } from '@vostride/agent-qa-mcp';
|
|
4
4
|
import { Document } from 'yaml';
|
|
5
5
|
import { EventEmitter } from 'node:events';
|
|
@@ -548,11 +548,13 @@ declare class AppiumManager {
|
|
|
548
548
|
private anonymousRefCount;
|
|
549
549
|
private leases;
|
|
550
550
|
private logLevel;
|
|
551
|
+
private appiumResolver;
|
|
551
552
|
constructor(opts?: {
|
|
552
553
|
port?: number;
|
|
553
554
|
startupTimeoutMs?: number;
|
|
554
555
|
pollIntervalMs?: number;
|
|
555
556
|
logLevel?: 'normal' | 'debug';
|
|
557
|
+
appiumResolver?: () => ResolvedAppiumExecutable;
|
|
556
558
|
});
|
|
557
559
|
acquire(): Promise<void>;
|
|
558
560
|
release(): void;
|
package/dist/index.cjs
CHANGED
|
@@ -8304,6 +8304,7 @@ var ConfigManager = class {
|
|
|
8304
8304
|
// src/execution/appium-manager.ts
|
|
8305
8305
|
var import_node_http = require("http");
|
|
8306
8306
|
var import_node_child_process2 = require("child_process");
|
|
8307
|
+
var import_agent_qa_core11 = require("@vostride/agent-qa-core");
|
|
8307
8308
|
var import_tree_kill2 = __toESM(require("tree-kill"), 1);
|
|
8308
8309
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
8309
8310
|
var APPIUM_PREFIX = import_picocolors.default.magenta("[appium]");
|
|
@@ -8318,11 +8319,13 @@ var AppiumManager = class {
|
|
|
8318
8319
|
anonymousRefCount = 0;
|
|
8319
8320
|
leases = /* @__PURE__ */ new Map();
|
|
8320
8321
|
logLevel;
|
|
8322
|
+
appiumResolver;
|
|
8321
8323
|
constructor(opts) {
|
|
8322
8324
|
this.port = opts?.port ?? 4723;
|
|
8323
8325
|
this.startupTimeoutMs = opts?.startupTimeoutMs ?? 3e4;
|
|
8324
8326
|
this.pollIntervalMs = opts?.pollIntervalMs ?? 500;
|
|
8325
8327
|
this.logLevel = opts?.logLevel ?? "normal";
|
|
8328
|
+
this.appiumResolver = opts?.appiumResolver ?? import_agent_qa_core11.resolveAppiumExecutable;
|
|
8326
8329
|
}
|
|
8327
8330
|
async acquire() {
|
|
8328
8331
|
await this.ensureRunning();
|
|
@@ -8417,14 +8420,15 @@ var AppiumManager = class {
|
|
|
8417
8420
|
});
|
|
8418
8421
|
}
|
|
8419
8422
|
async startAndWait() {
|
|
8420
|
-
const
|
|
8423
|
+
const appium = this.appiumResolver();
|
|
8424
|
+
const child = (0, import_node_child_process2.spawn)(appium.command, ["-p", String(this.port), "--relaxed-security", "--log-no-colors"], {
|
|
8421
8425
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8422
8426
|
});
|
|
8423
8427
|
this.process = child;
|
|
8424
8428
|
this.managed = true;
|
|
8425
8429
|
child.on("error", (err) => {
|
|
8426
8430
|
if (err.code === "ENOENT") {
|
|
8427
|
-
console.error(`${APPIUM_PREFIX} Appium not found.
|
|
8431
|
+
console.error(`${APPIUM_PREFIX} Appium not found. ${(0, import_agent_qa_core11.formatAppiumInstallGuidance)()}`);
|
|
8428
8432
|
} else {
|
|
8429
8433
|
console.error(`${APPIUM_PREFIX} Error: ${err.message}`);
|
|
8430
8434
|
}
|
|
@@ -8520,13 +8524,13 @@ var import_node_crypto4 = require("crypto");
|
|
|
8520
8524
|
|
|
8521
8525
|
// src/live-editor/live-session.ts
|
|
8522
8526
|
var import_node_crypto3 = require("crypto");
|
|
8523
|
-
var
|
|
8527
|
+
var import_agent_qa_core13 = require("@vostride/agent-qa-core");
|
|
8524
8528
|
|
|
8525
8529
|
// src/live-editor/mobile-bootstrap.ts
|
|
8526
8530
|
var import_promises10 = require("fs/promises");
|
|
8527
8531
|
var import_node_path12 = require("path");
|
|
8528
8532
|
var import_yaml8 = require("yaml");
|
|
8529
|
-
var
|
|
8533
|
+
var import_agent_qa_core12 = require("@vostride/agent-qa-core");
|
|
8530
8534
|
async function loadLocalBindings(configPath) {
|
|
8531
8535
|
const filePath = (0, import_node_path12.join)((0, import_node_path12.dirname)(configPath), "agent-qa.local.yaml");
|
|
8532
8536
|
try {
|
|
@@ -8544,8 +8548,8 @@ async function loadLocalBindings(configPath) {
|
|
|
8544
8548
|
}
|
|
8545
8549
|
}
|
|
8546
8550
|
function asMobileSetupError(err, category, message, input) {
|
|
8547
|
-
if (err instanceof
|
|
8548
|
-
return new
|
|
8551
|
+
if (err instanceof import_agent_qa_core12.MobileSetupError) return err;
|
|
8552
|
+
return new import_agent_qa_core12.MobileSetupError({
|
|
8549
8553
|
category,
|
|
8550
8554
|
message: `${message}: ${err instanceof Error ? err.message : String(err)}`,
|
|
8551
8555
|
platform: input.platform,
|
|
@@ -8555,7 +8559,7 @@ function asMobileSetupError(err, category, message, input) {
|
|
|
8555
8559
|
}
|
|
8556
8560
|
async function prepareMobileLiveSession(input) {
|
|
8557
8561
|
if (!input.targetName) {
|
|
8558
|
-
throw new
|
|
8562
|
+
throw new import_agent_qa_core12.MobileSetupError({
|
|
8559
8563
|
category: "device-resolution",
|
|
8560
8564
|
message: `No targetName provided for ${input.platform} live session`,
|
|
8561
8565
|
platform: input.platform
|
|
@@ -8571,7 +8575,7 @@ async function prepareMobileLiveSession(input) {
|
|
|
8571
8575
|
const configuredAppState = config.use?.mobile?.appState;
|
|
8572
8576
|
let resolved;
|
|
8573
8577
|
try {
|
|
8574
|
-
resolved = (0,
|
|
8578
|
+
resolved = (0, import_agent_qa_core12.resolveMobileRunConfig)({
|
|
8575
8579
|
config,
|
|
8576
8580
|
targetName: input.targetName,
|
|
8577
8581
|
platform: input.platform,
|
|
@@ -8587,7 +8591,7 @@ async function prepareMobileLiveSession(input) {
|
|
|
8587
8591
|
try {
|
|
8588
8592
|
await input.appiumManager.acquireLease({ runId: input.sessionId, platform: input.platform });
|
|
8589
8593
|
} catch (err) {
|
|
8590
|
-
throw new
|
|
8594
|
+
throw new import_agent_qa_core12.MobileSetupError({
|
|
8591
8595
|
category: "appium-startup",
|
|
8592
8596
|
message: `Failed to acquire Appium for ${input.platform} live session: ${err instanceof Error ? err.message : String(err)}`,
|
|
8593
8597
|
platform: input.platform,
|
|
@@ -8703,9 +8707,9 @@ function classifyAdapterSetupError(err) {
|
|
|
8703
8707
|
return "device-readiness";
|
|
8704
8708
|
}
|
|
8705
8709
|
function wrapAdapterSetupError(err, platform, config) {
|
|
8706
|
-
if (err instanceof
|
|
8710
|
+
if (err instanceof import_agent_qa_core13.MobileSetupError) return err;
|
|
8707
8711
|
const appId = platform === "android" ? config.appPackage : config.bundleId;
|
|
8708
|
-
return new
|
|
8712
|
+
return new import_agent_qa_core13.MobileSetupError({
|
|
8709
8713
|
category: classifyAdapterSetupError(err),
|
|
8710
8714
|
message: `Failed to create ${platform} adapter session: ${err instanceof Error ? err.message : String(err)}`,
|
|
8711
8715
|
platform,
|
|
@@ -8785,10 +8789,10 @@ var LiveSession = class {
|
|
|
8785
8789
|
this.pendingMessages.push(message);
|
|
8786
8790
|
}
|
|
8787
8791
|
redact(value) {
|
|
8788
|
-
return (0,
|
|
8792
|
+
return (0, import_agent_qa_core13.redactSecretValue)(value, this.secretRedactor);
|
|
8789
8793
|
}
|
|
8790
8794
|
resolveSecrets(value) {
|
|
8791
|
-
return (0,
|
|
8795
|
+
return (0, import_agent_qa_core13.resolveSecretTemplatesInValue)(value, this.secretStore);
|
|
8792
8796
|
}
|
|
8793
8797
|
emitHookStart(hookDef, phase, owner = { scope: "suite" }) {
|
|
8794
8798
|
const hook = {
|
|
@@ -8875,7 +8879,7 @@ var LiveSession = class {
|
|
|
8875
8879
|
}
|
|
8876
8880
|
continue;
|
|
8877
8881
|
}
|
|
8878
|
-
const result = await (0,
|
|
8882
|
+
const result = await (0, import_agent_qa_core13.runHooks)([hookDef], {
|
|
8879
8883
|
envVars: this.getHookEnvVars(),
|
|
8880
8884
|
secretStore: this.secretStore,
|
|
8881
8885
|
secretRedactor: this.secretRedactor
|
|
@@ -8985,7 +8989,7 @@ var LiveSession = class {
|
|
|
8985
8989
|
adapter = new IOSPlatformAdapter();
|
|
8986
8990
|
}
|
|
8987
8991
|
} catch (err) {
|
|
8988
|
-
throw new
|
|
8992
|
+
throw new import_agent_qa_core13.MobileSetupError({
|
|
8989
8993
|
category: "adapter-load",
|
|
8990
8994
|
message: `Failed to load ${platformLabel} adapter (@vostride/agent-qa-${platform}). Is the package installed? ${err instanceof Error ? err.message : String(err)}`,
|
|
8991
8995
|
platform,
|
|
@@ -9007,7 +9011,7 @@ var LiveSession = class {
|
|
|
9007
9011
|
} catch {
|
|
9008
9012
|
}
|
|
9009
9013
|
this.releaseMobileAppiumLease("setup-failed");
|
|
9010
|
-
if (err instanceof
|
|
9014
|
+
if (err instanceof import_agent_qa_core13.MobileSetupError) {
|
|
9011
9015
|
throw new Error(mobileSetupMessage(err));
|
|
9012
9016
|
}
|
|
9013
9017
|
throw err;
|
|
@@ -9016,7 +9020,7 @@ var LiveSession = class {
|
|
|
9016
9020
|
async initialize(config) {
|
|
9017
9021
|
this.platform = config.platform;
|
|
9018
9022
|
this._modelName = config.llmConfig.model ?? "unknown";
|
|
9019
|
-
this.variableStore = new
|
|
9023
|
+
this.variableStore = new import_agent_qa_core13.VariableStore();
|
|
9020
9024
|
this.secretStore = config.secretStore;
|
|
9021
9025
|
this.secretRedactor = config.secretRedactor;
|
|
9022
9026
|
if (config.envVars) {
|
|
@@ -9060,10 +9064,10 @@ var LiveSession = class {
|
|
|
9060
9064
|
...config.llmConfig,
|
|
9061
9065
|
...config.authFetch ? { fetch: config.authFetch } : {}
|
|
9062
9066
|
};
|
|
9063
|
-
this.model = await (0,
|
|
9064
|
-
const providerOptions = (0,
|
|
9065
|
-
this.planner = new
|
|
9066
|
-
this.verifier = new
|
|
9067
|
+
this.model = await (0, import_agent_qa_core13.createModel)(modelConfig);
|
|
9068
|
+
const providerOptions = (0, import_agent_qa_core13.getProviderOptions)(modelConfig);
|
|
9069
|
+
this.planner = new import_agent_qa_core13.LLMPlanner(this.model, config.platform, providerOptions, void 0, config.agentRules);
|
|
9070
|
+
this.verifier = new import_agent_qa_core13.LLMVerifier(this.model, providerOptions);
|
|
9067
9071
|
this.status = "idle";
|
|
9068
9072
|
this.createdAt = Date.now();
|
|
9069
9073
|
this.readyForInteraction = true;
|
|
@@ -9073,7 +9077,7 @@ var LiveSession = class {
|
|
|
9073
9077
|
let instruction = stepInstruction;
|
|
9074
9078
|
let hasTemplateVars = false;
|
|
9075
9079
|
const executionLogs = [];
|
|
9076
|
-
const inlineHookCalls = (0,
|
|
9080
|
+
const inlineHookCalls = (0, import_agent_qa_core13.parseHookInline)(stepInstruction);
|
|
9077
9081
|
if (inlineHookCalls.length > 0) {
|
|
9078
9082
|
let inlineHookFailed = false;
|
|
9079
9083
|
for (const call of inlineHookCalls) {
|
|
@@ -9088,7 +9092,7 @@ var LiveSession = class {
|
|
|
9088
9092
|
}
|
|
9089
9093
|
const startedAt = performance.now();
|
|
9090
9094
|
try {
|
|
9091
|
-
const result = await (0,
|
|
9095
|
+
const result = await (0, import_agent_qa_core13.runHookInSandbox)(hookDef, {
|
|
9092
9096
|
envVars: this.getHookEnvVars(),
|
|
9093
9097
|
secretStore: this.secretStore,
|
|
9094
9098
|
secretRedactor: this.secretRedactor
|
|
@@ -9134,7 +9138,7 @@ var LiveSession = class {
|
|
|
9134
9138
|
break;
|
|
9135
9139
|
}
|
|
9136
9140
|
}
|
|
9137
|
-
instruction = (0,
|
|
9141
|
+
instruction = (0, import_agent_qa_core13.stripHookInline)(stepInstruction);
|
|
9138
9142
|
hasTemplateVars = true;
|
|
9139
9143
|
if (inlineHookFailed) {
|
|
9140
9144
|
return {
|
|
@@ -9145,7 +9149,7 @@ var LiveSession = class {
|
|
|
9145
9149
|
};
|
|
9146
9150
|
}
|
|
9147
9151
|
}
|
|
9148
|
-
instruction = (0,
|
|
9152
|
+
instruction = (0, import_agent_qa_core13.interpolateVariables)(instruction, this.variableStore);
|
|
9149
9153
|
hasTemplateVars = hasTemplateVars || originalStepName !== instruction;
|
|
9150
9154
|
const runJSMatches = parseRunJSInline(instruction);
|
|
9151
9155
|
if (runJSMatches.length > 0) {
|
|
@@ -9272,7 +9276,7 @@ var LiveSession = class {
|
|
|
9272
9276
|
this.stepsExecuted++;
|
|
9273
9277
|
return result2;
|
|
9274
9278
|
}
|
|
9275
|
-
const unresolvedTemplates = (0,
|
|
9279
|
+
const unresolvedTemplates = (0, import_agent_qa_core13.findUnresolvedTemplates)(prepared.instruction);
|
|
9276
9280
|
if (unresolvedTemplates.length > 0) {
|
|
9277
9281
|
const errorLines = unresolvedTemplates.map((template) => ` - ${template.pattern}: ${template.message}`);
|
|
9278
9282
|
const error = `Unresolved template variable(s):
|
|
@@ -9314,7 +9318,7 @@ ${errorLines.join("\n")}`;
|
|
|
9314
9318
|
healingConfig: { maxAttempts: 3 },
|
|
9315
9319
|
variables: this.redact(variables)
|
|
9316
9320
|
};
|
|
9317
|
-
let result = await (0,
|
|
9321
|
+
let result = await (0, import_agent_qa_core13.executeStep)(prepared.instruction, loopConfig, stepContext);
|
|
9318
9322
|
result.originalStepName = prepared.originalStepName;
|
|
9319
9323
|
result.variableSnapshot = this.variableStore.snapshot();
|
|
9320
9324
|
result.executionLogs = this.redact(prepared.executionLogs);
|
|
@@ -9669,7 +9673,7 @@ var SessionManager = class {
|
|
|
9669
9673
|
};
|
|
9670
9674
|
|
|
9671
9675
|
// src/live-editor/ws-handler.ts
|
|
9672
|
-
var
|
|
9676
|
+
var import_agent_qa_core14 = require("@vostride/agent-qa-core");
|
|
9673
9677
|
function send(ws, msg) {
|
|
9674
9678
|
if (ws.readyState === ws.OPEN) {
|
|
9675
9679
|
ws.send(JSON.stringify(msg));
|
|
@@ -9837,7 +9841,7 @@ function createSessionHandler(session, onTerminate, onTokenUsage, testFileManage
|
|
|
9837
9841
|
console.error(`[ws-handler] execute-test: read failed for path=${msg.path}`, readErr);
|
|
9838
9842
|
throw new Error(`Cannot read test file "${msg.path}": ${readErr?.message ?? String(readErr)}`);
|
|
9839
9843
|
}
|
|
9840
|
-
const parsed = (0,
|
|
9844
|
+
const parsed = (0, import_agent_qa_core14.parseTestFile)(raw, msg.path);
|
|
9841
9845
|
if (parsed.errors.length > 0) {
|
|
9842
9846
|
console.error(`[ws-handler] execute-test: parse errors for ${msg.path}`, parsed.errors);
|
|
9843
9847
|
throw new Error(`Parse error in ${msg.path}: ${parsed.errors[0].message}`);
|
|
@@ -10017,7 +10021,7 @@ function createSessionHandler(session, onTerminate, onTokenUsage, testFileManage
|
|
|
10017
10021
|
}
|
|
10018
10022
|
|
|
10019
10023
|
// src/server/server.ts
|
|
10020
|
-
var
|
|
10024
|
+
var import_agent_qa_core15 = require("@vostride/agent-qa-core");
|
|
10021
10025
|
var import_agent_qa_mcp = require("@vostride/agent-qa-mcp");
|
|
10022
10026
|
var MIME_TYPES = {
|
|
10023
10027
|
".html": "text/html; charset=utf-8",
|
|
@@ -10436,8 +10440,8 @@ async function startServer(opts) {
|
|
|
10436
10440
|
const captureMcpLifecycle = async (properties) => {
|
|
10437
10441
|
if (isAnalyticsPrivacyEnabled(config)) return;
|
|
10438
10442
|
try {
|
|
10439
|
-
const standardProperties = await (0,
|
|
10440
|
-
await (0,
|
|
10443
|
+
const standardProperties = await (0, import_agent_qa_core15.resolveAnalyticsStandardProperties)({ surface: "dashboard-server" });
|
|
10444
|
+
await (0, import_agent_qa_core15.captureAnalytics)((0, import_agent_qa_core15.buildAnalyticsEvent)({
|
|
10441
10445
|
name: "agent-qa.mcp.server.lifecycle",
|
|
10442
10446
|
properties: {
|
|
10443
10447
|
...standardProperties,
|