@muggleai/works 5.0.4 → 5.1.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 +2 -3
- package/dist/{chunk-XO5BQZM3.js → chunk-2BHC6TQR.js} +3 -4
- package/dist/{chunk-KDRSEHK5.js → chunk-MOHR7QUN.js} +197 -291
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/scripts/ensure-electron-app.sh +1 -1
- package/dist/plugin/scripts/guardrails.mjs +4 -2
- package/dist/plugin/skills/_shared/dev-loop/publish.md +4 -8
- package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/dist/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
- package/dist/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/dist/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
- package/dist/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
- package/dist/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
- package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
- package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
- package/dist/plugin/skills/_shared/vcs/github.md +21 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
- package/dist/plugin/skills/_shared/vcs/gitlab.md +24 -0
- package/dist/plugin/skills/do/address-reviews.md +10 -6
- package/dist/plugin/skills/do/e2e-acceptance.md +4 -4
- package/dist/plugin/skills/do/fix-ci.md +1 -1
- package/dist/plugin/skills/do/input-routing.md +4 -4
- package/dist/plugin/skills/do/open-prs/forward.md +6 -4
- package/dist/plugin/skills/do/open-prs/update.md +8 -6
- package/dist/plugin/skills/do/per-comment-replies.md +22 -13
- package/dist/plugin/skills/do/resolve-conflicts.md +1 -1
- package/dist/plugin/skills/do/resolve-reminder.md +8 -6
- package/dist/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-do/SKILL.md +2 -2
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +4 -4
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
- package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
- package/dist/plugin/skills/muggle-pr-followup/contract.md +13 -9
- package/dist/plugin/skills/muggle-pr-followup/finalize.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +2 -2
- package/dist/plugin/skills/muggle-test/SKILL.md +23 -126
- package/dist/plugin/skills/muggle-test/execute-local.md +60 -0
- package/dist/plugin/skills/muggle-test/execute-remote.md +49 -0
- package/dist/plugin/skills/muggle-test/reference.md +1 -2
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +5 -5
- package/dist/release-manifest.json +4 -4
- package/dist/{src-2O5UH4FA.js → src-SS2AL3O7.js} +1 -1
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/scripts/ensure-electron-app.sh +1 -1
- package/plugin/scripts/guardrails.mjs +4 -2
- package/plugin/skills/_shared/dev-loop/publish.md +4 -8
- package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
- package/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
- package/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
- package/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
- package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
- package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
- package/plugin/skills/_shared/vcs/github.md +21 -0
- package/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
- package/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
- package/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
- package/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
- package/plugin/skills/_shared/vcs/gitlab.md +24 -0
- package/plugin/skills/do/address-reviews.md +10 -6
- package/plugin/skills/do/e2e-acceptance.md +4 -4
- package/plugin/skills/do/fix-ci.md +1 -1
- package/plugin/skills/do/input-routing.md +4 -4
- package/plugin/skills/do/open-prs/forward.md +6 -4
- package/plugin/skills/do/open-prs/update.md +8 -6
- package/plugin/skills/do/per-comment-replies.md +22 -13
- package/plugin/skills/do/resolve-conflicts.md +1 -1
- package/plugin/skills/do/resolve-reminder.md +8 -6
- package/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/plugin/skills/muggle-do/SKILL.md +2 -2
- package/plugin/skills/muggle-feedback/ops/submit.md +4 -4
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
- package/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
- package/plugin/skills/muggle-pr-followup/contract.md +13 -9
- package/plugin/skills/muggle-pr-followup/finalize.md +1 -1
- package/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
- package/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
- package/plugin/skills/muggle-preferences/ops/configure.md +2 -2
- package/plugin/skills/muggle-test/SKILL.md +23 -126
- package/plugin/skills/muggle-test/execute-local.md +60 -0
- package/plugin/skills/muggle-test/execute-remote.md +49 -0
- package/plugin/skills/muggle-test/reference.md +1 -2
- package/plugin/skills/muggle-test-feature-local/SKILL.md +5 -5
- package/dist/plugin/skills/_shared/github-cli-recipes.md +0 -21
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
- package/plugin/skills/_shared/github-cli-recipes.md +0 -21
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-metadata.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/top-level-comment.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-metadata.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/top-level-comment.md +0 -0
package/README.md
CHANGED
|
@@ -158,7 +158,7 @@ Screenshots captured per step → action-script.json recorded
|
|
|
158
158
|
Results: pass/fail with evidence at ~/.muggle-ai/sessions/{runId}/
|
|
159
159
|
│
|
|
160
160
|
v
|
|
161
|
-
|
|
161
|
+
studio publishes the run to the cloud during execution → run result carries viewUrl to open dashboard
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
---
|
|
@@ -309,8 +309,7 @@ Local Execution (muggle-local-*)
|
|
|
309
309
|
| `muggle-local-execute-replay` | Replay existing script locally |
|
|
310
310
|
| `muggle-local-cancel-execution` | Cancel active execution |
|
|
311
311
|
| `muggle-local-run-result-list` | List run results |
|
|
312
|
-
| `muggle-local-run-result-get` | Get detailed results + screenshots |
|
|
313
|
-
| `muggle-local-publish-test-script` | Publish script to cloud, returns `viewUrl` |
|
|
312
|
+
| `muggle-local-run-result-get` | Get detailed results + screenshots + studio-published cloud refs (`viewUrl`, `cloudTestScriptId`, `cloudActionScriptId`) |
|
|
314
313
|
|
|
315
314
|
|
|
316
315
|
Reports and Analytics (muggle-remote-report-*)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isFirstRun, writePreferences, DEFAULT_PREFERENCES, getDataDir, PREFERENCES_FILE_NAME, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-
|
|
1
|
+
import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isFirstRun, writePreferences, DEFAULT_PREFERENCES, getDataDir, PREFERENCES_FILE_NAME, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-MOHR7QUN.js';
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
3
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { v4 } from 'uuid';
|
|
@@ -736,7 +736,7 @@ async function resolveGsScreenshotUrls(report, opts) {
|
|
|
736
736
|
if (gsUrls.length === 0) {
|
|
737
737
|
return report;
|
|
738
738
|
}
|
|
739
|
-
const mcps = await import('./src-
|
|
739
|
+
const mcps = await import('./src-SS2AL3O7.js');
|
|
740
740
|
const credentials = await mcps.getCallerCredentialsAsync();
|
|
741
741
|
if (!credentials.bearerToken && !credentials.apiKey) {
|
|
742
742
|
stderrWrite(
|
|
@@ -1535,8 +1535,7 @@ function getHelpGuidance() {
|
|
|
1535
1535
|
"",
|
|
1536
1536
|
` ${colorize("Local E2E tools:", COLORS.bold)} (prefix: muggle-local-)`,
|
|
1537
1537
|
" muggle-local-execute-test-generation, muggle-local-execute-replay,",
|
|
1538
|
-
" muggle-local-
|
|
1539
|
-
" muggle-local-check-status, etc.",
|
|
1538
|
+
" muggle-local-run-result-get, muggle-local-check-status, etc.",
|
|
1540
1539
|
"",
|
|
1541
1540
|
header("Data Directory"),
|
|
1542
1541
|
"",
|
|
@@ -1987,6 +1987,162 @@ function resetRunResultStorageService() {
|
|
|
1987
1987
|
instance = null;
|
|
1988
1988
|
}
|
|
1989
1989
|
|
|
1990
|
+
// packages/mcps/src/mcp/local/services/replay-url-rewrite.ts
|
|
1991
|
+
function rewriteActionScriptUrls(params) {
|
|
1992
|
+
const { actionScript, originalUrl, localUrl } = params;
|
|
1993
|
+
if (!originalUrl) {
|
|
1994
|
+
return actionScript;
|
|
1995
|
+
}
|
|
1996
|
+
let originalHost;
|
|
1997
|
+
let localOrigin;
|
|
1998
|
+
try {
|
|
1999
|
+
originalHost = new URL(originalUrl).hostname;
|
|
2000
|
+
localOrigin = new URL(localUrl).origin;
|
|
2001
|
+
} catch {
|
|
2002
|
+
const serialized2 = JSON.stringify(actionScript);
|
|
2003
|
+
const rewritten2 = serialized2.replace(new RegExp(escapeRegex(originalUrl), "g"), localUrl);
|
|
2004
|
+
return JSON.parse(rewritten2);
|
|
2005
|
+
}
|
|
2006
|
+
const hostPattern = new RegExp(
|
|
2007
|
+
`https?://(?:[a-z0-9-]+\\.)*${escapeRegex(originalHost)}(?=[/?#:"'\\\\]|$)`,
|
|
2008
|
+
"gi"
|
|
2009
|
+
);
|
|
2010
|
+
const serialized = JSON.stringify(actionScript);
|
|
2011
|
+
const rewritten = serialized.replace(hostPattern, localOrigin);
|
|
2012
|
+
const result = JSON.parse(rewritten);
|
|
2013
|
+
forceFirstNavigateUrl({ steps: result, localUrl });
|
|
2014
|
+
return result;
|
|
2015
|
+
}
|
|
2016
|
+
function forceFirstNavigateUrl(params) {
|
|
2017
|
+
for (const step of params.steps) {
|
|
2018
|
+
if (!isPlainObject(step)) continue;
|
|
2019
|
+
const operation = step["operation"];
|
|
2020
|
+
if (!isPlainObject(operation)) continue;
|
|
2021
|
+
if (operation["action"] !== "navigate") continue;
|
|
2022
|
+
operation["url"] = params.localUrl;
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
function isPlainObject(value) {
|
|
2027
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2028
|
+
}
|
|
2029
|
+
function escapeRegex(str) {
|
|
2030
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
// packages/mcps/src/mcp/local/services/action-script-builders.ts
|
|
2034
|
+
function getRequiredStringField(params) {
|
|
2035
|
+
const value = params.source[params.fieldName];
|
|
2036
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
2037
|
+
throw new Error(
|
|
2038
|
+
`Missing required field '${params.fieldName}' in ${params.sourceLabel}. Please pass the full object from the corresponding muggle-remote-* get tool.`
|
|
2039
|
+
);
|
|
2040
|
+
}
|
|
2041
|
+
return value;
|
|
2042
|
+
}
|
|
2043
|
+
function buildGenerationActionScript(params) {
|
|
2044
|
+
const testCaseRecord = params.testCase;
|
|
2045
|
+
const projectId = getRequiredStringField({
|
|
2046
|
+
source: testCaseRecord,
|
|
2047
|
+
fieldName: "projectId",
|
|
2048
|
+
sourceLabel: "testCase"
|
|
2049
|
+
});
|
|
2050
|
+
const useCaseId = getRequiredStringField({
|
|
2051
|
+
source: testCaseRecord,
|
|
2052
|
+
fieldName: "useCaseId",
|
|
2053
|
+
sourceLabel: "testCase"
|
|
2054
|
+
});
|
|
2055
|
+
return {
|
|
2056
|
+
actionScriptId: params.localTestScriptId,
|
|
2057
|
+
actionScriptName: `Local Generation ${params.testCase.title}`,
|
|
2058
|
+
actionType: "UserDefined",
|
|
2059
|
+
actionParams: {
|
|
2060
|
+
type: "Test Script Generation Workflow",
|
|
2061
|
+
name: `Local Generation ${params.testCase.title}`,
|
|
2062
|
+
ownerId: params.ownerUserId,
|
|
2063
|
+
projectId,
|
|
2064
|
+
useCaseId,
|
|
2065
|
+
testCaseId: params.testCase.id,
|
|
2066
|
+
testScriptId: params.localTestScriptId,
|
|
2067
|
+
actionScriptId: params.localTestScriptId,
|
|
2068
|
+
workflowRunId: params.runId,
|
|
2069
|
+
url: params.localUrl,
|
|
2070
|
+
// Tags the run as locally executed so the studio skips its own cloud
|
|
2071
|
+
// ActionScript/TestScript write — the /local-run/upload path is the
|
|
2072
|
+
// single writer for local runs (avoids duplicate Firestore docs).
|
|
2073
|
+
executionSource: "local",
|
|
2074
|
+
// Resolved server-side (a UUID get-or-created per project, 1-1 with
|
|
2075
|
+
// projectId but NOT equal to it). The MCP has no client-side source for
|
|
2076
|
+
// it, so leave it empty here; STM-on-local needs a backend resolver.
|
|
2077
|
+
sharedTestMemoryId: "",
|
|
2078
|
+
runEnvironmentType: "local"
|
|
2079
|
+
},
|
|
2080
|
+
goal: params.testCase.goal,
|
|
2081
|
+
url: params.localUrl,
|
|
2082
|
+
description: params.testCase.title,
|
|
2083
|
+
precondition: params.testCase.precondition ?? "",
|
|
2084
|
+
instructions: params.testCase.instructions ?? "",
|
|
2085
|
+
expectedResult: params.testCase.expectedResult,
|
|
2086
|
+
steps: [],
|
|
2087
|
+
ownerId: params.ownerUserId,
|
|
2088
|
+
createdAt: Date.now(),
|
|
2089
|
+
isRemoteScript: false,
|
|
2090
|
+
status: "active"
|
|
2091
|
+
};
|
|
2092
|
+
}
|
|
2093
|
+
function buildReplayActionScript(params) {
|
|
2094
|
+
const testScriptRecord = params.testScript;
|
|
2095
|
+
const projectId = getRequiredStringField({
|
|
2096
|
+
source: testScriptRecord,
|
|
2097
|
+
fieldName: "projectId",
|
|
2098
|
+
sourceLabel: "testScript"
|
|
2099
|
+
});
|
|
2100
|
+
const useCaseId = getRequiredStringField({
|
|
2101
|
+
source: testScriptRecord,
|
|
2102
|
+
fieldName: "useCaseId",
|
|
2103
|
+
sourceLabel: "testScript"
|
|
2104
|
+
});
|
|
2105
|
+
const rewrittenActionScript = rewriteActionScriptUrls({
|
|
2106
|
+
actionScript: params.actionScript,
|
|
2107
|
+
originalUrl: params.testScript.url,
|
|
2108
|
+
localUrl: params.localUrl
|
|
2109
|
+
});
|
|
2110
|
+
return {
|
|
2111
|
+
actionScriptId: params.testScript.actionScriptId,
|
|
2112
|
+
actionScriptName: params.testScript.name,
|
|
2113
|
+
actionType: "UserDefined",
|
|
2114
|
+
actionParams: {
|
|
2115
|
+
type: "Test Script Replay Workflow",
|
|
2116
|
+
name: params.testScript.name,
|
|
2117
|
+
ownerId: params.ownerUserId,
|
|
2118
|
+
projectId,
|
|
2119
|
+
useCaseId,
|
|
2120
|
+
testCaseId: params.testScript.testCaseId,
|
|
2121
|
+
testScriptId: params.testScript.id,
|
|
2122
|
+
workflowRunId: params.runId,
|
|
2123
|
+
// Tags the run as locally executed so the studio skips its own cloud
|
|
2124
|
+
// ActionScript write — replay's cloud record is owned by the upload path
|
|
2125
|
+
// (avoids duplicate Firestore docs).
|
|
2126
|
+
executionSource: "local",
|
|
2127
|
+
// Resolved server-side (a UUID get-or-created per project, 1-1 with
|
|
2128
|
+
// projectId but NOT equal to it). The MCP has no client-side source for
|
|
2129
|
+
// it, so leave it empty here; STM-on-local needs a backend resolver.
|
|
2130
|
+
sharedTestMemoryId: "",
|
|
2131
|
+
runEnvironmentType: "local"
|
|
2132
|
+
},
|
|
2133
|
+
goal: params.testScript.name,
|
|
2134
|
+
url: params.localUrl,
|
|
2135
|
+
description: params.testScript.name,
|
|
2136
|
+
precondition: "",
|
|
2137
|
+
expectedResult: "Replay completes without critical failures.",
|
|
2138
|
+
steps: rewrittenActionScript,
|
|
2139
|
+
ownerId: params.ownerUserId,
|
|
2140
|
+
createdAt: Date.now(),
|
|
2141
|
+
isRemoteScript: true,
|
|
2142
|
+
status: "active"
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
|
|
1990
2146
|
// packages/mcps/src/mcp/local/services/local-execution-lock-constants.ts
|
|
1991
2147
|
var LOCK_FILE_NAME = "local-execution.lock";
|
|
1992
2148
|
var MODIFY_LOCK_SUFFIX = ".modify";
|
|
@@ -2157,51 +2313,34 @@ async function readLocalExecutionLockState() {
|
|
|
2157
2313
|
return readState();
|
|
2158
2314
|
}
|
|
2159
2315
|
|
|
2160
|
-
// packages/mcps/src/mcp/local/services/
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
if (
|
|
2164
|
-
return
|
|
2316
|
+
// packages/mcps/src/mcp/local/services/execution-service.ts
|
|
2317
|
+
var logger4 = getLogger();
|
|
2318
|
+
function extractStudioCloudRefs(studioReturnedResult) {
|
|
2319
|
+
if (typeof studioReturnedResult !== "object" || studioReturnedResult === null) {
|
|
2320
|
+
return {};
|
|
2165
2321
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2322
|
+
const source = studioReturnedResult;
|
|
2323
|
+
const asString = (value) => typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
2324
|
+
const refs = {};
|
|
2325
|
+
const viewUrl = asString(source.viewUrl);
|
|
2326
|
+
const cloudTestScriptId = asString(source.testScriptId);
|
|
2327
|
+
const cloudActionScriptId = asString(source.actionScriptId);
|
|
2328
|
+
if (viewUrl !== void 0) refs.viewUrl = viewUrl;
|
|
2329
|
+
if (cloudTestScriptId !== void 0) refs.cloudTestScriptId = cloudTestScriptId;
|
|
2330
|
+
if (cloudActionScriptId !== void 0) refs.cloudActionScriptId = cloudActionScriptId;
|
|
2331
|
+
return refs;
|
|
2332
|
+
}
|
|
2333
|
+
async function readCloudRefsFile(inputFilePath) {
|
|
2334
|
+
const cloudRefsPath = path9.join(
|
|
2335
|
+
path9.dirname(inputFilePath),
|
|
2336
|
+
`cloudrefs_${path9.basename(inputFilePath)}`
|
|
2337
|
+
);
|
|
2168
2338
|
try {
|
|
2169
|
-
|
|
2170
|
-
localOrigin = new URL(localUrl).origin;
|
|
2339
|
+
return JSON.parse(await fs8.readFile(cloudRefsPath, "utf-8"));
|
|
2171
2340
|
} catch {
|
|
2172
|
-
|
|
2173
|
-
const rewritten2 = serialized2.replace(new RegExp(escapeRegex(originalUrl), "g"), localUrl);
|
|
2174
|
-
return JSON.parse(rewritten2);
|
|
2175
|
-
}
|
|
2176
|
-
const hostPattern = new RegExp(
|
|
2177
|
-
`https?://(?:[a-z0-9-]+\\.)*${escapeRegex(originalHost)}(?=[/?#:"'\\\\]|$)`,
|
|
2178
|
-
"gi"
|
|
2179
|
-
);
|
|
2180
|
-
const serialized = JSON.stringify(actionScript);
|
|
2181
|
-
const rewritten = serialized.replace(hostPattern, localOrigin);
|
|
2182
|
-
const result = JSON.parse(rewritten);
|
|
2183
|
-
forceFirstNavigateUrl({ steps: result, localUrl });
|
|
2184
|
-
return result;
|
|
2185
|
-
}
|
|
2186
|
-
function forceFirstNavigateUrl(params) {
|
|
2187
|
-
for (const step of params.steps) {
|
|
2188
|
-
if (!isPlainObject(step)) continue;
|
|
2189
|
-
const operation = step["operation"];
|
|
2190
|
-
if (!isPlainObject(operation)) continue;
|
|
2191
|
-
if (operation["action"] !== "navigate") continue;
|
|
2192
|
-
operation["url"] = params.localUrl;
|
|
2193
|
-
return;
|
|
2341
|
+
return void 0;
|
|
2194
2342
|
}
|
|
2195
2343
|
}
|
|
2196
|
-
function isPlainObject(value) {
|
|
2197
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2198
|
-
}
|
|
2199
|
-
function escapeRegex(str) {
|
|
2200
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2201
|
-
}
|
|
2202
|
-
|
|
2203
|
-
// packages/mcps/src/mcp/local/services/execution-service.ts
|
|
2204
|
-
var logger4 = getLogger();
|
|
2205
2344
|
var activeProcesses = /* @__PURE__ */ new Map();
|
|
2206
2345
|
function getAuthenticatedUserId() {
|
|
2207
2346
|
const authService = getAuthService();
|
|
@@ -2414,101 +2553,6 @@ function getElectronAppPathOrThrow() {
|
|
|
2414
2553
|
errorLines.push("Or set ELECTRON_APP_PATH to the path of the MuggleAI executable.");
|
|
2415
2554
|
throw new Error(errorLines.join("\n"));
|
|
2416
2555
|
}
|
|
2417
|
-
function getRequiredStringField(params) {
|
|
2418
|
-
const value = params.source[params.fieldName];
|
|
2419
|
-
if (typeof value !== "string" || value.trim() === "") {
|
|
2420
|
-
throw new Error(
|
|
2421
|
-
`Missing required field '${params.fieldName}' in ${params.sourceLabel}. Please pass the full object from the corresponding muggle-remote-* get tool.`
|
|
2422
|
-
);
|
|
2423
|
-
}
|
|
2424
|
-
return value;
|
|
2425
|
-
}
|
|
2426
|
-
function buildGenerationActionScript(params) {
|
|
2427
|
-
const testCaseRecord = params.testCase;
|
|
2428
|
-
const projectId = getRequiredStringField({
|
|
2429
|
-
source: testCaseRecord,
|
|
2430
|
-
fieldName: "projectId",
|
|
2431
|
-
sourceLabel: "testCase"
|
|
2432
|
-
});
|
|
2433
|
-
const useCaseId = getRequiredStringField({
|
|
2434
|
-
source: testCaseRecord,
|
|
2435
|
-
fieldName: "useCaseId",
|
|
2436
|
-
sourceLabel: "testCase"
|
|
2437
|
-
});
|
|
2438
|
-
return {
|
|
2439
|
-
actionScriptId: params.localTestScriptId,
|
|
2440
|
-
actionScriptName: `Local Generation ${params.testCase.title}`,
|
|
2441
|
-
actionType: "UserDefined",
|
|
2442
|
-
actionParams: {
|
|
2443
|
-
type: "Test Script Generation Workflow",
|
|
2444
|
-
name: `Local Generation ${params.testCase.title}`,
|
|
2445
|
-
ownerId: params.ownerUserId,
|
|
2446
|
-
projectId,
|
|
2447
|
-
useCaseId,
|
|
2448
|
-
testCaseId: params.testCase.id,
|
|
2449
|
-
testScriptId: params.localTestScriptId,
|
|
2450
|
-
actionScriptId: params.localTestScriptId,
|
|
2451
|
-
workflowRunId: params.runId,
|
|
2452
|
-
url: params.localUrl,
|
|
2453
|
-
sharedTestMemoryId: ""
|
|
2454
|
-
},
|
|
2455
|
-
goal: params.testCase.goal,
|
|
2456
|
-
url: params.localUrl,
|
|
2457
|
-
description: params.testCase.title,
|
|
2458
|
-
precondition: params.testCase.precondition ?? "",
|
|
2459
|
-
instructions: params.testCase.instructions ?? "",
|
|
2460
|
-
expectedResult: params.testCase.expectedResult,
|
|
2461
|
-
steps: [],
|
|
2462
|
-
ownerId: params.ownerUserId,
|
|
2463
|
-
createdAt: Date.now(),
|
|
2464
|
-
isRemoteScript: false,
|
|
2465
|
-
status: "active"
|
|
2466
|
-
};
|
|
2467
|
-
}
|
|
2468
|
-
function buildReplayActionScript(params) {
|
|
2469
|
-
const testScriptRecord = params.testScript;
|
|
2470
|
-
const projectId = getRequiredStringField({
|
|
2471
|
-
source: testScriptRecord,
|
|
2472
|
-
fieldName: "projectId",
|
|
2473
|
-
sourceLabel: "testScript"
|
|
2474
|
-
});
|
|
2475
|
-
const useCaseId = getRequiredStringField({
|
|
2476
|
-
source: testScriptRecord,
|
|
2477
|
-
fieldName: "useCaseId",
|
|
2478
|
-
sourceLabel: "testScript"
|
|
2479
|
-
});
|
|
2480
|
-
const rewrittenActionScript = rewriteActionScriptUrls({
|
|
2481
|
-
actionScript: params.actionScript,
|
|
2482
|
-
originalUrl: params.testScript.url,
|
|
2483
|
-
localUrl: params.localUrl
|
|
2484
|
-
});
|
|
2485
|
-
return {
|
|
2486
|
-
actionScriptId: params.testScript.actionScriptId,
|
|
2487
|
-
actionScriptName: params.testScript.name,
|
|
2488
|
-
actionType: "UserDefined",
|
|
2489
|
-
actionParams: {
|
|
2490
|
-
type: "Test Script Replay Workflow",
|
|
2491
|
-
name: params.testScript.name,
|
|
2492
|
-
ownerId: params.ownerUserId,
|
|
2493
|
-
projectId,
|
|
2494
|
-
useCaseId,
|
|
2495
|
-
testCaseId: params.testScript.testCaseId,
|
|
2496
|
-
testScriptId: params.testScript.id,
|
|
2497
|
-
workflowRunId: params.runId,
|
|
2498
|
-
sharedTestMemoryId: ""
|
|
2499
|
-
},
|
|
2500
|
-
goal: params.testScript.name,
|
|
2501
|
-
url: params.localUrl,
|
|
2502
|
-
description: params.testScript.name,
|
|
2503
|
-
precondition: "",
|
|
2504
|
-
expectedResult: "Replay completes without critical failures.",
|
|
2505
|
-
steps: rewrittenActionScript,
|
|
2506
|
-
ownerId: params.ownerUserId,
|
|
2507
|
-
createdAt: Date.now(),
|
|
2508
|
-
isRemoteScript: true,
|
|
2509
|
-
status: "active"
|
|
2510
|
-
};
|
|
2511
|
-
}
|
|
2512
2556
|
async function executeElectronAppAsync(params) {
|
|
2513
2557
|
const mode = params.runType === "generation" ? "explore" : "engine";
|
|
2514
2558
|
const electronAppPath = getElectronAppPathOrThrow();
|
|
@@ -2709,18 +2753,24 @@ ${executionResult.stderr}`;
|
|
|
2709
2753
|
path9.dirname(inputFilePath),
|
|
2710
2754
|
`gen_${path9.basename(inputFilePath)}`
|
|
2711
2755
|
);
|
|
2756
|
+
let failedStudioResult;
|
|
2712
2757
|
try {
|
|
2758
|
+
const failedScriptRaw = await fs8.readFile(generatedScriptPath2, "utf-8");
|
|
2759
|
+
failedStudioResult = JSON.parse(failedScriptRaw);
|
|
2713
2760
|
await fs8.copyFile(generatedScriptPath2, path9.join(artifactsDir2, "action-script.json"));
|
|
2714
2761
|
await fs8.unlink(generatedScriptPath2).catch(() => {
|
|
2715
2762
|
});
|
|
2716
2763
|
} catch {
|
|
2717
2764
|
}
|
|
2765
|
+
const failedStudioCloudRefs = extractStudioCloudRefs(await readCloudRefsFile(inputFilePath));
|
|
2718
2766
|
storage.updateRunResult(runId, {
|
|
2719
2767
|
status: "failed",
|
|
2720
2768
|
testScriptId: localTestScript.id,
|
|
2721
2769
|
executionTimeMs,
|
|
2722
2770
|
errorMessage: failureMessage,
|
|
2723
2771
|
artifactsDir: artifactsDir2,
|
|
2772
|
+
studioReturnedResult: failedStudioResult,
|
|
2773
|
+
...failedStudioCloudRefs,
|
|
2724
2774
|
localExecutionContext: {
|
|
2725
2775
|
...localExecutionContextBase,
|
|
2726
2776
|
localExecutionCompletedAt: completedAt
|
|
@@ -2759,11 +2809,14 @@ ${executionResult.stderr}`;
|
|
|
2759
2809
|
runId,
|
|
2760
2810
|
generatedScriptPath
|
|
2761
2811
|
});
|
|
2812
|
+
const studioCloudRefs = extractStudioCloudRefs(await readCloudRefsFile(inputFilePath));
|
|
2762
2813
|
storage.updateRunResult(runId, {
|
|
2763
2814
|
status: "passed",
|
|
2764
2815
|
testScriptId: localTestScript.id,
|
|
2765
2816
|
executionTimeMs,
|
|
2766
2817
|
artifactsDir,
|
|
2818
|
+
studioReturnedResult: generatedScript,
|
|
2819
|
+
...studioCloudRefs,
|
|
2767
2820
|
localExecutionContext: {
|
|
2768
2821
|
...localExecutionContextBase,
|
|
2769
2822
|
localExecutionCompletedAt: completedAt
|
|
@@ -2900,10 +2953,14 @@ ${executionResult.stderr}`;
|
|
|
2900
2953
|
};
|
|
2901
2954
|
}
|
|
2902
2955
|
const artifactsDir = path9.join(getStorageService().getSessionsDir(), runId);
|
|
2956
|
+
const replayStudioResult = await readCloudRefsFile(inputFilePath);
|
|
2957
|
+
const replayStudioCloudRefs = extractStudioCloudRefs(replayStudioResult);
|
|
2903
2958
|
storage.updateRunResult(runId, {
|
|
2904
2959
|
status: "passed",
|
|
2905
2960
|
executionTimeMs,
|
|
2906
2961
|
artifactsDir,
|
|
2962
|
+
studioReturnedResult: replayStudioResult,
|
|
2963
|
+
...replayStudioCloudRefs,
|
|
2907
2964
|
localExecutionContext: {
|
|
2908
2965
|
...localExecutionContextBase,
|
|
2909
2966
|
localExecutionCompletedAt: completedAt
|
|
@@ -6152,10 +6209,6 @@ var TestScriptListInputSchema2 = z.object({
|
|
|
6152
6209
|
var TestScriptGetInputSchema2 = z.object({
|
|
6153
6210
|
testScriptId: MuggleEntityIdSchema.describe("Local stored test script ID (UUID) to retrieve")
|
|
6154
6211
|
});
|
|
6155
|
-
var PublishTestScriptInputSchema = z.object({
|
|
6156
|
-
runId: MuggleEntityIdSchema.describe("Local run result ID (UUID) from muggle_execute_test_generation"),
|
|
6157
|
-
cloudTestCaseId: MuggleEntityIdSchema.describe("Cloud test case ID (UUID) to publish the script under")
|
|
6158
|
-
});
|
|
6159
6212
|
var ListSessionsInputSchema = z.object({
|
|
6160
6213
|
limit: z.number().int().positive().optional().describe("Maximum number of sessions to return. Defaults to 10.")
|
|
6161
6214
|
});
|
|
@@ -6172,7 +6225,6 @@ var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
|
6172
6225
|
PreferenceKey2["ShowElectronBrowser"] = "showElectronBrowser";
|
|
6173
6226
|
PreferenceKey2["OpenTestResultsAfterRun"] = "openTestResultsAfterRun";
|
|
6174
6227
|
PreferenceKey2["DefaultExecutionMode"] = "defaultExecutionMode";
|
|
6175
|
-
PreferenceKey2["AutoPublishLocalResults"] = "autoPublishLocalResults";
|
|
6176
6228
|
PreferenceKey2["SuggestRelatedUseCases"] = "suggestRelatedUseCases";
|
|
6177
6229
|
PreferenceKey2["SuggestRelatedTestCases"] = "suggestRelatedTestCases";
|
|
6178
6230
|
PreferenceKey2["AutoDetectChanges"] = "autoDetectChanges";
|
|
@@ -6206,7 +6258,6 @@ var DEFAULT_PREFERENCES = {
|
|
|
6206
6258
|
["showElectronBrowser" /* ShowElectronBrowser */]: "ask" /* Ask */,
|
|
6207
6259
|
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "ask" /* Ask */,
|
|
6208
6260
|
["defaultExecutionMode" /* DefaultExecutionMode */]: "ask" /* Ask */,
|
|
6209
|
-
["autoPublishLocalResults" /* AutoPublishLocalResults */]: "ask" /* Ask */,
|
|
6210
6261
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: "ask" /* Ask */,
|
|
6211
6262
|
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: "ask" /* Ask */,
|
|
6212
6263
|
["autoDetectChanges" /* AutoDetectChanges */]: "ask" /* Ask */,
|
|
@@ -6240,7 +6291,6 @@ var PREFERENCE_ALLOWED_VALUES = {
|
|
|
6240
6291
|
["showElectronBrowser" /* ShowElectronBrowser */]: ALWAYS_ASK_NEVER,
|
|
6241
6292
|
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: ALWAYS_ASK_NEVER,
|
|
6242
6293
|
["defaultExecutionMode" /* DefaultExecutionMode */]: LOCAL_REMOTE_ASK,
|
|
6243
|
-
["autoPublishLocalResults" /* AutoPublishLocalResults */]: ALWAYS_ASK_NEVER,
|
|
6244
6294
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: ALWAYS_ASK_NEVER,
|
|
6245
6295
|
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: ALWAYS_ASK_NEVER,
|
|
6246
6296
|
["autoDetectChanges" /* AutoDetectChanges */]: ALWAYS_ASK_NEVER,
|
|
@@ -6272,9 +6322,6 @@ var PREFERENCES_SCHEMA = {
|
|
|
6272
6322
|
["defaultExecutionMode" /* DefaultExecutionMode */]: {
|
|
6273
6323
|
description: "When a skill supports both local and remote test execution, which to default to"
|
|
6274
6324
|
},
|
|
6275
|
-
["autoPublishLocalResults" /* AutoPublishLocalResults */]: {
|
|
6276
|
-
description: "After a local E2E test run completes, upload results to Muggle Test cloud for team visibility"
|
|
6277
|
-
},
|
|
6278
6325
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: {
|
|
6279
6326
|
description: "After creating or running a use case, suggest related use cases to add"
|
|
6280
6327
|
},
|
|
@@ -6659,7 +6706,11 @@ var runResultGetTool = {
|
|
|
6659
6706
|
`**Status:** ${result.status}`,
|
|
6660
6707
|
`**Cloud Test Case:** ${result.cloudTestCaseId}`,
|
|
6661
6708
|
`**Duration:** ${result.executionTimeMs ?? 0}ms`,
|
|
6662
|
-
result.errorMessage ? `**Error:** ${result.errorMessage}` : ""
|
|
6709
|
+
result.errorMessage ? `**Error:** ${result.errorMessage}` : "",
|
|
6710
|
+
// The studio publishes the run during execution; these are its returned cloud refs.
|
|
6711
|
+
result.viewUrl ? `**View URL:** ${result.viewUrl}` : "",
|
|
6712
|
+
result.cloudTestScriptId ? `**Cloud Test Script ID:** ${result.cloudTestScriptId}` : "",
|
|
6713
|
+
result.cloudActionScriptId ? `**Cloud Action Script ID:** ${result.cloudActionScriptId}` : ""
|
|
6663
6714
|
];
|
|
6664
6715
|
let testScriptSteps;
|
|
6665
6716
|
if (result.testScriptId) {
|
|
@@ -6858,148 +6909,6 @@ var cancelExecutionTool = {
|
|
|
6858
6909
|
return { content: `No active execution found with ID: ${input.runId}`, isError: true };
|
|
6859
6910
|
}
|
|
6860
6911
|
};
|
|
6861
|
-
var publishTestScriptTool = {
|
|
6862
|
-
name: "muggle-local-publish-test-script",
|
|
6863
|
-
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.",
|
|
6864
|
-
inputSchema: PublishTestScriptInputSchema,
|
|
6865
|
-
execute: async (ctx) => {
|
|
6866
|
-
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6867
|
-
logger6.info("Executing muggle-local-publish-test-script");
|
|
6868
|
-
const input = PublishTestScriptInputSchema.parse(ctx.input);
|
|
6869
|
-
const storage = getRunResultStorageService();
|
|
6870
|
-
const runResult = storage.getRunResult(input.runId);
|
|
6871
|
-
if (!runResult) {
|
|
6872
|
-
return { content: `Run result not found: ${input.runId}`, isError: true };
|
|
6873
|
-
}
|
|
6874
|
-
if (!runResult.testScriptId) {
|
|
6875
|
-
return { content: `Run result ${input.runId} does not have an associated test script`, isError: true };
|
|
6876
|
-
}
|
|
6877
|
-
const testScript = storage.getTestScript(runResult.testScriptId);
|
|
6878
|
-
if (!testScript) {
|
|
6879
|
-
return { content: `Test script not found: ${runResult.testScriptId}`, isError: true };
|
|
6880
|
-
}
|
|
6881
|
-
if (runResult.runType !== "generation") {
|
|
6882
|
-
return {
|
|
6883
|
-
content: `Only generation runs can be published. Run ${input.runId} is '${runResult.runType}'.`,
|
|
6884
|
-
isError: true
|
|
6885
|
-
};
|
|
6886
|
-
}
|
|
6887
|
-
if (runResult.status !== "passed" && runResult.status !== "failed") {
|
|
6888
|
-
return {
|
|
6889
|
-
content: `Run ${input.runId} must be in passed/failed state before publishing. Current status: ${runResult.status}.`,
|
|
6890
|
-
isError: true
|
|
6891
|
-
};
|
|
6892
|
-
}
|
|
6893
|
-
if (!Array.isArray(testScript.actionScript) || testScript.actionScript.length === 0) {
|
|
6894
|
-
return {
|
|
6895
|
-
content: `Test script ${testScript.id} has no generated actionScript steps to publish.`,
|
|
6896
|
-
isError: true
|
|
6897
|
-
};
|
|
6898
|
-
}
|
|
6899
|
-
if (!runResult.projectId) {
|
|
6900
|
-
return { content: `Run result ${input.runId} is missing projectId.`, isError: true };
|
|
6901
|
-
}
|
|
6902
|
-
if (!runResult.useCaseId) {
|
|
6903
|
-
return { content: `Run result ${input.runId} is missing useCaseId.`, isError: true };
|
|
6904
|
-
}
|
|
6905
|
-
if (!runResult.productionUrl) {
|
|
6906
|
-
return { content: `Run result ${input.runId} is missing productionUrl.`, isError: true };
|
|
6907
|
-
}
|
|
6908
|
-
if (!runResult.executionTimeMs && runResult.executionTimeMs !== 0) {
|
|
6909
|
-
return { content: `Run result ${input.runId} is missing executionTimeMs.`, isError: true };
|
|
6910
|
-
}
|
|
6911
|
-
if (!runResult.localExecutionContext) {
|
|
6912
|
-
return { content: `Run result ${input.runId} is missing localExecutionContext.`, isError: true };
|
|
6913
|
-
}
|
|
6914
|
-
if (!runResult.localExecutionContext.localExecutionCompletedAt) {
|
|
6915
|
-
return {
|
|
6916
|
-
content: `Run result ${input.runId} is missing localExecutionCompletedAt in localExecutionContext.`,
|
|
6917
|
-
isError: true
|
|
6918
|
-
};
|
|
6919
|
-
}
|
|
6920
|
-
const authStatus = getAuthService().getAuthStatus();
|
|
6921
|
-
if (!authStatus.userId) {
|
|
6922
|
-
return { content: "Authenticated user ID is missing. Please login again.", isError: true };
|
|
6923
|
-
}
|
|
6924
|
-
try {
|
|
6925
|
-
const credentials = await getCallerCredentialsAsync();
|
|
6926
|
-
const client = getPromptServiceClient();
|
|
6927
|
-
const uploadedAt = Date.now();
|
|
6928
|
-
const response = await client.execute(
|
|
6929
|
-
{
|
|
6930
|
-
method: "POST",
|
|
6931
|
-
path: "/v1/protected/muggle-test/local-run/upload",
|
|
6932
|
-
body: {
|
|
6933
|
-
projectId: runResult.projectId,
|
|
6934
|
-
useCaseId: runResult.useCaseId,
|
|
6935
|
-
testCaseId: input.cloudTestCaseId,
|
|
6936
|
-
runType: runResult.runType,
|
|
6937
|
-
// A published run always originates from local Electron execution, so it
|
|
6938
|
-
// belongs to the local lane — the cloud must resolve the developer's
|
|
6939
|
-
// localhost credentials, not the remote managed-profile pool.
|
|
6940
|
-
runEnvironmentType: "local" /* Local */,
|
|
6941
|
-
productionUrl: runResult.productionUrl,
|
|
6942
|
-
localExecutionContext: {
|
|
6943
|
-
originalUrl: runResult.localExecutionContext.originalUrl,
|
|
6944
|
-
productionUrl: runResult.localExecutionContext.productionUrl,
|
|
6945
|
-
runByUserId: authStatus.userId,
|
|
6946
|
-
machineHostname: runResult.localExecutionContext.machineHostname,
|
|
6947
|
-
osInfo: runResult.localExecutionContext.osInfo,
|
|
6948
|
-
electronAppVersion: runResult.localExecutionContext.electronAppVersion,
|
|
6949
|
-
mcpServerVersion: runResult.localExecutionContext.mcpServerVersion,
|
|
6950
|
-
localExecutionCompletedAt: runResult.localExecutionContext.localExecutionCompletedAt,
|
|
6951
|
-
uploadedAt
|
|
6952
|
-
},
|
|
6953
|
-
actionScript: testScript.actionScript,
|
|
6954
|
-
summaryStep: testScript.summaryStep,
|
|
6955
|
-
status: runResult.status === "passed" ? "passed" : "failed",
|
|
6956
|
-
executionTimeMs: runResult.executionTimeMs,
|
|
6957
|
-
errorMessage: runResult.errorMessage
|
|
6958
|
-
}
|
|
6959
|
-
},
|
|
6960
|
-
credentials,
|
|
6961
|
-
ctx.correlationId
|
|
6962
|
-
);
|
|
6963
|
-
storage.updateTestScript(testScript.id, {
|
|
6964
|
-
status: "published",
|
|
6965
|
-
cloudActionScriptId: response.data.actionScriptId
|
|
6966
|
-
});
|
|
6967
|
-
storage.updateRunResult(runResult.id, {
|
|
6968
|
-
localExecutionContext: {
|
|
6969
|
-
...runResult.localExecutionContext,
|
|
6970
|
-
runByUserId: authStatus.userId
|
|
6971
|
-
}
|
|
6972
|
-
});
|
|
6973
|
-
return {
|
|
6974
|
-
content: [
|
|
6975
|
-
"## Test Script Published",
|
|
6976
|
-
"",
|
|
6977
|
-
`**Run ID:** ${input.runId}`,
|
|
6978
|
-
`**Local Test Script ID:** ${testScript.id}`,
|
|
6979
|
-
`**Cloud Test Case ID:** ${input.cloudTestCaseId}`,
|
|
6980
|
-
`**Cloud Test Script ID:** ${response.data.testScriptId}`,
|
|
6981
|
-
`**Cloud Action Script ID:** ${response.data.actionScriptId}`,
|
|
6982
|
-
`**Workflow Runtime ID:** ${response.data.workflowRuntimeId}`,
|
|
6983
|
-
`**Workflow Run ID:** ${response.data.workflowRunId}`,
|
|
6984
|
-
`**View URL:** ${response.data.viewUrl}`
|
|
6985
|
-
].join("\n"),
|
|
6986
|
-
isError: false,
|
|
6987
|
-
data: response.data
|
|
6988
|
-
};
|
|
6989
|
-
} catch (error) {
|
|
6990
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6991
|
-
logger6.error("Failed to publish local test script to cloud", {
|
|
6992
|
-
runId: input.runId,
|
|
6993
|
-
cloudTestCaseId: input.cloudTestCaseId,
|
|
6994
|
-
error: errorMessage
|
|
6995
|
-
});
|
|
6996
|
-
return {
|
|
6997
|
-
content: `Failed to publish test script: ${errorMessage}`,
|
|
6998
|
-
isError: true
|
|
6999
|
-
};
|
|
7000
|
-
}
|
|
7001
|
-
}
|
|
7002
|
-
};
|
|
7003
6912
|
var preferencesSetTool = {
|
|
7004
6913
|
name: "muggle-local-preferences-set",
|
|
7005
6914
|
description: "Set a Muggle AI user preference. Preferences control automation behavior (auto-login, show browser, suggest test cases, etc.). Values: 'always' (proceed without asking), 'ask' (prompt each time), 'never' (skip without asking). Scope: 'global' writes to ~/.muggle-ai/preferences.json, 'project' writes to .muggle-ai/preferences.json in the repo root.",
|
|
@@ -7194,8 +7103,6 @@ var allLocalQaTools = [
|
|
|
7194
7103
|
executeTestGenerationTool,
|
|
7195
7104
|
executeReplayTool,
|
|
7196
7105
|
cancelExecutionTool,
|
|
7197
|
-
// Publishing tools
|
|
7198
|
-
publishTestScriptTool,
|
|
7199
7106
|
// Preferences tools
|
|
7200
7107
|
preferencesSetTool,
|
|
7201
7108
|
// Last-project cache tools (per-repo "last used Muggle Test project")
|
|
@@ -7412,7 +7319,6 @@ __export(local_exports2, {
|
|
|
7412
7319
|
LocalWorkflowRunStatus: () => LocalWorkflowRunStatus,
|
|
7413
7320
|
MuggleEntityIdSchema: () => MuggleEntityIdSchema,
|
|
7414
7321
|
PreferencesSetInputSchema: () => PreferencesSetInputSchema,
|
|
7415
|
-
PublishTestScriptInputSchema: () => PublishTestScriptInputSchema,
|
|
7416
7322
|
RunResultGetInputSchema: () => RunResultGetInputSchema,
|
|
7417
7323
|
RunResultListInputSchema: () => RunResultListInputSchema,
|
|
7418
7324
|
RunResultStorageService: () => RunResultStorageService,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-
|
|
2
|
-
export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-
|
|
1
|
+
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-2BHC6TQR.js';
|
|
2
|
+
export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-MOHR7QUN.js';
|