@muggleai/works 5.0.4 → 5.2.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-KDRSEHK5.js → chunk-3HSV6EXR.js} +245 -309
- package/dist/{chunk-XO5BQZM3.js → chunk-IIQZLG34.js} +3 -4
- 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-preferences/preference-gates/README.md +8 -5
- 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-KHZUV253.js} +1 -1
- package/package.json +8 -7
- 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-preferences/preference-gates/README.md +8 -5
- 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
|
@@ -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";
|
|
@@ -6184,6 +6236,11 @@ var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
|
6184
6236
|
PreferenceKey2["AutoRebase"] = "autoRebase";
|
|
6185
6237
|
PreferenceKey2["AutoCleanup"] = "autoCleanup";
|
|
6186
6238
|
PreferenceKey2["AutoE2ETest"] = "autoE2ETest";
|
|
6239
|
+
PreferenceKey2["AutoResolveConflicts"] = "autoResolveConflicts";
|
|
6240
|
+
PreferenceKey2["AutoReuseValidationContext"] = "autoReuseValidationContext";
|
|
6241
|
+
PreferenceKey2["AutoRouteBuildToMuggleDo"] = "autoRouteBuildToMuggleDo";
|
|
6242
|
+
PreferenceKey2["AutoWatchPR"] = "autoWatchPR";
|
|
6243
|
+
PreferenceKey2["ReusePreparePlan"] = "reusePreparePlan";
|
|
6187
6244
|
return PreferenceKey2;
|
|
6188
6245
|
})(PreferenceKey || {});
|
|
6189
6246
|
var PreferenceValue = /* @__PURE__ */ ((PreferenceValue2) => {
|
|
@@ -6200,24 +6257,28 @@ var PREFERENCES_FILE_NAME = "preferences.json";
|
|
|
6200
6257
|
var PREFERENCES_PROJECT_DIR_NAME = ".muggle-ai";
|
|
6201
6258
|
var PREFERENCES_VERSION = 1;
|
|
6202
6259
|
var DEFAULT_PREFERENCES = {
|
|
6203
|
-
["autoLogin" /* AutoLogin */]: "
|
|
6204
|
-
["autoSelectProject" /* AutoSelectProject */]: "
|
|
6205
|
-
["autoSelectLocalHost" /* AutoSelectLocalHost */]: "
|
|
6206
|
-
["showElectronBrowser" /* ShowElectronBrowser */]: "
|
|
6207
|
-
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "
|
|
6208
|
-
["defaultExecutionMode" /* DefaultExecutionMode */]: "
|
|
6209
|
-
["
|
|
6210
|
-
["
|
|
6211
|
-
["
|
|
6212
|
-
["
|
|
6213
|
-
["
|
|
6214
|
-
["
|
|
6215
|
-
["
|
|
6216
|
-
["
|
|
6217
|
-
["
|
|
6218
|
-
["
|
|
6219
|
-
["
|
|
6220
|
-
["
|
|
6260
|
+
["autoLogin" /* AutoLogin */]: "always" /* Always */,
|
|
6261
|
+
["autoSelectProject" /* AutoSelectProject */]: "always" /* Always */,
|
|
6262
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: "always" /* Always */,
|
|
6263
|
+
["showElectronBrowser" /* ShowElectronBrowser */]: "always" /* Always */,
|
|
6264
|
+
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "always" /* Always */,
|
|
6265
|
+
["defaultExecutionMode" /* DefaultExecutionMode */]: "local" /* Local */,
|
|
6266
|
+
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: "always" /* Always */,
|
|
6267
|
+
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: "always" /* Always */,
|
|
6268
|
+
["autoDetectChanges" /* AutoDetectChanges */]: "always" /* Always */,
|
|
6269
|
+
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: "always" /* Always */,
|
|
6270
|
+
["autoCreatePR" /* AutoCreatePR */]: "always" /* Always */,
|
|
6271
|
+
["checkForUpdates" /* CheckForUpdates */]: "always" /* Always */,
|
|
6272
|
+
["verboseOutput" /* VerboseOutput */]: "never" /* Never */,
|
|
6273
|
+
["autoUseWorktree" /* AutoUseWorktree */]: "always" /* Always */,
|
|
6274
|
+
["autoRebase" /* AutoRebase */]: "always" /* Always */,
|
|
6275
|
+
["autoCleanup" /* AutoCleanup */]: "always" /* Always */,
|
|
6276
|
+
["autoE2ETest" /* AutoE2ETest */]: "always" /* Always */,
|
|
6277
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: "always" /* Always */,
|
|
6278
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: "always" /* Always */,
|
|
6279
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: "always" /* Always */,
|
|
6280
|
+
["autoWatchPR" /* AutoWatchPR */]: "always" /* Always */,
|
|
6281
|
+
["reusePreparePlan" /* ReusePreparePlan */]: "always" /* Always */
|
|
6221
6282
|
};
|
|
6222
6283
|
var ALWAYS_ASK_NEVER = [
|
|
6223
6284
|
"always" /* Always */,
|
|
@@ -6240,7 +6301,6 @@ var PREFERENCE_ALLOWED_VALUES = {
|
|
|
6240
6301
|
["showElectronBrowser" /* ShowElectronBrowser */]: ALWAYS_ASK_NEVER,
|
|
6241
6302
|
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: ALWAYS_ASK_NEVER,
|
|
6242
6303
|
["defaultExecutionMode" /* DefaultExecutionMode */]: LOCAL_REMOTE_ASK,
|
|
6243
|
-
["autoPublishLocalResults" /* AutoPublishLocalResults */]: ALWAYS_ASK_NEVER,
|
|
6244
6304
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: ALWAYS_ASK_NEVER,
|
|
6245
6305
|
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: ALWAYS_ASK_NEVER,
|
|
6246
6306
|
["autoDetectChanges" /* AutoDetectChanges */]: ALWAYS_ASK_NEVER,
|
|
@@ -6251,7 +6311,12 @@ var PREFERENCE_ALLOWED_VALUES = {
|
|
|
6251
6311
|
["autoUseWorktree" /* AutoUseWorktree */]: ALWAYS_ASK_NEVER,
|
|
6252
6312
|
["autoRebase" /* AutoRebase */]: ALWAYS_ASK_NEVER,
|
|
6253
6313
|
["autoCleanup" /* AutoCleanup */]: ALWAYS_ASK_NEVER,
|
|
6254
|
-
["autoE2ETest" /* AutoE2ETest */]: ALWAYS_ASK
|
|
6314
|
+
["autoE2ETest" /* AutoE2ETest */]: ALWAYS_ASK,
|
|
6315
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: ALWAYS_ASK_NEVER,
|
|
6316
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: ALWAYS_ASK_NEVER,
|
|
6317
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: ALWAYS_ASK_NEVER,
|
|
6318
|
+
["autoWatchPR" /* AutoWatchPR */]: ALWAYS_ASK_NEVER,
|
|
6319
|
+
["reusePreparePlan" /* ReusePreparePlan */]: ALWAYS_ASK_NEVER
|
|
6255
6320
|
};
|
|
6256
6321
|
var PREFERENCES_SCHEMA = {
|
|
6257
6322
|
["autoLogin" /* AutoLogin */]: {
|
|
@@ -6272,9 +6337,6 @@ var PREFERENCES_SCHEMA = {
|
|
|
6272
6337
|
["defaultExecutionMode" /* DefaultExecutionMode */]: {
|
|
6273
6338
|
description: "When a skill supports both local and remote test execution, which to default to"
|
|
6274
6339
|
},
|
|
6275
|
-
["autoPublishLocalResults" /* AutoPublishLocalResults */]: {
|
|
6276
|
-
description: "After a local E2E test run completes, upload results to Muggle Test cloud for team visibility"
|
|
6277
|
-
},
|
|
6278
6340
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: {
|
|
6279
6341
|
description: "After creating or running a use case, suggest related use cases to add"
|
|
6280
6342
|
},
|
|
@@ -6307,6 +6369,21 @@ var PREFERENCES_SCHEMA = {
|
|
|
6307
6369
|
},
|
|
6308
6370
|
["autoE2ETest" /* AutoE2ETest */]: {
|
|
6309
6371
|
description: "Run Stage 6 (E2E acceptance) at the end of every /muggle-do cycle (default always \u2014 running E2E is the point of muggle-do; never is not an option)"
|
|
6372
|
+
},
|
|
6373
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: {
|
|
6374
|
+
description: "When a rebase onto the default branch hits conflicts, resolve them autonomously behind a verify-or-rollback gate instead of aborting and escalating"
|
|
6375
|
+
},
|
|
6376
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: {
|
|
6377
|
+
description: "When a prior session left an E2E validation context for this working tree, reuse it instead of re-asking the validation questions"
|
|
6378
|
+
},
|
|
6379
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: {
|
|
6380
|
+
description: "When a prompt looks like a build/implement/fix request, route it through the /muggle-do pipeline (requirements \u2192 build \u2192 impact \u2192 tests \u2192 E2E \u2192 PR \u2192 watcher)"
|
|
6381
|
+
},
|
|
6382
|
+
["autoWatchPR" /* AutoWatchPR */]: {
|
|
6383
|
+
description: "After a test run opens a PR, start a muggle-pr-followup watcher that polls for new reviews and hands them to /muggle-do"
|
|
6384
|
+
},
|
|
6385
|
+
["reusePreparePlan" /* ReusePreparePlan */]: {
|
|
6386
|
+
description: "Reuse the saved prepare plan for this stack (skip discovery, jump to check-running + smoke-test) instead of rediscovering from scratch"
|
|
6310
6387
|
}
|
|
6311
6388
|
};
|
|
6312
6389
|
|
|
@@ -6659,7 +6736,11 @@ var runResultGetTool = {
|
|
|
6659
6736
|
`**Status:** ${result.status}`,
|
|
6660
6737
|
`**Cloud Test Case:** ${result.cloudTestCaseId}`,
|
|
6661
6738
|
`**Duration:** ${result.executionTimeMs ?? 0}ms`,
|
|
6662
|
-
result.errorMessage ? `**Error:** ${result.errorMessage}` : ""
|
|
6739
|
+
result.errorMessage ? `**Error:** ${result.errorMessage}` : "",
|
|
6740
|
+
// The studio publishes the run during execution; these are its returned cloud refs.
|
|
6741
|
+
result.viewUrl ? `**View URL:** ${result.viewUrl}` : "",
|
|
6742
|
+
result.cloudTestScriptId ? `**Cloud Test Script ID:** ${result.cloudTestScriptId}` : "",
|
|
6743
|
+
result.cloudActionScriptId ? `**Cloud Action Script ID:** ${result.cloudActionScriptId}` : ""
|
|
6663
6744
|
];
|
|
6664
6745
|
let testScriptSteps;
|
|
6665
6746
|
if (result.testScriptId) {
|
|
@@ -6858,148 +6939,6 @@ var cancelExecutionTool = {
|
|
|
6858
6939
|
return { content: `No active execution found with ID: ${input.runId}`, isError: true };
|
|
6859
6940
|
}
|
|
6860
6941
|
};
|
|
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
6942
|
var preferencesSetTool = {
|
|
7004
6943
|
name: "muggle-local-preferences-set",
|
|
7005
6944
|
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 +7133,6 @@ var allLocalQaTools = [
|
|
|
7194
7133
|
executeTestGenerationTool,
|
|
7195
7134
|
executeReplayTool,
|
|
7196
7135
|
cancelExecutionTool,
|
|
7197
|
-
// Publishing tools
|
|
7198
|
-
publishTestScriptTool,
|
|
7199
7136
|
// Preferences tools
|
|
7200
7137
|
preferencesSetTool,
|
|
7201
7138
|
// Last-project cache tools (per-repo "last used Muggle Test project")
|
|
@@ -7412,7 +7349,6 @@ __export(local_exports2, {
|
|
|
7412
7349
|
LocalWorkflowRunStatus: () => LocalWorkflowRunStatus,
|
|
7413
7350
|
MuggleEntityIdSchema: () => MuggleEntityIdSchema,
|
|
7414
7351
|
PreferencesSetInputSchema: () => PreferencesSetInputSchema,
|
|
7415
|
-
PublishTestScriptInputSchema: () => PublishTestScriptInputSchema,
|
|
7416
7352
|
RunResultGetInputSchema: () => RunResultGetInputSchema,
|
|
7417
7353
|
RunResultListInputSchema: () => RunResultListInputSchema,
|
|
7418
7354
|
RunResultStorageService: () => RunResultStorageService,
|