@muggleai/works 4.2.1 → 4.3.0
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/README.md +100 -50
- package/dist/{chunk-CXTJOYWM.js → chunk-23NOSJFH.js} +284 -184
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +4 -4
- package/dist/plugin/.cursor-plugin/plugin.json +3 -3
- package/dist/plugin/README.md +7 -5
- package/dist/plugin/scripts/ensure-electron-app.sh +3 -3
- package/dist/plugin/skills/do/e2e-acceptance.md +161 -0
- package/dist/plugin/skills/do/open-prs.md +78 -14
- package/dist/plugin/skills/muggle/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-do/SKILL.md +6 -6
- package/dist/plugin/skills/muggle-test/SKILL.md +416 -0
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +77 -80
- package/dist/plugin/skills/muggle-test-import/SKILL.md +276 -0
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +1 -1
- package/dist/plugin/skills/optimize-descriptions/SKILL.md +8 -8
- package/package.json +15 -12
- package/plugin/.claude-plugin/plugin.json +4 -4
- package/plugin/.cursor-plugin/plugin.json +3 -3
- package/plugin/README.md +7 -5
- package/plugin/scripts/ensure-electron-app.sh +3 -3
- package/plugin/skills/do/e2e-acceptance.md +161 -0
- package/plugin/skills/do/open-prs.md +78 -14
- package/plugin/skills/muggle/SKILL.md +4 -2
- package/plugin/skills/muggle-do/SKILL.md +6 -6
- package/plugin/skills/muggle-test/SKILL.md +416 -0
- package/plugin/skills/muggle-test-feature-local/SKILL.md +77 -80
- package/plugin/skills/muggle-test-import/SKILL.md +276 -0
- package/plugin/skills/muggle-upgrade/SKILL.md +1 -1
- package/plugin/skills/optimize-descriptions/SKILL.md +8 -8
- package/scripts/postinstall.mjs +2 -2
- package/dist/plugin/skills/do/qa.md +0 -89
- package/plugin/skills/do/qa.md +0 -89
|
@@ -8,9 +8,10 @@ import { fileURLToPath } from 'url';
|
|
|
8
8
|
import winston from 'winston';
|
|
9
9
|
import axios, { AxiosError } from 'axios';
|
|
10
10
|
import { spawn, exec, execFile } from 'child_process';
|
|
11
|
+
import * as crypto from 'crypto';
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
11
13
|
import * as fs5 from 'fs/promises';
|
|
12
14
|
import { z, ZodError } from 'zod';
|
|
13
|
-
import * as crypto from 'crypto';
|
|
14
15
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
15
16
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
16
17
|
import { v4 } from 'uuid';
|
|
@@ -39,6 +40,7 @@ var DEFAULT_PROMPT_SERVICE_PRODUCTION_URL = "https://promptservice.muggle-ai.com
|
|
|
39
40
|
var DEFAULT_PROMPT_SERVICE_DEV_URL = "http://localhost:5050";
|
|
40
41
|
var DEFAULT_WEB_SERVICE_URL = "http://localhost:3001";
|
|
41
42
|
var ELECTRON_APP_DIR = "electron-app";
|
|
43
|
+
var ELECTRON_APP_RELEASE_TAG_PREFIX = "electron-app-v";
|
|
42
44
|
var API_KEY_FILE = "api-key.json";
|
|
43
45
|
var DEFAULT_AUTH0_PRODUCTION_DOMAIN = "login.muggle-ai.com";
|
|
44
46
|
var DEFAULT_AUTH0_PRODUCTION_CLIENT_ID = "UgG5UjoyLksxMciWWKqVpwfWrJ4rFvtT";
|
|
@@ -262,7 +264,7 @@ function buildAuth0Config() {
|
|
|
262
264
|
scope: process.env.AUTH0_SCOPE ?? DEFAULT_AUTH0_SCOPE
|
|
263
265
|
};
|
|
264
266
|
}
|
|
265
|
-
function
|
|
267
|
+
function buildE2eConfig() {
|
|
266
268
|
const defaultPromptServiceUrl = getDefaultPromptServiceUrl();
|
|
267
269
|
return {
|
|
268
270
|
promptServiceBaseUrl: process.env.PROMPT_SERVICE_BASE_URL ?? defaultPromptServiceUrl,
|
|
@@ -306,7 +308,7 @@ function getConfig() {
|
|
|
306
308
|
serverVersion: "1.0.0",
|
|
307
309
|
logLevel: process.env.LOG_LEVEL ?? "info",
|
|
308
310
|
auth0: buildAuth0Config(),
|
|
309
|
-
|
|
311
|
+
e2e: buildE2eConfig(),
|
|
310
312
|
localQa: buildLocalQaConfig()
|
|
311
313
|
};
|
|
312
314
|
return configInstance;
|
|
@@ -357,6 +359,15 @@ function getBundledElectronAppVersion() {
|
|
|
357
359
|
function getDownloadBaseUrl() {
|
|
358
360
|
return getMuggleConfig().downloadBaseUrl;
|
|
359
361
|
}
|
|
362
|
+
function buildElectronAppReleaseTag(version) {
|
|
363
|
+
return `${ELECTRON_APP_RELEASE_TAG_PREFIX}${version}`;
|
|
364
|
+
}
|
|
365
|
+
function buildElectronAppReleaseAssetUrl(params) {
|
|
366
|
+
return `${getDownloadBaseUrl()}/${buildElectronAppReleaseTag(params.version)}/${params.assetFileName}`;
|
|
367
|
+
}
|
|
368
|
+
function buildElectronAppChecksumsUrl(version) {
|
|
369
|
+
return `${getDownloadBaseUrl()}/${buildElectronAppReleaseTag(version)}/checksums.txt`;
|
|
370
|
+
}
|
|
360
371
|
function getElectronAppChecksums() {
|
|
361
372
|
return getMuggleConfig().checksums;
|
|
362
373
|
}
|
|
@@ -403,12 +414,14 @@ function resetLogger() {
|
|
|
403
414
|
loggerInstance = null;
|
|
404
415
|
}
|
|
405
416
|
|
|
406
|
-
// packages/mcps/src/mcp/
|
|
407
|
-
var
|
|
408
|
-
__export(
|
|
417
|
+
// packages/mcps/src/mcp/e2e/index.ts
|
|
418
|
+
var e2e_exports2 = {};
|
|
419
|
+
__export(e2e_exports2, {
|
|
420
|
+
ActionScriptGetInputSchema: () => ActionScriptGetInputSchema,
|
|
409
421
|
ApiKeyCreateInputSchema: () => ApiKeyCreateInputSchema,
|
|
410
422
|
ApiKeyGetInputSchema: () => ApiKeyGetInputSchema,
|
|
411
423
|
ApiKeyListInputSchema: () => ApiKeyListInputSchema,
|
|
424
|
+
ApiKeyRecordIdSchema: () => ApiKeyRecordIdSchema,
|
|
412
425
|
ApiKeyRevokeInputSchema: () => ApiKeyRevokeInputSchema,
|
|
413
426
|
AuthLoginInputSchema: () => AuthLoginInputSchema,
|
|
414
427
|
AuthPollInputSchema: () => AuthPollInputSchema,
|
|
@@ -418,6 +431,7 @@ __export(qa_exports2, {
|
|
|
418
431
|
LocalExecutionContextInputSchema: () => LocalExecutionContextInputSchema,
|
|
419
432
|
LocalRunUploadInputSchema: () => LocalRunUploadInputSchema,
|
|
420
433
|
McpErrorCode: () => McpErrorCode,
|
|
434
|
+
MuggleEntityIdSchema: () => MuggleEntityIdSchema,
|
|
421
435
|
PaginationInputSchema: () => PaginationInputSchema,
|
|
422
436
|
PrdFileDeleteInputSchema: () => PrdFileDeleteInputSchema,
|
|
423
437
|
PrdFileListInputSchema: () => PrdFileListInputSchema,
|
|
@@ -439,11 +453,13 @@ __export(qa_exports2, {
|
|
|
439
453
|
ReportFinalGenerateInputSchema: () => ReportFinalGenerateInputSchema,
|
|
440
454
|
ReportPreferencesUpsertInputSchema: () => ReportPreferencesUpsertInputSchema,
|
|
441
455
|
ReportStatsSummaryInputSchema: () => ReportStatsSummaryInputSchema,
|
|
456
|
+
RunBatchIdSchema: () => RunBatchIdSchema,
|
|
442
457
|
SecretCreateInputSchema: () => SecretCreateInputSchema,
|
|
443
458
|
SecretDeleteInputSchema: () => SecretDeleteInputSchema,
|
|
444
459
|
SecretGetInputSchema: () => SecretGetInputSchema,
|
|
445
460
|
SecretListInputSchema: () => SecretListInputSchema,
|
|
446
461
|
SecretUpdateInputSchema: () => SecretUpdateInputSchema,
|
|
462
|
+
StripePaymentMethodIdSchema: () => StripePaymentMethodIdSchema,
|
|
447
463
|
TestCaseCreateInputSchema: () => TestCaseCreateInputSchema,
|
|
448
464
|
TestCaseGenerateFromPromptInputSchema: () => TestCaseGenerateFromPromptInputSchema,
|
|
449
465
|
TestCaseGetInputSchema: () => TestCaseGetInputSchema,
|
|
@@ -452,6 +468,8 @@ __export(qa_exports2, {
|
|
|
452
468
|
TestScriptGetInputSchema: () => TestScriptGetInputSchema,
|
|
453
469
|
TestScriptListInputSchema: () => TestScriptListInputSchema,
|
|
454
470
|
TestScriptListPaginatedInputSchema: () => TestScriptListPaginatedInputSchema,
|
|
471
|
+
TokenPackageIdSchema: () => TokenPackageIdSchema,
|
|
472
|
+
TokenUsageFilterTypeSchema: () => TokenUsageFilterTypeSchema,
|
|
455
473
|
UseCaseCandidatesApproveInputSchema: () => UseCaseCandidatesApproveInputSchema,
|
|
456
474
|
UseCaseCreateFromPromptsInputSchema: () => UseCaseCreateFromPromptsInputSchema,
|
|
457
475
|
UseCaseDiscoveryMemoryGetInputSchema: () => UseCaseDiscoveryMemoryGetInputSchema,
|
|
@@ -1620,7 +1638,7 @@ var RunResultStorageService = class {
|
|
|
1620
1638
|
*/
|
|
1621
1639
|
createRunResult(params) {
|
|
1622
1640
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1623
|
-
const id =
|
|
1641
|
+
const id = randomUUID();
|
|
1624
1642
|
const result = {
|
|
1625
1643
|
id,
|
|
1626
1644
|
runType: params.runType,
|
|
@@ -1703,7 +1721,7 @@ var RunResultStorageService = class {
|
|
|
1703
1721
|
*/
|
|
1704
1722
|
createTestScript(params) {
|
|
1705
1723
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1706
|
-
const id =
|
|
1724
|
+
const id = randomUUID();
|
|
1707
1725
|
const script = {
|
|
1708
1726
|
id,
|
|
1709
1727
|
name: params.name,
|
|
@@ -1750,7 +1768,7 @@ function getAuthenticatedUserId() {
|
|
|
1750
1768
|
const authService = getAuthService();
|
|
1751
1769
|
const authStatus = authService.getAuthStatus();
|
|
1752
1770
|
if (!authStatus.authenticated) {
|
|
1753
|
-
throw new Error("Not authenticated. Please run
|
|
1771
|
+
throw new Error("Not authenticated. Please run muggle-remote-auth-login first.");
|
|
1754
1772
|
}
|
|
1755
1773
|
if (!authStatus.userId) {
|
|
1756
1774
|
throw new Error("User ID not found in auth. Please re-authenticate.");
|
|
@@ -1800,7 +1818,7 @@ function buildStudioAuthContent() {
|
|
|
1800
1818
|
const authStatus = authService.getAuthStatus();
|
|
1801
1819
|
const storedAuth = authService.loadStoredAuth();
|
|
1802
1820
|
if (!authStatus.authenticated || !storedAuth) {
|
|
1803
|
-
throw new Error("Not authenticated. Please run
|
|
1821
|
+
throw new Error("Not authenticated. Please run muggle-remote-auth-login first.");
|
|
1804
1822
|
}
|
|
1805
1823
|
if (!storedAuth.email || !storedAuth.userId) {
|
|
1806
1824
|
throw new Error("Auth data incomplete. Please re-authenticate.");
|
|
@@ -1927,6 +1945,7 @@ function buildGenerationActionScript(params) {
|
|
|
1927
1945
|
url: params.localUrl,
|
|
1928
1946
|
description: params.testCase.title,
|
|
1929
1947
|
precondition: params.testCase.precondition ?? "",
|
|
1948
|
+
instructions: params.testCase.instructions ?? "",
|
|
1930
1949
|
expectedResult: params.testCase.expectedResult,
|
|
1931
1950
|
steps: [],
|
|
1932
1951
|
ownerId: params.ownerUserId,
|
|
@@ -1948,12 +1967,12 @@ function buildReplayActionScript(params) {
|
|
|
1948
1967
|
sourceLabel: "testScript"
|
|
1949
1968
|
});
|
|
1950
1969
|
const rewrittenActionScript = rewriteActionScriptUrls({
|
|
1951
|
-
actionScript: params.
|
|
1970
|
+
actionScript: params.actionScript,
|
|
1952
1971
|
originalUrl: params.testScript.url,
|
|
1953
1972
|
localUrl: params.localUrl
|
|
1954
1973
|
});
|
|
1955
1974
|
return {
|
|
1956
|
-
actionScriptId: params.testScript.
|
|
1975
|
+
actionScriptId: params.testScript.actionScriptId,
|
|
1957
1976
|
actionScriptName: params.testScript.name,
|
|
1958
1977
|
actionType: "UserDefined",
|
|
1959
1978
|
actionParams: {
|
|
@@ -2231,7 +2250,7 @@ ${executionResult.stderr}`;
|
|
|
2231
2250
|
}
|
|
2232
2251
|
}
|
|
2233
2252
|
async function executeReplay(params) {
|
|
2234
|
-
const { testScript, localUrl } = params;
|
|
2253
|
+
const { testScript, actionScript, localUrl } = params;
|
|
2235
2254
|
const timeoutMs = params.timeoutMs ?? 18e4;
|
|
2236
2255
|
const userId = getAuthenticatedUserId();
|
|
2237
2256
|
const authContent = buildStudioAuthContent();
|
|
@@ -2256,15 +2275,16 @@ async function executeReplay(params) {
|
|
|
2256
2275
|
try {
|
|
2257
2276
|
const runId = runResult.id;
|
|
2258
2277
|
const startedAt = Date.now();
|
|
2259
|
-
const
|
|
2278
|
+
const builtActionScript = buildReplayActionScript({
|
|
2260
2279
|
testScript,
|
|
2280
|
+
actionScript,
|
|
2261
2281
|
localUrl,
|
|
2262
2282
|
runId,
|
|
2263
2283
|
ownerUserId: authContent.userId
|
|
2264
2284
|
});
|
|
2265
2285
|
const inputFilePath = await writeTempFile({
|
|
2266
2286
|
filename: `${runId}_input.json`,
|
|
2267
|
-
data:
|
|
2287
|
+
data: builtActionScript
|
|
2268
2288
|
});
|
|
2269
2289
|
const authFilePath = await writeTempFile({
|
|
2270
2290
|
filename: `${runId}_auth.json`,
|
|
@@ -2614,7 +2634,7 @@ async function pollDeviceCode(config, deviceCode) {
|
|
|
2614
2634
|
}
|
|
2615
2635
|
async function createApiKeyWithToken(accessToken, keyName, expiry = "90d") {
|
|
2616
2636
|
const config = getConfig();
|
|
2617
|
-
const apiKeyUrl = `${config.
|
|
2637
|
+
const apiKeyUrl = `${config.e2e.promptServiceBaseUrl}/v1/protected/api-keys`;
|
|
2618
2638
|
try {
|
|
2619
2639
|
logger4.info("[Auth] Creating API key", {
|
|
2620
2640
|
keyName,
|
|
@@ -2807,6 +2827,7 @@ function toolRequiresAuth(toolName) {
|
|
|
2807
2827
|
];
|
|
2808
2828
|
return !noAuthTools.includes(toolName);
|
|
2809
2829
|
}
|
|
2830
|
+
var MuggleEntityIdSchema = z.string().uuid();
|
|
2810
2831
|
var LocalExecutionContextInputSchema = z.object({
|
|
2811
2832
|
originalUrl: z.string().url().describe("Original local URL used during local execution (typically localhost)"),
|
|
2812
2833
|
productionUrl: z.string().url().describe("Cloud production URL for the test case"),
|
|
@@ -2819,9 +2840,9 @@ var LocalExecutionContextInputSchema = z.object({
|
|
|
2819
2840
|
uploadedAt: z.number().int().positive().optional().describe("Epoch milliseconds when uploaded to cloud")
|
|
2820
2841
|
});
|
|
2821
2842
|
var LocalRunUploadInputSchema = z.object({
|
|
2822
|
-
projectId:
|
|
2823
|
-
useCaseId:
|
|
2824
|
-
testCaseId:
|
|
2843
|
+
projectId: MuggleEntityIdSchema.describe("Project ID (UUID) for the local run"),
|
|
2844
|
+
useCaseId: MuggleEntityIdSchema.describe("Use case ID (UUID) for the local run"),
|
|
2845
|
+
testCaseId: MuggleEntityIdSchema.describe("Test case ID (UUID) for the local run"),
|
|
2825
2846
|
runType: z.enum(["generation", "replay"]).describe("Type of local run to upload"),
|
|
2826
2847
|
productionUrl: z.string().url().describe("Cloud production URL associated with the run"),
|
|
2827
2848
|
localExecutionContext: LocalExecutionContextInputSchema.describe("Local execution metadata"),
|
|
@@ -2831,12 +2852,16 @@ var LocalRunUploadInputSchema = z.object({
|
|
|
2831
2852
|
errorMessage: z.string().optional().describe("Error message when status is failed")
|
|
2832
2853
|
});
|
|
2833
2854
|
|
|
2834
|
-
// packages/mcps/src/mcp/
|
|
2855
|
+
// packages/mcps/src/mcp/e2e/contracts/index.ts
|
|
2835
2856
|
var PaginationInputSchema = z.object({
|
|
2836
2857
|
page: z.number().int().positive().optional().describe("Page number (1-based)"),
|
|
2837
2858
|
pageSize: z.number().int().positive().max(100).optional().describe("Number of items per page")
|
|
2838
2859
|
});
|
|
2839
|
-
var IdSchema =
|
|
2860
|
+
var IdSchema = MuggleEntityIdSchema;
|
|
2861
|
+
var RunBatchIdSchema = MuggleEntityIdSchema.describe("Bulk replay run batch ID (UUID)");
|
|
2862
|
+
var TokenPackageIdSchema = z.string().min(1).describe("Token package ID from wallet catalog");
|
|
2863
|
+
var StripePaymentMethodIdSchema = z.string().regex(/^pm_[a-zA-Z0-9]+$/).describe("Stripe payment method ID (pm_\u2026)");
|
|
2864
|
+
var ApiKeyRecordIdSchema = z.string().length(24).regex(/^[0-9a-f]+$/i).describe("API key record ID (24-character hex)");
|
|
2840
2865
|
var WorkflowMemoryParamsSchema = z.object({
|
|
2841
2866
|
enableSharedTestMemory: z.boolean().optional().describe("Override to enable/disable SharedTestMemory for this workflow run"),
|
|
2842
2867
|
enableEverMemOS: z.boolean().optional().describe("Override to enable/disable EverMemOS for this workflow run")
|
|
@@ -2844,39 +2869,46 @@ var WorkflowMemoryParamsSchema = z.object({
|
|
|
2844
2869
|
var WorkflowParamsSchema = z.object({
|
|
2845
2870
|
memory: WorkflowMemoryParamsSchema.optional().describe("Per-run memory override settings")
|
|
2846
2871
|
}).passthrough().optional().describe("Optional workflow parameters for workflow-level overrides");
|
|
2872
|
+
var TokenUsageFilterTypeSchema = z.enum([
|
|
2873
|
+
"project",
|
|
2874
|
+
"useCase",
|
|
2875
|
+
"testCase",
|
|
2876
|
+
"testScript",
|
|
2877
|
+
"actionScript"
|
|
2878
|
+
]).describe("Token cost aggregation dimension");
|
|
2847
2879
|
var ProjectCreateInputSchema = z.object({
|
|
2848
2880
|
projectName: z.string().min(1).max(255).describe("Name of the project"),
|
|
2849
2881
|
description: z.string().min(1).describe("Project description"),
|
|
2850
2882
|
url: z.string().url().describe("Target website URL to test")
|
|
2851
2883
|
});
|
|
2852
2884
|
var ProjectGetInputSchema = z.object({
|
|
2853
|
-
projectId: IdSchema.describe("Project ID to retrieve")
|
|
2885
|
+
projectId: IdSchema.describe("Project ID (UUID) to retrieve")
|
|
2854
2886
|
});
|
|
2855
2887
|
var ProjectDeleteInputSchema = z.object({
|
|
2856
|
-
projectId: IdSchema.describe("Project ID to delete")
|
|
2888
|
+
projectId: IdSchema.describe("Project ID (UUID) to delete")
|
|
2857
2889
|
});
|
|
2858
2890
|
var ProjectUpdateInputSchema = z.object({
|
|
2859
|
-
projectId: IdSchema.describe("Project ID to update"),
|
|
2891
|
+
projectId: IdSchema.describe("Project ID (UUID) to update"),
|
|
2860
2892
|
projectName: z.string().min(1).max(255).optional().describe("New project name"),
|
|
2861
2893
|
description: z.string().optional().describe("Updated description"),
|
|
2862
2894
|
url: z.string().url().optional().describe("Updated target URL")
|
|
2863
2895
|
});
|
|
2864
2896
|
var ProjectListInputSchema = PaginationInputSchema.extend({});
|
|
2865
2897
|
var PrdFileUploadInputSchema = z.object({
|
|
2866
|
-
projectId: IdSchema.describe("Project ID to associate the PRD file with"),
|
|
2898
|
+
projectId: IdSchema.describe("Project ID (UUID) to associate the PRD file with"),
|
|
2867
2899
|
fileName: z.string().min(1).describe("Name of the file"),
|
|
2868
2900
|
contentBase64: z.string().min(1).describe("Base64-encoded file content"),
|
|
2869
2901
|
contentType: z.string().optional().describe("MIME type of the file")
|
|
2870
2902
|
});
|
|
2871
2903
|
var PrdFileListInputSchema = z.object({
|
|
2872
|
-
projectId: IdSchema.describe("Project ID to list PRD files for")
|
|
2904
|
+
projectId: IdSchema.describe("Project ID (UUID) to list PRD files for")
|
|
2873
2905
|
});
|
|
2874
2906
|
var PrdFileDeleteInputSchema = z.object({
|
|
2875
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2876
|
-
prdFileId: IdSchema.describe("PRD file ID to delete")
|
|
2907
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
2908
|
+
prdFileId: IdSchema.describe("PRD file ID (UUID) to delete")
|
|
2877
2909
|
});
|
|
2878
2910
|
var PrdFileProcessStartInputSchema = z.object({
|
|
2879
|
-
projectId: IdSchema.describe("Project ID to process PRD files for"),
|
|
2911
|
+
projectId: IdSchema.describe("Project ID (UUID) to process PRD files for"),
|
|
2880
2912
|
name: z.string().min(1).describe("Workflow name"),
|
|
2881
2913
|
description: z.string().min(1).describe("Description of the PRD processing workflow"),
|
|
2882
2914
|
prdFilePath: z.string().min(1).describe("Storage path of the uploaded PRD file (from upload response)"),
|
|
@@ -2886,75 +2918,75 @@ var PrdFileProcessStartInputSchema = z.object({
|
|
|
2886
2918
|
fileSize: z.number().int().min(0).describe("Size of the PRD file in bytes (from upload response)")
|
|
2887
2919
|
});
|
|
2888
2920
|
var PrdFileProcessLatestRunInputSchema = z.object({
|
|
2889
|
-
workflowRuntimeId: IdSchema.describe("PRD processing workflow runtime ID")
|
|
2921
|
+
workflowRuntimeId: IdSchema.describe("PRD processing workflow runtime ID (UUID)")
|
|
2890
2922
|
});
|
|
2891
2923
|
var SecretListInputSchema = z.object({
|
|
2892
|
-
projectId: IdSchema.describe("Project ID to list secrets for")
|
|
2924
|
+
projectId: IdSchema.describe("Project ID (UUID) to list secrets for")
|
|
2893
2925
|
});
|
|
2894
2926
|
var SecretCreateInputSchema = z.object({
|
|
2895
|
-
projectId: IdSchema.describe("Project ID to create the secret for"),
|
|
2927
|
+
projectId: IdSchema.describe("Project ID (UUID) to create the secret for"),
|
|
2896
2928
|
name: z.string().min(1).describe("Secret name/key"),
|
|
2897
2929
|
value: z.string().min(1).describe("Secret value"),
|
|
2898
2930
|
description: z.string().min(1).describe("Human-readable description for selection guidance"),
|
|
2899
2931
|
source: z.enum(["user", "agent"]).optional().describe("Source of the secret: 'user' for user-provided credentials, 'agent' for agent-generated credentials")
|
|
2900
2932
|
});
|
|
2901
2933
|
var SecretGetInputSchema = z.object({
|
|
2902
|
-
secretId: IdSchema.describe("Secret ID to retrieve")
|
|
2934
|
+
secretId: IdSchema.describe("Secret ID (UUID) to retrieve")
|
|
2903
2935
|
});
|
|
2904
2936
|
var SecretUpdateInputSchema = z.object({
|
|
2905
|
-
secretId: IdSchema.describe("Secret ID to update"),
|
|
2937
|
+
secretId: IdSchema.describe("Secret ID (UUID) to update"),
|
|
2906
2938
|
name: z.string().min(1).optional().describe("Updated secret name"),
|
|
2907
2939
|
value: z.string().min(1).optional().describe("Updated secret value"),
|
|
2908
2940
|
description: z.string().optional().describe("Updated description")
|
|
2909
2941
|
});
|
|
2910
2942
|
var SecretDeleteInputSchema = z.object({
|
|
2911
|
-
secretId: IdSchema.describe("Secret ID to delete")
|
|
2943
|
+
secretId: IdSchema.describe("Secret ID (UUID) to delete")
|
|
2912
2944
|
});
|
|
2913
2945
|
var UseCaseDiscoveryMemoryGetInputSchema = z.object({
|
|
2914
|
-
projectId: IdSchema.describe("Project ID to get use case discovery memory for")
|
|
2946
|
+
projectId: IdSchema.describe("Project ID (UUID) to get use case discovery memory for")
|
|
2915
2947
|
});
|
|
2916
2948
|
var UseCaseCandidatesApproveInputSchema = z.object({
|
|
2917
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2949
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
2918
2950
|
approvedCandidateIds: z.array(IdSchema).min(1).describe("IDs of candidates to approve/graduate")
|
|
2919
2951
|
});
|
|
2920
2952
|
var UseCaseListInputSchema = z.object({
|
|
2921
|
-
projectId: IdSchema.describe("Project ID to list use cases for")
|
|
2953
|
+
projectId: IdSchema.describe("Project ID (UUID) to list use cases for")
|
|
2922
2954
|
}).merge(PaginationInputSchema);
|
|
2923
2955
|
var UseCaseGetInputSchema = z.object({
|
|
2924
|
-
useCaseId: IdSchema.describe("Use case ID to retrieve")
|
|
2956
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to retrieve")
|
|
2925
2957
|
});
|
|
2926
2958
|
var UseCasePromptPreviewInputSchema = z.object({
|
|
2927
|
-
projectId: IdSchema.describe("Project ID to generate use case for"),
|
|
2959
|
+
projectId: IdSchema.describe("Project ID (UUID) to generate use case for"),
|
|
2928
2960
|
instruction: z.string().min(1).describe("Natural language instruction describing the use case (e.g., 'As a logged-in user, I can add items to cart')")
|
|
2929
2961
|
});
|
|
2930
2962
|
var UseCaseCreateFromPromptsInputSchema = z.object({
|
|
2931
|
-
projectId: IdSchema.describe("Project ID to create use cases for"),
|
|
2963
|
+
projectId: IdSchema.describe("Project ID (UUID) to create use cases for"),
|
|
2932
2964
|
prompts: z.array(z.object({
|
|
2933
2965
|
instruction: z.string().min(1).describe("Natural language instruction describing the use case")
|
|
2934
2966
|
})).min(1).describe("Array of prompts to generate use cases from")
|
|
2935
2967
|
});
|
|
2936
2968
|
var UseCaseUpdateFromPromptInputSchema = z.object({
|
|
2937
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2938
|
-
useCaseId: IdSchema.describe("Use case ID to update"),
|
|
2969
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
2970
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to update"),
|
|
2939
2971
|
instruction: z.string().min(1).describe("Natural language instruction to regenerate the use case from")
|
|
2940
2972
|
});
|
|
2941
2973
|
var TestCaseListInputSchema = z.object({
|
|
2942
|
-
projectId: IdSchema.describe("Project ID to list test cases for")
|
|
2974
|
+
projectId: IdSchema.describe("Project ID (UUID) to list test cases for")
|
|
2943
2975
|
}).merge(PaginationInputSchema);
|
|
2944
2976
|
var TestCaseGetInputSchema = z.object({
|
|
2945
|
-
testCaseId: IdSchema.describe("Test case ID to retrieve")
|
|
2977
|
+
testCaseId: IdSchema.describe("Test case ID (UUID) to retrieve")
|
|
2946
2978
|
});
|
|
2947
2979
|
var TestCaseListByUseCaseInputSchema = z.object({
|
|
2948
|
-
useCaseId: IdSchema.describe("Use case ID to list test cases for")
|
|
2980
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to list test cases for")
|
|
2949
2981
|
});
|
|
2950
2982
|
var TestCaseGenerateFromPromptInputSchema = z.object({
|
|
2951
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2952
|
-
useCaseId: IdSchema.describe("Use case ID to generate test cases for"),
|
|
2983
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
2984
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to generate test cases for"),
|
|
2953
2985
|
instruction: z.string().min(1).describe("Natural language instruction describing the test cases to generate")
|
|
2954
2986
|
});
|
|
2955
2987
|
var TestCaseCreateInputSchema = z.object({
|
|
2956
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2957
|
-
useCaseId: IdSchema.describe("Use case ID to associate the test case with"),
|
|
2988
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
2989
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to associate the test case with"),
|
|
2958
2990
|
title: z.string().min(1).describe("Test case title"),
|
|
2959
2991
|
description: z.string().min(1).describe("Detailed description of what the test case validates"),
|
|
2960
2992
|
goal: z.string().min(1).describe("Concise, measurable goal of the test"),
|
|
@@ -2968,39 +3000,43 @@ var TestCaseCreateInputSchema = z.object({
|
|
|
2968
3000
|
automated: z.boolean().optional().describe("Whether this test case is automated (default: true)")
|
|
2969
3001
|
});
|
|
2970
3002
|
var TestScriptListInputSchema = z.object({
|
|
2971
|
-
projectId: IdSchema.describe("Project ID to list test scripts for")
|
|
3003
|
+
projectId: IdSchema.describe("Project ID (UUID) to list test scripts for"),
|
|
3004
|
+
testCaseId: IdSchema.optional().describe("Optional test case ID (UUID) to filter scripts by")
|
|
2972
3005
|
}).merge(PaginationInputSchema);
|
|
2973
3006
|
var TestScriptGetInputSchema = z.object({
|
|
2974
|
-
testScriptId: IdSchema.describe("Test script ID to retrieve")
|
|
3007
|
+
testScriptId: IdSchema.describe("Test script ID (UUID) to retrieve")
|
|
2975
3008
|
});
|
|
2976
3009
|
var TestScriptListPaginatedInputSchema = z.object({
|
|
2977
|
-
projectId: IdSchema.describe("Project ID to list test scripts for")
|
|
3010
|
+
projectId: IdSchema.describe("Project ID (UUID) to list test scripts for")
|
|
2978
3011
|
}).merge(PaginationInputSchema);
|
|
3012
|
+
var ActionScriptGetInputSchema = z.object({
|
|
3013
|
+
actionScriptId: IdSchema.describe("Action script ID (UUID) to retrieve")
|
|
3014
|
+
});
|
|
2979
3015
|
var WorkflowStartWebsiteScanInputSchema = z.object({
|
|
2980
|
-
projectId: IdSchema.describe("Project ID to scan"),
|
|
3016
|
+
projectId: IdSchema.describe("Project ID (UUID) to scan"),
|
|
2981
3017
|
url: z.string().url().describe("Website URL to scan"),
|
|
2982
3018
|
description: z.string().min(1).describe("Description of what to scan/discover"),
|
|
2983
3019
|
archiveUnapproved: z.boolean().optional().describe("Whether to archive unapproved candidates before scanning"),
|
|
2984
3020
|
workflowParams: WorkflowParamsSchema
|
|
2985
3021
|
});
|
|
2986
3022
|
var WorkflowListRuntimesInputSchema = z.object({
|
|
2987
|
-
projectId: IdSchema.optional().describe("Filter by project ID")
|
|
3023
|
+
projectId: IdSchema.optional().describe("Filter by project ID (UUID)")
|
|
2988
3024
|
});
|
|
2989
3025
|
var WorkflowGetLatestRunInputSchema = z.object({
|
|
2990
|
-
workflowRuntimeId: IdSchema.describe("Workflow runtime ID")
|
|
3026
|
+
workflowRuntimeId: IdSchema.describe("Workflow runtime ID (UUID)")
|
|
2991
3027
|
});
|
|
2992
3028
|
var WorkflowStartTestCaseDetectionInputSchema = z.object({
|
|
2993
|
-
projectId: IdSchema.describe("Project ID"),
|
|
2994
|
-
useCaseId: IdSchema.describe("Use case ID to detect test cases for"),
|
|
3029
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3030
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to detect test cases for"),
|
|
2995
3031
|
name: z.string().min(1).describe("Workflow name"),
|
|
2996
3032
|
description: z.string().min(1).describe("Workflow description"),
|
|
2997
3033
|
url: z.string().url().describe("Target website URL"),
|
|
2998
3034
|
workflowParams: WorkflowParamsSchema
|
|
2999
3035
|
});
|
|
3000
3036
|
var WorkflowStartTestScriptGenerationInputSchema = z.object({
|
|
3001
|
-
projectId: IdSchema.describe("Project ID"),
|
|
3002
|
-
useCaseId: IdSchema.describe("Use case ID"),
|
|
3003
|
-
testCaseId: IdSchema.describe("Test case ID"),
|
|
3037
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3038
|
+
useCaseId: IdSchema.describe("Use case ID (UUID)"),
|
|
3039
|
+
testCaseId: IdSchema.describe("Test case ID (UUID)"),
|
|
3004
3040
|
name: z.string().min(1).describe("Workflow name"),
|
|
3005
3041
|
url: z.string().url().describe("Target website URL"),
|
|
3006
3042
|
goal: z.string().min(1).describe("Test goal"),
|
|
@@ -3010,57 +3046,57 @@ var WorkflowStartTestScriptGenerationInputSchema = z.object({
|
|
|
3010
3046
|
workflowParams: WorkflowParamsSchema
|
|
3011
3047
|
});
|
|
3012
3048
|
var WorkflowGetLatestScriptGenByTestCaseInputSchema = z.object({
|
|
3013
|
-
testCaseId: IdSchema.describe("Test case ID")
|
|
3049
|
+
testCaseId: IdSchema.describe("Test case ID (UUID)")
|
|
3014
3050
|
});
|
|
3015
3051
|
var WorkflowStartTestScriptReplayInputSchema = z.object({
|
|
3016
|
-
projectId: IdSchema.describe("Project ID"),
|
|
3017
|
-
useCaseId: IdSchema.describe("Use case ID"),
|
|
3018
|
-
testCaseId: IdSchema.describe("Test case ID"),
|
|
3019
|
-
testScriptId: IdSchema.describe("Test script ID to replay"),
|
|
3052
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3053
|
+
useCaseId: IdSchema.describe("Use case ID (UUID)"),
|
|
3054
|
+
testCaseId: IdSchema.describe("Test case ID (UUID)"),
|
|
3055
|
+
testScriptId: IdSchema.describe("Test script ID (UUID) to replay"),
|
|
3020
3056
|
name: z.string().min(1).describe("Workflow name"),
|
|
3021
3057
|
workflowParams: WorkflowParamsSchema
|
|
3022
3058
|
});
|
|
3023
3059
|
var WorkflowStartTestScriptReplayBulkInputSchema = z.object({
|
|
3024
|
-
projectId: IdSchema.describe("Project ID"),
|
|
3060
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3025
3061
|
name: z.string().min(1).describe("Workflow name"),
|
|
3026
3062
|
intervalSec: z.number().int().describe("Interval in seconds (-1 for one-time / on-demand)"),
|
|
3027
|
-
useCaseId: IdSchema.optional().describe("Optional: only replay test cases under this use case"),
|
|
3063
|
+
useCaseId: IdSchema.optional().describe("Optional: only replay test cases under this use case (UUID)"),
|
|
3028
3064
|
namePrefix: z.string().optional().describe("Optional: prefix for generated workflow names"),
|
|
3029
3065
|
limit: z.number().int().optional().describe("Optional: limit number of test cases to replay"),
|
|
3030
|
-
testCaseIds: z.array(IdSchema).optional().describe("Optional: targeted test
|
|
3066
|
+
testCaseIds: z.array(IdSchema).optional().describe("Optional: targeted test case UUIDs to replay"),
|
|
3031
3067
|
repeatPerTestCase: z.number().int().optional().describe("Optional: repeat count per test case"),
|
|
3032
3068
|
workflowParams: WorkflowParamsSchema
|
|
3033
3069
|
});
|
|
3034
3070
|
var WorkflowGetReplayBulkBatchSummaryInputSchema = z.object({
|
|
3035
|
-
runBatchId:
|
|
3071
|
+
runBatchId: RunBatchIdSchema.describe("Run batch ID (UUID) from bulk replay workflow")
|
|
3036
3072
|
});
|
|
3037
3073
|
var WorkflowCancelRunInputSchema = z.object({
|
|
3038
|
-
workflowRunId: IdSchema.describe("Workflow run ID to cancel")
|
|
3074
|
+
workflowRunId: IdSchema.describe("Workflow run ID (UUID) to cancel")
|
|
3039
3075
|
});
|
|
3040
3076
|
var WorkflowCancelRuntimeInputSchema = z.object({
|
|
3041
|
-
workflowRuntimeId: IdSchema.describe("Workflow runtime ID to cancel")
|
|
3077
|
+
workflowRuntimeId: IdSchema.describe("Workflow runtime ID (UUID) to cancel")
|
|
3042
3078
|
});
|
|
3043
3079
|
var ProjectTestResultsSummaryInputSchema = z.object({
|
|
3044
|
-
projectId: IdSchema.describe("Project ID to get test results summary for")
|
|
3080
|
+
projectId: IdSchema.describe("Project ID (UUID) to get test results summary for")
|
|
3045
3081
|
});
|
|
3046
3082
|
var ProjectTestScriptsSummaryInputSchema = z.object({
|
|
3047
|
-
projectId: IdSchema.describe("Project ID to get test scripts summary for")
|
|
3083
|
+
projectId: IdSchema.describe("Project ID (UUID) to get test scripts summary for")
|
|
3048
3084
|
});
|
|
3049
3085
|
var ProjectTestRunsSummaryInputSchema = z.object({
|
|
3050
|
-
projectId: IdSchema.describe("Project ID to get test runs summary for")
|
|
3086
|
+
projectId: IdSchema.describe("Project ID (UUID) to get test runs summary for")
|
|
3051
3087
|
});
|
|
3052
3088
|
var ReportStatsSummaryInputSchema = z.object({
|
|
3053
|
-
projectId: IdSchema.describe("Project ID to get report stats for")
|
|
3089
|
+
projectId: IdSchema.describe("Project ID (UUID) to get report stats for")
|
|
3054
3090
|
});
|
|
3055
3091
|
var ReportCostQueryInputSchema = z.object({
|
|
3056
|
-
projectId: IdSchema.describe("Project ID"),
|
|
3092
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3057
3093
|
startDateKey: z.string().optional().describe("Start date key (YYYYMMDD)"),
|
|
3058
3094
|
endDateKey: z.string().optional().describe("End date key (YYYYMMDD)"),
|
|
3059
|
-
filterType:
|
|
3060
|
-
filterIds: z.array(
|
|
3095
|
+
filterType: TokenUsageFilterTypeSchema.optional().describe("Aggregation dimension for cost breakdown"),
|
|
3096
|
+
filterIds: z.array(IdSchema).optional().describe("Entity UUIDs matching filterType (project / use case / test case / test script / action script)")
|
|
3061
3097
|
});
|
|
3062
3098
|
var ReportPreferencesUpsertInputSchema = z.object({
|
|
3063
|
-
projectId: IdSchema.describe("Project ID"),
|
|
3099
|
+
projectId: IdSchema.describe("Project ID (UUID)"),
|
|
3064
3100
|
channels: z.array(z.unknown()).describe("Delivery channels to enable"),
|
|
3065
3101
|
emails: z.array(z.unknown()).optional().describe("Email addresses for delivery"),
|
|
3066
3102
|
phones: z.array(z.unknown()).optional().describe("Phone numbers for SMS delivery"),
|
|
@@ -3068,11 +3104,11 @@ var ReportPreferencesUpsertInputSchema = z.object({
|
|
|
3068
3104
|
defaultExportFormat: z.string().optional().describe("Default export format (pdf, html, etc.)")
|
|
3069
3105
|
});
|
|
3070
3106
|
var ReportFinalGenerateInputSchema = z.object({
|
|
3071
|
-
projectId: IdSchema.describe("Project ID to generate report for"),
|
|
3107
|
+
projectId: IdSchema.describe("Project ID (UUID) to generate report for"),
|
|
3072
3108
|
exportFormat: z.enum(["pdf", "html", "markdown"]).describe("Export format for the report")
|
|
3073
3109
|
});
|
|
3074
3110
|
var WalletTopUpInputSchema = z.object({
|
|
3075
|
-
packageId:
|
|
3111
|
+
packageId: TokenPackageIdSchema.describe("Token package ID to purchase"),
|
|
3076
3112
|
checkoutSuccessCallback: z.string().url().describe("URL to redirect to when checkout succeeds"),
|
|
3077
3113
|
checkoutCancelCallback: z.string().url().describe("URL to redirect to when checkout is canceled")
|
|
3078
3114
|
});
|
|
@@ -3081,21 +3117,21 @@ var WalletPaymentMethodCreateSetupSessionInputSchema = z.object({
|
|
|
3081
3117
|
checkoutCancelCallback: z.string().url().describe("URL to redirect to when payment method setup is canceled")
|
|
3082
3118
|
});
|
|
3083
3119
|
var WalletAutoTopUpSetPaymentMethodInputSchema = z.object({
|
|
3084
|
-
paymentMethodId:
|
|
3120
|
+
paymentMethodId: StripePaymentMethodIdSchema.describe("Saved Stripe payment method ID")
|
|
3085
3121
|
});
|
|
3086
3122
|
var WalletPaymentMethodListInputSchema = z.object({});
|
|
3087
3123
|
var WalletAutoTopUpUpdateInputSchema = z.object({
|
|
3088
3124
|
enabled: z.boolean().describe("Whether auto top-up is enabled"),
|
|
3089
3125
|
topUpTriggerTokenThreshold: z.number().int().min(0).describe("Token balance threshold to trigger auto top-up"),
|
|
3090
|
-
packageId:
|
|
3126
|
+
packageId: TokenPackageIdSchema.describe("Token package ID to purchase when auto top-up triggers")
|
|
3091
3127
|
});
|
|
3092
3128
|
var RecommendScheduleInputSchema = z.object({
|
|
3093
|
-
projectId: IdSchema.optional().describe("Project ID for context"),
|
|
3129
|
+
projectId: IdSchema.optional().describe("Project ID (UUID) for context"),
|
|
3094
3130
|
testFrequency: z.enum(["daily", "weekly", "onDemand"]).optional().describe("Desired test frequency"),
|
|
3095
3131
|
timezone: z.string().optional().describe("Timezone for scheduling")
|
|
3096
3132
|
});
|
|
3097
3133
|
var RecommendCicdSetupInputSchema = z.object({
|
|
3098
|
-
projectId: IdSchema.optional().describe("Project ID for context"),
|
|
3134
|
+
projectId: IdSchema.optional().describe("Project ID (UUID) for context"),
|
|
3099
3135
|
repositoryProvider: z.enum(["github", "azureDevOps", "gitlab", "other"]).optional().describe("Git repository provider"),
|
|
3100
3136
|
cadence: z.enum(["onPullRequest", "nightly", "onDemand"]).optional().describe("CI/CD trigger cadence")
|
|
3101
3137
|
});
|
|
@@ -3105,10 +3141,10 @@ var ApiKeyCreateInputSchema = z.object({
|
|
|
3105
3141
|
});
|
|
3106
3142
|
var ApiKeyListInputSchema = z.object({});
|
|
3107
3143
|
var ApiKeyGetInputSchema = z.object({
|
|
3108
|
-
apiKeyId:
|
|
3144
|
+
apiKeyId: ApiKeyRecordIdSchema.describe("ID of the API key record to retrieve")
|
|
3109
3145
|
});
|
|
3110
3146
|
var ApiKeyRevokeInputSchema = z.object({
|
|
3111
|
-
apiKeyId:
|
|
3147
|
+
apiKeyId: ApiKeyRecordIdSchema.describe("ID of the API key record to revoke")
|
|
3112
3148
|
});
|
|
3113
3149
|
var AuthLoginInputSchema = z.object({
|
|
3114
3150
|
waitForCompletion: z.boolean().optional().describe("Whether to wait for browser login completion before returning. Default: true"),
|
|
@@ -3119,7 +3155,7 @@ var AuthPollInputSchema = z.object({
|
|
|
3119
3155
|
});
|
|
3120
3156
|
var EmptyInputSchema = z.object({});
|
|
3121
3157
|
|
|
3122
|
-
// packages/mcps/src/mcp/
|
|
3158
|
+
// packages/mcps/src/mcp/e2e/types.ts
|
|
3123
3159
|
var McpErrorCode = /* @__PURE__ */ ((McpErrorCode2) => {
|
|
3124
3160
|
McpErrorCode2["UNAUTHORIZED"] = "UNAUTHORIZED";
|
|
3125
3161
|
McpErrorCode2["FORBIDDEN"] = "FORBIDDEN";
|
|
@@ -3147,7 +3183,8 @@ var GatewayError = class extends Error {
|
|
|
3147
3183
|
var ALLOWED_UPSTREAM_PREFIXES = [
|
|
3148
3184
|
"/v1/protected/muggle-test/",
|
|
3149
3185
|
"/v1/protected/wallet/",
|
|
3150
|
-
"/v1/protected/api-keys"
|
|
3186
|
+
"/v1/protected/api-keys",
|
|
3187
|
+
"/v1/protected/actionScript/"
|
|
3151
3188
|
];
|
|
3152
3189
|
var PromptServiceClient = class {
|
|
3153
3190
|
httpClient;
|
|
@@ -3155,8 +3192,8 @@ var PromptServiceClient = class {
|
|
|
3155
3192
|
requestTimeoutMs;
|
|
3156
3193
|
constructor() {
|
|
3157
3194
|
const config = getConfig();
|
|
3158
|
-
this.baseUrl = config.
|
|
3159
|
-
this.requestTimeoutMs = config.
|
|
3195
|
+
this.baseUrl = config.e2e.promptServiceBaseUrl;
|
|
3196
|
+
this.requestTimeoutMs = config.e2e.requestTimeoutMs;
|
|
3160
3197
|
this.httpClient = axios.create({
|
|
3161
3198
|
baseURL: this.baseUrl,
|
|
3162
3199
|
timeout: this.requestTimeoutMs,
|
|
@@ -3387,13 +3424,13 @@ function getPromptServiceClient() {
|
|
|
3387
3424
|
return clientInstance;
|
|
3388
3425
|
}
|
|
3389
3426
|
|
|
3390
|
-
// packages/mcps/src/mcp/tools/
|
|
3427
|
+
// packages/mcps/src/mcp/tools/e2e/tool-registry.ts
|
|
3391
3428
|
var MUGGLE_TEST_PREFIX = "/v1/protected/muggle-test";
|
|
3392
|
-
var getWorkflowTimeoutMs = () => getConfig().
|
|
3429
|
+
var getWorkflowTimeoutMs = () => getConfig().e2e.workflowTimeoutMs;
|
|
3393
3430
|
var projectTools = [
|
|
3394
3431
|
{
|
|
3395
3432
|
name: "muggle-remote-project-create",
|
|
3396
|
-
description: "Create
|
|
3433
|
+
description: "Create an E2E acceptance testing project to organize browser tests for a web app. A project groups test scenarios (use cases), specific test steps (test cases), and replayable browser scripts (test scripts) for one application. Create a project first before generating or running any E2E tests.",
|
|
3397
3434
|
inputSchema: ProjectCreateInputSchema,
|
|
3398
3435
|
mapToUpstream: (input) => {
|
|
3399
3436
|
const data = input;
|
|
@@ -3594,7 +3631,7 @@ var testCaseTools = [
|
|
|
3594
3631
|
},
|
|
3595
3632
|
{
|
|
3596
3633
|
name: "muggle-remote-test-case-generate-from-prompt",
|
|
3597
|
-
description: "Generate
|
|
3634
|
+
description: "Generate E2E acceptance test cases from a plain-English description of what to test \u2014 e.g., 'test the signup flow with invalid email' or 'verify the checkout handles empty cart'. Returns preview test cases that can be used to generate executable browser test scripts.",
|
|
3598
3635
|
inputSchema: TestCaseGenerateFromPromptInputSchema,
|
|
3599
3636
|
mapToUpstream: (input) => {
|
|
3600
3637
|
const data = input;
|
|
@@ -3636,14 +3673,14 @@ var testCaseTools = [
|
|
|
3636
3673
|
var testScriptTools = [
|
|
3637
3674
|
{
|
|
3638
3675
|
name: "muggle-remote-test-script-list",
|
|
3639
|
-
description: "List test scripts for a project.",
|
|
3676
|
+
description: "List test scripts for a project, optionally filtered by test case.",
|
|
3640
3677
|
inputSchema: TestScriptListInputSchema,
|
|
3641
3678
|
mapToUpstream: (input) => {
|
|
3642
3679
|
const data = input;
|
|
3643
3680
|
return {
|
|
3644
3681
|
method: "GET",
|
|
3645
3682
|
path: `${MUGGLE_TEST_PREFIX}/test-scripts`,
|
|
3646
|
-
queryParams: { projectId: data.projectId, page: data.page, pageSize: data.pageSize }
|
|
3683
|
+
queryParams: { projectId: data.projectId, testCaseId: data.testCaseId, page: data.page, pageSize: data.pageSize }
|
|
3647
3684
|
};
|
|
3648
3685
|
}
|
|
3649
3686
|
},
|
|
@@ -3673,10 +3710,24 @@ var testScriptTools = [
|
|
|
3673
3710
|
}
|
|
3674
3711
|
}
|
|
3675
3712
|
];
|
|
3713
|
+
var actionScriptTools = [
|
|
3714
|
+
{
|
|
3715
|
+
name: "muggle-remote-action-script-get",
|
|
3716
|
+
description: "Get the full action script content by ID. Use actionScriptId from a test script to fetch the complete script with all steps and element labels needed for replay.",
|
|
3717
|
+
inputSchema: ActionScriptGetInputSchema,
|
|
3718
|
+
mapToUpstream: (input) => {
|
|
3719
|
+
const data = input;
|
|
3720
|
+
return {
|
|
3721
|
+
method: "GET",
|
|
3722
|
+
path: `/v1/protected/actionScript/${data.actionScriptId}`
|
|
3723
|
+
};
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
];
|
|
3676
3727
|
var workflowTools = [
|
|
3677
3728
|
{
|
|
3678
3729
|
name: "muggle-remote-workflow-start-website-scan",
|
|
3679
|
-
description: "Scan a website to automatically discover testable user flows and UI interactions. Crawls the site and identifies use cases like signup, login, search, checkout, form submissions, and navigation patterns. Use this when setting up
|
|
3730
|
+
description: "Scan a website to automatically discover testable user flows and UI interactions. Crawls the site and identifies use cases like signup, login, search, checkout, form submissions, and navigation patterns. Use this when setting up E2E acceptance testing for a site without predefined test cases.",
|
|
3680
3731
|
inputSchema: WorkflowStartWebsiteScanInputSchema,
|
|
3681
3732
|
mapToUpstream: (input) => {
|
|
3682
3733
|
const data = input;
|
|
@@ -4499,7 +4550,7 @@ var apiKeyTools = [
|
|
|
4499
4550
|
},
|
|
4500
4551
|
{
|
|
4501
4552
|
name: "muggle-remote-auth-api-key-revoke",
|
|
4502
|
-
description: "Revoke an API key. The key will immediately stop working. Use
|
|
4553
|
+
description: "Revoke an API key. The key will immediately stop working. Use muggle-remote-auth-api-key-list to find the key ID first.",
|
|
4503
4554
|
inputSchema: ApiKeyRevokeInputSchema,
|
|
4504
4555
|
mapToUpstream: (input) => {
|
|
4505
4556
|
const data = input;
|
|
@@ -4641,6 +4692,7 @@ var allQaToolDefinitions = [
|
|
|
4641
4692
|
...useCaseTools,
|
|
4642
4693
|
...testCaseTools,
|
|
4643
4694
|
...testScriptTools,
|
|
4695
|
+
...actionScriptTools,
|
|
4644
4696
|
...workflowTools,
|
|
4645
4697
|
...reportTools,
|
|
4646
4698
|
...secretTools,
|
|
@@ -4717,15 +4769,15 @@ async function executeQaTool(toolName, input, correlationId) {
|
|
|
4717
4769
|
}
|
|
4718
4770
|
}
|
|
4719
4771
|
|
|
4720
|
-
// packages/mcps/src/mcp/tools/
|
|
4721
|
-
var
|
|
4722
|
-
__export(
|
|
4772
|
+
// packages/mcps/src/mcp/tools/e2e/index.ts
|
|
4773
|
+
var e2e_exports = {};
|
|
4774
|
+
__export(e2e_exports, {
|
|
4723
4775
|
allQaToolDefinitions: () => allQaToolDefinitions,
|
|
4724
4776
|
executeQaTool: () => executeQaTool,
|
|
4725
4777
|
getQaToolByName: () => getQaToolByName
|
|
4726
4778
|
});
|
|
4727
4779
|
|
|
4728
|
-
// packages/mcps/src/mcp/
|
|
4780
|
+
// packages/mcps/src/mcp/e2e/index.ts
|
|
4729
4781
|
function getQaTools() {
|
|
4730
4782
|
return allQaToolDefinitions.map((tool) => ({
|
|
4731
4783
|
name: tool.name,
|
|
@@ -4759,6 +4811,7 @@ __export(local_exports2, {
|
|
|
4759
4811
|
LocalTestScriptStatus: () => LocalTestScriptStatus,
|
|
4760
4812
|
LocalWorkflowFileEntityType: () => LocalWorkflowFileEntityType,
|
|
4761
4813
|
LocalWorkflowRunStatus: () => LocalWorkflowRunStatus,
|
|
4814
|
+
MuggleEntityIdSchema: () => MuggleEntityIdSchema,
|
|
4762
4815
|
PublishTestScriptInputSchema: () => PublishTestScriptInputSchema,
|
|
4763
4816
|
RunResultGetInputSchema: () => RunResultGetInputSchema,
|
|
4764
4817
|
RunResultListInputSchema: () => RunResultListInputSchema,
|
|
@@ -4803,7 +4856,7 @@ var AuthPollInputSchema2 = z.object({
|
|
|
4803
4856
|
var EmptyInputSchema2 = z.object({});
|
|
4804
4857
|
var TestCaseDetailsSchema = z.object({
|
|
4805
4858
|
/** Cloud test case ID. */
|
|
4806
|
-
id:
|
|
4859
|
+
id: MuggleEntityIdSchema.describe("Cloud test case ID (UUID)"),
|
|
4807
4860
|
/** Test case title. */
|
|
4808
4861
|
title: z.string().min(1).describe("Test case title"),
|
|
4809
4862
|
/** Test goal. */
|
|
@@ -4817,69 +4870,73 @@ var TestCaseDetailsSchema = z.object({
|
|
|
4817
4870
|
/** Original cloud URL (for reference, replaced by localUrl). */
|
|
4818
4871
|
url: z.string().url().optional().describe("Original cloud URL (replaced by localUrl during execution)"),
|
|
4819
4872
|
/** Cloud project ID (required for electron workflow context). */
|
|
4820
|
-
projectId:
|
|
4873
|
+
projectId: MuggleEntityIdSchema.describe("Cloud project ID (UUID)"),
|
|
4821
4874
|
/** Cloud use case ID (required for electron workflow context). */
|
|
4822
|
-
useCaseId:
|
|
4875
|
+
useCaseId: MuggleEntityIdSchema.describe("Cloud use case ID (UUID)")
|
|
4823
4876
|
});
|
|
4824
4877
|
var TestScriptDetailsSchema = z.object({
|
|
4825
4878
|
/** Cloud test script ID. */
|
|
4826
|
-
id:
|
|
4879
|
+
id: MuggleEntityIdSchema.describe("Cloud test script ID (UUID)"),
|
|
4827
4880
|
/** Script name. */
|
|
4828
4881
|
name: z.string().min(1).describe("Test script name"),
|
|
4829
4882
|
/** Cloud test case ID this script belongs to. */
|
|
4830
|
-
testCaseId:
|
|
4831
|
-
/** Action script
|
|
4832
|
-
|
|
4883
|
+
testCaseId: MuggleEntityIdSchema.describe("Cloud test case ID (UUID) this script was generated from"),
|
|
4884
|
+
/** Action script ID reference (use muggle-remote-action-script-get to fetch content). */
|
|
4885
|
+
actionScriptId: MuggleEntityIdSchema.describe(
|
|
4886
|
+
"Action script ID (UUID) \u2014 use muggle-remote-action-script-get to fetch the full script"
|
|
4887
|
+
),
|
|
4833
4888
|
/** Original cloud URL (for reference, replaced by localUrl). */
|
|
4834
4889
|
url: z.string().url().optional().describe("Original cloud URL (replaced by localUrl during execution)"),
|
|
4835
4890
|
/** Cloud project ID (required for electron workflow context). */
|
|
4836
|
-
projectId:
|
|
4891
|
+
projectId: MuggleEntityIdSchema.describe("Cloud project ID (UUID)"),
|
|
4837
4892
|
/** Cloud use case ID (required for electron workflow context). */
|
|
4838
|
-
useCaseId:
|
|
4893
|
+
useCaseId: MuggleEntityIdSchema.describe("Cloud use case ID (UUID)")
|
|
4839
4894
|
});
|
|
4840
4895
|
var ExecuteTestGenerationInputSchema = z.object({
|
|
4841
|
-
/** Test case details from
|
|
4842
|
-
testCase: TestCaseDetailsSchema.describe("Test case details obtained from
|
|
4896
|
+
/** Test case details from muggle-remote-test-case-get. */
|
|
4897
|
+
testCase: TestCaseDetailsSchema.describe("Test case details obtained from muggle-remote-test-case-get"),
|
|
4843
4898
|
/** Local URL to test against. */
|
|
4844
4899
|
localUrl: z.string().url().describe("Local URL to test against (e.g., http://localhost:3000)"),
|
|
4845
4900
|
/** Explicit approval to launch electron-app. */
|
|
4846
4901
|
approveElectronAppLaunch: z.boolean().describe("Set to true after the user explicitly approves launching electron-app"),
|
|
4847
4902
|
/** Optional timeout. */
|
|
4848
4903
|
timeoutMs: z.number().int().positive().optional().describe("Timeout in milliseconds (default: 300000 = 5 min)"),
|
|
4849
|
-
/** Show the electron-app UI during execution. */
|
|
4850
|
-
showUi: z.boolean().optional().describe("Show the electron-app UI during
|
|
4904
|
+
/** Show the electron-app UI during execution. Ask the user before approving; true = visible window, false or omit = headless. */
|
|
4905
|
+
showUi: z.boolean().optional().describe("Show the electron-app UI during generation. Ask the user: true to watch the window, false or omit for headless.")
|
|
4851
4906
|
});
|
|
4852
4907
|
var ExecuteReplayInputSchema = z.object({
|
|
4853
|
-
/** Test script
|
|
4854
|
-
testScript: TestScriptDetailsSchema.describe("Test script
|
|
4908
|
+
/** Test script metadata from muggle-remote-test-script-get. */
|
|
4909
|
+
testScript: TestScriptDetailsSchema.describe("Test script metadata from muggle-remote-test-script-get"),
|
|
4910
|
+
/** Action script content from muggle-remote-action-script-get (using testScript.actionScriptId). */
|
|
4911
|
+
actionScript: z.array(z.unknown()).describe("Action script steps from muggle-remote-action-script-get"),
|
|
4855
4912
|
/** Local URL to test against. */
|
|
4856
4913
|
localUrl: z.string().url().describe("Local URL to test against (e.g., http://localhost:3000)"),
|
|
4857
4914
|
/** Explicit approval to launch electron-app. */
|
|
4858
4915
|
approveElectronAppLaunch: z.boolean().describe("Set to true after the user explicitly approves launching electron-app"),
|
|
4859
4916
|
/** Optional timeout. */
|
|
4860
4917
|
timeoutMs: z.number().int().positive().optional().describe("Timeout in milliseconds (default: 180000 = 3 min)"),
|
|
4861
|
-
/** Show the electron-app UI during execution. */
|
|
4862
|
-
showUi: z.boolean().optional().describe("Show the electron-app UI during
|
|
4918
|
+
/** Show the electron-app UI during execution. Ask the user before approving; true = visible window, false or omit = headless. */
|
|
4919
|
+
showUi: z.boolean().optional().describe("Show the electron-app UI during replay. Ask the user: true to watch the window, false or omit for headless.")
|
|
4863
4920
|
});
|
|
4864
4921
|
var CancelExecutionInputSchema = z.object({
|
|
4865
|
-
runId:
|
|
4922
|
+
runId: MuggleEntityIdSchema.describe("Run ID (UUID) to cancel")
|
|
4866
4923
|
});
|
|
4867
4924
|
var RunResultListInputSchema = z.object({
|
|
4868
|
-
cloudTestCaseId:
|
|
4925
|
+
cloudTestCaseId: MuggleEntityIdSchema.optional().describe("Optional cloud test case ID (UUID) to filter by"),
|
|
4869
4926
|
limit: z.number().int().positive().optional().describe("Maximum results to return (default: 20)")
|
|
4870
4927
|
});
|
|
4871
4928
|
var RunResultGetInputSchema = z.object({
|
|
4872
|
-
runId:
|
|
4929
|
+
runId: MuggleEntityIdSchema.describe("Run result ID (UUID) to retrieve")
|
|
4873
4930
|
});
|
|
4874
4931
|
var TestScriptListInputSchema2 = z.object({
|
|
4875
|
-
cloudTestCaseId:
|
|
4932
|
+
cloudTestCaseId: MuggleEntityIdSchema.optional().describe("Optional cloud test case ID (UUID) to filter by")
|
|
4876
4933
|
});
|
|
4877
4934
|
var TestScriptGetInputSchema2 = z.object({
|
|
4878
|
-
testScriptId:
|
|
4935
|
+
testScriptId: MuggleEntityIdSchema.describe("Local stored test script ID (UUID) to retrieve")
|
|
4879
4936
|
});
|
|
4880
4937
|
var PublishTestScriptInputSchema = z.object({
|
|
4881
|
-
runId:
|
|
4882
|
-
cloudTestCaseId:
|
|
4938
|
+
runId: MuggleEntityIdSchema.describe("Local run result ID (UUID) from muggle_execute_test_generation"),
|
|
4939
|
+
cloudTestCaseId: MuggleEntityIdSchema.describe("Cloud test case ID (UUID) to publish the script under")
|
|
4883
4940
|
});
|
|
4884
4941
|
var ListSessionsInputSchema = z.object({
|
|
4885
4942
|
limit: z.number().int().positive().optional().describe("Maximum number of sessions to return. Defaults to 10.")
|
|
@@ -5099,14 +5156,15 @@ var testScriptGetTool = {
|
|
|
5099
5156
|
};
|
|
5100
5157
|
var executeTestGenerationTool = {
|
|
5101
5158
|
name: "muggle-local-execute-test-generation",
|
|
5102
|
-
description: "Generate
|
|
5159
|
+
description: "Generate an end-to-end (E2E) acceptance test script by launching a real browser against your web app. The browser navigates your app, executes the test case steps (like signing up, filling forms, clicking through flows), and produces a replayable test script with screenshots. Use this to create new browser tests for any user flow. Requires a test case (from muggle-remote-test-case-get) and a localhost URL. Launches an Electron browser \u2014 requires explicit approval via approveElectronAppLaunch. Before approving, ask the user whether they want a visible GUI; pass showUi: true to watch the window or showUi: false for headless (default when omitted).",
|
|
5103
5160
|
inputSchema: ExecuteTestGenerationInputSchema,
|
|
5104
5161
|
execute: async (ctx) => {
|
|
5105
5162
|
const logger14 = createChildLogger2(ctx.correlationId);
|
|
5106
5163
|
logger14.info("Executing muggle-local-execute-test-generation");
|
|
5107
5164
|
const input = ExecuteTestGenerationInputSchema.parse(ctx.input);
|
|
5108
5165
|
if (!input.approveElectronAppLaunch) {
|
|
5109
|
-
const
|
|
5166
|
+
const showUiExplicit = input.showUi !== void 0;
|
|
5167
|
+
const uiMode = input.showUi === true ? "visible GUI (showUi: true)" : "headless (showUi: false or omitted)";
|
|
5110
5168
|
return {
|
|
5111
5169
|
content: [
|
|
5112
5170
|
"## Electron App Launch Required",
|
|
@@ -5114,22 +5172,28 @@ var executeTestGenerationTool = {
|
|
|
5114
5172
|
"This tool will launch the electron-app to generate a test script.",
|
|
5115
5173
|
"Please set `approveElectronAppLaunch: true` to proceed.",
|
|
5116
5174
|
"",
|
|
5175
|
+
"**Visible GUI:** Ask the user whether they want to watch the Electron window during generation.",
|
|
5176
|
+
"- If **yes** \u2192 when approving, pass `showUi: true`.",
|
|
5177
|
+
"- If **no** \u2192 when approving, pass `showUi: false` (or omit `showUi`; generation runs headless).",
|
|
5178
|
+
"",
|
|
5179
|
+
showUiExplicit ? `**Current choice:** ${uiMode}` : "**Current choice:** not set \u2014 default on approval is headless unless you pass `showUi: true`.",
|
|
5180
|
+
"",
|
|
5117
5181
|
`**Test Case:** ${input.testCase.title}`,
|
|
5118
5182
|
`**Local URL:** ${input.localUrl}`,
|
|
5119
|
-
`**UI Mode:** ${uiMode}`,
|
|
5120
5183
|
"",
|
|
5121
|
-
"**Note:** The electron-app will
|
|
5184
|
+
"**Note:** The electron-app will navigate your test URL and record steps."
|
|
5122
5185
|
].join("\n"),
|
|
5123
5186
|
isError: false,
|
|
5124
5187
|
data: { requiresApproval: true }
|
|
5125
5188
|
};
|
|
5126
5189
|
}
|
|
5190
|
+
const showUi = input.showUi === true;
|
|
5127
5191
|
try {
|
|
5128
5192
|
const result = await executeTestGeneration({
|
|
5129
5193
|
testCase: input.testCase,
|
|
5130
5194
|
localUrl: input.localUrl,
|
|
5131
5195
|
timeoutMs: input.timeoutMs,
|
|
5132
|
-
showUi
|
|
5196
|
+
showUi
|
|
5133
5197
|
});
|
|
5134
5198
|
const content = [
|
|
5135
5199
|
"## Test Generation " + (result.status === "passed" ? "Successful" : "Failed"),
|
|
@@ -5138,6 +5202,7 @@ var executeTestGenerationTool = {
|
|
|
5138
5202
|
`**Test Script ID:** ${result.testScriptId}`,
|
|
5139
5203
|
`**Status:** ${result.status}`,
|
|
5140
5204
|
`**Duration:** ${result.executionTimeMs}ms`,
|
|
5205
|
+
`**UI:** ${showUi ? "visible GUI" : "headless"}`,
|
|
5141
5206
|
result.errorMessage ? `**Error:** ${result.errorMessage}` : ""
|
|
5142
5207
|
].filter(Boolean).join("\n");
|
|
5143
5208
|
return {
|
|
@@ -5154,14 +5219,15 @@ var executeTestGenerationTool = {
|
|
|
5154
5219
|
};
|
|
5155
5220
|
var executeReplayTool = {
|
|
5156
5221
|
name: "muggle-local-execute-replay",
|
|
5157
|
-
description: "Replay an existing
|
|
5222
|
+
description: "Replay an existing E2E acceptance test script in a real browser to verify your app still works correctly \u2014 use this for regression testing after code changes. The browser executes each saved step and captures screenshots so you can see what happened. Requires: (1) test script metadata from muggle-remote-test-script-get, (2) actionScript content from muggle-remote-action-script-get using the testScript.actionScriptId, and (3) a localhost URL. Launches an Electron browser \u2014 requires explicit approval via approveElectronAppLaunch. Before approving, ask the user whether they want a visible GUI; pass showUi: true to watch the window or showUi: false for headless (default when omitted).",
|
|
5158
5223
|
inputSchema: ExecuteReplayInputSchema,
|
|
5159
5224
|
execute: async (ctx) => {
|
|
5160
5225
|
const logger14 = createChildLogger2(ctx.correlationId);
|
|
5161
5226
|
logger14.info("Executing muggle-local-execute-replay");
|
|
5162
5227
|
const input = ExecuteReplayInputSchema.parse(ctx.input);
|
|
5163
5228
|
if (!input.approveElectronAppLaunch) {
|
|
5164
|
-
const
|
|
5229
|
+
const showUiExplicit = input.showUi !== void 0;
|
|
5230
|
+
const uiMode = input.showUi === true ? "visible GUI (showUi: true)" : "headless (showUi: false or omitted)";
|
|
5165
5231
|
return {
|
|
5166
5232
|
content: [
|
|
5167
5233
|
"## Electron App Launch Required",
|
|
@@ -5169,23 +5235,30 @@ var executeReplayTool = {
|
|
|
5169
5235
|
"This tool will launch the electron-app to replay a test script.",
|
|
5170
5236
|
"Please set `approveElectronAppLaunch: true` to proceed.",
|
|
5171
5237
|
"",
|
|
5238
|
+
"**Visible GUI:** Ask the user whether they want to watch the Electron window during replay.",
|
|
5239
|
+
"- If **yes** \u2192 when approving, pass `showUi: true`.",
|
|
5240
|
+
"- If **no** \u2192 when approving, pass `showUi: false` (or omit `showUi`; replay runs headless).",
|
|
5241
|
+
"",
|
|
5242
|
+
showUiExplicit ? `**Current choice:** ${uiMode}` : "**Current choice:** not set \u2014 default on approval is headless unless you pass `showUi: true`.",
|
|
5243
|
+
"",
|
|
5172
5244
|
`**Test Script:** ${input.testScript.name}`,
|
|
5173
5245
|
`**Local URL:** ${input.localUrl}`,
|
|
5174
|
-
`**Steps:** ${input.
|
|
5175
|
-
`**UI Mode:** ${uiMode}`,
|
|
5246
|
+
`**Steps:** ${input.actionScript.length}`,
|
|
5176
5247
|
"",
|
|
5177
|
-
"**Note:** The electron-app will
|
|
5248
|
+
"**Note:** The electron-app will execute the test steps against your local URL."
|
|
5178
5249
|
].join("\n"),
|
|
5179
5250
|
isError: false,
|
|
5180
5251
|
data: { requiresApproval: true }
|
|
5181
5252
|
};
|
|
5182
5253
|
}
|
|
5254
|
+
const showUi = input.showUi === true;
|
|
5183
5255
|
try {
|
|
5184
5256
|
const result = await executeReplay({
|
|
5185
5257
|
testScript: input.testScript,
|
|
5258
|
+
actionScript: input.actionScript,
|
|
5186
5259
|
localUrl: input.localUrl,
|
|
5187
5260
|
timeoutMs: input.timeoutMs,
|
|
5188
|
-
showUi
|
|
5261
|
+
showUi
|
|
5189
5262
|
});
|
|
5190
5263
|
const content = [
|
|
5191
5264
|
"## Test Replay " + (result.status === "passed" ? "Successful" : "Failed"),
|
|
@@ -5194,6 +5267,7 @@ var executeReplayTool = {
|
|
|
5194
5267
|
`**Test Script ID:** ${result.testScriptId}`,
|
|
5195
5268
|
`**Status:** ${result.status}`,
|
|
5196
5269
|
`**Duration:** ${result.executionTimeMs}ms`,
|
|
5270
|
+
`**UI:** ${showUi ? "visible GUI" : "headless"}`,
|
|
5197
5271
|
result.errorMessage ? `**Error:** ${result.errorMessage}` : ""
|
|
5198
5272
|
].filter(Boolean).join("\n");
|
|
5199
5273
|
return {
|
|
@@ -5225,7 +5299,7 @@ var cancelExecutionTool = {
|
|
|
5225
5299
|
};
|
|
5226
5300
|
var publishTestScriptTool = {
|
|
5227
5301
|
name: "muggle-local-publish-test-script",
|
|
5228
|
-
description: "Publish a locally generated test script to the cloud. Uses the run ID from muggle_execute_test_generation to find the script and uploads it to the specified cloud test case.",
|
|
5302
|
+
description: "Publish a locally generated test script to the cloud. Uses the run ID from muggle_execute_test_generation to find the script and uploads it to the specified cloud test case. Returns a viewUrl that can be opened in the user's browser to view the published test script on the dashboard.",
|
|
5229
5303
|
inputSchema: PublishTestScriptInputSchema,
|
|
5230
5304
|
execute: async (ctx) => {
|
|
5231
5305
|
const logger14 = createChildLogger2(ctx.correlationId);
|
|
@@ -5432,9 +5506,10 @@ function isLocalOnlyTool(toolName) {
|
|
|
5432
5506
|
var mcp_exports = {};
|
|
5433
5507
|
__export(mcp_exports, {
|
|
5434
5508
|
agents: () => agents_exports,
|
|
5509
|
+
e2e: () => e2e_exports2,
|
|
5435
5510
|
localQa: () => local_exports2,
|
|
5436
5511
|
plugins: () => plugins_exports,
|
|
5437
|
-
qa: () =>
|
|
5512
|
+
qa: () => e2e_exports2,
|
|
5438
5513
|
skills: () => skills_exports,
|
|
5439
5514
|
tools: () => tools_exports
|
|
5440
5515
|
});
|
|
@@ -5442,8 +5517,9 @@ __export(mcp_exports, {
|
|
|
5442
5517
|
// packages/mcps/src/mcp/tools/index.ts
|
|
5443
5518
|
var tools_exports = {};
|
|
5444
5519
|
__export(tools_exports, {
|
|
5520
|
+
e2e: () => e2e_exports,
|
|
5445
5521
|
localQa: () => local_exports,
|
|
5446
|
-
qa: () =>
|
|
5522
|
+
qa: () => e2e_exports
|
|
5447
5523
|
});
|
|
5448
5524
|
|
|
5449
5525
|
// packages/mcps/src/mcp/skills/index.ts
|
|
@@ -5458,11 +5534,15 @@ var agents_exports = {};
|
|
|
5458
5534
|
// packages/mcps/src/index.ts
|
|
5459
5535
|
var src_exports = {};
|
|
5460
5536
|
__export(src_exports, {
|
|
5537
|
+
buildElectronAppChecksumsUrl: () => buildElectronAppChecksumsUrl,
|
|
5538
|
+
buildElectronAppReleaseAssetUrl: () => buildElectronAppReleaseAssetUrl,
|
|
5539
|
+
buildElectronAppReleaseTag: () => buildElectronAppReleaseTag,
|
|
5461
5540
|
calculateFileChecksum: () => calculateFileChecksum,
|
|
5462
5541
|
createApiKeyWithToken: () => createApiKeyWithToken,
|
|
5463
5542
|
createChildLogger: () => createChildLogger,
|
|
5464
5543
|
deleteApiKeyData: () => deleteApiKeyData,
|
|
5465
5544
|
deleteCredentials: () => deleteCredentials,
|
|
5545
|
+
e2e: () => e2e_exports2,
|
|
5466
5546
|
getApiKey: () => getApiKey,
|
|
5467
5547
|
getApiKeyFilePath: () => getApiKeyFilePath,
|
|
5468
5548
|
getAuthService: () => getAuthService,
|
|
@@ -5494,7 +5574,7 @@ __export(src_exports, {
|
|
|
5494
5574
|
performLogin: () => performLogin,
|
|
5495
5575
|
performLogout: () => performLogout,
|
|
5496
5576
|
pollDeviceCode: () => pollDeviceCode,
|
|
5497
|
-
qa: () =>
|
|
5577
|
+
qa: () => e2e_exports2,
|
|
5498
5578
|
resetConfig: () => resetConfig,
|
|
5499
5579
|
resetLogger: () => resetLogger,
|
|
5500
5580
|
saveApiKey: () => saveApiKey,
|
|
@@ -5601,6 +5681,12 @@ function clearTools() {
|
|
|
5601
5681
|
registeredTools = [];
|
|
5602
5682
|
}
|
|
5603
5683
|
function zodToJsonSchema(schema) {
|
|
5684
|
+
try {
|
|
5685
|
+
if (schema && typeof schema === "object" && "safeParse" in schema) {
|
|
5686
|
+
return z.toJSONSchema(schema);
|
|
5687
|
+
}
|
|
5688
|
+
} catch {
|
|
5689
|
+
}
|
|
5604
5690
|
try {
|
|
5605
5691
|
const zodSchema = schema;
|
|
5606
5692
|
if (zodSchema._def) {
|
|
@@ -5620,10 +5706,12 @@ function convertZodDef(schema) {
|
|
|
5620
5706
|
return { type: "object" };
|
|
5621
5707
|
}
|
|
5622
5708
|
const def = zodSchema._def;
|
|
5623
|
-
const typeName = def.typeName;
|
|
5709
|
+
const typeName = def.typeName ?? def.type;
|
|
5624
5710
|
switch (typeName) {
|
|
5625
|
-
case "ZodObject":
|
|
5626
|
-
|
|
5711
|
+
case "ZodObject":
|
|
5712
|
+
case "object": {
|
|
5713
|
+
const shapeFromDef = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
5714
|
+
const shape = shapeFromDef || zodSchema.shape || {};
|
|
5627
5715
|
const properties = {};
|
|
5628
5716
|
const required = [];
|
|
5629
5717
|
for (const [key, value] of Object.entries(shape)) {
|
|
@@ -5642,7 +5730,8 @@ function convertZodDef(schema) {
|
|
|
5642
5730
|
}
|
|
5643
5731
|
return result;
|
|
5644
5732
|
}
|
|
5645
|
-
case "ZodString":
|
|
5733
|
+
case "ZodString":
|
|
5734
|
+
case "string": {
|
|
5646
5735
|
const result = { type: "string" };
|
|
5647
5736
|
if (def.description) result.description = def.description;
|
|
5648
5737
|
if (def.checks) {
|
|
@@ -5655,7 +5744,8 @@ function convertZodDef(schema) {
|
|
|
5655
5744
|
}
|
|
5656
5745
|
return result;
|
|
5657
5746
|
}
|
|
5658
|
-
case "ZodNumber":
|
|
5747
|
+
case "ZodNumber":
|
|
5748
|
+
case "number": {
|
|
5659
5749
|
const result = { type: "number" };
|
|
5660
5750
|
if (def.description) result.description = def.description;
|
|
5661
5751
|
if (def.checks) {
|
|
@@ -5667,28 +5757,33 @@ function convertZodDef(schema) {
|
|
|
5667
5757
|
}
|
|
5668
5758
|
return result;
|
|
5669
5759
|
}
|
|
5670
|
-
case "ZodBoolean":
|
|
5760
|
+
case "ZodBoolean":
|
|
5761
|
+
case "boolean": {
|
|
5671
5762
|
const result = { type: "boolean" };
|
|
5672
5763
|
if (def.description) result.description = def.description;
|
|
5673
5764
|
return result;
|
|
5674
5765
|
}
|
|
5675
|
-
case "ZodArray":
|
|
5766
|
+
case "ZodArray":
|
|
5767
|
+
case "array": {
|
|
5676
5768
|
const result = {
|
|
5677
5769
|
type: "array",
|
|
5678
|
-
items: def.innerType ? convertZodDef(def.innerType) : {}
|
|
5770
|
+
items: def.innerType ? convertZodDef(def.innerType) : def.element ? convertZodDef(def.element) : {}
|
|
5679
5771
|
};
|
|
5680
5772
|
if (def.description) result.description = def.description;
|
|
5681
5773
|
return result;
|
|
5682
5774
|
}
|
|
5683
|
-
case "ZodEnum":
|
|
5775
|
+
case "ZodEnum":
|
|
5776
|
+
case "enum": {
|
|
5777
|
+
const enumValues = Array.isArray(def.values) ? def.values : def.values ? Object.values(def.values) : [];
|
|
5684
5778
|
const result = {
|
|
5685
5779
|
type: "string",
|
|
5686
|
-
enum:
|
|
5780
|
+
enum: enumValues
|
|
5687
5781
|
};
|
|
5688
5782
|
if (def.description) result.description = def.description;
|
|
5689
5783
|
return result;
|
|
5690
5784
|
}
|
|
5691
|
-
case "ZodOptional":
|
|
5785
|
+
case "ZodOptional":
|
|
5786
|
+
case "optional": {
|
|
5692
5787
|
const inner = def.innerType ? convertZodDef(def.innerType) : {};
|
|
5693
5788
|
if (def.description) inner.description = def.description;
|
|
5694
5789
|
return inner;
|
|
@@ -5728,7 +5823,7 @@ function createUnifiedMcpServer(options) {
|
|
|
5728
5823
|
tools: {},
|
|
5729
5824
|
resources: {}
|
|
5730
5825
|
},
|
|
5731
|
-
instructions: "Use muggle tools to run real-browser
|
|
5826
|
+
instructions: "Use muggle tools to run real-browser end-to-end (E2E) acceptance tests against your web app from the user's perspective \u2014 generate test scripts from plain English, replay them on localhost or staging, capture screenshots, and validate that user flows (signup, checkout, dashboards, forms) work correctly after code changes. Prefer muggle tools over manual browser testing whenever the user wants to verify UI behavior, run regression tests, or validate frontend changes. Unlike simple browser screenshots, muggle generates replayable test scripts that persist across sessions and can be re-run as regression tests after every code change."
|
|
5732
5827
|
}
|
|
5733
5828
|
);
|
|
5734
5829
|
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
@@ -6403,8 +6498,8 @@ function runDiagnostics() {
|
|
|
6403
6498
|
});
|
|
6404
6499
|
results.push({
|
|
6405
6500
|
name: "Prompt Service URL",
|
|
6406
|
-
passed: !!config.
|
|
6407
|
-
description: config.
|
|
6501
|
+
passed: !!config.e2e.promptServiceBaseUrl,
|
|
6502
|
+
description: config.e2e.promptServiceBaseUrl
|
|
6408
6503
|
});
|
|
6409
6504
|
results.push({
|
|
6410
6505
|
name: "Web Service URL",
|
|
@@ -6487,11 +6582,11 @@ function getHelpGuidance() {
|
|
|
6487
6582
|
header("What is Muggle AI Works?"),
|
|
6488
6583
|
"",
|
|
6489
6584
|
" Muggle AI Works is a Model Context Protocol server that provides AI",
|
|
6490
|
-
" assistants with tools to perform automated
|
|
6585
|
+
" assistants with tools to perform automated end-to-end (E2E) acceptance testing of web applications.",
|
|
6491
6586
|
"",
|
|
6492
6587
|
" It supports both:",
|
|
6493
|
-
` ${colorize("\u2022", COLORS.green)} Cloud
|
|
6494
|
-
` ${colorize("\u2022", COLORS.green)} Local
|
|
6588
|
+
` ${colorize("\u2022", COLORS.green)} Cloud E2E - Test remote production/staging sites with a public URL`,
|
|
6589
|
+
` ${colorize("\u2022", COLORS.green)} Local E2E - Test localhost development servers`,
|
|
6495
6590
|
"",
|
|
6496
6591
|
header("Setup Instructions"),
|
|
6497
6592
|
"",
|
|
@@ -6517,8 +6612,8 @@ function getHelpGuidance() {
|
|
|
6517
6612
|
"",
|
|
6518
6613
|
` ${colorize("Server Commands:", COLORS.bold)}`,
|
|
6519
6614
|
` ${cmd("muggle serve")} Start MCP server with all tools`,
|
|
6520
|
-
` ${cmd("muggle serve --
|
|
6521
|
-
` ${cmd("muggle serve --local")} Start with
|
|
6615
|
+
` ${cmd("muggle serve --e2e")} Start with cloud E2E tools only`,
|
|
6616
|
+
` ${cmd("muggle serve --local")} Start with local E2E tools only`,
|
|
6522
6617
|
"",
|
|
6523
6618
|
` ${colorize("Setup & Diagnostics:", COLORS.bold)}`,
|
|
6524
6619
|
` ${cmd("muggle setup")} Download/update Electron app`,
|
|
@@ -6556,14 +6651,14 @@ function getHelpGuidance() {
|
|
|
6556
6651
|
"",
|
|
6557
6652
|
header("Available MCP Tools"),
|
|
6558
6653
|
"",
|
|
6559
|
-
` ${colorize("Cloud
|
|
6560
|
-
"
|
|
6561
|
-
"
|
|
6654
|
+
` ${colorize("Cloud E2E tools:", COLORS.bold)} (prefix: muggle-remote-)`,
|
|
6655
|
+
" muggle-remote-project-create, muggle-remote-project-list, muggle-remote-use-case-create-from-prompts,",
|
|
6656
|
+
" muggle-remote-test-case-generate-from-prompt, muggle-remote-workflow-start-*, etc.",
|
|
6562
6657
|
"",
|
|
6563
|
-
` ${colorize("Local
|
|
6564
|
-
"
|
|
6565
|
-
"
|
|
6566
|
-
"
|
|
6658
|
+
` ${colorize("Local E2E tools:", COLORS.bold)} (prefix: muggle-local-)`,
|
|
6659
|
+
" muggle-local-execute-test-generation, muggle-local-execute-replay,",
|
|
6660
|
+
" muggle-local-publish-test-script, muggle-local-run-result-get,",
|
|
6661
|
+
" muggle-local-check-status, etc.",
|
|
6567
6662
|
"",
|
|
6568
6663
|
header("Data Directory"),
|
|
6569
6664
|
"",
|
|
@@ -6674,7 +6769,7 @@ var logger10 = getLogger();
|
|
|
6674
6769
|
async function serveCommand(options) {
|
|
6675
6770
|
const config = getConfig();
|
|
6676
6771
|
const enableQa = options.local ? false : true;
|
|
6677
|
-
const enableLocal = options.
|
|
6772
|
+
const enableLocal = options.e2e ? false : true;
|
|
6678
6773
|
logger10.info("Starting Muggle MCP Server", {
|
|
6679
6774
|
version: config.serverVersion,
|
|
6680
6775
|
enableQa,
|
|
@@ -6685,12 +6780,12 @@ async function serveCommand(options) {
|
|
|
6685
6780
|
if (enableQa) {
|
|
6686
6781
|
const qaTools = getQaTools();
|
|
6687
6782
|
registerTools(qaTools);
|
|
6688
|
-
logger10.info("Registered
|
|
6783
|
+
logger10.info("Registered cloud E2E acceptance tools", { count: qaTools.length });
|
|
6689
6784
|
}
|
|
6690
6785
|
if (enableLocal) {
|
|
6691
6786
|
const localTools = getLocalQaTools();
|
|
6692
6787
|
registerTools(localTools);
|
|
6693
|
-
logger10.info("Registered
|
|
6788
|
+
logger10.info("Registered local E2E acceptance tools", { count: localTools.length });
|
|
6694
6789
|
}
|
|
6695
6790
|
const mcpServer = createUnifiedMcpServer({
|
|
6696
6791
|
enableQaTools: enableQa,
|
|
@@ -6832,7 +6927,6 @@ function cleanupFailedInstall(versionDir) {
|
|
|
6832
6927
|
}
|
|
6833
6928
|
async function setupCommand(options) {
|
|
6834
6929
|
const version = getElectronAppVersion();
|
|
6835
|
-
const baseUrl = getDownloadBaseUrl();
|
|
6836
6930
|
const versionDir = getElectronAppDir(version);
|
|
6837
6931
|
const platformKey = getPlatformKey();
|
|
6838
6932
|
if (!options.force && isElectronAppInstalled()) {
|
|
@@ -6841,7 +6935,10 @@ async function setupCommand(options) {
|
|
|
6841
6935
|
return;
|
|
6842
6936
|
}
|
|
6843
6937
|
const binaryName = getBinaryName();
|
|
6844
|
-
const downloadUrl =
|
|
6938
|
+
const downloadUrl = buildElectronAppReleaseAssetUrl({
|
|
6939
|
+
version,
|
|
6940
|
+
assetFileName: binaryName
|
|
6941
|
+
});
|
|
6845
6942
|
console.log(`Downloading Muggle Test Electron app v${version}...`);
|
|
6846
6943
|
console.log(`URL: ${downloadUrl}`);
|
|
6847
6944
|
try {
|
|
@@ -6923,7 +7020,7 @@ function getBinaryName2() {
|
|
|
6923
7020
|
}
|
|
6924
7021
|
}
|
|
6925
7022
|
function extractVersionFromTag(tag) {
|
|
6926
|
-
const match = tag.match(/^electron-app-v(\d+\.\d+\.\d+)$/);
|
|
7023
|
+
const match = tag.match(/^(?:electron-app-)?v(\d+\.\d+\.\d+)$/);
|
|
6927
7024
|
return match ? match[1] : null;
|
|
6928
7025
|
}
|
|
6929
7026
|
function getVersionOverridePath() {
|
|
@@ -6973,13 +7070,15 @@ async function checkForUpdates() {
|
|
|
6973
7070
|
const version = extractVersionFromTag(release2.tag_name);
|
|
6974
7071
|
if (version) {
|
|
6975
7072
|
const updateAvailable = compareVersions2(version, currentVersion) > 0;
|
|
6976
|
-
const baseUrl = getDownloadBaseUrl();
|
|
6977
7073
|
const binaryName = getBinaryName2();
|
|
6978
7074
|
return {
|
|
6979
7075
|
currentVersion,
|
|
6980
7076
|
latestVersion: version,
|
|
6981
7077
|
updateAvailable,
|
|
6982
|
-
downloadUrl:
|
|
7078
|
+
downloadUrl: buildElectronAppReleaseAssetUrl({
|
|
7079
|
+
version,
|
|
7080
|
+
assetFileName: binaryName
|
|
7081
|
+
})
|
|
6983
7082
|
};
|
|
6984
7083
|
}
|
|
6985
7084
|
}
|
|
@@ -7071,8 +7170,7 @@ async function extractTarGz2(tarPath, destDir) {
|
|
|
7071
7170
|
});
|
|
7072
7171
|
}
|
|
7073
7172
|
async function fetchChecksumFromRelease(version) {
|
|
7074
|
-
const
|
|
7075
|
-
const checksumUrl = `${baseUrl}/electron-app-v${version}/checksums.txt`;
|
|
7173
|
+
const checksumUrl = buildElectronAppChecksumsUrl(version);
|
|
7076
7174
|
try {
|
|
7077
7175
|
const response = await fetch(checksumUrl);
|
|
7078
7176
|
if (!response.ok) {
|
|
@@ -7189,9 +7287,11 @@ The archive may be corrupted or in an unexpected format.`
|
|
|
7189
7287
|
async function upgradeCommand(options) {
|
|
7190
7288
|
try {
|
|
7191
7289
|
if (options.version) {
|
|
7192
|
-
const baseUrl = getDownloadBaseUrl();
|
|
7193
7290
|
const binaryName = getBinaryName2();
|
|
7194
|
-
const downloadUrl =
|
|
7291
|
+
const downloadUrl = buildElectronAppReleaseAssetUrl({
|
|
7292
|
+
version: options.version,
|
|
7293
|
+
assetFileName: binaryName
|
|
7294
|
+
});
|
|
7195
7295
|
await downloadAndInstall(options.version, downloadUrl);
|
|
7196
7296
|
const cleanupResult2 = cleanupOldVersions({ all: false });
|
|
7197
7297
|
if (cleanupResult2.removed.length > 0) {
|
|
@@ -7252,8 +7352,8 @@ var packageVersion = JSON.parse(
|
|
|
7252
7352
|
var logger13 = getLogger();
|
|
7253
7353
|
function createProgram() {
|
|
7254
7354
|
const program = new Command();
|
|
7255
|
-
program.name("muggle").description("Unified MCP server for Muggle AI
|
|
7256
|
-
program.command("serve").description("Start the MCP server").option("--
|
|
7355
|
+
program.name("muggle").description("Unified MCP server for Muggle AI \u2014 cloud E2E and local E2E testing").version(packageVersion);
|
|
7356
|
+
program.command("serve").description("Start the MCP server").option("--e2e", "Only enable cloud E2E tools (remote URLs; muggle-remote-* prefix)").option("--local", "Only enable local E2E tools (localhost; muggle-local-* prefix)").option("--stdio", "Use stdio transport (default)").action(serveCommand);
|
|
7257
7357
|
program.command("setup").description("Download/update the Electron app for local testing").option("--force", "Force re-download even if already installed").action(setupCommand);
|
|
7258
7358
|
program.command("upgrade").description("Check for and install the latest electron-app version").option("--force", "Force re-download even if already on latest").option("--check", "Check for updates only, don't download").option("--version <version>", "Download a specific version (e.g., 1.0.2)").action(upgradeCommand);
|
|
7259
7359
|
program.command("versions").description("List installed electron-app versions").action(versionsCommand);
|
|
@@ -7315,4 +7415,4 @@ __export(src_exports2, {
|
|
|
7315
7415
|
function registerCoreCommands(commandRegistrationContext) {
|
|
7316
7416
|
}
|
|
7317
7417
|
|
|
7318
|
-
export { createChildLogger, createUnifiedMcpServer, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports2 as local_exports, mcp_exports,
|
|
7418
|
+
export { createChildLogger, createUnifiedMcpServer, e2e_exports2 as e2e_exports, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports2 as local_exports, mcp_exports, runCli, server_exports, src_exports, src_exports2 };
|