@muggleai/works 4.9.2 → 4.10.1
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 +3 -3
- package/dist/{chunk-6N7OIBAS.js → chunk-Q7WNEMN4.js} +109 -43
- package/dist/{chunk-4KQZLF56.js → chunk-ZKRHFTIC.js} +996 -91
- 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/README.md +4 -2
- package/dist/plugin/agents/acceptance-tester.md +24 -10
- package/dist/plugin/commands/m.md +7 -0
- package/dist/plugin/commands/mdo.md +7 -0
- package/dist/plugin/commands/mfeedback.md +7 -0
- package/dist/plugin/commands/mimport.md +7 -0
- package/dist/plugin/commands/mpr.md +7 -0
- package/dist/plugin/commands/mprefs.md +7 -0
- package/dist/plugin/commands/mregen.md +7 -0
- package/dist/plugin/commands/mrelease.md +7 -0
- package/dist/plugin/commands/mrepair.md +7 -0
- package/dist/plugin/commands/mstatus.md +7 -0
- package/dist/plugin/commands/mtest.md +7 -0
- package/dist/plugin/commands/mtestlocal.md +7 -0
- package/dist/plugin/commands/mtestprep.md +7 -0
- package/dist/plugin/commands/mupgrade.md +7 -0
- package/dist/plugin/scripts/ensure-electron-app.sh +56 -6
- package/dist/plugin/skills/_aliases.json +18 -0
- package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
- package/dist/plugin/skills/do/impact-analysis.md +45 -5
- package/dist/plugin/skills/do/open-prs.md +13 -4
- package/dist/plugin/skills/do/pr-followup.md +225 -0
- package/dist/plugin/skills/do/pre-flight.md +18 -11
- package/dist/plugin/skills/m/SKILL.md +8 -0
- package/dist/plugin/skills/mdo/SKILL.md +8 -0
- package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
- package/dist/plugin/skills/mimport/SKILL.md +8 -0
- package/dist/plugin/skills/mpr/SKILL.md +8 -0
- package/dist/plugin/skills/mprefs/SKILL.md +8 -0
- package/dist/plugin/skills/mregen/SKILL.md +8 -0
- package/dist/plugin/skills/mrelease/SKILL.md +8 -0
- package/dist/plugin/skills/mrepair/SKILL.md +8 -0
- package/dist/plugin/skills/mstatus/SKILL.md +8 -0
- package/dist/plugin/skills/mtest/SKILL.md +8 -0
- package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
- package/dist/plugin/skills/muggle/SKILL.md +11 -17
- package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
- package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +17 -68
- package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
- package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-status/SKILL.md +14 -16
- package/dist/plugin/skills/muggle-test/SKILL.md +148 -123
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
- package/dist/plugin/skills/muggle-test-import/SKILL.md +74 -35
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
- package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
- package/dist/release-manifest.json +4 -4
- package/dist/src-2G7ENRGI.js +1 -0
- package/package.json +10 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/README.md +4 -2
- package/plugin/agents/acceptance-tester.md +24 -10
- package/plugin/commands/m.md +7 -0
- package/plugin/commands/mdo.md +7 -0
- package/plugin/commands/mfeedback.md +7 -0
- package/plugin/commands/mimport.md +7 -0
- package/plugin/commands/mpr.md +7 -0
- package/plugin/commands/mprefs.md +7 -0
- package/plugin/commands/mregen.md +7 -0
- package/plugin/commands/mrelease.md +7 -0
- package/plugin/commands/mrepair.md +7 -0
- package/plugin/commands/mstatus.md +7 -0
- package/plugin/commands/mtest.md +7 -0
- package/plugin/commands/mtestlocal.md +7 -0
- package/plugin/commands/mtestprep.md +7 -0
- package/plugin/commands/mupgrade.md +7 -0
- package/plugin/scripts/ensure-electron-app.sh +56 -6
- package/plugin/skills/_aliases.json +18 -0
- package/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/plugin/skills/_shared/use-worktrees.md +53 -0
- package/plugin/skills/do/e2e-acceptance.md +63 -18
- package/plugin/skills/do/impact-analysis.md +45 -5
- package/plugin/skills/do/open-prs.md +13 -4
- package/plugin/skills/do/pr-followup.md +225 -0
- package/plugin/skills/do/pre-flight.md +18 -11
- package/plugin/skills/m/SKILL.md +8 -0
- package/plugin/skills/mdo/SKILL.md +8 -0
- package/plugin/skills/mfeedback/SKILL.md +8 -0
- package/plugin/skills/mimport/SKILL.md +8 -0
- package/plugin/skills/mpr/SKILL.md +8 -0
- package/plugin/skills/mprefs/SKILL.md +8 -0
- package/plugin/skills/mregen/SKILL.md +8 -0
- package/plugin/skills/mrelease/SKILL.md +8 -0
- package/plugin/skills/mrepair/SKILL.md +8 -0
- package/plugin/skills/mstatus/SKILL.md +8 -0
- package/plugin/skills/mtest/SKILL.md +8 -0
- package/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/plugin/skills/mtestprep/SKILL.md +8 -0
- package/plugin/skills/muggle/SKILL.md +11 -17
- package/plugin/skills/muggle-do/SKILL.md +22 -4
- package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/plugin/skills/muggle-preferences/SKILL.md +17 -68
- package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
- package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
- package/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/plugin/skills/muggle-status/SKILL.md +14 -16
- package/plugin/skills/muggle-test/SKILL.md +148 -123
- package/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
- package/plugin/skills/muggle-test-import/SKILL.md +74 -35
- package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
- package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/plugin/skills/mupgrade/SKILL.md +8 -0
- package/scripts/postinstall.mjs +11 -1
- package/dist/src-7GB7WIFT.js +0 -1
|
@@ -11,6 +11,7 @@ import { fileURLToPath } from 'url';
|
|
|
11
11
|
import { spawn, exec } from 'child_process';
|
|
12
12
|
import axios, { AxiosError } from 'axios';
|
|
13
13
|
import * as fs7 from 'fs/promises';
|
|
14
|
+
import AppInsights from 'applicationinsights';
|
|
14
15
|
import { z } from 'zod';
|
|
15
16
|
|
|
16
17
|
var __defProp = Object.defineProperty;
|
|
@@ -33,6 +34,7 @@ __export(src_exports, {
|
|
|
33
34
|
PREFERENCES_PROJECT_DIR_NAME: () => PREFERENCES_PROJECT_DIR_NAME,
|
|
34
35
|
PREFERENCES_SCHEMA: () => PREFERENCES_SCHEMA,
|
|
35
36
|
PREFERENCES_VERSION: () => PREFERENCES_VERSION,
|
|
37
|
+
PREFERENCE_ALLOWED_VALUES: () => PREFERENCE_ALLOWED_VALUES,
|
|
36
38
|
PreferenceKey: () => PreferenceKey,
|
|
37
39
|
PreferenceValue: () => PreferenceValue,
|
|
38
40
|
buildElectronAppChecksumsUrl: () => buildElectronAppChecksumsUrl,
|
|
@@ -83,6 +85,7 @@ __export(src_exports, {
|
|
|
83
85
|
resetConfig: () => resetConfig,
|
|
84
86
|
resetLogger: () => resetLogger,
|
|
85
87
|
resetPreference: () => resetPreference,
|
|
88
|
+
resolveElectronAppPathOrNull: () => resolveElectronAppPathOrNull,
|
|
86
89
|
resolvePreferences: () => resolvePreferences,
|
|
87
90
|
saveApiKey: () => saveApiKey,
|
|
88
91
|
saveApiKeyData: () => saveApiKeyData,
|
|
@@ -394,7 +397,6 @@ function buildLocalQaConfig() {
|
|
|
394
397
|
tempDir: path2.join(dataDir, "temp"),
|
|
395
398
|
apiKeyFilePath: path2.join(dataDir, API_KEY_FILE),
|
|
396
399
|
oauthSessionFilePath: path2.join(dataDir, "oauth-session.json"),
|
|
397
|
-
electronAppPath: resolveElectronAppPathOrNull(),
|
|
398
400
|
webServicePath: resolveWebServicePath(),
|
|
399
401
|
webServicePidFile: path2.join(dataDir, "web-service.pid"),
|
|
400
402
|
auth0: {
|
|
@@ -526,9 +528,9 @@ function resetLogger() {
|
|
|
526
528
|
// packages/mcps/src/shared/checksum.ts
|
|
527
529
|
var logger = getLogger();
|
|
528
530
|
function getPlatformKey() {
|
|
529
|
-
const
|
|
531
|
+
const os5 = platform();
|
|
530
532
|
const arch2 = process.arch;
|
|
531
|
-
switch (
|
|
533
|
+
switch (os5) {
|
|
532
534
|
case "darwin":
|
|
533
535
|
return arch2 === "arm64" ? "darwin-arm64" : "darwin-x64";
|
|
534
536
|
case "win32":
|
|
@@ -536,7 +538,7 @@ function getPlatformKey() {
|
|
|
536
538
|
case "linux":
|
|
537
539
|
return "linux-x64";
|
|
538
540
|
default:
|
|
539
|
-
throw new Error(`Unsupported platform: ${
|
|
541
|
+
throw new Error(`Unsupported platform: ${os5}`);
|
|
540
542
|
}
|
|
541
543
|
}
|
|
542
544
|
async function calculateFileChecksum(filePath) {
|
|
@@ -1998,7 +2000,7 @@ function getAuthenticatedUserId() {
|
|
|
1998
2000
|
}
|
|
1999
2001
|
async function findPackageJsonAsync() {
|
|
2000
2002
|
const currentFileUrl = import.meta.url;
|
|
2001
|
-
const currentDir = path2.dirname(
|
|
2003
|
+
const currentDir = path2.dirname(fileURLToPath(currentFileUrl));
|
|
2002
2004
|
const candidatePaths = [
|
|
2003
2005
|
path2.resolve(currentDir, "../../../package.json"),
|
|
2004
2006
|
path2.resolve(currentDir, "../package.json"),
|
|
@@ -2100,29 +2102,28 @@ async function writeExecutionLogs(params) {
|
|
|
2100
2102
|
});
|
|
2101
2103
|
}
|
|
2102
2104
|
function getElectronAppPathOrThrow() {
|
|
2103
|
-
const
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
const version = getElectronAppVersion();
|
|
2107
|
-
const versionDir = getElectronAppDir(version);
|
|
2108
|
-
const envPath = process.env.ELECTRON_APP_PATH;
|
|
2109
|
-
const errorLines = [
|
|
2110
|
-
"Electron app binary not found.",
|
|
2111
|
-
"",
|
|
2112
|
-
` Expected version: ${version}`,
|
|
2113
|
-
` Checked directory: ${versionDir}`
|
|
2114
|
-
];
|
|
2115
|
-
if (envPath) {
|
|
2116
|
-
errorLines.push(` ELECTRON_APP_PATH: ${envPath} (not found or invalid)`);
|
|
2117
|
-
} else {
|
|
2118
|
-
errorLines.push(" ELECTRON_APP_PATH: (not set)");
|
|
2119
|
-
}
|
|
2120
|
-
errorLines.push("");
|
|
2121
|
-
errorLines.push("To fix this, run: muggle setup");
|
|
2122
|
-
errorLines.push("Or set ELECTRON_APP_PATH to the path of the MuggleAI executable.");
|
|
2123
|
-
throw new Error(errorLines.join("\n"));
|
|
2105
|
+
const electronAppPath = resolveElectronAppPathOrNull();
|
|
2106
|
+
if (electronAppPath && electronAppPath.trim() !== "") {
|
|
2107
|
+
return electronAppPath;
|
|
2124
2108
|
}
|
|
2125
|
-
|
|
2109
|
+
const version = getElectronAppVersion();
|
|
2110
|
+
const versionDir = getElectronAppDir(version);
|
|
2111
|
+
const envPath = process.env.ELECTRON_APP_PATH;
|
|
2112
|
+
const errorLines = [
|
|
2113
|
+
"Electron app binary not found.",
|
|
2114
|
+
"",
|
|
2115
|
+
` Expected version: ${version}`,
|
|
2116
|
+
` Checked directory: ${versionDir}`
|
|
2117
|
+
];
|
|
2118
|
+
if (envPath) {
|
|
2119
|
+
errorLines.push(` ELECTRON_APP_PATH: ${envPath} (not found or invalid)`);
|
|
2120
|
+
} else {
|
|
2121
|
+
errorLines.push(" ELECTRON_APP_PATH: (not set)");
|
|
2122
|
+
}
|
|
2123
|
+
errorLines.push("");
|
|
2124
|
+
errorLines.push("To fix this, run: muggle setup");
|
|
2125
|
+
errorLines.push("Or set ELECTRON_APP_PATH to the path of the MuggleAI executable.");
|
|
2126
|
+
throw new Error(errorLines.join("\n"));
|
|
2126
2127
|
}
|
|
2127
2128
|
function getRequiredStringField(params) {
|
|
2128
2129
|
const value = params.source[params.fieldName];
|
|
@@ -2222,7 +2223,7 @@ function buildReplayActionScript(params) {
|
|
|
2222
2223
|
async function executeElectronAppAsync(params) {
|
|
2223
2224
|
const mode = params.runType === "generation" ? "explore" : "engine";
|
|
2224
2225
|
const electronAppPath = getElectronAppPathOrThrow();
|
|
2225
|
-
const spawnArgs = [mode, params.scriptFilePath, "", params.authFilePath];
|
|
2226
|
+
const spawnArgs = [mode, params.scriptFilePath, params.mutationsFilePath ?? "", params.authFilePath];
|
|
2226
2227
|
if (params.showUi) {
|
|
2227
2228
|
spawnArgs.push("--show-ui");
|
|
2228
2229
|
}
|
|
@@ -2370,11 +2371,16 @@ async function executeTestGeneration(params) {
|
|
|
2370
2371
|
filename: `${runId}_auth.json`,
|
|
2371
2372
|
data: authContent
|
|
2372
2373
|
});
|
|
2374
|
+
const mutationsFilePath = params.mutations && params.mutations.length > 0 ? await writeTempFile({
|
|
2375
|
+
filename: `${runId}_mutations.json`,
|
|
2376
|
+
data: params.mutations
|
|
2377
|
+
}) : void 0;
|
|
2373
2378
|
try {
|
|
2374
2379
|
const executionResult = await executeElectronAppAsync({
|
|
2375
2380
|
runId,
|
|
2376
2381
|
runType: "generation",
|
|
2377
2382
|
scriptFilePath: inputFilePath,
|
|
2383
|
+
mutationsFilePath,
|
|
2378
2384
|
authFilePath,
|
|
2379
2385
|
timeoutMs,
|
|
2380
2386
|
showUi: params.showUi,
|
|
@@ -2517,11 +2523,16 @@ async function executeReplay(params) {
|
|
|
2517
2523
|
filename: `${runId}_auth.json`,
|
|
2518
2524
|
data: authContent
|
|
2519
2525
|
});
|
|
2526
|
+
const mutationsFilePath = params.mutations && params.mutations.length > 0 ? await writeTempFile({
|
|
2527
|
+
filename: `${runId}_mutations.json`,
|
|
2528
|
+
data: params.mutations
|
|
2529
|
+
}) : void 0;
|
|
2520
2530
|
try {
|
|
2521
2531
|
const executionResult = await executeElectronAppAsync({
|
|
2522
2532
|
runId,
|
|
2523
2533
|
runType: "replay",
|
|
2524
2534
|
scriptFilePath: inputFilePath,
|
|
2535
|
+
mutationsFilePath,
|
|
2525
2536
|
authFilePath,
|
|
2526
2537
|
timeoutMs,
|
|
2527
2538
|
showUi: params.showUi,
|
|
@@ -2990,6 +3001,268 @@ __export(e2e_exports, {
|
|
|
2990
3001
|
executeQaTool: () => executeQaTool,
|
|
2991
3002
|
getQaToolByName: () => getQaToolByName
|
|
2992
3003
|
});
|
|
3004
|
+
|
|
3005
|
+
var ENV_CONNECTION_STRING = "APPLICATIONINSIGHTS_CONNECTION_STRING";
|
|
3006
|
+
var ENV_VITE_CONNECTION_STRING = "VITE_APPLICATIONINSIGHTS_CONNECTION_STRING";
|
|
3007
|
+
var ENV_TELEMETRY_DISABLED = "MUGGLE_TELEMETRY_DISABLED";
|
|
3008
|
+
|
|
3009
|
+
var DATA_DIR_NAME2 = ".muggle-ai";
|
|
3010
|
+
var INSTALL_ID_FILENAME = "install-id.json";
|
|
3011
|
+
var PREFS_FILENAME = "preferences.json";
|
|
3012
|
+
var OAUTH_SESSION_FILENAME = "oauth-session.json";
|
|
3013
|
+
var RELEASE_MANIFEST_FILENAME = "release-manifest.json";
|
|
3014
|
+
function getDataDir3() {
|
|
3015
|
+
return path2.join(os3.homedir(), DATA_DIR_NAME2);
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
var cachedInstallId;
|
|
3019
|
+
function installIdFilePath() {
|
|
3020
|
+
return join(getDataDir3(), INSTALL_ID_FILENAME);
|
|
3021
|
+
}
|
|
3022
|
+
function generateAndPersist(filePath) {
|
|
3023
|
+
const installId = randomUUID();
|
|
3024
|
+
const contents = { installId };
|
|
3025
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
3026
|
+
writeFileSync(filePath, JSON.stringify(contents, null, 2) + "\n", "utf8");
|
|
3027
|
+
return installId;
|
|
3028
|
+
}
|
|
3029
|
+
function isValid(value) {
|
|
3030
|
+
return typeof value === "object" && value !== null && typeof value.installId === "string" && value.installId.length > 0;
|
|
3031
|
+
}
|
|
3032
|
+
function getInstallId() {
|
|
3033
|
+
if (cachedInstallId !== void 0)
|
|
3034
|
+
return cachedInstallId;
|
|
3035
|
+
const filePath = installIdFilePath();
|
|
3036
|
+
if (!existsSync(filePath)) {
|
|
3037
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
3038
|
+
return cachedInstallId;
|
|
3039
|
+
}
|
|
3040
|
+
try {
|
|
3041
|
+
const raw = readFileSync(filePath, "utf8");
|
|
3042
|
+
const parsed = JSON.parse(raw);
|
|
3043
|
+
if (isValid(parsed)) {
|
|
3044
|
+
cachedInstallId = parsed.installId;
|
|
3045
|
+
return cachedInstallId;
|
|
3046
|
+
}
|
|
3047
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
3048
|
+
return cachedInstallId;
|
|
3049
|
+
} catch {
|
|
3050
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
3051
|
+
return cachedInstallId;
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
var DEV_MANIFEST2 = {
|
|
3056
|
+
release: "dev",
|
|
3057
|
+
buildId: "dev",
|
|
3058
|
+
commitSha: "dev",
|
|
3059
|
+
buildTime: "1970-01-01T00:00:00Z",
|
|
3060
|
+
serviceName: "muggle-ai-telemetry"
|
|
3061
|
+
};
|
|
3062
|
+
|
|
3063
|
+
var MANIFEST_PATH2 = (() => {
|
|
3064
|
+
try {
|
|
3065
|
+
return join(dirname(fileURLToPath(import.meta.url)), RELEASE_MANIFEST_FILENAME);
|
|
3066
|
+
} catch {
|
|
3067
|
+
return RELEASE_MANIFEST_FILENAME;
|
|
3068
|
+
}
|
|
3069
|
+
})();
|
|
3070
|
+
var cachedManifest2;
|
|
3071
|
+
function isValid2(value) {
|
|
3072
|
+
if (typeof value !== "object" || value === null)
|
|
3073
|
+
return false;
|
|
3074
|
+
const m = value;
|
|
3075
|
+
return typeof m.release === "string" && typeof m.buildId === "string" && typeof m.commitSha === "string" && typeof m.buildTime === "string" && typeof m.serviceName === "string";
|
|
3076
|
+
}
|
|
3077
|
+
function readReleaseManifest2() {
|
|
3078
|
+
if (cachedManifest2 !== void 0)
|
|
3079
|
+
return cachedManifest2;
|
|
3080
|
+
const path15 = MANIFEST_PATH2;
|
|
3081
|
+
try {
|
|
3082
|
+
const raw = readFileSync(path15, "utf8");
|
|
3083
|
+
const parsed = JSON.parse(raw);
|
|
3084
|
+
cachedManifest2 = isValid2(parsed) ? parsed : DEV_MANIFEST2;
|
|
3085
|
+
return cachedManifest2;
|
|
3086
|
+
} catch (err) {
|
|
3087
|
+
const code = err.code;
|
|
3088
|
+
if (code !== "ENOENT") {
|
|
3089
|
+
console.warn("release-manifest: unexpected read error, using DEV fallback", {
|
|
3090
|
+
error: err.message
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
cachedManifest2 = DEV_MANIFEST2;
|
|
3094
|
+
return cachedManifest2;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
function readUserId() {
|
|
3098
|
+
const filePath = join(getDataDir3(), OAUTH_SESSION_FILENAME);
|
|
3099
|
+
if (!existsSync(filePath))
|
|
3100
|
+
return void 0;
|
|
3101
|
+
try {
|
|
3102
|
+
const raw = readFileSync(filePath, "utf8");
|
|
3103
|
+
const parsed = JSON.parse(raw);
|
|
3104
|
+
if (typeof parsed.userId === "string" && parsed.userId.length > 0) {
|
|
3105
|
+
return parsed.userId;
|
|
3106
|
+
}
|
|
3107
|
+
return void 0;
|
|
3108
|
+
} catch {
|
|
3109
|
+
return void 0;
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3113
|
+
var state = null;
|
|
3114
|
+
function resolveConnectionString(explicit) {
|
|
3115
|
+
if (explicit && explicit.length > 0)
|
|
3116
|
+
return explicit;
|
|
3117
|
+
return process.env[ENV_CONNECTION_STRING] ?? process.env[ENV_VITE_CONNECTION_STRING] ?? void 0;
|
|
3118
|
+
}
|
|
3119
|
+
function buildCommonProperties(serviceName, surface) {
|
|
3120
|
+
const manifest = readReleaseManifest2();
|
|
3121
|
+
const props = {
|
|
3122
|
+
source: "client",
|
|
3123
|
+
serviceName,
|
|
3124
|
+
surface,
|
|
3125
|
+
release: manifest.release,
|
|
3126
|
+
buildId: manifest.buildId,
|
|
3127
|
+
commitSha: manifest.commitSha,
|
|
3128
|
+
buildTime: manifest.buildTime,
|
|
3129
|
+
installId: getInstallId(),
|
|
3130
|
+
nodeVersion: process.version,
|
|
3131
|
+
platform: process.platform
|
|
3132
|
+
};
|
|
3133
|
+
const userId = readUserId();
|
|
3134
|
+
if (userId !== void 0)
|
|
3135
|
+
props.userId = userId;
|
|
3136
|
+
return props;
|
|
3137
|
+
}
|
|
3138
|
+
function initTelemetry(options) {
|
|
3139
|
+
if (state !== null && state.initialized)
|
|
3140
|
+
return;
|
|
3141
|
+
const connectionString = resolveConnectionString(options.connectionString);
|
|
3142
|
+
if (!connectionString) {
|
|
3143
|
+
state = {
|
|
3144
|
+
client: null,
|
|
3145
|
+
serviceName: options.serviceName,
|
|
3146
|
+
surface: options.surface,
|
|
3147
|
+
initialized: true
|
|
3148
|
+
};
|
|
3149
|
+
return;
|
|
3150
|
+
}
|
|
3151
|
+
try {
|
|
3152
|
+
AppInsights.setup(connectionString).setUseDiskRetryCaching(true).setDistributedTracingMode(AppInsights.DistributedTracingModes.AI_AND_W3C).setAutoCollectRequests(false).setAutoCollectPerformance(false, false).setAutoCollectExceptions(true).setAutoCollectDependencies(false).setAutoCollectConsole(false).setSendLiveMetrics(false);
|
|
3153
|
+
const client = AppInsights.defaultClient;
|
|
3154
|
+
const manifest = readReleaseManifest2();
|
|
3155
|
+
client.context.tags[client.context.keys.cloudRole] = options.serviceName;
|
|
3156
|
+
client.context.tags[client.context.keys.applicationVersion] = manifest.release;
|
|
3157
|
+
client.commonProperties = {
|
|
3158
|
+
...client.commonProperties,
|
|
3159
|
+
...buildCommonProperties(options.serviceName, options.surface)
|
|
3160
|
+
};
|
|
3161
|
+
AppInsights.start();
|
|
3162
|
+
state = {
|
|
3163
|
+
client,
|
|
3164
|
+
serviceName: options.serviceName,
|
|
3165
|
+
surface: options.surface,
|
|
3166
|
+
initialized: true
|
|
3167
|
+
};
|
|
3168
|
+
} catch (err) {
|
|
3169
|
+
console.warn("[muggle-telemetry] init failed; events will be dropped", {
|
|
3170
|
+
error: err.message
|
|
3171
|
+
});
|
|
3172
|
+
state = {
|
|
3173
|
+
client: null,
|
|
3174
|
+
serviceName: options.serviceName,
|
|
3175
|
+
surface: options.surface,
|
|
3176
|
+
initialized: true
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
function getClient() {
|
|
3181
|
+
return state?.client ?? null;
|
|
3182
|
+
}
|
|
3183
|
+
function prefsFilePath() {
|
|
3184
|
+
return join(getDataDir3(), PREFS_FILENAME);
|
|
3185
|
+
}
|
|
3186
|
+
function readPreferences() {
|
|
3187
|
+
const filePath = prefsFilePath();
|
|
3188
|
+
if (!existsSync(filePath))
|
|
3189
|
+
return {};
|
|
3190
|
+
try {
|
|
3191
|
+
const raw = readFileSync(filePath, "utf8");
|
|
3192
|
+
const parsed = JSON.parse(raw);
|
|
3193
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
3194
|
+
return parsed;
|
|
3195
|
+
}
|
|
3196
|
+
return {};
|
|
3197
|
+
} catch {
|
|
3198
|
+
return {};
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
function isTelemetryEnabled() {
|
|
3203
|
+
if (process.env[ENV_TELEMETRY_DISABLED] === "1")
|
|
3204
|
+
return false;
|
|
3205
|
+
const prefs = readPreferences();
|
|
3206
|
+
if (prefs.telemetryEnabled === false)
|
|
3207
|
+
return false;
|
|
3208
|
+
return true;
|
|
3209
|
+
}
|
|
3210
|
+
|
|
3211
|
+
function track(event) {
|
|
3212
|
+
if (!isTelemetryEnabled())
|
|
3213
|
+
return;
|
|
3214
|
+
const client = getClient();
|
|
3215
|
+
if (!client)
|
|
3216
|
+
return;
|
|
3217
|
+
try {
|
|
3218
|
+
client.trackEvent({
|
|
3219
|
+
name: event.name,
|
|
3220
|
+
properties: event.props
|
|
3221
|
+
});
|
|
3222
|
+
} catch {
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
|
|
3226
|
+
var Trigger;
|
|
3227
|
+
(function(Trigger2) {
|
|
3228
|
+
Trigger2["UserSlash"] = "user-slash";
|
|
3229
|
+
Trigger2["ClaudeProactive"] = "claude-proactive";
|
|
3230
|
+
Trigger2["NestedSkill"] = "nested-skill";
|
|
3231
|
+
})(Trigger || (Trigger = {}));
|
|
3232
|
+
var Outcome;
|
|
3233
|
+
(function(Outcome2) {
|
|
3234
|
+
Outcome2["Success"] = "success";
|
|
3235
|
+
Outcome2["Error"] = "error";
|
|
3236
|
+
Outcome2["Cancelled"] = "cancelled";
|
|
3237
|
+
})(Outcome || (Outcome = {}));
|
|
3238
|
+
var ToolSurface;
|
|
3239
|
+
(function(ToolSurface2) {
|
|
3240
|
+
ToolSurface2["Local"] = "local";
|
|
3241
|
+
ToolSurface2["Remote"] = "remote";
|
|
3242
|
+
})(ToolSurface || (ToolSurface = {}));
|
|
3243
|
+
var Surface;
|
|
3244
|
+
(function(Surface2) {
|
|
3245
|
+
Surface2["McpLocal"] = "mcp-local";
|
|
3246
|
+
Surface2["McpRemote"] = "mcp-remote";
|
|
3247
|
+
Surface2["Skill"] = "skill";
|
|
3248
|
+
Surface2["Electron"] = "electron";
|
|
3249
|
+
})(Surface || (Surface = {}));
|
|
3250
|
+
var ServiceName;
|
|
3251
|
+
(function(ServiceName2) {
|
|
3252
|
+
ServiceName2["MuggleMcp"] = "muggle-mcp";
|
|
3253
|
+
ServiceName2["MuggleElectron"] = "muggle-electron";
|
|
3254
|
+
ServiceName2["MuggleSkill"] = "muggle-skill";
|
|
3255
|
+
})(ServiceName || (ServiceName = {}));
|
|
3256
|
+
var EventName;
|
|
3257
|
+
(function(EventName2) {
|
|
3258
|
+
EventName2["SkillInvoked"] = "skill.invoked";
|
|
3259
|
+
EventName2["SkillCompleted"] = "skill.completed";
|
|
3260
|
+
EventName2["McpToolInvoked"] = "mcp.tool.invoked";
|
|
3261
|
+
EventName2["McpToolCompleted"] = "mcp.tool.completed";
|
|
3262
|
+
EventName2["SystemStartup"] = "system.startup";
|
|
3263
|
+
EventName2["SystemOptOutChanged"] = "system.opt_out_changed";
|
|
3264
|
+
EventName2["SystemDisclosureShown"] = "system.disclosure_shown";
|
|
3265
|
+
})(EventName || (EventName = {}));
|
|
2993
3266
|
var MuggleEntityIdSchema = z.string().uuid();
|
|
2994
3267
|
var LocalExecutionContextInputSchema = z.object({
|
|
2995
3268
|
originalUrl: z.string().url().describe("Original local URL used during local execution (typically localhost)"),
|
|
@@ -3133,6 +3406,21 @@ var UseCaseUpdateFromPromptInputSchema = z.object({
|
|
|
3133
3406
|
useCaseId: IdSchema.describe("Use case ID (UUID) to update"),
|
|
3134
3407
|
instruction: z.string().min(1).describe("Natural language instruction to regenerate the use case from")
|
|
3135
3408
|
});
|
|
3409
|
+
var UseCaseUpdateInputSchema = z.object({
|
|
3410
|
+
useCaseId: IdSchema.describe("Use case ID (UUID) to update"),
|
|
3411
|
+
title: z.string().min(1).optional().describe("Updated use case title"),
|
|
3412
|
+
description: z.string().min(1).optional().describe("Updated description"),
|
|
3413
|
+
userStory: z.string().min(1).optional().describe("Updated one-line user story"),
|
|
3414
|
+
url: z.string().url().optional().describe("Updated target URL"),
|
|
3415
|
+
useCaseBreakdown: z.array(z.object({
|
|
3416
|
+
requirement: z.string().min(1).describe("One requirement of the use case"),
|
|
3417
|
+
acceptanceCriteria: z.string().min(1).describe("Concrete, measurable acceptance criteria for the requirement")
|
|
3418
|
+
})).optional().describe("Updated main/alternative/error flows as requirement + acceptance criteria pairs"),
|
|
3419
|
+
status: z.enum(["DRAFT", "IN_REVIEW", "APPROVED", "IMPLEMENTED", "ARCHIVED"]).optional().describe("Updated status"),
|
|
3420
|
+
priority: z.enum(["LOW", "MEDIUM", "HIGH", "CRITICAL"]).optional().describe("Updated priority"),
|
|
3421
|
+
source: z.enum(["PRD_FILE", "SITEMAP", "CRAWLER", "PROMPT", "MANUAL"]).optional().describe("Updated source"),
|
|
3422
|
+
category: z.string().optional().describe("Updated category")
|
|
3423
|
+
});
|
|
3136
3424
|
var UseCaseCreateInputSchema = z.object({
|
|
3137
3425
|
projectId: IdSchema.describe("Project ID (UUID) the use case belongs to"),
|
|
3138
3426
|
title: z.string().min(1).describe("Use case title"),
|
|
@@ -3216,6 +3504,20 @@ var TestCaseCreateInputSchema = z.object({
|
|
|
3216
3504
|
category: z.string().optional().describe("Test case category"),
|
|
3217
3505
|
automated: z.boolean().optional().describe("Whether this test case is automated (default: true)")
|
|
3218
3506
|
});
|
|
3507
|
+
var TestCaseUpdateInputSchema = z.object({
|
|
3508
|
+
testCaseId: IdSchema.describe("Test case ID (UUID) to update"),
|
|
3509
|
+
title: z.string().min(1).optional().describe("Updated test case title"),
|
|
3510
|
+
description: z.string().min(1).optional().describe("Updated description"),
|
|
3511
|
+
goal: z.string().min(1).optional().describe("Updated goal"),
|
|
3512
|
+
precondition: z.string().optional().describe("Updated precondition"),
|
|
3513
|
+
expectedResult: z.string().min(1).optional().describe("Updated expected result"),
|
|
3514
|
+
url: z.string().url().optional().describe("Updated target URL"),
|
|
3515
|
+
status: z.enum(["DRAFT", "ACTIVE", "DEPRECATED", "ARCHIVED"]).optional().describe("Updated status"),
|
|
3516
|
+
priority: z.enum(["HIGH", "MEDIUM", "LOW"]).optional().describe("Updated priority"),
|
|
3517
|
+
tags: z.array(z.string()).optional().describe("Updated tags"),
|
|
3518
|
+
category: z.string().optional().describe("Updated category"),
|
|
3519
|
+
automated: z.boolean().optional().describe("Whether this test case is automated")
|
|
3520
|
+
});
|
|
3219
3521
|
var TestScriptListInputSchema = z.object({
|
|
3220
3522
|
projectId: IdSchema.describe("Project ID (UUID) to list test scripts for"),
|
|
3221
3523
|
testCaseId: IdSchema.optional().describe("Optional test case ID (UUID) to filter scripts by")
|
|
@@ -3366,6 +3668,34 @@ var ApiKeyGetInputSchema = z.object({
|
|
|
3366
3668
|
var ApiKeyRevokeInputSchema = z.object({
|
|
3367
3669
|
apiKeyId: ApiKeyRecordIdSchema.describe("ID of the API key record to revoke")
|
|
3368
3670
|
});
|
|
3671
|
+
var UserFeedbackTargetTypeSchema = z.enum(["actionScript", "step"]);
|
|
3672
|
+
var UserFeedbackTargetSchema = z.object({
|
|
3673
|
+
targetType: UserFeedbackTargetTypeSchema.describe("Target entity kind: 'actionScript' for whole-script feedback, 'step' for a specific step"),
|
|
3674
|
+
targetId: z.string().min(1).describe("Target identifier. For 'actionScript' use the actionScriptId; for 'step' use `${actionScriptId}:${stepIndex}` (0-based stepIndex)")
|
|
3675
|
+
});
|
|
3676
|
+
var UserFeedbackCreateInputSchema = z.object({
|
|
3677
|
+
projectId: IdSchema.describe("Project ID (UUID) the feedback belongs to"),
|
|
3678
|
+
target: UserFeedbackTargetSchema.describe("What entity this feedback is about (action script or a specific step)"),
|
|
3679
|
+
feedbackText: z.string().min(1).describe("Free-form paragraph describing what went wrong and what the expected behavior should be")
|
|
3680
|
+
});
|
|
3681
|
+
var UserFeedbackListInputSchema = z.object({
|
|
3682
|
+
projectId: IdSchema.describe("Project ID (UUID) to list feedback for. Always required \u2014 defines the auth boundary."),
|
|
3683
|
+
actionScriptId: IdSchema.optional().describe("Narrow to feedback whose target resolves to this action script. Mutually exclusive with the other narrowing filters."),
|
|
3684
|
+
testScriptId: IdSchema.optional().describe("Narrow to feedback on the action script of this test script. Mutually exclusive with the other narrowing filters."),
|
|
3685
|
+
testCaseId: IdSchema.optional().describe("Narrow to feedback on any action script ever generated for this test case. Mutually exclusive with the other narrowing filters."),
|
|
3686
|
+
useCaseId: IdSchema.optional().describe("Narrow to feedback on any action script ever generated under this use case. Mutually exclusive with the other narrowing filters."),
|
|
3687
|
+
limit: z.number().int().positive().max(1e3).optional().describe("Max entries to return (default 100)"),
|
|
3688
|
+
offset: z.number().int().min(0).optional().describe("Offset for pagination (default 0)")
|
|
3689
|
+
}).refine(
|
|
3690
|
+
(data) => {
|
|
3691
|
+
const set = [data.actionScriptId, data.testScriptId, data.testCaseId, data.useCaseId].filter(Boolean);
|
|
3692
|
+
return set.length <= 1;
|
|
3693
|
+
},
|
|
3694
|
+
{ message: "At most one of actionScriptId / testScriptId / testCaseId / useCaseId may be set" }
|
|
3695
|
+
);
|
|
3696
|
+
var UserFeedbackDeleteInputSchema = z.object({
|
|
3697
|
+
feedbackId: IdSchema.describe("User feedback ID (UUID) to soft-delete")
|
|
3698
|
+
});
|
|
3369
3699
|
var AuthLoginInputSchema = z.object({
|
|
3370
3700
|
waitForCompletion: z.boolean().optional().describe("Whether to wait for browser login completion before returning. Default: true"),
|
|
3371
3701
|
timeoutMs: z.number().int().positive().min(1e3).max(9e5).optional().describe("Maximum time to wait for login completion in milliseconds. Default: 120000"),
|
|
@@ -3418,40 +3748,40 @@ function detectMcpHost(env = process.env) {
|
|
|
3418
3748
|
}
|
|
3419
3749
|
return "unknown";
|
|
3420
3750
|
}
|
|
3421
|
-
var
|
|
3422
|
-
var
|
|
3423
|
-
function
|
|
3424
|
-
return join(getDataDir(),
|
|
3751
|
+
var INSTALL_ID_FILENAME2 = "install-id.json";
|
|
3752
|
+
var cachedInstallId2;
|
|
3753
|
+
function installIdFilePath2() {
|
|
3754
|
+
return join(getDataDir(), INSTALL_ID_FILENAME2);
|
|
3425
3755
|
}
|
|
3426
|
-
function
|
|
3756
|
+
function generateAndPersist2(filePath) {
|
|
3427
3757
|
const installId = randomUUID();
|
|
3428
3758
|
const contents = { installId };
|
|
3429
3759
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
3430
3760
|
writeFileSync(filePath, JSON.stringify(contents, null, 2) + "\n", "utf8");
|
|
3431
3761
|
return installId;
|
|
3432
3762
|
}
|
|
3433
|
-
function
|
|
3763
|
+
function isValid3(value) {
|
|
3434
3764
|
return typeof value === "object" && value !== null && typeof value.installId === "string" && value.installId.length > 0;
|
|
3435
3765
|
}
|
|
3436
|
-
function
|
|
3437
|
-
if (
|
|
3438
|
-
const filePath =
|
|
3766
|
+
function getInstallId2() {
|
|
3767
|
+
if (cachedInstallId2 !== void 0) return cachedInstallId2;
|
|
3768
|
+
const filePath = installIdFilePath2();
|
|
3439
3769
|
if (!existsSync(filePath)) {
|
|
3440
|
-
|
|
3441
|
-
return
|
|
3770
|
+
cachedInstallId2 = generateAndPersist2(filePath);
|
|
3771
|
+
return cachedInstallId2;
|
|
3442
3772
|
}
|
|
3443
3773
|
try {
|
|
3444
3774
|
const raw = readFileSync(filePath, "utf8");
|
|
3445
3775
|
const parsed = JSON.parse(raw);
|
|
3446
|
-
if (
|
|
3447
|
-
|
|
3448
|
-
return
|
|
3776
|
+
if (isValid3(parsed)) {
|
|
3777
|
+
cachedInstallId2 = parsed.installId;
|
|
3778
|
+
return cachedInstallId2;
|
|
3449
3779
|
}
|
|
3450
|
-
|
|
3451
|
-
return
|
|
3780
|
+
cachedInstallId2 = generateAndPersist2(filePath);
|
|
3781
|
+
return cachedInstallId2;
|
|
3452
3782
|
} catch {
|
|
3453
|
-
|
|
3454
|
-
return
|
|
3783
|
+
cachedInstallId2 = generateAndPersist2(filePath);
|
|
3784
|
+
return cachedInstallId2;
|
|
3455
3785
|
}
|
|
3456
3786
|
}
|
|
3457
3787
|
|
|
@@ -3481,17 +3811,17 @@ var PromptServiceClient = class {
|
|
|
3481
3811
|
* @param path - Path to validate.
|
|
3482
3812
|
* @throws GatewayError if path is not allowed.
|
|
3483
3813
|
*/
|
|
3484
|
-
validatePath(
|
|
3485
|
-
const isAllowed = ALLOWED_UPSTREAM_PREFIXES.some((prefix) =>
|
|
3814
|
+
validatePath(path15) {
|
|
3815
|
+
const isAllowed = ALLOWED_UPSTREAM_PREFIXES.some((prefix) => path15.startsWith(prefix));
|
|
3486
3816
|
if (!isAllowed) {
|
|
3487
3817
|
const logger6 = getLogger();
|
|
3488
3818
|
logger6.error("Path not in allowlist", {
|
|
3489
|
-
path:
|
|
3819
|
+
path: path15,
|
|
3490
3820
|
allowedPrefixes: ALLOWED_UPSTREAM_PREFIXES
|
|
3491
3821
|
});
|
|
3492
3822
|
throw new GatewayError({
|
|
3493
3823
|
code: "FORBIDDEN" /* FORBIDDEN */,
|
|
3494
|
-
message: `Path '${
|
|
3824
|
+
message: `Path '${path15}' is not allowed`
|
|
3495
3825
|
});
|
|
3496
3826
|
}
|
|
3497
3827
|
}
|
|
@@ -3503,7 +3833,7 @@ var PromptServiceClient = class {
|
|
|
3503
3833
|
*/
|
|
3504
3834
|
buildHeaders(credentials, correlationId) {
|
|
3505
3835
|
const manifest = readReleaseManifest();
|
|
3506
|
-
const installId =
|
|
3836
|
+
const installId = getInstallId2();
|
|
3507
3837
|
const host = detectMcpHost();
|
|
3508
3838
|
const headers = {
|
|
3509
3839
|
"X-Correlation-Id": correlationId,
|
|
@@ -3889,6 +4219,29 @@ var useCaseTools = [
|
|
|
3889
4219
|
};
|
|
3890
4220
|
}
|
|
3891
4221
|
},
|
|
4222
|
+
{
|
|
4223
|
+
name: "muggle-remote-use-case-update",
|
|
4224
|
+
description: "Directly update an existing use case's fields without invoking the LLM. Pass only the fields you want to change \u2014 others are left untouched. Use this for cheap, deterministic edits (rename, flip status DRAFT\u2192APPROVED, change priority, edit acceptance criteria). For LLM regeneration from a new instruction, use muggle-remote-use-case-update-from-prompt instead. Note: changing title, description, or url triggers background regeneration of dependent test cases on the server.",
|
|
4225
|
+
inputSchema: UseCaseUpdateInputSchema,
|
|
4226
|
+
mapToUpstream: (input) => {
|
|
4227
|
+
const data = input;
|
|
4228
|
+
const body = { id: data.useCaseId };
|
|
4229
|
+
if (data.title !== void 0) body.title = data.title;
|
|
4230
|
+
if (data.description !== void 0) body.description = data.description;
|
|
4231
|
+
if (data.userStory !== void 0) body.userStory = data.userStory;
|
|
4232
|
+
if (data.url !== void 0) body.url = data.url;
|
|
4233
|
+
if (data.useCaseBreakdown !== void 0) body.useCaseBreakdown = data.useCaseBreakdown;
|
|
4234
|
+
if (data.status !== void 0) body.status = data.status;
|
|
4235
|
+
if (data.priority !== void 0) body.priority = data.priority;
|
|
4236
|
+
if (data.source !== void 0) body.source = data.source;
|
|
4237
|
+
if (data.category !== void 0) body.category = data.category;
|
|
4238
|
+
return {
|
|
4239
|
+
method: "PUT",
|
|
4240
|
+
path: `${MUGGLE_TEST_PREFIX}/use-cases/${data.useCaseId}`,
|
|
4241
|
+
body
|
|
4242
|
+
};
|
|
4243
|
+
}
|
|
4244
|
+
},
|
|
3892
4245
|
{
|
|
3893
4246
|
name: "muggle-remote-use-case-create",
|
|
3894
4247
|
description: "Create a single use case from a fully-specified payload. Use this to persist use cases returned by muggle-remote-use-case-bulk-preview-submit \u2014 no LLM is invoked.",
|
|
@@ -4011,6 +4364,31 @@ var testCaseTools = [
|
|
|
4011
4364
|
};
|
|
4012
4365
|
}
|
|
4013
4366
|
},
|
|
4367
|
+
{
|
|
4368
|
+
name: "muggle-remote-test-case-update",
|
|
4369
|
+
description: "Directly update an existing test case's fields. Pass only the fields you want to change \u2014 others are left untouched. Use this for cheap, deterministic edits (rename, change status/priority, fix expected result, add tags). Does not touch the associated test script \u2014 script regeneration is a separate workflow (muggle-remote-workflow-start-test-script-generation).",
|
|
4370
|
+
inputSchema: TestCaseUpdateInputSchema,
|
|
4371
|
+
mapToUpstream: (input) => {
|
|
4372
|
+
const data = input;
|
|
4373
|
+
const body = { id: data.testCaseId };
|
|
4374
|
+
if (data.title !== void 0) body.title = data.title;
|
|
4375
|
+
if (data.description !== void 0) body.description = data.description;
|
|
4376
|
+
if (data.goal !== void 0) body.goal = data.goal;
|
|
4377
|
+
if (data.precondition !== void 0) body.precondition = data.precondition;
|
|
4378
|
+
if (data.expectedResult !== void 0) body.expectedResult = data.expectedResult;
|
|
4379
|
+
if (data.url !== void 0) body.url = data.url;
|
|
4380
|
+
if (data.status !== void 0) body.status = data.status;
|
|
4381
|
+
if (data.priority !== void 0) body.priority = data.priority;
|
|
4382
|
+
if (data.tags !== void 0) body.tags = data.tags;
|
|
4383
|
+
if (data.category !== void 0) body.category = data.category;
|
|
4384
|
+
if (data.automated !== void 0) body.automated = data.automated;
|
|
4385
|
+
return {
|
|
4386
|
+
method: "PUT",
|
|
4387
|
+
path: `${MUGGLE_TEST_PREFIX}/test-cases/${data.testCaseId}`,
|
|
4388
|
+
body
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4391
|
+
},
|
|
4014
4392
|
{
|
|
4015
4393
|
name: "muggle-remote-test-case-bulk-preview-submit",
|
|
4016
4394
|
description: "Submit an async bulk-preview job that uses the OpenAI Batch API to generate test cases for a single use case from many prompts at ~50% of normal LLM cost. Returns a job ID immediately; poll with muggle-remote-bulk-preview-job-get until the job reaches a terminal status, then persist each successful result via muggle-remote-test-case-create. Note: one input prompt may fan out to 1\u20135 test cases.",
|
|
@@ -4979,6 +5357,58 @@ var apiKeyTools = [
|
|
|
4979
5357
|
}
|
|
4980
5358
|
}
|
|
4981
5359
|
];
|
|
5360
|
+
var userFeedbackTools = [
|
|
5361
|
+
{
|
|
5362
|
+
name: "muggle-remote-user-feedback-create",
|
|
5363
|
+
description: "Submit user feedback on a generated action script \u2014 either the whole script (targetType='actionScript', targetId=actionScriptId) or a specific step (targetType='step', targetId=`${actionScriptId}:${stepIndex}` with 0-based stepIndex). Persists the feedback and triggers an async feedback-analysis workflow that may regenerate the script. The response includes the saved feedback and, when the analysis workflow was started, a feedbackAnalysisWorkflowRuntimeId for polling.",
|
|
5364
|
+
inputSchema: UserFeedbackCreateInputSchema,
|
|
5365
|
+
mapToUpstream: (input) => {
|
|
5366
|
+
const data = input;
|
|
5367
|
+
return {
|
|
5368
|
+
method: "POST",
|
|
5369
|
+
path: `${MUGGLE_TEST_PREFIX}/user-feedback`,
|
|
5370
|
+
body: {
|
|
5371
|
+
projectId: data.projectId,
|
|
5372
|
+
target: data.target,
|
|
5373
|
+
feedbackText: data.feedbackText
|
|
5374
|
+
}
|
|
5375
|
+
};
|
|
5376
|
+
}
|
|
5377
|
+
},
|
|
5378
|
+
{
|
|
5379
|
+
name: "muggle-remote-user-feedback-list",
|
|
5380
|
+
description: "List active user feedback entries for a project. Optionally narrow by exactly one of actionScriptId / testScriptId / testCaseId / useCaseId \u2014 the typical query is 'show me feedback on this test case (or test script, or use case).' Supports limit/offset pagination. Response: { feedback: IUserFeedback[], total: number, hasMore: boolean }.",
|
|
5381
|
+
inputSchema: UserFeedbackListInputSchema,
|
|
5382
|
+
mapToUpstream: (input) => {
|
|
5383
|
+
const data = input;
|
|
5384
|
+
return {
|
|
5385
|
+
method: "GET",
|
|
5386
|
+
path: `${MUGGLE_TEST_PREFIX}/user-feedback`,
|
|
5387
|
+
queryParams: {
|
|
5388
|
+
projectId: data.projectId,
|
|
5389
|
+
actionScriptId: data.actionScriptId,
|
|
5390
|
+
testScriptId: data.testScriptId,
|
|
5391
|
+
testCaseId: data.testCaseId,
|
|
5392
|
+
useCaseId: data.useCaseId,
|
|
5393
|
+
limit: data.limit,
|
|
5394
|
+
offset: data.offset
|
|
5395
|
+
}
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
},
|
|
5399
|
+
{
|
|
5400
|
+
name: "muggle-remote-user-feedback-delete",
|
|
5401
|
+
description: "Soft-delete a user feedback entry by ID. Returns 204 on success.",
|
|
5402
|
+
inputSchema: UserFeedbackDeleteInputSchema,
|
|
5403
|
+
mapToUpstream: (input) => {
|
|
5404
|
+
const data = input;
|
|
5405
|
+
return {
|
|
5406
|
+
method: "DELETE",
|
|
5407
|
+
path: `${MUGGLE_TEST_PREFIX}/user-feedback/${data.feedbackId}`
|
|
5408
|
+
};
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
];
|
|
4982
5412
|
var authTools = [
|
|
4983
5413
|
{
|
|
4984
5414
|
name: "muggle-remote-auth-status",
|
|
@@ -5115,6 +5545,7 @@ var allQaToolDefinitions = [
|
|
|
5115
5545
|
...walletTools,
|
|
5116
5546
|
...recommendationTools,
|
|
5117
5547
|
...apiKeyTools,
|
|
5548
|
+
...userFeedbackTools,
|
|
5118
5549
|
...authTools
|
|
5119
5550
|
];
|
|
5120
5551
|
function getQaToolByName(name) {
|
|
@@ -5132,6 +5563,13 @@ async function executeQaTool(toolName, input, correlationId) {
|
|
|
5132
5563
|
isError: true
|
|
5133
5564
|
};
|
|
5134
5565
|
}
|
|
5566
|
+
const startTime = Date.now();
|
|
5567
|
+
safeTrack({
|
|
5568
|
+
name: EventName.McpToolInvoked,
|
|
5569
|
+
props: { toolName, toolSurface: ToolSurface.Remote, correlationId }
|
|
5570
|
+
});
|
|
5571
|
+
let outcome = Outcome.Success;
|
|
5572
|
+
let errorCode;
|
|
5135
5573
|
try {
|
|
5136
5574
|
const validatedInput = tool.inputSchema.parse(input);
|
|
5137
5575
|
if (tool.localHandler) {
|
|
@@ -5164,7 +5602,9 @@ async function executeQaTool(toolName, input, correlationId) {
|
|
|
5164
5602
|
throw error;
|
|
5165
5603
|
}
|
|
5166
5604
|
} catch (error) {
|
|
5605
|
+
outcome = Outcome.Error;
|
|
5167
5606
|
if (error instanceof GatewayError) {
|
|
5607
|
+
errorCode = error.code;
|
|
5168
5608
|
logger6.warn("Tool call failed with gateway error", {
|
|
5169
5609
|
tool: toolName,
|
|
5170
5610
|
code: error.code,
|
|
@@ -5175,12 +5615,31 @@ async function executeQaTool(toolName, input, correlationId) {
|
|
|
5175
5615
|
isError: true
|
|
5176
5616
|
};
|
|
5177
5617
|
}
|
|
5618
|
+
errorCode = error instanceof Error ? error.name : "UnknownError";
|
|
5178
5619
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
5179
5620
|
logger6.error("Tool call failed", { tool: toolName, error: errorMessage });
|
|
5180
5621
|
return {
|
|
5181
5622
|
content: JSON.stringify({ error: "INTERNAL_ERROR", message: errorMessage }),
|
|
5182
5623
|
isError: true
|
|
5183
5624
|
};
|
|
5625
|
+
} finally {
|
|
5626
|
+
safeTrack({
|
|
5627
|
+
name: EventName.McpToolCompleted,
|
|
5628
|
+
props: {
|
|
5629
|
+
toolName,
|
|
5630
|
+
toolSurface: ToolSurface.Remote,
|
|
5631
|
+
correlationId,
|
|
5632
|
+
durationMs: Date.now() - startTime,
|
|
5633
|
+
outcome,
|
|
5634
|
+
...errorCode !== void 0 ? { errorCode } : {}
|
|
5635
|
+
}
|
|
5636
|
+
});
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
function safeTrack(event) {
|
|
5640
|
+
try {
|
|
5641
|
+
track(event);
|
|
5642
|
+
} catch {
|
|
5184
5643
|
}
|
|
5185
5644
|
}
|
|
5186
5645
|
|
|
@@ -5239,7 +5698,9 @@ var ExecuteTestGenerationInputSchema = z.object({
|
|
|
5239
5698
|
/** Show the electron-app UI during execution. Default: visible window. Pass false to run headless. */
|
|
5240
5699
|
showUi: z.boolean().optional().describe("Show the electron-app UI during generation. Defaults to visible; pass false to run headless."),
|
|
5241
5700
|
/** Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state, such as registration, login, or cookie consent flows. */
|
|
5242
|
-
freshSession: z.boolean().optional().describe("Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state \u2014 e.g. registration, login, or cookie consent flows. Default: false.")
|
|
5701
|
+
freshSession: z.boolean().optional().describe("Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state \u2014 e.g. registration, login, or cookie consent flows. Default: false."),
|
|
5702
|
+
/** Mutation parameters providing variable context for this generation run — a string[] where each element is a plain-English instruction or a local file path for uploads (e.g. "Attach the image at C:\\Users\\user\\photo.jpg"). Matches the electron-app's string[] mutation file format. */
|
|
5703
|
+
mutations: z.array(z.string()).optional().describe(`Mutation parameters: string[] where each element is a plain-English instruction or a local file path (e.g. ["The post content should be 'Hello'", "Attach the image at C:\\\\Users\\\\user\\\\photo.jpg"]).`)
|
|
5243
5704
|
});
|
|
5244
5705
|
var ExecuteReplayInputSchema = z.object({
|
|
5245
5706
|
/** Test script metadata from muggle-remote-test-script-get. */
|
|
@@ -5253,7 +5714,9 @@ var ExecuteReplayInputSchema = z.object({
|
|
|
5253
5714
|
/** Show the electron-app UI during execution. Default: visible window. Pass false to run headless. */
|
|
5254
5715
|
showUi: z.boolean().optional().describe("Show the electron-app UI during replay. Defaults to visible; pass false to run headless."),
|
|
5255
5716
|
/** Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state, such as registration, login, or cookie consent flows. */
|
|
5256
|
-
freshSession: z.boolean().optional().describe("Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state \u2014 e.g. registration, login, or cookie consent flows. Default: false.")
|
|
5717
|
+
freshSession: z.boolean().optional().describe("Clear all session storage (cookies, localStorage, etc.) before execution. Use for test cases that require a clean browser state \u2014 e.g. registration, login, or cookie consent flows. Default: false."),
|
|
5718
|
+
/** Mutation parameters passed to the LLM step predictor — a string[] where each element is an instruction describing what varies this run. Supports plain-English instructions (e.g. "The post content should be 'Hello world'") and local file paths for uploads (e.g. "Attach the image at C:\\Users\\user\\photo.jpg"). Matches the electron-app's string[] mutation file format. When provided, the electron app uses LLM-driven step prediction instead of deterministic replay. */
|
|
5719
|
+
mutations: z.array(z.string()).optional().describe(`Mutation parameters: string[] where each element is a plain-English instruction or a local file path (e.g. ["The post content should be 'Hello'", "Attach the image at C:\\\\Users\\\\user\\\\photo.jpg"]).`)
|
|
5257
5720
|
});
|
|
5258
5721
|
var CancelExecutionInputSchema = z.object({
|
|
5259
5722
|
runId: MuggleEntityIdSchema.describe("Run ID (UUID) to cancel")
|
|
@@ -5287,6 +5750,7 @@ var EmptyInputSchema2 = z.object({});
|
|
|
5287
5750
|
var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
5288
5751
|
PreferenceKey2["AutoLogin"] = "autoLogin";
|
|
5289
5752
|
PreferenceKey2["AutoSelectProject"] = "autoSelectProject";
|
|
5753
|
+
PreferenceKey2["AutoSelectLocalHost"] = "autoSelectLocalHost";
|
|
5290
5754
|
PreferenceKey2["ShowElectronBrowser"] = "showElectronBrowser";
|
|
5291
5755
|
PreferenceKey2["OpenTestResultsAfterRun"] = "openTestResultsAfterRun";
|
|
5292
5756
|
PreferenceKey2["DefaultExecutionMode"] = "defaultExecutionMode";
|
|
@@ -5295,27 +5759,24 @@ var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
|
5295
5759
|
PreferenceKey2["SuggestRelatedTestCases"] = "suggestRelatedTestCases";
|
|
5296
5760
|
PreferenceKey2["AutoDetectChanges"] = "autoDetectChanges";
|
|
5297
5761
|
PreferenceKey2["PostPRVisualWalkthrough"] = "postPRVisualWalkthrough";
|
|
5762
|
+
PreferenceKey2["AutoCreatePR"] = "autoCreatePR";
|
|
5298
5763
|
PreferenceKey2["CheckForUpdates"] = "checkForUpdates";
|
|
5299
5764
|
PreferenceKey2["VerboseOutput"] = "verboseOutput";
|
|
5765
|
+
PreferenceKey2["AutoUseWorktree"] = "autoUseWorktree";
|
|
5766
|
+
PreferenceKey2["AutoRebase"] = "autoRebase";
|
|
5767
|
+
PreferenceKey2["AutoCleanup"] = "autoCleanup";
|
|
5768
|
+
PreferenceKey2["AutoE2ETest"] = "autoE2ETest";
|
|
5300
5769
|
return PreferenceKey2;
|
|
5301
5770
|
})(PreferenceKey || {});
|
|
5302
5771
|
var PreferenceValue = /* @__PURE__ */ ((PreferenceValue2) => {
|
|
5303
5772
|
PreferenceValue2["Always"] = "always";
|
|
5304
5773
|
PreferenceValue2["Ask"] = "ask";
|
|
5305
5774
|
PreferenceValue2["Never"] = "never";
|
|
5775
|
+
PreferenceValue2["Local"] = "local";
|
|
5776
|
+
PreferenceValue2["Remote"] = "remote";
|
|
5306
5777
|
return PreferenceValue2;
|
|
5307
5778
|
})(PreferenceValue || {});
|
|
5308
5779
|
|
|
5309
|
-
// packages/mcps/src/mcp/local/contracts/preferences-schemas.ts
|
|
5310
|
-
var preferenceKeyValues = Object.values(PreferenceKey);
|
|
5311
|
-
var preferenceValueValues = Object.values(PreferenceValue);
|
|
5312
|
-
var PreferencesSetInputSchema = z.object({
|
|
5313
|
-
key: z.enum(preferenceKeyValues).describe("The preference key to set."),
|
|
5314
|
-
value: z.enum(preferenceValueValues).describe("The value: always, ask, or never."),
|
|
5315
|
-
scope: z.enum(["global", "project"]).default("global").describe("Write to global (~/.muggle-ai/) or project (.muggle-ai/) preferences."),
|
|
5316
|
-
cwd: z.string().optional().describe("Project root directory. Required when scope is 'project'.")
|
|
5317
|
-
});
|
|
5318
|
-
|
|
5319
5780
|
// packages/mcps/src/shared/preferences-constants.ts
|
|
5320
5781
|
var PREFERENCES_FILE_NAME = "preferences.json";
|
|
5321
5782
|
var PREFERENCES_PROJECT_DIR_NAME = ".muggle-ai";
|
|
@@ -5323,6 +5784,7 @@ var PREFERENCES_VERSION = 1;
|
|
|
5323
5784
|
var DEFAULT_PREFERENCES = {
|
|
5324
5785
|
["autoLogin" /* AutoLogin */]: "ask" /* Ask */,
|
|
5325
5786
|
["autoSelectProject" /* AutoSelectProject */]: "ask" /* Ask */,
|
|
5787
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: "ask" /* Ask */,
|
|
5326
5788
|
["showElectronBrowser" /* ShowElectronBrowser */]: "ask" /* Ask */,
|
|
5327
5789
|
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "ask" /* Ask */,
|
|
5328
5790
|
["defaultExecutionMode" /* DefaultExecutionMode */]: "ask" /* Ask */,
|
|
@@ -5331,27 +5793,69 @@ var DEFAULT_PREFERENCES = {
|
|
|
5331
5793
|
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: "ask" /* Ask */,
|
|
5332
5794
|
["autoDetectChanges" /* AutoDetectChanges */]: "ask" /* Ask */,
|
|
5333
5795
|
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: "ask" /* Ask */,
|
|
5796
|
+
["autoCreatePR" /* AutoCreatePR */]: "ask" /* Ask */,
|
|
5334
5797
|
["checkForUpdates" /* CheckForUpdates */]: "ask" /* Ask */,
|
|
5335
|
-
["verboseOutput" /* VerboseOutput */]: "ask" /* Ask
|
|
5798
|
+
["verboseOutput" /* VerboseOutput */]: "ask" /* Ask */,
|
|
5799
|
+
["autoUseWorktree" /* AutoUseWorktree */]: "ask" /* Ask */,
|
|
5800
|
+
["autoRebase" /* AutoRebase */]: "ask" /* Ask */,
|
|
5801
|
+
["autoCleanup" /* AutoCleanup */]: "ask" /* Ask */,
|
|
5802
|
+
["autoE2ETest" /* AutoE2ETest */]: "always" /* Always */
|
|
5803
|
+
};
|
|
5804
|
+
var ALWAYS_ASK_NEVER = [
|
|
5805
|
+
"always" /* Always */,
|
|
5806
|
+
"ask" /* Ask */,
|
|
5807
|
+
"never" /* Never */
|
|
5808
|
+
];
|
|
5809
|
+
var ALWAYS_ASK = [
|
|
5810
|
+
"always" /* Always */,
|
|
5811
|
+
"ask" /* Ask */
|
|
5812
|
+
];
|
|
5813
|
+
var LOCAL_REMOTE_ASK = [
|
|
5814
|
+
"local" /* Local */,
|
|
5815
|
+
"remote" /* Remote */,
|
|
5816
|
+
"ask" /* Ask */
|
|
5817
|
+
];
|
|
5818
|
+
var PREFERENCE_ALLOWED_VALUES = {
|
|
5819
|
+
["autoLogin" /* AutoLogin */]: ALWAYS_ASK_NEVER,
|
|
5820
|
+
["autoSelectProject" /* AutoSelectProject */]: ALWAYS_ASK_NEVER,
|
|
5821
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: ALWAYS_ASK_NEVER,
|
|
5822
|
+
["showElectronBrowser" /* ShowElectronBrowser */]: ALWAYS_ASK_NEVER,
|
|
5823
|
+
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: ALWAYS_ASK_NEVER,
|
|
5824
|
+
["defaultExecutionMode" /* DefaultExecutionMode */]: LOCAL_REMOTE_ASK,
|
|
5825
|
+
["autoPublishLocalResults" /* AutoPublishLocalResults */]: ALWAYS_ASK_NEVER,
|
|
5826
|
+
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: ALWAYS_ASK_NEVER,
|
|
5827
|
+
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: ALWAYS_ASK_NEVER,
|
|
5828
|
+
["autoDetectChanges" /* AutoDetectChanges */]: ALWAYS_ASK_NEVER,
|
|
5829
|
+
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: ALWAYS_ASK_NEVER,
|
|
5830
|
+
["autoCreatePR" /* AutoCreatePR */]: ALWAYS_ASK_NEVER,
|
|
5831
|
+
["checkForUpdates" /* CheckForUpdates */]: ALWAYS_ASK_NEVER,
|
|
5832
|
+
["verboseOutput" /* VerboseOutput */]: ALWAYS_ASK_NEVER,
|
|
5833
|
+
["autoUseWorktree" /* AutoUseWorktree */]: ALWAYS_ASK_NEVER,
|
|
5834
|
+
["autoRebase" /* AutoRebase */]: ALWAYS_ASK_NEVER,
|
|
5835
|
+
["autoCleanup" /* AutoCleanup */]: ALWAYS_ASK_NEVER,
|
|
5836
|
+
["autoE2ETest" /* AutoE2ETest */]: ALWAYS_ASK
|
|
5336
5837
|
};
|
|
5337
5838
|
var PREFERENCES_SCHEMA = {
|
|
5338
5839
|
["autoLogin" /* AutoLogin */]: {
|
|
5339
5840
|
description: "When a tool requires auth and saved credentials exist, reuse them without prompting"
|
|
5340
5841
|
},
|
|
5341
5842
|
["autoSelectProject" /* AutoSelectProject */]: {
|
|
5342
|
-
description: "When a skill needs a Muggle project and one was used previously in this repo, reuse it without prompting"
|
|
5843
|
+
description: "When a skill needs a Muggle Test project and one was used previously in this repo, reuse it without prompting"
|
|
5844
|
+
},
|
|
5845
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: {
|
|
5846
|
+
description: "When running local tests, reuse the dev server URL from the previous run in this repo without prompting"
|
|
5343
5847
|
},
|
|
5344
5848
|
["showElectronBrowser" /* ShowElectronBrowser */]: {
|
|
5345
5849
|
description: "When running local E2E tests, show the Electron browser window"
|
|
5346
5850
|
},
|
|
5347
5851
|
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: {
|
|
5348
|
-
description: "After a local E2E test run completes, open the per-run results page on Muggle dashboard"
|
|
5852
|
+
description: "After a local E2E test run completes, open the per-run results page on Muggle Test dashboard"
|
|
5349
5853
|
},
|
|
5350
5854
|
["defaultExecutionMode" /* DefaultExecutionMode */]: {
|
|
5351
5855
|
description: "When a skill supports both local and remote test execution, which to default to"
|
|
5352
5856
|
},
|
|
5353
5857
|
["autoPublishLocalResults" /* AutoPublishLocalResults */]: {
|
|
5354
|
-
description: "After a local E2E test run completes, upload results to Muggle cloud for team visibility"
|
|
5858
|
+
description: "After a local E2E test run completes, upload results to Muggle Test cloud for team visibility"
|
|
5355
5859
|
},
|
|
5356
5860
|
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: {
|
|
5357
5861
|
description: "After creating or running a use case, suggest related use cases to add"
|
|
@@ -5365,17 +5869,121 @@ var PREFERENCES_SCHEMA = {
|
|
|
5365
5869
|
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: {
|
|
5366
5870
|
description: "After test results are available, post visual walkthrough comment with screenshots to the PR"
|
|
5367
5871
|
},
|
|
5872
|
+
["autoCreatePR" /* AutoCreatePR */]: {
|
|
5873
|
+
description: "At the end of the muggle-do dev cycle (or when a test needs an open PR to post results to), push the branch and open a PR without prompting"
|
|
5874
|
+
},
|
|
5368
5875
|
["checkForUpdates" /* CheckForUpdates */]: {
|
|
5369
|
-
description: "At session start, check if a newer Muggle version is available and notify"
|
|
5876
|
+
description: "At session start, check if a newer Muggle Test version is available and notify"
|
|
5370
5877
|
},
|
|
5371
5878
|
["verboseOutput" /* VerboseOutput */]: {
|
|
5372
5879
|
description: "Show detailed progress logs during skill and tool execution"
|
|
5880
|
+
},
|
|
5881
|
+
["autoUseWorktree" /* AutoUseWorktree */]: {
|
|
5882
|
+
description: "When starting non-trivial development work, create a git worktree to isolate the change from the current checkout"
|
|
5883
|
+
},
|
|
5884
|
+
["autoRebase" /* AutoRebase */]: {
|
|
5885
|
+
description: "Before running dev servers or E2E tests on a branch behind origin, rebase onto the default branch first"
|
|
5886
|
+
},
|
|
5887
|
+
["autoCleanup" /* AutoCleanup */]: {
|
|
5888
|
+
description: "After a PR is merged, automatically run the cleanup sequence: remove worktree, delete branches, clear local artifacts, prune [gone] branches"
|
|
5889
|
+
},
|
|
5890
|
+
["autoE2ETest" /* AutoE2ETest */]: {
|
|
5891
|
+
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)"
|
|
5373
5892
|
}
|
|
5374
5893
|
};
|
|
5375
5894
|
|
|
5376
|
-
// packages/mcps/src/
|
|
5377
|
-
|
|
5378
|
-
|
|
5895
|
+
// packages/mcps/src/mcp/local/contracts/preferences-schemas.ts
|
|
5896
|
+
var preferenceKeyValues = Object.values(PreferenceKey);
|
|
5897
|
+
var preferenceValueValues = Object.values(PreferenceValue);
|
|
5898
|
+
var PreferencesSetInputSchema = z.object({
|
|
5899
|
+
key: z.enum(preferenceKeyValues).describe("The preference key to set."),
|
|
5900
|
+
value: z.enum(preferenceValueValues).describe("The value. Most keys accept always/ask/never; defaultExecutionMode accepts local/remote/ask."),
|
|
5901
|
+
scope: z.enum(["global", "project"]).default("global").describe("Write to global (~/.muggle-ai/) or project (.muggle-ai/) preferences."),
|
|
5902
|
+
cwd: z.string().optional().describe("Project root directory. Required when scope is 'project'.")
|
|
5903
|
+
}).superRefine((data, ctx) => {
|
|
5904
|
+
const allowed = PREFERENCE_ALLOWED_VALUES[data.key];
|
|
5905
|
+
if (!allowed.includes(data.value)) {
|
|
5906
|
+
ctx.addIssue({
|
|
5907
|
+
code: "custom",
|
|
5908
|
+
message: `Value "${data.value}" is not allowed for preference "${data.key}". Allowed: ${allowed.join(", ")}`,
|
|
5909
|
+
path: ["value"]
|
|
5910
|
+
});
|
|
5911
|
+
}
|
|
5912
|
+
});
|
|
5913
|
+
var LastProjectGetInputSchema = z.object({
|
|
5914
|
+
cwd: z.string().describe("Project root directory whose last-used project to return.")
|
|
5915
|
+
});
|
|
5916
|
+
var LastProjectSetInputSchema = z.object({
|
|
5917
|
+
cwd: z.string().describe("Project root directory to save the cached project to."),
|
|
5918
|
+
projectId: z.string().min(1).describe("Muggle Test project ID."),
|
|
5919
|
+
projectUrl: z.string().min(1).describe("Muggle Test project URL."),
|
|
5920
|
+
projectName: z.string().min(1).describe("Muggle Test project name.")
|
|
5921
|
+
});
|
|
5922
|
+
var LastProjectClearInputSchema = z.object({
|
|
5923
|
+
cwd: z.string().describe("Project root directory whose last-used project cache to remove.")
|
|
5924
|
+
});
|
|
5925
|
+
var LastHostGetInputSchema = z.object({
|
|
5926
|
+
cwd: z.string().describe("Project root directory whose last-used host to return.")
|
|
5927
|
+
});
|
|
5928
|
+
var LastHostSetInputSchema = z.object({
|
|
5929
|
+
cwd: z.string().describe("Project root directory to save the cached host to."),
|
|
5930
|
+
host: z.string().min(1).describe("Local dev server URL (e.g. http://localhost:3000).")
|
|
5931
|
+
});
|
|
5932
|
+
var LastHostClearInputSchema = z.object({
|
|
5933
|
+
cwd: z.string().describe("Project root directory whose last-used host cache to remove.")
|
|
5934
|
+
});
|
|
5935
|
+
var SkillTelemetryEmitInputSchema = z.object({
|
|
5936
|
+
skillName: z.string().min(1).describe("Name of the skill being invoked, e.g. 'muggle-test'."),
|
|
5937
|
+
trigger: z.nativeEnum(Trigger).default(Trigger.UserSlash).describe("Why this skill ran. Defaults to 'user-slash' (user typed /skill-name).")
|
|
5938
|
+
});
|
|
5939
|
+
var FailureEventType = /* @__PURE__ */ ((FailureEventType2) => {
|
|
5940
|
+
FailureEventType2["PreExecutionClassification"] = "pre-execution-classification";
|
|
5941
|
+
FailureEventType2["ReplayFailureClassified"] = "replay-failure-classified";
|
|
5942
|
+
FailureEventType2["ReplayFailureResolved"] = "replay-failure-resolved";
|
|
5943
|
+
FailureEventType2["RegenFailureClassified"] = "regen-failure-classified";
|
|
5944
|
+
FailureEventType2["RegenFailureResolved"] = "regen-failure-resolved";
|
|
5945
|
+
return FailureEventType2;
|
|
5946
|
+
})(FailureEventType || {});
|
|
5947
|
+
var EventTelemetryEmitInputSchema = z.object({
|
|
5948
|
+
eventType: z.nativeEnum(FailureEventType).describe(
|
|
5949
|
+
"Which decision point this event records. Five values cover the AI's pre-execution replay-vs-regen choice and the four post-failure classify\u2192resolve pairs."
|
|
5950
|
+
),
|
|
5951
|
+
skillName: z.string().min(1).describe("Skill that emitted this event (e.g. 'muggle-test', 'muggle-test-feature-local')."),
|
|
5952
|
+
aiClassification: z.string().optional().describe(
|
|
5953
|
+
"What the AI classified the situation as. pre-execution: 'replay' or 'regen'. replay-failure: 'infra' | 'stale-script' | 'product-defect'. regen-failure: 'transient' | 'infra' | 'agent-course' | 'product-uxux'."
|
|
5954
|
+
),
|
|
5955
|
+
aiSuggestion: z.string().optional().describe(
|
|
5956
|
+
"What the AI suggested the user do. Examples: 'regenerate', 'report-bug', 'muggle-feedback', 'retry', 'wait-and-share'."
|
|
5957
|
+
),
|
|
5958
|
+
userAction: z.string().optional().describe(
|
|
5959
|
+
"What the user actually picked (only set on *-resolved events). Compare against aiSuggestion to measure classification accuracy."
|
|
5960
|
+
),
|
|
5961
|
+
runId: z.string().optional().describe("Anchor: local run ID for the affected execution."),
|
|
5962
|
+
testCaseId: z.string().optional().describe("Anchor: cloud test case ID."),
|
|
5963
|
+
projectId: z.string().optional().describe("Anchor: cloud project ID."),
|
|
5964
|
+
signals: z.array(z.string()).optional().describe(
|
|
5965
|
+
"Signals that drove the classification, e.g. ['element-not-found', 'selector-timeout', 'electron-exit-26', 'goal-not-achievable']. Used to refine the rules later."
|
|
5966
|
+
),
|
|
5967
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe("Free-form additional context (e.g. error excerpt, last step name).")
|
|
5968
|
+
});
|
|
5969
|
+
var TELEMETRY_DIR_NAME = "telemetry";
|
|
5970
|
+
var FAILURE_EVENTS_FILE_NAME = "failure-events.jsonl";
|
|
5971
|
+
function appendFailureEvent(record) {
|
|
5972
|
+
try {
|
|
5973
|
+
const dir = path2.join(getDataDir(), TELEMETRY_DIR_NAME);
|
|
5974
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
5975
|
+
const filePath = path2.join(dir, FAILURE_EVENTS_FILE_NAME);
|
|
5976
|
+
const full = { ts: (/* @__PURE__ */ new Date()).toISOString(), ...record };
|
|
5977
|
+
fs5.appendFileSync(filePath, `${JSON.stringify(full)}
|
|
5978
|
+
`, "utf-8");
|
|
5979
|
+
} catch (error) {
|
|
5980
|
+
getLogger().warn("Failed to append failure event", {
|
|
5981
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5982
|
+
});
|
|
5983
|
+
}
|
|
5984
|
+
}
|
|
5985
|
+
function isFirstRun(dataDirOverride2) {
|
|
5986
|
+
const filePath = path2.join(dataDirOverride2 ?? getDataDir(), PREFERENCES_FILE_NAME);
|
|
5379
5987
|
return !fs5.existsSync(filePath);
|
|
5380
5988
|
}
|
|
5381
5989
|
function readPreferencesFile(filePath) {
|
|
@@ -5393,8 +6001,8 @@ function readPreferencesFile(filePath) {
|
|
|
5393
6001
|
return {};
|
|
5394
6002
|
}
|
|
5395
6003
|
}
|
|
5396
|
-
function readGlobalPreferences(
|
|
5397
|
-
const filePath = path2.join(
|
|
6004
|
+
function readGlobalPreferences(dataDirOverride2) {
|
|
6005
|
+
const filePath = path2.join(dataDirOverride2 ?? getDataDir(), PREFERENCES_FILE_NAME);
|
|
5398
6006
|
const partial = readPreferencesFile(filePath);
|
|
5399
6007
|
return { ...DEFAULT_PREFERENCES, ...partial };
|
|
5400
6008
|
}
|
|
@@ -5402,16 +6010,16 @@ function readProjectPreferences(cwd) {
|
|
|
5402
6010
|
const filePath = path2.join(cwd, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_FILE_NAME);
|
|
5403
6011
|
return readPreferencesFile(filePath);
|
|
5404
6012
|
}
|
|
5405
|
-
function resolvePreferences(
|
|
5406
|
-
const global = readGlobalPreferences(
|
|
6013
|
+
function resolvePreferences(dataDirOverride2, cwd) {
|
|
6014
|
+
const global = readGlobalPreferences(dataDirOverride2);
|
|
5407
6015
|
if (!cwd) {
|
|
5408
6016
|
return global;
|
|
5409
6017
|
}
|
|
5410
6018
|
const project = readProjectPreferences(cwd);
|
|
5411
6019
|
return { ...global, ...project };
|
|
5412
6020
|
}
|
|
5413
|
-
function writePreferences(prefs, scope,
|
|
5414
|
-
const dir = scope === "project" && cwd ? path2.join(cwd, PREFERENCES_PROJECT_DIR_NAME) :
|
|
6021
|
+
function writePreferences(prefs, scope, dataDirOverride2, cwd) {
|
|
6022
|
+
const dir = scope === "project" && cwd ? path2.join(cwd, PREFERENCES_PROJECT_DIR_NAME) : dataDirOverride2 ?? getDataDir();
|
|
5415
6023
|
fs5.mkdirSync(dir, { recursive: true });
|
|
5416
6024
|
const filePath = path2.join(dir, PREFERENCES_FILE_NAME);
|
|
5417
6025
|
const existing = readPreferencesFile(filePath);
|
|
@@ -5423,8 +6031,8 @@ function writePreferences(prefs, scope, dataDirOverride, cwd) {
|
|
|
5423
6031
|
fs5.writeFileSync(filePath, `${JSON.stringify(file, null, 2)}
|
|
5424
6032
|
`, "utf-8");
|
|
5425
6033
|
}
|
|
5426
|
-
function resetPreference(key, scope,
|
|
5427
|
-
const dir = scope === "project" && cwd ? path2.join(cwd, PREFERENCES_PROJECT_DIR_NAME) :
|
|
6034
|
+
function resetPreference(key, scope, dataDirOverride2, cwd) {
|
|
6035
|
+
const dir = scope === "project" && cwd ? path2.join(cwd, PREFERENCES_PROJECT_DIR_NAME) : dataDirOverride2 ?? getDataDir();
|
|
5428
6036
|
const filePath = path2.join(dir, PREFERENCES_FILE_NAME);
|
|
5429
6037
|
if (!fs5.existsSync(filePath)) {
|
|
5430
6038
|
return;
|
|
@@ -5443,12 +6051,87 @@ function resetPreference(key, scope, dataDirOverride, cwd) {
|
|
|
5443
6051
|
}
|
|
5444
6052
|
function validatePreference(key, value) {
|
|
5445
6053
|
const validKeys = Object.values(PreferenceKey);
|
|
5446
|
-
|
|
5447
|
-
|
|
6054
|
+
if (!validKeys.includes(key)) {
|
|
6055
|
+
return false;
|
|
6056
|
+
}
|
|
6057
|
+
const allowed = PREFERENCE_ALLOWED_VALUES[key];
|
|
6058
|
+
return allowed.includes(value);
|
|
5448
6059
|
}
|
|
5449
6060
|
function formatPreferencesOneLiner(prefs) {
|
|
5450
6061
|
return Object.entries(prefs).map(([key, value]) => `${key}=${value}`).join(" ");
|
|
5451
6062
|
}
|
|
6063
|
+
var LAST_PROJECT_FILE_NAME = "last-project.json";
|
|
6064
|
+
var LAST_PROJECT_DIR_NAME = ".muggle-ai";
|
|
6065
|
+
var LAST_PROJECT_VERSION = 1;
|
|
6066
|
+
function readLastProject(cwd) {
|
|
6067
|
+
const filePath = path2.join(cwd, LAST_PROJECT_DIR_NAME, LAST_PROJECT_FILE_NAME);
|
|
6068
|
+
try {
|
|
6069
|
+
if (!fs5.existsSync(filePath)) {
|
|
6070
|
+
return null;
|
|
6071
|
+
}
|
|
6072
|
+
const raw = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
6073
|
+
return raw.lastProject ?? null;
|
|
6074
|
+
} catch (error) {
|
|
6075
|
+
getLogger().warn("Failed to read last-project file", {
|
|
6076
|
+
path: filePath,
|
|
6077
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6078
|
+
});
|
|
6079
|
+
return null;
|
|
6080
|
+
}
|
|
6081
|
+
}
|
|
6082
|
+
function writeLastProject(cwd, lastProject) {
|
|
6083
|
+
const dir = path2.join(cwd, LAST_PROJECT_DIR_NAME);
|
|
6084
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
6085
|
+
const filePath = path2.join(dir, LAST_PROJECT_FILE_NAME);
|
|
6086
|
+
const file = {
|
|
6087
|
+
version: LAST_PROJECT_VERSION,
|
|
6088
|
+
lastProject: { ...lastProject, savedAt: (/* @__PURE__ */ new Date()).toISOString() }
|
|
6089
|
+
};
|
|
6090
|
+
fs5.writeFileSync(filePath, `${JSON.stringify(file, null, 2)}
|
|
6091
|
+
`, "utf-8");
|
|
6092
|
+
}
|
|
6093
|
+
function clearLastProject(cwd) {
|
|
6094
|
+
const filePath = path2.join(cwd, LAST_PROJECT_DIR_NAME, LAST_PROJECT_FILE_NAME);
|
|
6095
|
+
if (fs5.existsSync(filePath)) {
|
|
6096
|
+
fs5.unlinkSync(filePath);
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
6099
|
+
var LAST_HOST_FILE_NAME = "last-host.json";
|
|
6100
|
+
var LAST_HOST_DIR_NAME = ".muggle-ai";
|
|
6101
|
+
var LAST_HOST_VERSION = 1;
|
|
6102
|
+
function readLastHost(cwd) {
|
|
6103
|
+
const filePath = path2.join(cwd, LAST_HOST_DIR_NAME, LAST_HOST_FILE_NAME);
|
|
6104
|
+
try {
|
|
6105
|
+
if (!fs5.existsSync(filePath)) {
|
|
6106
|
+
return null;
|
|
6107
|
+
}
|
|
6108
|
+
const raw = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
6109
|
+
return raw.lastHost ?? null;
|
|
6110
|
+
} catch (error) {
|
|
6111
|
+
getLogger().warn("Failed to read last-host file", {
|
|
6112
|
+
path: filePath,
|
|
6113
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6114
|
+
});
|
|
6115
|
+
return null;
|
|
6116
|
+
}
|
|
6117
|
+
}
|
|
6118
|
+
function writeLastHost(cwd, host) {
|
|
6119
|
+
const dir = path2.join(cwd, LAST_HOST_DIR_NAME);
|
|
6120
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
6121
|
+
const filePath = path2.join(dir, LAST_HOST_FILE_NAME);
|
|
6122
|
+
const file = {
|
|
6123
|
+
version: LAST_HOST_VERSION,
|
|
6124
|
+
lastHost: { host, savedAt: (/* @__PURE__ */ new Date()).toISOString() }
|
|
6125
|
+
};
|
|
6126
|
+
fs5.writeFileSync(filePath, `${JSON.stringify(file, null, 2)}
|
|
6127
|
+
`, "utf-8");
|
|
6128
|
+
}
|
|
6129
|
+
function clearLastHost(cwd) {
|
|
6130
|
+
const filePath = path2.join(cwd, LAST_HOST_DIR_NAME, LAST_HOST_FILE_NAME);
|
|
6131
|
+
if (fs5.existsSync(filePath)) {
|
|
6132
|
+
fs5.unlinkSync(filePath);
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
5452
6135
|
|
|
5453
6136
|
// packages/mcps/src/mcp/tools/local/tool-registry.ts
|
|
5454
6137
|
function createChildLogger2(correlationId) {
|
|
@@ -5672,6 +6355,7 @@ var executeTestGenerationTool = {
|
|
|
5672
6355
|
const result = await executeTestGeneration({
|
|
5673
6356
|
testCase: input.testCase,
|
|
5674
6357
|
localUrl: input.localUrl,
|
|
6358
|
+
mutations: input.mutations,
|
|
5675
6359
|
timeoutMs: input.timeoutMs,
|
|
5676
6360
|
showUi,
|
|
5677
6361
|
freshSession: input.freshSession
|
|
@@ -5712,6 +6396,7 @@ var executeReplayTool = {
|
|
|
5712
6396
|
testScript: input.testScript,
|
|
5713
6397
|
actionScript: input.actionScript,
|
|
5714
6398
|
localUrl: input.localUrl,
|
|
6399
|
+
mutations: input.mutations,
|
|
5715
6400
|
timeoutMs: input.timeoutMs,
|
|
5716
6401
|
showUi,
|
|
5717
6402
|
freshSession: input.freshSession
|
|
@@ -5905,19 +6590,172 @@ var preferencesSetTool = {
|
|
|
5905
6590
|
void 0,
|
|
5906
6591
|
input.cwd
|
|
5907
6592
|
);
|
|
5908
|
-
|
|
5909
|
-
|
|
6593
|
+
return {
|
|
6594
|
+
content: `**${input.key}** set to **${input.value}** (${input.scope}).`,
|
|
6595
|
+
isError: false
|
|
6596
|
+
};
|
|
6597
|
+
}
|
|
6598
|
+
};
|
|
6599
|
+
var lastProjectGetTool = {
|
|
6600
|
+
name: "muggle-local-last-project-get",
|
|
6601
|
+
description: "Get the cached last-used Muggle Test project for a repo (read from <cwd>/.muggle-ai/last-project.json). Returns the project ID, URL, name, and saved-at timestamp, or null if no cache exists. Skills consult this when 'autoSelectProject = always' to silently reuse the project the user picked previously, instead of presenting the project picker every time.",
|
|
6602
|
+
inputSchema: LastProjectGetInputSchema,
|
|
6603
|
+
execute: async (ctx) => {
|
|
6604
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6605
|
+
logger6.info("Executing muggle-local-last-project-get");
|
|
6606
|
+
const input = LastProjectGetInputSchema.parse(ctx.input);
|
|
6607
|
+
const cached = readLastProject(input.cwd);
|
|
6608
|
+
if (!cached) {
|
|
6609
|
+
const content2 = [
|
|
6610
|
+
"No cached last-used project for this repo.",
|
|
6611
|
+
"",
|
|
6612
|
+
`Looked at: \`${input.cwd}/.muggle-ai/${LAST_PROJECT_FILE_NAME}\``,
|
|
6613
|
+
"",
|
|
6614
|
+
"The cache is populated when a user picks an existing project AND chooses 'Yes, save it' on the memory picker (the autoSelectProject preference)."
|
|
6615
|
+
].join("\n");
|
|
6616
|
+
return { content: content2, isError: false };
|
|
6617
|
+
}
|
|
5910
6618
|
const content = [
|
|
5911
|
-
|
|
6619
|
+
"**Cached last-used project:**",
|
|
5912
6620
|
"",
|
|
5913
|
-
|
|
6621
|
+
`- ID: \`${cached.projectId}\``,
|
|
6622
|
+
`- URL: ${cached.projectUrl}`,
|
|
6623
|
+
`- Name: ${cached.projectName}`,
|
|
6624
|
+
`- Saved at: ${cached.savedAt}`
|
|
6625
|
+
].join("\n");
|
|
6626
|
+
return { content, isError: false };
|
|
6627
|
+
}
|
|
6628
|
+
};
|
|
6629
|
+
var lastProjectSetTool = {
|
|
6630
|
+
name: "muggle-local-last-project-set",
|
|
6631
|
+
description: "Save the user's selected Muggle Test project as the cached last-used project for this repo. Writes to <cwd>/.muggle-ai/last-project.json. Subsequent skill invocations honor 'autoSelectProject = always' by silently reusing this entry \u2014 no project picker shown. Always pair this call with 'muggle-local-preferences-set autoSelectProject=always' when the user chose 'Yes, save it'.",
|
|
6632
|
+
inputSchema: LastProjectSetInputSchema,
|
|
6633
|
+
execute: async (ctx) => {
|
|
6634
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6635
|
+
logger6.info("Executing muggle-local-last-project-set");
|
|
6636
|
+
const input = LastProjectSetInputSchema.parse(ctx.input);
|
|
6637
|
+
writeLastProject(input.cwd, {
|
|
6638
|
+
projectId: input.projectId,
|
|
6639
|
+
projectUrl: input.projectUrl,
|
|
6640
|
+
projectName: input.projectName
|
|
6641
|
+
});
|
|
6642
|
+
const content = [
|
|
6643
|
+
`Cached **${input.projectName}** as the last-used project for this repo.`,
|
|
5914
6644
|
"",
|
|
5915
|
-
|
|
5916
|
-
|
|
6645
|
+
`Written to: \`${input.cwd}/.muggle-ai/${LAST_PROJECT_FILE_NAME}\``,
|
|
6646
|
+
"",
|
|
6647
|
+
"Skills will silently reuse this project on future runs when `autoSelectProject = always`."
|
|
5917
6648
|
].join("\n");
|
|
5918
6649
|
return { content, isError: false };
|
|
5919
6650
|
}
|
|
5920
6651
|
};
|
|
6652
|
+
var lastProjectClearTool = {
|
|
6653
|
+
name: "muggle-local-last-project-clear",
|
|
6654
|
+
description: "Remove the cached last-used project for this repo. After this, `autoSelectProject = always` will fall through to ask until the user picks a new project. No-op if no cache exists.",
|
|
6655
|
+
inputSchema: LastProjectClearInputSchema,
|
|
6656
|
+
execute: async (ctx) => {
|
|
6657
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6658
|
+
logger6.info("Executing muggle-local-last-project-clear");
|
|
6659
|
+
const input = LastProjectClearInputSchema.parse(ctx.input);
|
|
6660
|
+
clearLastProject(input.cwd);
|
|
6661
|
+
const content = [
|
|
6662
|
+
"Cleared the cached last-used project for this repo.",
|
|
6663
|
+
"",
|
|
6664
|
+
`Path: \`${input.cwd}/.muggle-ai/${LAST_PROJECT_FILE_NAME}\``
|
|
6665
|
+
].join("\n");
|
|
6666
|
+
return { content, isError: false };
|
|
6667
|
+
}
|
|
6668
|
+
};
|
|
6669
|
+
var lastHostGetTool = {
|
|
6670
|
+
name: "muggle-local-last-host-get",
|
|
6671
|
+
description: "Get the cached last-used local dev server URL for a repo (read from <cwd>/.muggle-ai/last-host.json). Returns the URL and saved-at timestamp, or null if no cache exists. Skills consult this when 'autoSelectLocalHost = always' to silently reuse the URL the user used previously.",
|
|
6672
|
+
inputSchema: LastHostGetInputSchema,
|
|
6673
|
+
execute: async (ctx) => {
|
|
6674
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6675
|
+
logger6.info("Executing muggle-local-last-host-get");
|
|
6676
|
+
const input = LastHostGetInputSchema.parse(ctx.input);
|
|
6677
|
+
const cached = readLastHost(input.cwd);
|
|
6678
|
+
if (!cached) {
|
|
6679
|
+
const content2 = [
|
|
6680
|
+
"No cached last-used host for this repo.",
|
|
6681
|
+
"",
|
|
6682
|
+
`Looked at: \`${input.cwd}/.muggle-ai/${LAST_HOST_FILE_NAME}\``
|
|
6683
|
+
].join("\n");
|
|
6684
|
+
return { content: content2, isError: false };
|
|
6685
|
+
}
|
|
6686
|
+
const content = [
|
|
6687
|
+
"**Cached last-used host:**",
|
|
6688
|
+
"",
|
|
6689
|
+
`- URL: ${cached.host}`,
|
|
6690
|
+
`- Saved at: ${cached.savedAt}`
|
|
6691
|
+
].join("\n");
|
|
6692
|
+
return { content, isError: false };
|
|
6693
|
+
}
|
|
6694
|
+
};
|
|
6695
|
+
var lastHostSetTool = {
|
|
6696
|
+
name: "muggle-local-last-host-set",
|
|
6697
|
+
description: "Save the user's chosen local dev server URL as the cached last-used host for this repo. Writes to <cwd>/.muggle-ai/last-host.json. Call this on every host pick (independent of 'Remember this URL?' Picker 2) so future runs can offer 'Use {lastHost}' regardless of whether the user opted to set autoSelectLocalHost=always.",
|
|
6698
|
+
inputSchema: LastHostSetInputSchema,
|
|
6699
|
+
execute: async (ctx) => {
|
|
6700
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6701
|
+
logger6.info("Executing muggle-local-last-host-set");
|
|
6702
|
+
const input = LastHostSetInputSchema.parse(ctx.input);
|
|
6703
|
+
writeLastHost(input.cwd, input.host);
|
|
6704
|
+
return {
|
|
6705
|
+
content: `Cached **${input.host}** as the last-used host for this repo.`,
|
|
6706
|
+
isError: false
|
|
6707
|
+
};
|
|
6708
|
+
}
|
|
6709
|
+
};
|
|
6710
|
+
var lastHostClearTool = {
|
|
6711
|
+
name: "muggle-local-last-host-clear",
|
|
6712
|
+
description: "Remove the cached last-used host for this repo. After this, `autoSelectLocalHost = always` will fall through to ask until the user picks a new URL. No-op if no cache exists.",
|
|
6713
|
+
inputSchema: LastHostClearInputSchema,
|
|
6714
|
+
execute: async (ctx) => {
|
|
6715
|
+
const logger6 = createChildLogger2(ctx.correlationId);
|
|
6716
|
+
logger6.info("Executing muggle-local-last-host-clear");
|
|
6717
|
+
const input = LastHostClearInputSchema.parse(ctx.input);
|
|
6718
|
+
clearLastHost(input.cwd);
|
|
6719
|
+
return {
|
|
6720
|
+
content: `Cleared the cached last-used host for this repo.`,
|
|
6721
|
+
isError: false
|
|
6722
|
+
};
|
|
6723
|
+
}
|
|
6724
|
+
};
|
|
6725
|
+
var telemetrySkillEmitTool = {
|
|
6726
|
+
name: "muggle-local-telemetry-skill-emit",
|
|
6727
|
+
description: "Emit a client telemetry event recording that a Muggle Test skill was invoked. Each muggle-* skill calls this in its first step so we can measure skill usage. Never fails the skill on telemetry errors.",
|
|
6728
|
+
inputSchema: SkillTelemetryEmitInputSchema,
|
|
6729
|
+
execute: async (ctx) => {
|
|
6730
|
+
const input = SkillTelemetryEmitInputSchema.parse(ctx.input);
|
|
6731
|
+
safeTrack2({
|
|
6732
|
+
name: EventName.SkillInvoked,
|
|
6733
|
+
props: { skillName: input.skillName, trigger: input.trigger }
|
|
6734
|
+
});
|
|
6735
|
+
return { content: "ok", isError: false, data: { recorded: true } };
|
|
6736
|
+
}
|
|
6737
|
+
};
|
|
6738
|
+
var telemetryEventEmitTool = {
|
|
6739
|
+
name: "muggle-local-telemetry-event-emit",
|
|
6740
|
+
description: "Emit a structured failure-mode telemetry event recording how a Muggle Test skill classified a situation and what action the user took. Used at five decision points: 'pre-execution-classification' (replay vs regen), 'replay-failure-classified', 'replay-failure-resolved', 'regen-failure-classified', 'regen-failure-resolved'. Records to ~/.muggle-ai/telemetry/failure-events.jsonl. Never fails the skill on telemetry errors.",
|
|
6741
|
+
inputSchema: EventTelemetryEmitInputSchema,
|
|
6742
|
+
execute: async (ctx) => {
|
|
6743
|
+
const input = EventTelemetryEmitInputSchema.parse(ctx.input);
|
|
6744
|
+
appendFailureEvent({
|
|
6745
|
+
eventType: input.eventType,
|
|
6746
|
+
skillName: input.skillName,
|
|
6747
|
+
aiClassification: input.aiClassification,
|
|
6748
|
+
aiSuggestion: input.aiSuggestion,
|
|
6749
|
+
userAction: input.userAction,
|
|
6750
|
+
runId: input.runId,
|
|
6751
|
+
testCaseId: input.testCaseId,
|
|
6752
|
+
projectId: input.projectId,
|
|
6753
|
+
signals: input.signals,
|
|
6754
|
+
metadata: input.metadata
|
|
6755
|
+
});
|
|
6756
|
+
return { content: "ok", isError: false, data: { recorded: true } };
|
|
6757
|
+
}
|
|
6758
|
+
};
|
|
5921
6759
|
var allLocalQaTools = [
|
|
5922
6760
|
// Status tools
|
|
5923
6761
|
checkStatusTool,
|
|
@@ -5935,7 +6773,18 @@ var allLocalQaTools = [
|
|
|
5935
6773
|
// Publishing tools
|
|
5936
6774
|
publishTestScriptTool,
|
|
5937
6775
|
// Preferences tools
|
|
5938
|
-
preferencesSetTool
|
|
6776
|
+
preferencesSetTool,
|
|
6777
|
+
// Last-project cache tools (per-repo "last used Muggle Test project")
|
|
6778
|
+
lastProjectGetTool,
|
|
6779
|
+
lastProjectSetTool,
|
|
6780
|
+
lastProjectClearTool,
|
|
6781
|
+
// Last-host cache tools (per-repo "last used local dev server URL")
|
|
6782
|
+
lastHostGetTool,
|
|
6783
|
+
lastHostSetTool,
|
|
6784
|
+
lastHostClearTool,
|
|
6785
|
+
// Client telemetry: skills emit invocation events through this tool
|
|
6786
|
+
telemetrySkillEmitTool,
|
|
6787
|
+
telemetryEventEmitTool
|
|
5939
6788
|
];
|
|
5940
6789
|
var toolMap = new Map(
|
|
5941
6790
|
allLocalQaTools.map((tool) => [tool.name, tool])
|
|
@@ -5951,7 +6800,44 @@ async function executeTool(name, input, correlationId) {
|
|
|
5951
6800
|
isError: true
|
|
5952
6801
|
};
|
|
5953
6802
|
}
|
|
5954
|
-
|
|
6803
|
+
const startTime = Date.now();
|
|
6804
|
+
safeTrack2({
|
|
6805
|
+
name: EventName.McpToolInvoked,
|
|
6806
|
+
props: { toolName: name, toolSurface: ToolSurface.Local, correlationId }
|
|
6807
|
+
});
|
|
6808
|
+
try {
|
|
6809
|
+
const result = await tool.execute({ input, correlationId });
|
|
6810
|
+
safeTrack2({
|
|
6811
|
+
name: EventName.McpToolCompleted,
|
|
6812
|
+
props: {
|
|
6813
|
+
toolName: name,
|
|
6814
|
+
toolSurface: ToolSurface.Local,
|
|
6815
|
+
correlationId,
|
|
6816
|
+
durationMs: Date.now() - startTime,
|
|
6817
|
+
outcome: result.isError ? Outcome.Error : Outcome.Success
|
|
6818
|
+
}
|
|
6819
|
+
});
|
|
6820
|
+
return result;
|
|
6821
|
+
} catch (err) {
|
|
6822
|
+
safeTrack2({
|
|
6823
|
+
name: EventName.McpToolCompleted,
|
|
6824
|
+
props: {
|
|
6825
|
+
toolName: name,
|
|
6826
|
+
toolSurface: ToolSurface.Local,
|
|
6827
|
+
correlationId,
|
|
6828
|
+
durationMs: Date.now() - startTime,
|
|
6829
|
+
outcome: Outcome.Error,
|
|
6830
|
+
errorCode: err instanceof Error ? err.name : "UnknownError"
|
|
6831
|
+
}
|
|
6832
|
+
});
|
|
6833
|
+
throw err;
|
|
6834
|
+
}
|
|
6835
|
+
}
|
|
6836
|
+
function safeTrack2(event) {
|
|
6837
|
+
try {
|
|
6838
|
+
track(event);
|
|
6839
|
+
} catch {
|
|
6840
|
+
}
|
|
5955
6841
|
}
|
|
5956
6842
|
|
|
5957
6843
|
// packages/mcps/src/mcp/e2e/index.ts
|
|
@@ -6013,6 +6899,7 @@ __export(e2e_exports2, {
|
|
|
6013
6899
|
TestCaseGetInputSchema: () => TestCaseGetInputSchema,
|
|
6014
6900
|
TestCaseListByUseCaseInputSchema: () => TestCaseListByUseCaseInputSchema,
|
|
6015
6901
|
TestCaseListInputSchema: () => TestCaseListInputSchema,
|
|
6902
|
+
TestCaseUpdateInputSchema: () => TestCaseUpdateInputSchema,
|
|
6016
6903
|
TestScriptGetInputSchema: () => TestScriptGetInputSchema,
|
|
6017
6904
|
TestScriptListInputSchema: () => TestScriptListInputSchema,
|
|
6018
6905
|
TokenPackageIdSchema: () => TokenPackageIdSchema,
|
|
@@ -6025,6 +6912,12 @@ __export(e2e_exports2, {
|
|
|
6025
6912
|
UseCaseListInputSchema: () => UseCaseListInputSchema,
|
|
6026
6913
|
UseCasePromptPreviewInputSchema: () => UseCasePromptPreviewInputSchema,
|
|
6027
6914
|
UseCaseUpdateFromPromptInputSchema: () => UseCaseUpdateFromPromptInputSchema,
|
|
6915
|
+
UseCaseUpdateInputSchema: () => UseCaseUpdateInputSchema,
|
|
6916
|
+
UserFeedbackCreateInputSchema: () => UserFeedbackCreateInputSchema,
|
|
6917
|
+
UserFeedbackDeleteInputSchema: () => UserFeedbackDeleteInputSchema,
|
|
6918
|
+
UserFeedbackListInputSchema: () => UserFeedbackListInputSchema,
|
|
6919
|
+
UserFeedbackTargetSchema: () => UserFeedbackTargetSchema,
|
|
6920
|
+
UserFeedbackTargetTypeSchema: () => UserFeedbackTargetTypeSchema,
|
|
6028
6921
|
WalletAutoTopUpSetPaymentMethodInputSchema: () => WalletAutoTopUpSetPaymentMethodInputSchema,
|
|
6029
6922
|
WalletAutoTopUpUpdateInputSchema: () => WalletAutoTopUpUpdateInputSchema,
|
|
6030
6923
|
WalletPaymentMethodCreateSetupSessionInputSchema: () => WalletPaymentMethodCreateSetupSessionInputSchema,
|
|
@@ -6071,10 +6964,18 @@ __export(local_exports2, {
|
|
|
6071
6964
|
CloudMappingEntityType: () => CloudMappingEntityType,
|
|
6072
6965
|
DeviceCodePollStatus: () => DeviceCodePollStatus,
|
|
6073
6966
|
EmptyInputSchema: () => EmptyInputSchema2,
|
|
6967
|
+
EventTelemetryEmitInputSchema: () => EventTelemetryEmitInputSchema,
|
|
6074
6968
|
ExecuteReplayInputSchema: () => ExecuteReplayInputSchema,
|
|
6075
6969
|
ExecuteTestGenerationInputSchema: () => ExecuteTestGenerationInputSchema,
|
|
6076
6970
|
ExecutionStatus: () => ExecutionStatus,
|
|
6971
|
+
FailureEventType: () => FailureEventType,
|
|
6077
6972
|
HealthStatus: () => HealthStatus,
|
|
6973
|
+
LastHostClearInputSchema: () => LastHostClearInputSchema,
|
|
6974
|
+
LastHostGetInputSchema: () => LastHostGetInputSchema,
|
|
6975
|
+
LastHostSetInputSchema: () => LastHostSetInputSchema,
|
|
6976
|
+
LastProjectClearInputSchema: () => LastProjectClearInputSchema,
|
|
6977
|
+
LastProjectGetInputSchema: () => LastProjectGetInputSchema,
|
|
6978
|
+
LastProjectSetInputSchema: () => LastProjectSetInputSchema,
|
|
6078
6979
|
ListSessionsInputSchema: () => ListSessionsInputSchema,
|
|
6079
6980
|
LocalRunStatus: () => LocalRunStatus,
|
|
6080
6981
|
LocalRunType: () => LocalRunType,
|
|
@@ -6088,6 +6989,7 @@ __export(local_exports2, {
|
|
|
6088
6989
|
RunResultListInputSchema: () => RunResultListInputSchema,
|
|
6089
6990
|
RunResultStorageService: () => RunResultStorageService,
|
|
6090
6991
|
SessionStatus: () => SessionStatus,
|
|
6992
|
+
SkillTelemetryEmitInputSchema: () => SkillTelemetryEmitInputSchema,
|
|
6091
6993
|
StorageService: () => StorageService,
|
|
6092
6994
|
TestCaseDetailsSchema: () => TestCaseDetailsSchema,
|
|
6093
6995
|
TestResultStatus: () => TestResultStatus,
|
|
@@ -6137,7 +7039,10 @@ function isLocalOnlyTool(toolName) {
|
|
|
6137
7039
|
"muggle_run_result_list",
|
|
6138
7040
|
"muggle_run_result_get",
|
|
6139
7041
|
"muggle_test_script_list",
|
|
6140
|
-
"muggle_test_script_get"
|
|
7042
|
+
"muggle_test_script_get",
|
|
7043
|
+
// Client telemetry — purely local, no backend call
|
|
7044
|
+
"muggle-local-telemetry-skill-emit",
|
|
7045
|
+
"muggle-local-telemetry-event-emit"
|
|
6141
7046
|
];
|
|
6142
7047
|
return localOnlyTools.includes(toolName);
|
|
6143
7048
|
}
|
|
@@ -6151,4 +7056,4 @@ var plugins_exports = {};
|
|
|
6151
7056
|
// packages/mcps/src/mcp/agents/index.ts
|
|
6152
7057
|
var agents_exports = {};
|
|
6153
7058
|
|
|
6154
|
-
export { DEFAULT_PREFERENCES, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PreferenceKey, PreferenceValue, __export, __require, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports2 as e2e_exports, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir2 as getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports2 as local_exports, mcp_exports, openBrowserUrl, performLogin, performLogout, pollDeviceCode, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, src_exports, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences };
|
|
7059
|
+
export { DEFAULT_PREFERENCES, EventName, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, ServiceName, Surface, __export, __require, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports2 as e2e_exports, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir2 as getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, initTelemetry, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports2 as local_exports, mcp_exports, openBrowserUrl, performLogin, performLogout, pollDeviceCode, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, src_exports, startDeviceCodeFlow, toolRequiresAuth, track, validatePreference, verifyFileChecksum, writePreferences };
|