@muggleai/works 5.10.0 → 5.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-OCLMXAVJ.js → chunk-MSPMXBO5.js} +418 -326
- package/dist/{chunk-7NC2DJTK.js → chunk-WUMAJOBT.js} +9 -4
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/agents/test-prepare-runner.md +3 -1
- package/dist/plugin/agents/visual-walkthrough-builder.md +12 -5
- package/dist/plugin/commands/mtest.md +1 -1
- package/dist/plugin/hooks/README.md +15 -3
- package/dist/plugin/hooks/hooks.json +79 -0
- package/dist/plugin/scripts/guardrail-classify-gate.sh +23 -0
- package/dist/plugin/scripts/guardrail-debug-path-gate.sh +41 -0
- package/dist/plugin/scripts/guardrail-pr-terminal.sh +6 -2
- package/dist/plugin/scripts/guardrail-record-stage-read.sh +21 -0
- package/dist/plugin/scripts/guardrail-record-stage-signals.sh +23 -0
- package/dist/plugin/scripts/guardrail-record-tests.sh +11 -4
- package/dist/plugin/scripts/guardrail-report-format.sh +9 -5
- package/dist/plugin/scripts/guardrail-skill-stages.sh +35 -0
- package/dist/plugin/scripts/guardrail-stage-gate.sh +43 -0
- package/dist/plugin/scripts/guardrail-walkthrough-gate.sh +41 -0
- package/dist/plugin/scripts/guardrails.mjs +428 -35
- package/dist/plugin/scripts/pr-watch-events.sh +116 -0
- package/dist/plugin/scripts/pr-watch-guards.sh +8 -2
- package/dist/plugin/scripts/pr-watch-loop.sh +254 -0
- package/dist/plugin/scripts/reconcile-stale-watchers.sh +66 -18
- package/dist/plugin/scripts/sign-body.sh +88 -0
- package/dist/plugin/skills/CLAUDE.md +16 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +83 -3
- package/dist/plugin/skills/_shared/pr-followup-helpers/loop-signature.md +6 -8
- package/dist/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +10 -18
- package/dist/plugin/skills/_shared/vcs/CLAUDE.md +1 -0
- package/dist/plugin/skills/_shared/vcs/github/pr-edit.md +3 -2
- package/dist/plugin/skills/_shared/vcs/github/reply-line-comment.md +3 -2
- package/dist/plugin/skills/_shared/vcs/github/top-level-comment.md +3 -2
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-create.md +4 -1
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-edit.md +4 -1
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-note.md +4 -1
- package/dist/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +4 -1
- package/dist/plugin/skills/_shared/vcs/post-signature.md +23 -12
- package/dist/plugin/skills/do/open-prs/forward.md +2 -2
- package/dist/plugin/skills/do/per-comment-replies.md +2 -15
- package/dist/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -1
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +6 -3
- package/dist/plugin/skills/muggle-pr-followup/adopt.md +60 -0
- package/dist/plugin/skills/muggle-pr-followup/arm-watcher.md +10 -14
- package/dist/plugin/skills/muggle-pr-followup/auto-track.md +2 -0
- package/dist/plugin/skills/muggle-pr-followup/evals/evals.json +63 -1
- package/dist/plugin/skills/muggle-pr-followup/output-templates/help.md +11 -1
- package/dist/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +1 -7
- package/dist/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +1 -4
- package/dist/plugin/skills/muggle-pr-followup/reconcile.md +32 -6
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +18 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/watcherLifetime.md +23 -0
- package/dist/plugin/skills/muggle-test/SKILL.md +22 -2
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +3 -0
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +19 -12
- package/dist/plugin/skills/muggle-test-prepare/steps/confirm-recipe.md +56 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/derive-service-graph.md +51 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/e2e-instructions.md +13 -2
- package/dist/plugin/skills/muggle-test-prepare/steps/identify-services.md +4 -2
- package/dist/plugin/skills/muggle-test-prepare/steps/readiness-report.md +3 -1
- package/dist/plugin/skills/muggle-test-prepare/steps/record-resolution.md +32 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/replay-or-learn.md +20 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +4 -2
- package/dist/plugin/skills/muggle-test-prepare/steps/smoke-test.md +5 -1
- package/dist/plugin/skills/muggle-test-prepare/steps/start-services.md +3 -1
- package/dist/release-manifest.json +4 -4
- package/dist/src-B5OTAZKM.js +1 -0
- package/package.json +7 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/agents/test-prepare-runner.md +3 -1
- package/plugin/agents/visual-walkthrough-builder.md +12 -5
- package/plugin/commands/mtest.md +1 -1
- package/plugin/hooks/README.md +15 -3
- package/plugin/hooks/hooks.json +79 -0
- package/plugin/scripts/guardrail-classify-gate.sh +23 -0
- package/plugin/scripts/guardrail-debug-path-gate.sh +41 -0
- package/plugin/scripts/guardrail-pr-terminal.sh +6 -2
- package/plugin/scripts/guardrail-record-stage-read.sh +21 -0
- package/plugin/scripts/guardrail-record-stage-signals.sh +23 -0
- package/plugin/scripts/guardrail-record-tests.sh +11 -4
- package/plugin/scripts/guardrail-report-format.sh +9 -5
- package/plugin/scripts/guardrail-skill-stages.sh +35 -0
- package/plugin/scripts/guardrail-stage-gate.sh +43 -0
- package/plugin/scripts/guardrail-walkthrough-gate.sh +41 -0
- package/plugin/scripts/guardrails.mjs +428 -35
- package/plugin/scripts/pr-watch-events.sh +116 -0
- package/plugin/scripts/pr-watch-guards.sh +8 -2
- package/plugin/scripts/pr-watch-loop.sh +254 -0
- package/plugin/scripts/reconcile-stale-watchers.sh +66 -18
- package/plugin/scripts/sign-body.sh +88 -0
- package/plugin/skills/CLAUDE.md +16 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +83 -3
- package/plugin/skills/_shared/pr-followup-helpers/loop-signature.md +6 -8
- package/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +10 -18
- package/plugin/skills/_shared/vcs/CLAUDE.md +1 -0
- package/plugin/skills/_shared/vcs/github/pr-edit.md +3 -2
- package/plugin/skills/_shared/vcs/github/reply-line-comment.md +3 -2
- package/plugin/skills/_shared/vcs/github/top-level-comment.md +3 -2
- package/plugin/skills/_shared/vcs/gitlab/mr-create.md +4 -1
- package/plugin/skills/_shared/vcs/gitlab/mr-edit.md +4 -1
- package/plugin/skills/_shared/vcs/gitlab/mr-note.md +4 -1
- package/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +4 -1
- package/plugin/skills/_shared/vcs/post-signature.md +23 -12
- package/plugin/skills/do/open-prs/forward.md +2 -2
- package/plugin/skills/do/per-comment-replies.md +2 -15
- package/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -1
- package/plugin/skills/muggle-pr-followup/SKILL.md +6 -3
- package/plugin/skills/muggle-pr-followup/adopt.md +60 -0
- package/plugin/skills/muggle-pr-followup/arm-watcher.md +10 -14
- package/plugin/skills/muggle-pr-followup/auto-track.md +2 -0
- package/plugin/skills/muggle-pr-followup/evals/evals.json +63 -1
- package/plugin/skills/muggle-pr-followup/output-templates/help.md +11 -1
- package/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +1 -7
- package/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +1 -4
- package/plugin/skills/muggle-pr-followup/reconcile.md +32 -6
- package/plugin/skills/muggle-pr-followup/state-schemas.md +18 -0
- package/plugin/skills/muggle-preferences/preference-gates/watcherLifetime.md +23 -0
- package/plugin/skills/muggle-test/SKILL.md +22 -2
- package/plugin/skills/muggle-test-feature-local/SKILL.md +3 -0
- package/plugin/skills/muggle-test-prepare/SKILL.md +19 -12
- package/plugin/skills/muggle-test-prepare/steps/confirm-recipe.md +56 -0
- package/plugin/skills/muggle-test-prepare/steps/derive-service-graph.md +51 -0
- package/plugin/skills/muggle-test-prepare/steps/e2e-instructions.md +13 -2
- package/plugin/skills/muggle-test-prepare/steps/identify-services.md +4 -2
- package/plugin/skills/muggle-test-prepare/steps/readiness-report.md +3 -1
- package/plugin/skills/muggle-test-prepare/steps/record-resolution.md +32 -0
- package/plugin/skills/muggle-test-prepare/steps/replay-or-learn.md +20 -0
- package/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +4 -2
- package/plugin/skills/muggle-test-prepare/steps/smoke-test.md +5 -1
- package/plugin/skills/muggle-test-prepare/steps/start-services.md +3 -1
- package/dist/src-AWUORQZZ.js +0 -1
|
@@ -2,7 +2,7 @@ import * as crypto from 'crypto';
|
|
|
2
2
|
import { randomUUID } from 'crypto';
|
|
3
3
|
import * as fs5 from 'fs';
|
|
4
4
|
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
5
|
-
import * as
|
|
5
|
+
import * as path10 from 'path';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
7
7
|
import * as os4 from 'os';
|
|
8
8
|
import { platform } from 'os';
|
|
@@ -10,7 +10,7 @@ import winston from 'winston';
|
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import { exec, spawn } from 'child_process';
|
|
12
12
|
import axios, { AxiosError } from 'axios';
|
|
13
|
-
import * as
|
|
13
|
+
import * as fs9 from 'fs/promises';
|
|
14
14
|
import AppInsights from 'applicationinsights';
|
|
15
15
|
import { z } from 'zod';
|
|
16
16
|
|
|
@@ -38,6 +38,8 @@ __export(src_exports, {
|
|
|
38
38
|
PreferenceKey: () => PreferenceKey,
|
|
39
39
|
PreferenceValue: () => PreferenceValue,
|
|
40
40
|
ProjectPreferencesReconcileOutcome: () => ProjectPreferencesReconcileOutcome,
|
|
41
|
+
WATCHER_LIFETIME_SECONDS: () => WATCHER_LIFETIME_SECONDS,
|
|
42
|
+
WATCHER_LIFETIME_UNBOUNDED_SECONDS: () => WATCHER_LIFETIME_UNBOUNDED_SECONDS,
|
|
41
43
|
buildElectronAppChecksumsUrl: () => buildElectronAppChecksumsUrl,
|
|
42
44
|
buildElectronAppReleaseAssetUrl: () => buildElectronAppReleaseAssetUrl,
|
|
43
45
|
buildElectronAppReleaseTag: () => buildElectronAppReleaseTag,
|
|
@@ -98,7 +100,7 @@ __export(src_exports, {
|
|
|
98
100
|
});
|
|
99
101
|
var DATA_DIR_NAME = ".muggle-ai";
|
|
100
102
|
function getDataDir() {
|
|
101
|
-
return
|
|
103
|
+
return path10.join(os4.homedir(), DATA_DIR_NAME);
|
|
102
104
|
}
|
|
103
105
|
var DEV_MANIFEST = {
|
|
104
106
|
release: "dev",
|
|
@@ -162,24 +164,24 @@ var configInstance = null;
|
|
|
162
164
|
var muggleConfigCache = null;
|
|
163
165
|
function getPackageRoot() {
|
|
164
166
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
165
|
-
const currentDir =
|
|
166
|
-
if (currentDir.includes(
|
|
167
|
-
return
|
|
167
|
+
const currentDir = path10.dirname(currentFilePath);
|
|
168
|
+
if (currentDir.includes(path10.join("dist", "shared"))) {
|
|
169
|
+
return path10.resolve(currentDir, "..", "..");
|
|
168
170
|
}
|
|
169
171
|
if (currentDir.endsWith("dist")) {
|
|
170
|
-
return
|
|
172
|
+
return path10.resolve(currentDir, "..");
|
|
171
173
|
}
|
|
172
|
-
if (currentDir.includes(
|
|
173
|
-
return
|
|
174
|
+
if (currentDir.includes(path10.join("src", "shared"))) {
|
|
175
|
+
return path10.resolve(currentDir, "..", "..");
|
|
174
176
|
}
|
|
175
|
-
return
|
|
177
|
+
return path10.dirname(currentDir);
|
|
176
178
|
}
|
|
177
179
|
function getMuggleConfig() {
|
|
178
180
|
if (muggleConfigCache) {
|
|
179
181
|
return muggleConfigCache;
|
|
180
182
|
}
|
|
181
183
|
const packageRoot = getPackageRoot();
|
|
182
|
-
const packageJsonPath =
|
|
184
|
+
const packageJsonPath = path10.join(packageRoot, "package.json");
|
|
183
185
|
let packageJson;
|
|
184
186
|
try {
|
|
185
187
|
const content = fs5.readFileSync(packageJsonPath, "utf-8");
|
|
@@ -242,17 +244,17 @@ function getDataDir2() {
|
|
|
242
244
|
function getDownloadedElectronAppPath() {
|
|
243
245
|
const platformName = os4.platform();
|
|
244
246
|
const version = getElectronAppVersion();
|
|
245
|
-
const baseDir =
|
|
247
|
+
const baseDir = path10.join(getDataDir2(), ELECTRON_APP_DIR, version);
|
|
246
248
|
let binaryPath;
|
|
247
249
|
switch (platformName) {
|
|
248
250
|
case "darwin":
|
|
249
|
-
binaryPath =
|
|
251
|
+
binaryPath = path10.join(baseDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
|
|
250
252
|
break;
|
|
251
253
|
case "win32":
|
|
252
|
-
binaryPath =
|
|
254
|
+
binaryPath = path10.join(baseDir, "MuggleAI.exe");
|
|
253
255
|
break;
|
|
254
256
|
case "linux":
|
|
255
|
-
binaryPath =
|
|
257
|
+
binaryPath = path10.join(baseDir, "MuggleAI");
|
|
256
258
|
break;
|
|
257
259
|
default:
|
|
258
260
|
return null;
|
|
@@ -268,13 +270,13 @@ function getSystemElectronAppPath() {
|
|
|
268
270
|
let binaryPath;
|
|
269
271
|
switch (platformName) {
|
|
270
272
|
case "darwin":
|
|
271
|
-
binaryPath =
|
|
273
|
+
binaryPath = path10.join(homeDir, "Applications", "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
|
|
272
274
|
break;
|
|
273
275
|
case "win32":
|
|
274
|
-
binaryPath =
|
|
276
|
+
binaryPath = path10.join(homeDir, "AppData", "Local", "Programs", "MuggleAI", "MuggleAI.exe");
|
|
275
277
|
break;
|
|
276
278
|
case "linux":
|
|
277
|
-
binaryPath =
|
|
279
|
+
binaryPath = path10.join(homeDir, ".local", "share", "muggle-ai", "MuggleAI");
|
|
278
280
|
break;
|
|
279
281
|
default:
|
|
280
282
|
return null;
|
|
@@ -305,7 +307,7 @@ function resolveWebServicePath() {
|
|
|
305
307
|
return customPath;
|
|
306
308
|
}
|
|
307
309
|
const packageRoot = getPackageRoot();
|
|
308
|
-
const siblingPath =
|
|
310
|
+
const siblingPath = path10.resolve(packageRoot, "..", "web-service", "dist", "src", "index.js");
|
|
309
311
|
if (fs5.existsSync(siblingPath)) {
|
|
310
312
|
return siblingPath;
|
|
311
313
|
}
|
|
@@ -392,13 +394,13 @@ function buildLocalQaConfig() {
|
|
|
392
394
|
webServiceUrl: process.env.WEB_SERVICE_URL ?? DEFAULT_WEB_SERVICE_URL,
|
|
393
395
|
promptServiceUrl: process.env.PROMPT_SERVICE_BASE_URL ?? defaultPromptServiceUrl,
|
|
394
396
|
dataDir,
|
|
395
|
-
sessionsDir:
|
|
396
|
-
projectsDir:
|
|
397
|
-
tempDir:
|
|
398
|
-
apiKeyFilePath:
|
|
399
|
-
oauthSessionFilePath:
|
|
397
|
+
sessionsDir: path10.join(dataDir, "sessions"),
|
|
398
|
+
projectsDir: path10.join(dataDir, "projects"),
|
|
399
|
+
tempDir: path10.join(dataDir, "temp"),
|
|
400
|
+
apiKeyFilePath: path10.join(dataDir, API_KEY_FILE),
|
|
401
|
+
oauthSessionFilePath: path10.join(dataDir, "oauth-session.json"),
|
|
400
402
|
webServicePath: resolveWebServicePath(),
|
|
401
|
-
webServicePidFile:
|
|
403
|
+
webServicePidFile: path10.join(dataDir, "web-service.pid"),
|
|
402
404
|
auth0: {
|
|
403
405
|
domain: process.env.AUTH0_DOMAIN ?? defaultAuth0Domain,
|
|
404
406
|
clientId: process.env.AUTH0_CLIENT_ID ?? defaultAuth0ClientId,
|
|
@@ -433,7 +435,7 @@ function getElectronAppVersion() {
|
|
|
433
435
|
if (envVersion && /^\d+\.\d+\.\d+$/.test(envVersion)) {
|
|
434
436
|
return envVersion;
|
|
435
437
|
}
|
|
436
|
-
const overridePath =
|
|
438
|
+
const overridePath = path10.join(getDataDir2(), VERSION_OVERRIDE_FILE);
|
|
437
439
|
if (fs5.existsSync(overridePath)) {
|
|
438
440
|
try {
|
|
439
441
|
const content = JSON.parse(fs5.readFileSync(overridePath, "utf-8"));
|
|
@@ -450,7 +452,7 @@ function getElectronAppVersionSource() {
|
|
|
450
452
|
if (envVersion && /^\d+\.\d+\.\d+$/.test(envVersion)) {
|
|
451
453
|
return "env";
|
|
452
454
|
}
|
|
453
|
-
const overridePath =
|
|
455
|
+
const overridePath = path10.join(getDataDir2(), VERSION_OVERRIDE_FILE);
|
|
454
456
|
if (fs5.existsSync(overridePath)) {
|
|
455
457
|
try {
|
|
456
458
|
const content = JSON.parse(fs5.readFileSync(overridePath, "utf-8"));
|
|
@@ -485,7 +487,7 @@ function isElectronAppInstalled() {
|
|
|
485
487
|
}
|
|
486
488
|
function getElectronAppDir(version) {
|
|
487
489
|
const resolvedVersion = version ?? getElectronAppVersion();
|
|
488
|
-
return
|
|
490
|
+
return path10.join(getDataDir2(), ELECTRON_APP_DIR, resolvedVersion);
|
|
489
491
|
}
|
|
490
492
|
|
|
491
493
|
// packages/mcps/src/shared/logger.ts
|
|
@@ -559,7 +561,7 @@ async function calculateFileChecksum(filePath) {
|
|
|
559
561
|
async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
560
562
|
if (!expectedChecksum || expectedChecksum.trim() === "") {
|
|
561
563
|
logger.warn("Checksum verification skipped - no checksum provided", {
|
|
562
|
-
file:
|
|
564
|
+
file: path10.basename(filePath)
|
|
563
565
|
});
|
|
564
566
|
return {
|
|
565
567
|
valid: true,
|
|
@@ -575,13 +577,13 @@ async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
|
575
577
|
const valid = normalizedExpected === normalizedActual;
|
|
576
578
|
if (!valid) {
|
|
577
579
|
logger.error("Checksum verification failed", {
|
|
578
|
-
file:
|
|
580
|
+
file: path10.basename(filePath),
|
|
579
581
|
expected: normalizedExpected,
|
|
580
582
|
actual: normalizedActual
|
|
581
583
|
});
|
|
582
584
|
} else {
|
|
583
585
|
logger.info("Checksum verified successfully", {
|
|
584
|
-
file:
|
|
586
|
+
file: path10.basename(filePath),
|
|
585
587
|
checksum: normalizedActual
|
|
586
588
|
});
|
|
587
589
|
}
|
|
@@ -594,7 +596,7 @@ async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
|
594
596
|
} catch (error) {
|
|
595
597
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
596
598
|
logger.error("Checksum calculation failed", {
|
|
597
|
-
file:
|
|
599
|
+
file: path10.basename(filePath),
|
|
598
600
|
error: errorMessage
|
|
599
601
|
});
|
|
600
602
|
return {
|
|
@@ -661,7 +663,7 @@ async function openBrowserUrl(options) {
|
|
|
661
663
|
}
|
|
662
664
|
var API_KEY_FILE2 = "api-key.json";
|
|
663
665
|
function getApiKeyFilePath() {
|
|
664
|
-
return
|
|
666
|
+
return path10.join(getDataDir(), API_KEY_FILE2);
|
|
665
667
|
}
|
|
666
668
|
function ensureDataDir() {
|
|
667
669
|
const dataDir = getDataDir();
|
|
@@ -850,8 +852,8 @@ var AuthService = class {
|
|
|
850
852
|
constructor() {
|
|
851
853
|
const config = getConfig();
|
|
852
854
|
this.oauthSessionFilePath = config.localQa.oauthSessionFilePath;
|
|
853
|
-
this.pendingDeviceCodePath =
|
|
854
|
-
|
|
855
|
+
this.pendingDeviceCodePath = path10.join(
|
|
856
|
+
path10.dirname(config.localQa.oauthSessionFilePath),
|
|
855
857
|
"pending-device-code.json"
|
|
856
858
|
);
|
|
857
859
|
}
|
|
@@ -960,7 +962,7 @@ var AuthService = class {
|
|
|
960
962
|
*/
|
|
961
963
|
storePendingDeviceCode(params) {
|
|
962
964
|
const logger6 = getLogger();
|
|
963
|
-
const dir =
|
|
965
|
+
const dir = path10.dirname(this.pendingDeviceCodePath);
|
|
964
966
|
if (!fs5.existsSync(dir)) {
|
|
965
967
|
fs5.mkdirSync(dir, { recursive: true });
|
|
966
968
|
}
|
|
@@ -1173,7 +1175,7 @@ var AuthService = class {
|
|
|
1173
1175
|
email,
|
|
1174
1176
|
userId
|
|
1175
1177
|
};
|
|
1176
|
-
const dir =
|
|
1178
|
+
const dir = path10.dirname(this.oauthSessionFilePath);
|
|
1177
1179
|
if (!fs5.existsSync(dir)) {
|
|
1178
1180
|
fs5.mkdirSync(dir, { recursive: true });
|
|
1179
1181
|
}
|
|
@@ -1276,7 +1278,7 @@ var AuthService = class {
|
|
|
1276
1278
|
email: storedAuth.email,
|
|
1277
1279
|
userId: storedAuth.userId
|
|
1278
1280
|
};
|
|
1279
|
-
const dir =
|
|
1281
|
+
const dir = path10.dirname(this.oauthSessionFilePath);
|
|
1280
1282
|
if (!fs5.existsSync(dir)) {
|
|
1281
1283
|
fs5.mkdirSync(dir, { recursive: true });
|
|
1282
1284
|
}
|
|
@@ -1399,11 +1401,11 @@ var StorageService = class {
|
|
|
1399
1401
|
createSessionDirectory(sessionId) {
|
|
1400
1402
|
const logger6 = getLogger();
|
|
1401
1403
|
this.ensureDirectories();
|
|
1402
|
-
const sessionDir =
|
|
1404
|
+
const sessionDir = path10.join(this.sessionsDir, sessionId);
|
|
1403
1405
|
if (!fs5.existsSync(sessionDir)) {
|
|
1404
1406
|
fs5.mkdirSync(sessionDir, { recursive: true });
|
|
1405
|
-
fs5.mkdirSync(
|
|
1406
|
-
fs5.mkdirSync(
|
|
1407
|
+
fs5.mkdirSync(path10.join(sessionDir, "screenshots"), { recursive: true });
|
|
1408
|
+
fs5.mkdirSync(path10.join(sessionDir, "logs"), { recursive: true });
|
|
1407
1409
|
logger6.info("Created session directory", { sessionId, path: sessionDir });
|
|
1408
1410
|
}
|
|
1409
1411
|
return sessionDir;
|
|
@@ -1415,7 +1417,7 @@ var StorageService = class {
|
|
|
1415
1417
|
saveSessionMetadata(metadata) {
|
|
1416
1418
|
const logger6 = getLogger();
|
|
1417
1419
|
const sessionDir = this.createSessionDirectory(metadata.sessionId);
|
|
1418
|
-
const metadataPath =
|
|
1420
|
+
const metadataPath = path10.join(sessionDir, "metadata.json");
|
|
1419
1421
|
fs5.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
|
|
1420
1422
|
logger6.debug("Saved session metadata", { sessionId: metadata.sessionId });
|
|
1421
1423
|
}
|
|
@@ -1426,7 +1428,7 @@ var StorageService = class {
|
|
|
1426
1428
|
*/
|
|
1427
1429
|
loadSessionMetadata(sessionId) {
|
|
1428
1430
|
const logger6 = getLogger();
|
|
1429
|
-
const metadataPath =
|
|
1431
|
+
const metadataPath = path10.join(this.sessionsDir, sessionId, "metadata.json");
|
|
1430
1432
|
if (!fs5.existsSync(metadataPath)) {
|
|
1431
1433
|
return null;
|
|
1432
1434
|
}
|
|
@@ -1450,7 +1452,7 @@ var StorageService = class {
|
|
|
1450
1452
|
return [];
|
|
1451
1453
|
}
|
|
1452
1454
|
return fs5.readdirSync(this.sessionsDir).filter((entry) => {
|
|
1453
|
-
const entryPath =
|
|
1455
|
+
const entryPath = path10.join(this.sessionsDir, entry);
|
|
1454
1456
|
return fs5.statSync(entryPath).isDirectory();
|
|
1455
1457
|
});
|
|
1456
1458
|
}
|
|
@@ -1459,13 +1461,13 @@ var StorageService = class {
|
|
|
1459
1461
|
* @returns Current session ID, or null.
|
|
1460
1462
|
*/
|
|
1461
1463
|
getCurrentSessionId() {
|
|
1462
|
-
const currentPath =
|
|
1464
|
+
const currentPath = path10.join(this.sessionsDir, "current");
|
|
1463
1465
|
if (!fs5.existsSync(currentPath)) {
|
|
1464
1466
|
return null;
|
|
1465
1467
|
}
|
|
1466
1468
|
try {
|
|
1467
1469
|
const target = fs5.readlinkSync(currentPath);
|
|
1468
|
-
return
|
|
1470
|
+
return path10.basename(target);
|
|
1469
1471
|
} catch {
|
|
1470
1472
|
return null;
|
|
1471
1473
|
}
|
|
@@ -1476,8 +1478,8 @@ var StorageService = class {
|
|
|
1476
1478
|
*/
|
|
1477
1479
|
setCurrentSession(sessionId) {
|
|
1478
1480
|
const logger6 = getLogger();
|
|
1479
|
-
const currentPath =
|
|
1480
|
-
const targetPath =
|
|
1481
|
+
const currentPath = path10.join(this.sessionsDir, "current");
|
|
1482
|
+
const targetPath = path10.join(this.sessionsDir, sessionId);
|
|
1481
1483
|
if (fs5.existsSync(currentPath)) {
|
|
1482
1484
|
fs5.unlinkSync(currentPath);
|
|
1483
1485
|
}
|
|
@@ -1492,7 +1494,7 @@ var StorageService = class {
|
|
|
1492
1494
|
const { sessionId, filename, data } = params;
|
|
1493
1495
|
const logger6 = getLogger();
|
|
1494
1496
|
const sessionDir = this.createSessionDirectory(sessionId);
|
|
1495
|
-
const screenshotPath =
|
|
1497
|
+
const screenshotPath = path10.join(sessionDir, "screenshots", filename);
|
|
1496
1498
|
fs5.writeFileSync(screenshotPath, data);
|
|
1497
1499
|
logger6.debug("Saved screenshot", { sessionId, filename });
|
|
1498
1500
|
return screenshotPath;
|
|
@@ -1505,7 +1507,7 @@ var StorageService = class {
|
|
|
1505
1507
|
const { sessionId, content } = params;
|
|
1506
1508
|
const logger6 = getLogger();
|
|
1507
1509
|
const sessionDir = this.createSessionDirectory(sessionId);
|
|
1508
|
-
const resultsPath =
|
|
1510
|
+
const resultsPath = path10.join(sessionDir, "results.md");
|
|
1509
1511
|
fs5.appendFileSync(resultsPath, content + "\n", "utf-8");
|
|
1510
1512
|
logger6.debug("Appended to results", { sessionId });
|
|
1511
1513
|
}
|
|
@@ -1515,7 +1517,7 @@ var StorageService = class {
|
|
|
1515
1517
|
* @returns Results content, or null if not found.
|
|
1516
1518
|
*/
|
|
1517
1519
|
getResults(sessionId) {
|
|
1518
|
-
const resultsPath =
|
|
1520
|
+
const resultsPath = path10.join(this.sessionsDir, sessionId, "results.md");
|
|
1519
1521
|
if (!fs5.existsSync(resultsPath)) {
|
|
1520
1522
|
return null;
|
|
1521
1523
|
}
|
|
@@ -1584,7 +1586,7 @@ var StorageService = class {
|
|
|
1584
1586
|
const { sessionId, targetUrl, testInstructions } = params;
|
|
1585
1587
|
const logger6 = getLogger();
|
|
1586
1588
|
const sessionDir = this.createSessionDirectory(sessionId);
|
|
1587
|
-
const resultsPath =
|
|
1589
|
+
const resultsPath = path10.join(sessionDir, "results.md");
|
|
1588
1590
|
const header = [
|
|
1589
1591
|
`# Test Results: ${sessionId}`,
|
|
1590
1592
|
"",
|
|
@@ -1608,7 +1610,7 @@ var StorageService = class {
|
|
|
1608
1610
|
const { sessionId, step } = params;
|
|
1609
1611
|
const logger6 = getLogger();
|
|
1610
1612
|
const sessionDir = this.createSessionDirectory(sessionId);
|
|
1611
|
-
const resultsPath =
|
|
1613
|
+
const resultsPath = path10.join(sessionDir, "results.md");
|
|
1612
1614
|
const statusIcon = step.success ? "\u2713" : "\u2717";
|
|
1613
1615
|
const stepContent = [
|
|
1614
1616
|
`### Step ${step.stepNumber}: ${step.action}`,
|
|
@@ -1633,8 +1635,8 @@ var StorageService = class {
|
|
|
1633
1635
|
finalizeResults(params) {
|
|
1634
1636
|
const { sessionId, status, summary } = params;
|
|
1635
1637
|
const logger6 = getLogger();
|
|
1636
|
-
const sessionDir =
|
|
1637
|
-
const resultsPath =
|
|
1638
|
+
const sessionDir = path10.join(this.sessionsDir, sessionId);
|
|
1639
|
+
const resultsPath = path10.join(sessionDir, "results.md");
|
|
1638
1640
|
if (!fs5.existsSync(resultsPath)) {
|
|
1639
1641
|
logger6.warn("Results file not found for finalization", { sessionId });
|
|
1640
1642
|
return;
|
|
@@ -1716,7 +1718,7 @@ var StorageService = class {
|
|
|
1716
1718
|
}
|
|
1717
1719
|
const sessionDate = new Date(metadata.startTime);
|
|
1718
1720
|
if (sessionDate < cutoffDate) {
|
|
1719
|
-
const sessionDir =
|
|
1721
|
+
const sessionDir = path10.join(this.sessionsDir, sessionId);
|
|
1720
1722
|
try {
|
|
1721
1723
|
fs5.rmSync(sessionDir, { recursive: true, force: true });
|
|
1722
1724
|
deletedCount++;
|
|
@@ -1746,7 +1748,7 @@ var StorageService = class {
|
|
|
1746
1748
|
* @returns Session directory path.
|
|
1747
1749
|
*/
|
|
1748
1750
|
getSessionPath(sessionId) {
|
|
1749
|
-
return
|
|
1751
|
+
return path10.join(this.sessionsDir, sessionId);
|
|
1750
1752
|
}
|
|
1751
1753
|
/**
|
|
1752
1754
|
* Delete a specific session.
|
|
@@ -1755,7 +1757,7 @@ var StorageService = class {
|
|
|
1755
1757
|
*/
|
|
1756
1758
|
deleteSession(sessionId) {
|
|
1757
1759
|
const logger6 = getLogger();
|
|
1758
|
-
const sessionDir =
|
|
1760
|
+
const sessionDir = path10.join(this.sessionsDir, sessionId);
|
|
1759
1761
|
if (!fs5.existsSync(sessionDir)) {
|
|
1760
1762
|
logger6.warn("Session not found for deletion", { sessionId });
|
|
1761
1763
|
return false;
|
|
@@ -1763,7 +1765,7 @@ var StorageService = class {
|
|
|
1763
1765
|
try {
|
|
1764
1766
|
const currentId = this.getCurrentSessionId();
|
|
1765
1767
|
if (currentId === sessionId) {
|
|
1766
|
-
const currentPath =
|
|
1768
|
+
const currentPath = path10.join(this.sessionsDir, "current");
|
|
1767
1769
|
if (fs5.existsSync(currentPath)) {
|
|
1768
1770
|
fs5.unlinkSync(currentPath);
|
|
1769
1771
|
}
|
|
@@ -1797,8 +1799,8 @@ var RunResultStorageService = class {
|
|
|
1797
1799
|
constructor() {
|
|
1798
1800
|
const storageService = getStorageService();
|
|
1799
1801
|
const dataDir = storageService.getDataDir();
|
|
1800
|
-
this.runResultsDir =
|
|
1801
|
-
this.testScriptsDir =
|
|
1802
|
+
this.runResultsDir = path10.join(dataDir, "run-results");
|
|
1803
|
+
this.testScriptsDir = path10.join(dataDir, "test-scripts");
|
|
1802
1804
|
this.ensureDirectories();
|
|
1803
1805
|
}
|
|
1804
1806
|
/**
|
|
@@ -1824,7 +1826,7 @@ var RunResultStorageService = class {
|
|
|
1824
1826
|
const results = [];
|
|
1825
1827
|
for (const file of files) {
|
|
1826
1828
|
try {
|
|
1827
|
-
const content = fs5.readFileSync(
|
|
1829
|
+
const content = fs5.readFileSync(path10.join(this.runResultsDir, file), "utf-8");
|
|
1828
1830
|
results.push(JSON.parse(content));
|
|
1829
1831
|
} catch {
|
|
1830
1832
|
logger3.warn("Failed to read run result file", { file });
|
|
@@ -1839,7 +1841,7 @@ var RunResultStorageService = class {
|
|
|
1839
1841
|
* Get a run result by ID.
|
|
1840
1842
|
*/
|
|
1841
1843
|
getRunResult(runId) {
|
|
1842
|
-
const filePath =
|
|
1844
|
+
const filePath = path10.join(this.runResultsDir, `${runId}.json`);
|
|
1843
1845
|
if (!fs5.existsSync(filePath)) {
|
|
1844
1846
|
return void 0;
|
|
1845
1847
|
}
|
|
@@ -1854,7 +1856,7 @@ var RunResultStorageService = class {
|
|
|
1854
1856
|
* Save a run result.
|
|
1855
1857
|
*/
|
|
1856
1858
|
saveRunResult(result) {
|
|
1857
|
-
const filePath =
|
|
1859
|
+
const filePath = path10.join(this.runResultsDir, `${result.id}.json`);
|
|
1858
1860
|
fs5.writeFileSync(filePath, JSON.stringify(result, null, 2));
|
|
1859
1861
|
}
|
|
1860
1862
|
/**
|
|
@@ -1907,7 +1909,7 @@ var RunResultStorageService = class {
|
|
|
1907
1909
|
const scripts = [];
|
|
1908
1910
|
for (const file of files) {
|
|
1909
1911
|
try {
|
|
1910
|
-
const content = fs5.readFileSync(
|
|
1912
|
+
const content = fs5.readFileSync(path10.join(this.testScriptsDir, file), "utf-8");
|
|
1911
1913
|
scripts.push(JSON.parse(content));
|
|
1912
1914
|
} catch {
|
|
1913
1915
|
logger3.warn("Failed to read test script file", { file });
|
|
@@ -1922,7 +1924,7 @@ var RunResultStorageService = class {
|
|
|
1922
1924
|
* Get a test script by ID.
|
|
1923
1925
|
*/
|
|
1924
1926
|
getTestScript(testScriptId) {
|
|
1925
|
-
const filePath =
|
|
1927
|
+
const filePath = path10.join(this.testScriptsDir, `${testScriptId}.json`);
|
|
1926
1928
|
if (!fs5.existsSync(filePath)) {
|
|
1927
1929
|
return void 0;
|
|
1928
1930
|
}
|
|
@@ -1937,7 +1939,7 @@ var RunResultStorageService = class {
|
|
|
1937
1939
|
* Save a test script.
|
|
1938
1940
|
*/
|
|
1939
1941
|
saveTestScript(script) {
|
|
1940
|
-
const filePath =
|
|
1942
|
+
const filePath = path10.join(this.testScriptsDir, `${script.id}.json`);
|
|
1941
1943
|
fs5.writeFileSync(filePath, JSON.stringify(script, null, 2));
|
|
1942
1944
|
}
|
|
1943
1945
|
/**
|
|
@@ -1987,6 +1989,246 @@ function resetRunResultStorageService() {
|
|
|
1987
1989
|
instance = null;
|
|
1988
1990
|
}
|
|
1989
1991
|
|
|
1992
|
+
// packages/mcps/src/shared/llm-env-constants.ts
|
|
1993
|
+
var LLM_ENV_PREFERENCE_KEY = "llmEnv";
|
|
1994
|
+
var FORWARDABLE_LLM_ENV_NAMES = [
|
|
1995
|
+
"MUGGLE_LLM_PROVIDER",
|
|
1996
|
+
"MUGGLE_LLM_BASE_URL",
|
|
1997
|
+
"MUGGLE_LLM_API_KEY",
|
|
1998
|
+
"MUGGLE_LLM_MODEL",
|
|
1999
|
+
"MUGGLE_LLM_MODEL_PREDICTION",
|
|
2000
|
+
"MUGGLE_LLM_MODEL_SUMMARIZER",
|
|
2001
|
+
"MUGGLE_LLM_MODEL_EVAL",
|
|
2002
|
+
"MUGGLE_LLM_MAX_TOKENS",
|
|
2003
|
+
"MUGGLE_LLM_TEMPERATURE",
|
|
2004
|
+
"MUGGLE_LLM_TOP_P",
|
|
2005
|
+
"MUGGLE_LLM_TIMEOUT_MS"
|
|
2006
|
+
];
|
|
2007
|
+
|
|
2008
|
+
// packages/mcps/src/shared/preferences-types.ts
|
|
2009
|
+
var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
2010
|
+
PreferenceKey2["AutoLogin"] = "autoLogin";
|
|
2011
|
+
PreferenceKey2["AutoSelectProject"] = "autoSelectProject";
|
|
2012
|
+
PreferenceKey2["AutoSelectLocalHost"] = "autoSelectLocalHost";
|
|
2013
|
+
PreferenceKey2["ShowElectronBrowser"] = "showElectronBrowser";
|
|
2014
|
+
PreferenceKey2["OpenTestResultsAfterRun"] = "openTestResultsAfterRun";
|
|
2015
|
+
PreferenceKey2["DefaultExecutionMode"] = "defaultExecutionMode";
|
|
2016
|
+
PreferenceKey2["SuggestRelatedUseCases"] = "suggestRelatedUseCases";
|
|
2017
|
+
PreferenceKey2["SuggestRelatedTestCases"] = "suggestRelatedTestCases";
|
|
2018
|
+
PreferenceKey2["AutoDetectChanges"] = "autoDetectChanges";
|
|
2019
|
+
PreferenceKey2["PostPRVisualWalkthrough"] = "postPRVisualWalkthrough";
|
|
2020
|
+
PreferenceKey2["AutoCreatePR"] = "autoCreatePR";
|
|
2021
|
+
PreferenceKey2["CheckForUpdates"] = "checkForUpdates";
|
|
2022
|
+
PreferenceKey2["VerboseOutput"] = "verboseOutput";
|
|
2023
|
+
PreferenceKey2["AutoUseWorktree"] = "autoUseWorktree";
|
|
2024
|
+
PreferenceKey2["AutoRebase"] = "autoRebase";
|
|
2025
|
+
PreferenceKey2["AutoCleanup"] = "autoCleanup";
|
|
2026
|
+
PreferenceKey2["AutoE2ETest"] = "autoE2ETest";
|
|
2027
|
+
PreferenceKey2["AutoResolveConflicts"] = "autoResolveConflicts";
|
|
2028
|
+
PreferenceKey2["AutoReuseValidationContext"] = "autoReuseValidationContext";
|
|
2029
|
+
PreferenceKey2["AutoRouteBuildToMuggleDo"] = "autoRouteBuildToMuggleDo";
|
|
2030
|
+
PreferenceKey2["AutoWatchPR"] = "autoWatchPR";
|
|
2031
|
+
PreferenceKey2["WatcherLifetime"] = "watcherLifetime";
|
|
2032
|
+
PreferenceKey2["ReusePreparePlan"] = "reusePreparePlan";
|
|
2033
|
+
return PreferenceKey2;
|
|
2034
|
+
})(PreferenceKey || {});
|
|
2035
|
+
var PreferenceValue = /* @__PURE__ */ ((PreferenceValue2) => {
|
|
2036
|
+
PreferenceValue2["Always"] = "always";
|
|
2037
|
+
PreferenceValue2["Ask"] = "ask";
|
|
2038
|
+
PreferenceValue2["Never"] = "never";
|
|
2039
|
+
PreferenceValue2["Local"] = "local";
|
|
2040
|
+
PreferenceValue2["Remote"] = "remote";
|
|
2041
|
+
PreferenceValue2["OneDay"] = "1d";
|
|
2042
|
+
PreferenceValue2["SevenDays"] = "7d";
|
|
2043
|
+
return PreferenceValue2;
|
|
2044
|
+
})(PreferenceValue || {});
|
|
2045
|
+
|
|
2046
|
+
// packages/mcps/src/shared/preferences-constants.ts
|
|
2047
|
+
var PREFERENCES_FILE_NAME = "preferences.json";
|
|
2048
|
+
var PREFERENCES_PROJECT_DIR_NAME = ".muggle-ai";
|
|
2049
|
+
var PREFERENCES_VERSION = 1;
|
|
2050
|
+
var DEFAULT_PREFERENCES = {
|
|
2051
|
+
["autoLogin" /* AutoLogin */]: "always" /* Always */,
|
|
2052
|
+
["autoSelectProject" /* AutoSelectProject */]: "always" /* Always */,
|
|
2053
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: "always" /* Always */,
|
|
2054
|
+
["showElectronBrowser" /* ShowElectronBrowser */]: "always" /* Always */,
|
|
2055
|
+
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "always" /* Always */,
|
|
2056
|
+
["defaultExecutionMode" /* DefaultExecutionMode */]: "local" /* Local */,
|
|
2057
|
+
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: "always" /* Always */,
|
|
2058
|
+
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: "always" /* Always */,
|
|
2059
|
+
["autoDetectChanges" /* AutoDetectChanges */]: "always" /* Always */,
|
|
2060
|
+
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: "always" /* Always */,
|
|
2061
|
+
["autoCreatePR" /* AutoCreatePR */]: "always" /* Always */,
|
|
2062
|
+
["checkForUpdates" /* CheckForUpdates */]: "always" /* Always */,
|
|
2063
|
+
["verboseOutput" /* VerboseOutput */]: "never" /* Never */,
|
|
2064
|
+
["autoUseWorktree" /* AutoUseWorktree */]: "always" /* Always */,
|
|
2065
|
+
["autoRebase" /* AutoRebase */]: "always" /* Always */,
|
|
2066
|
+
["autoCleanup" /* AutoCleanup */]: "always" /* Always */,
|
|
2067
|
+
["autoE2ETest" /* AutoE2ETest */]: "always" /* Always */,
|
|
2068
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: "always" /* Always */,
|
|
2069
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: "always" /* Always */,
|
|
2070
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: "always" /* Always */,
|
|
2071
|
+
["autoWatchPR" /* AutoWatchPR */]: "always" /* Always */,
|
|
2072
|
+
["reusePreparePlan" /* ReusePreparePlan */]: "always" /* Always */,
|
|
2073
|
+
["watcherLifetime" /* WatcherLifetime */]: "7d" /* SevenDays */
|
|
2074
|
+
};
|
|
2075
|
+
var ALWAYS_ASK_NEVER = [
|
|
2076
|
+
"always" /* Always */,
|
|
2077
|
+
"ask" /* Ask */,
|
|
2078
|
+
"never" /* Never */
|
|
2079
|
+
];
|
|
2080
|
+
var ALWAYS_ASK = [
|
|
2081
|
+
"always" /* Always */,
|
|
2082
|
+
"ask" /* Ask */
|
|
2083
|
+
];
|
|
2084
|
+
var LOCAL_REMOTE_ASK = [
|
|
2085
|
+
"local" /* Local */,
|
|
2086
|
+
"remote" /* Remote */,
|
|
2087
|
+
"ask" /* Ask */
|
|
2088
|
+
];
|
|
2089
|
+
var WATCHER_LIFETIMES = [
|
|
2090
|
+
"1d" /* OneDay */,
|
|
2091
|
+
"7d" /* SevenDays */,
|
|
2092
|
+
"never" /* Never */
|
|
2093
|
+
];
|
|
2094
|
+
var PREFERENCE_ALLOWED_VALUES = {
|
|
2095
|
+
["autoLogin" /* AutoLogin */]: ALWAYS_ASK_NEVER,
|
|
2096
|
+
["autoSelectProject" /* AutoSelectProject */]: ALWAYS_ASK_NEVER,
|
|
2097
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: ALWAYS_ASK_NEVER,
|
|
2098
|
+
["showElectronBrowser" /* ShowElectronBrowser */]: ALWAYS_ASK_NEVER,
|
|
2099
|
+
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: ALWAYS_ASK_NEVER,
|
|
2100
|
+
["defaultExecutionMode" /* DefaultExecutionMode */]: LOCAL_REMOTE_ASK,
|
|
2101
|
+
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: ALWAYS_ASK_NEVER,
|
|
2102
|
+
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: ALWAYS_ASK_NEVER,
|
|
2103
|
+
["autoDetectChanges" /* AutoDetectChanges */]: ALWAYS_ASK_NEVER,
|
|
2104
|
+
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: ALWAYS_ASK_NEVER,
|
|
2105
|
+
["autoCreatePR" /* AutoCreatePR */]: ALWAYS_ASK_NEVER,
|
|
2106
|
+
["checkForUpdates" /* CheckForUpdates */]: ALWAYS_ASK_NEVER,
|
|
2107
|
+
["verboseOutput" /* VerboseOutput */]: ALWAYS_ASK_NEVER,
|
|
2108
|
+
["autoUseWorktree" /* AutoUseWorktree */]: ALWAYS_ASK_NEVER,
|
|
2109
|
+
["autoRebase" /* AutoRebase */]: ALWAYS_ASK_NEVER,
|
|
2110
|
+
["autoCleanup" /* AutoCleanup */]: ALWAYS_ASK_NEVER,
|
|
2111
|
+
["autoE2ETest" /* AutoE2ETest */]: ALWAYS_ASK,
|
|
2112
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: ALWAYS_ASK_NEVER,
|
|
2113
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: ALWAYS_ASK_NEVER,
|
|
2114
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: ALWAYS_ASK_NEVER,
|
|
2115
|
+
["autoWatchPR" /* AutoWatchPR */]: ALWAYS_ASK_NEVER,
|
|
2116
|
+
["reusePreparePlan" /* ReusePreparePlan */]: ALWAYS_ASK_NEVER,
|
|
2117
|
+
["watcherLifetime" /* WatcherLifetime */]: WATCHER_LIFETIMES
|
|
2118
|
+
};
|
|
2119
|
+
var PREFERENCES_SCHEMA = {
|
|
2120
|
+
["autoLogin" /* AutoLogin */]: {
|
|
2121
|
+
description: "When a tool requires auth and saved credentials exist, reuse them without prompting"
|
|
2122
|
+
},
|
|
2123
|
+
["autoSelectProject" /* AutoSelectProject */]: {
|
|
2124
|
+
description: "When a skill needs a Muggle Test project and one was used previously in this repo, reuse it without prompting"
|
|
2125
|
+
},
|
|
2126
|
+
["autoSelectLocalHost" /* AutoSelectLocalHost */]: {
|
|
2127
|
+
description: "When running local tests, reuse the dev server URL from the previous run in this repo without prompting"
|
|
2128
|
+
},
|
|
2129
|
+
["showElectronBrowser" /* ShowElectronBrowser */]: {
|
|
2130
|
+
description: "When running local E2E tests, show the Electron browser window"
|
|
2131
|
+
},
|
|
2132
|
+
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: {
|
|
2133
|
+
description: "After a local E2E test run completes, open the per-run results page on Muggle Test dashboard"
|
|
2134
|
+
},
|
|
2135
|
+
["defaultExecutionMode" /* DefaultExecutionMode */]: {
|
|
2136
|
+
description: "When a skill supports both local and remote test execution, which to default to"
|
|
2137
|
+
},
|
|
2138
|
+
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: {
|
|
2139
|
+
description: "After creating or running a use case, suggest related use cases to add"
|
|
2140
|
+
},
|
|
2141
|
+
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: {
|
|
2142
|
+
description: "After creating or running a test case, suggest related test cases to add"
|
|
2143
|
+
},
|
|
2144
|
+
["autoDetectChanges" /* AutoDetectChanges */]: {
|
|
2145
|
+
description: "When running muggle-test, scan local git changes and map to affected test cases"
|
|
2146
|
+
},
|
|
2147
|
+
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: {
|
|
2148
|
+
description: "After test results are available, post visual walkthrough comment with screenshots to the PR"
|
|
2149
|
+
},
|
|
2150
|
+
["autoCreatePR" /* AutoCreatePR */]: {
|
|
2151
|
+
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"
|
|
2152
|
+
},
|
|
2153
|
+
["checkForUpdates" /* CheckForUpdates */]: {
|
|
2154
|
+
description: "At session start, check if a newer Muggle Test version is available and notify"
|
|
2155
|
+
},
|
|
2156
|
+
["verboseOutput" /* VerboseOutput */]: {
|
|
2157
|
+
description: "Show detailed progress logs during skill and tool execution"
|
|
2158
|
+
},
|
|
2159
|
+
["autoUseWorktree" /* AutoUseWorktree */]: {
|
|
2160
|
+
description: "When starting non-trivial development work, create a git worktree to isolate the change from the current checkout"
|
|
2161
|
+
},
|
|
2162
|
+
["autoRebase" /* AutoRebase */]: {
|
|
2163
|
+
description: "Before running dev servers or E2E tests on a branch behind origin, rebase onto the default branch first"
|
|
2164
|
+
},
|
|
2165
|
+
["autoCleanup" /* AutoCleanup */]: {
|
|
2166
|
+
description: "After a PR is merged, automatically run the cleanup sequence: remove worktree, delete branches, clear local artifacts, prune [gone] branches"
|
|
2167
|
+
},
|
|
2168
|
+
["autoE2ETest" /* AutoE2ETest */]: {
|
|
2169
|
+
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)"
|
|
2170
|
+
},
|
|
2171
|
+
["autoResolveConflicts" /* AutoResolveConflicts */]: {
|
|
2172
|
+
description: "When a rebase onto the default branch hits conflicts, resolve them autonomously behind a verify-or-rollback gate instead of aborting and escalating"
|
|
2173
|
+
},
|
|
2174
|
+
["autoReuseValidationContext" /* AutoReuseValidationContext */]: {
|
|
2175
|
+
description: "When a prior session left an E2E validation context for this working tree, reuse it instead of re-asking the validation questions"
|
|
2176
|
+
},
|
|
2177
|
+
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: {
|
|
2178
|
+
description: "When a prompt looks like a build/implement/fix request, route it through the /muggle-do pipeline (requirements \u2192 build \u2192 impact \u2192 tests \u2192 E2E \u2192 PR \u2192 watcher)"
|
|
2179
|
+
},
|
|
2180
|
+
["autoWatchPR" /* AutoWatchPR */]: {
|
|
2181
|
+
description: "After a test run opens a PR, start a muggle-pr-followup watcher that polls for new reviews and hands them to /muggle-do"
|
|
2182
|
+
},
|
|
2183
|
+
["reusePreparePlan" /* ReusePreparePlan */]: {
|
|
2184
|
+
description: "Reuse the saved prepare plan for this stack (skip discovery, jump to check-running + smoke-test) instead of rediscovering from scratch"
|
|
2185
|
+
},
|
|
2186
|
+
["watcherLifetime" /* WatcherLifetime */]: {
|
|
2187
|
+
description: "How long a muggle-pr-followup watch loop polls before retiring itself \u2014 1d, 7d, or never (unbounded, which leaves no time-based reaper for an orphaned loop)"
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
|
|
2191
|
+
// packages/mcps/src/shared/llm-env-service.ts
|
|
2192
|
+
function resolveLlmEnvOverrides(dataDirOverride2) {
|
|
2193
|
+
const filePath = path10.join(getDataDir(), PREFERENCES_FILE_NAME);
|
|
2194
|
+
let block;
|
|
2195
|
+
try {
|
|
2196
|
+
if (!fs5.existsSync(filePath)) {
|
|
2197
|
+
return {};
|
|
2198
|
+
}
|
|
2199
|
+
const raw = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
2200
|
+
block = raw[LLM_ENV_PREFERENCE_KEY];
|
|
2201
|
+
} catch {
|
|
2202
|
+
return {};
|
|
2203
|
+
}
|
|
2204
|
+
if (!block || typeof block !== "object" || Array.isArray(block)) {
|
|
2205
|
+
return {};
|
|
2206
|
+
}
|
|
2207
|
+
const overrides = {};
|
|
2208
|
+
for (const [name, value] of Object.entries(block)) {
|
|
2209
|
+
if (!FORWARDABLE_LLM_ENV_NAMES.includes(name)) {
|
|
2210
|
+
continue;
|
|
2211
|
+
}
|
|
2212
|
+
if (value === null || value === void 0 || value === "") {
|
|
2213
|
+
continue;
|
|
2214
|
+
}
|
|
2215
|
+
overrides[name] = String(value);
|
|
2216
|
+
}
|
|
2217
|
+
return overrides;
|
|
2218
|
+
}
|
|
2219
|
+
function applyLlmEnvOverrides(baseEnv, dataDirOverride2) {
|
|
2220
|
+
const overrides = resolveLlmEnvOverrides();
|
|
2221
|
+
const appliedNames = [];
|
|
2222
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
2223
|
+
if (baseEnv[name] !== void 0 && baseEnv[name] !== "") {
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
baseEnv[name] = value;
|
|
2227
|
+
appliedNames.push(name);
|
|
2228
|
+
}
|
|
2229
|
+
return { env: baseEnv, appliedNames };
|
|
2230
|
+
}
|
|
2231
|
+
|
|
1990
2232
|
// packages/mcps/src/mcp/local/services/replay-url-rewrite.ts
|
|
1991
2233
|
function rewriteActionScriptUrls(params) {
|
|
1992
2234
|
const { actionScript, originalUrl, localUrl } = params;
|
|
@@ -2162,13 +2404,13 @@ var MODIFY_LOCK_STALE_MS = 5e3;
|
|
|
2162
2404
|
|
|
2163
2405
|
// packages/mcps/src/mcp/local/services/local-execution-lock.ts
|
|
2164
2406
|
function lockFilePath() {
|
|
2165
|
-
return
|
|
2407
|
+
return path10.join(getDataDir(), LOCK_FILE_NAME);
|
|
2166
2408
|
}
|
|
2167
2409
|
function modifyLockPath() {
|
|
2168
2410
|
return lockFilePath() + MODIFY_LOCK_SUFFIX;
|
|
2169
2411
|
}
|
|
2170
2412
|
function normalizeCwd(cwd) {
|
|
2171
|
-
const resolved =
|
|
2413
|
+
const resolved = path10.resolve(cwd);
|
|
2172
2414
|
return os4.platform() === "win32" ? resolved.toLowerCase() : resolved;
|
|
2173
2415
|
}
|
|
2174
2416
|
function pidIsAlive(pid) {
|
|
@@ -2184,7 +2426,7 @@ function pidIsAlive(pid) {
|
|
|
2184
2426
|
}
|
|
2185
2427
|
async function readState() {
|
|
2186
2428
|
try {
|
|
2187
|
-
const raw = await
|
|
2429
|
+
const raw = await fs9.readFile(lockFilePath(), "utf-8");
|
|
2188
2430
|
return JSON.parse(raw);
|
|
2189
2431
|
} catch (error) {
|
|
2190
2432
|
if (error.code === "ENOENT") return null;
|
|
@@ -2192,28 +2434,28 @@ async function readState() {
|
|
|
2192
2434
|
}
|
|
2193
2435
|
}
|
|
2194
2436
|
async function writeState(state2) {
|
|
2195
|
-
await
|
|
2437
|
+
await fs9.writeFile(lockFilePath(), JSON.stringify(state2, null, 2), "utf-8");
|
|
2196
2438
|
}
|
|
2197
2439
|
async function deleteStateFile() {
|
|
2198
2440
|
try {
|
|
2199
|
-
await
|
|
2441
|
+
await fs9.unlink(lockFilePath());
|
|
2200
2442
|
} catch (error) {
|
|
2201
2443
|
if (error.code !== "ENOENT") throw error;
|
|
2202
2444
|
}
|
|
2203
2445
|
}
|
|
2204
2446
|
async function withModifyLock(fn) {
|
|
2205
|
-
await
|
|
2447
|
+
await fs9.mkdir(path10.dirname(modifyLockPath()), { recursive: true });
|
|
2206
2448
|
const modifyPath = modifyLockPath();
|
|
2207
2449
|
let fileHandle = null;
|
|
2208
2450
|
while (fileHandle === null) {
|
|
2209
2451
|
try {
|
|
2210
|
-
fileHandle = await
|
|
2452
|
+
fileHandle = await fs9.open(modifyPath, "wx");
|
|
2211
2453
|
} catch (error) {
|
|
2212
2454
|
if (error.code !== "EEXIST") throw error;
|
|
2213
2455
|
try {
|
|
2214
|
-
const stat3 = await
|
|
2456
|
+
const stat3 = await fs9.stat(modifyPath);
|
|
2215
2457
|
if (Date.now() - stat3.mtimeMs > MODIFY_LOCK_STALE_MS) {
|
|
2216
|
-
await
|
|
2458
|
+
await fs9.unlink(modifyPath).catch(() => void 0);
|
|
2217
2459
|
continue;
|
|
2218
2460
|
}
|
|
2219
2461
|
} catch {
|
|
@@ -2226,7 +2468,7 @@ async function withModifyLock(fn) {
|
|
|
2226
2468
|
return await fn();
|
|
2227
2469
|
} finally {
|
|
2228
2470
|
await fileHandle.close().catch(() => void 0);
|
|
2229
|
-
await
|
|
2471
|
+
await fs9.unlink(modifyPath).catch(() => void 0);
|
|
2230
2472
|
}
|
|
2231
2473
|
}
|
|
2232
2474
|
async function tryAcquireOnce(params) {
|
|
@@ -2365,12 +2607,12 @@ function extractStudioCloudRefs(studioReturnedResult) {
|
|
|
2365
2607
|
return refs;
|
|
2366
2608
|
}
|
|
2367
2609
|
async function readCloudRefsFile(inputFilePath) {
|
|
2368
|
-
const cloudRefsPath =
|
|
2369
|
-
|
|
2370
|
-
`cloudrefs_${
|
|
2610
|
+
const cloudRefsPath = path10.join(
|
|
2611
|
+
path10.dirname(inputFilePath),
|
|
2612
|
+
`cloudrefs_${path10.basename(inputFilePath)}`
|
|
2371
2613
|
);
|
|
2372
2614
|
try {
|
|
2373
|
-
return JSON.parse(await
|
|
2615
|
+
return JSON.parse(await fs9.readFile(cloudRefsPath, "utf-8"));
|
|
2374
2616
|
} catch {
|
|
2375
2617
|
return void 0;
|
|
2376
2618
|
}
|
|
@@ -2389,15 +2631,15 @@ function getAuthenticatedUserId() {
|
|
|
2389
2631
|
}
|
|
2390
2632
|
async function findPackageJsonAsync() {
|
|
2391
2633
|
const currentFileUrl = import.meta.url;
|
|
2392
|
-
const currentDir =
|
|
2634
|
+
const currentDir = path10.dirname(fileURLToPath(currentFileUrl));
|
|
2393
2635
|
const candidatePaths = [
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2636
|
+
path10.resolve(currentDir, "../../../package.json"),
|
|
2637
|
+
path10.resolve(currentDir, "../package.json"),
|
|
2638
|
+
path10.resolve(currentDir, "../../package.json")
|
|
2397
2639
|
];
|
|
2398
2640
|
for (const candidatePath of candidatePaths) {
|
|
2399
2641
|
try {
|
|
2400
|
-
const packageJsonRaw = await
|
|
2642
|
+
const packageJsonRaw = await fs9.readFile(candidatePath, "utf-8");
|
|
2401
2643
|
const packageJson = JSON.parse(packageJsonRaw);
|
|
2402
2644
|
if (packageJson.name === "@muggleai/works" && packageJson.version && packageJson.muggleConfig?.electronAppVersion) {
|
|
2403
2645
|
return {
|
|
@@ -2443,20 +2685,20 @@ function buildStudioAuthContent() {
|
|
|
2443
2685
|
}
|
|
2444
2686
|
async function ensureTempDir() {
|
|
2445
2687
|
const config = getConfig();
|
|
2446
|
-
const tempDir =
|
|
2447
|
-
await
|
|
2688
|
+
const tempDir = path10.join(config.localQa.dataDir, "temp");
|
|
2689
|
+
await fs9.mkdir(tempDir, { recursive: true });
|
|
2448
2690
|
return tempDir;
|
|
2449
2691
|
}
|
|
2450
2692
|
async function writeTempFile(params) {
|
|
2451
2693
|
const tempDir = await ensureTempDir();
|
|
2452
|
-
const filePath =
|
|
2453
|
-
await
|
|
2694
|
+
const filePath = path10.join(tempDir, params.filename);
|
|
2695
|
+
await fs9.writeFile(filePath, JSON.stringify(params.data, null, 2));
|
|
2454
2696
|
return filePath;
|
|
2455
2697
|
}
|
|
2456
2698
|
async function cleanupTempFiles(params) {
|
|
2457
2699
|
for (const filePath of params.filePaths) {
|
|
2458
2700
|
try {
|
|
2459
|
-
await
|
|
2701
|
+
await fs9.unlink(filePath);
|
|
2460
2702
|
} catch {
|
|
2461
2703
|
}
|
|
2462
2704
|
}
|
|
@@ -2464,12 +2706,12 @@ async function cleanupTempFiles(params) {
|
|
|
2464
2706
|
async function moveResultsToArtifacts(params) {
|
|
2465
2707
|
const storageService = getStorageService();
|
|
2466
2708
|
const sessionsDir = storageService.getSessionsDir();
|
|
2467
|
-
const artifactsDir =
|
|
2468
|
-
const actionScriptPath =
|
|
2469
|
-
await
|
|
2470
|
-
await
|
|
2709
|
+
const artifactsDir = path10.join(sessionsDir, params.runId);
|
|
2710
|
+
const actionScriptPath = path10.join(artifactsDir, "action-script.json");
|
|
2711
|
+
await fs9.mkdir(artifactsDir, { recursive: true });
|
|
2712
|
+
await fs9.copyFile(params.generatedScriptPath, actionScriptPath);
|
|
2471
2713
|
try {
|
|
2472
|
-
await
|
|
2714
|
+
await fs9.unlink(params.generatedScriptPath);
|
|
2473
2715
|
} catch {
|
|
2474
2716
|
}
|
|
2475
2717
|
return artifactsDir;
|
|
@@ -2477,13 +2719,13 @@ async function moveResultsToArtifacts(params) {
|
|
|
2477
2719
|
async function writeExecutionLogs(params) {
|
|
2478
2720
|
const storageService = getStorageService();
|
|
2479
2721
|
const sessionsDir = storageService.getSessionsDir();
|
|
2480
|
-
const artifactsDir =
|
|
2481
|
-
await
|
|
2482
|
-
const stdoutPath =
|
|
2483
|
-
const stderrPath =
|
|
2722
|
+
const artifactsDir = path10.join(sessionsDir, params.runId);
|
|
2723
|
+
await fs9.mkdir(artifactsDir, { recursive: true });
|
|
2724
|
+
const stdoutPath = path10.join(artifactsDir, "stdout.log");
|
|
2725
|
+
const stderrPath = path10.join(artifactsDir, "stderr.log");
|
|
2484
2726
|
await Promise.all([
|
|
2485
|
-
|
|
2486
|
-
|
|
2727
|
+
fs9.writeFile(stdoutPath, params.stdout, "utf-8"),
|
|
2728
|
+
fs9.writeFile(stderrPath, params.stderr, "utf-8")
|
|
2487
2729
|
]);
|
|
2488
2730
|
logger4.info("Wrote execution logs to artifacts directory", {
|
|
2489
2731
|
runId: params.runId,
|
|
@@ -2493,10 +2735,10 @@ async function writeExecutionLogs(params) {
|
|
|
2493
2735
|
async function preserveElectronRuntimeArtifacts(params) {
|
|
2494
2736
|
try {
|
|
2495
2737
|
const tempDir = await ensureTempDir();
|
|
2496
|
-
const markerPath =
|
|
2738
|
+
const markerPath = path10.join(tempDir, `${params.runId}_runtime_dir.txt`);
|
|
2497
2739
|
let runtimeDir = null;
|
|
2498
2740
|
try {
|
|
2499
|
-
const marker = await
|
|
2741
|
+
const marker = await fs9.readFile(markerPath, "utf-8");
|
|
2500
2742
|
const trimmed = marker.trim();
|
|
2501
2743
|
if (trimmed.length > 0) runtimeDir = trimmed;
|
|
2502
2744
|
} catch (markerReadError) {
|
|
@@ -2518,25 +2760,25 @@ async function preserveElectronRuntimeArtifacts(params) {
|
|
|
2518
2760
|
return;
|
|
2519
2761
|
}
|
|
2520
2762
|
try {
|
|
2521
|
-
await
|
|
2763
|
+
await fs9.access(runtimeDir);
|
|
2522
2764
|
} catch {
|
|
2523
2765
|
logger4.warn("Electron runtime dir referenced but missing on disk", {
|
|
2524
2766
|
runId: params.runId,
|
|
2525
2767
|
runtimeDir
|
|
2526
2768
|
});
|
|
2527
|
-
await
|
|
2769
|
+
await fs9.unlink(markerPath).catch(() => void 0);
|
|
2528
2770
|
return;
|
|
2529
2771
|
}
|
|
2530
2772
|
const storage = getStorageService();
|
|
2531
|
-
const destDir =
|
|
2532
|
-
await
|
|
2533
|
-
await
|
|
2773
|
+
const destDir = path10.join(storage.getSessionsDir(), params.runId, "electron-runtime");
|
|
2774
|
+
await fs9.mkdir(destDir, { recursive: true });
|
|
2775
|
+
await fs9.cp(runtimeDir, destDir, { recursive: true });
|
|
2534
2776
|
logger4.info("Preserved Electron runtime artifacts", {
|
|
2535
2777
|
runId: params.runId,
|
|
2536
2778
|
sourceDir: runtimeDir,
|
|
2537
2779
|
destDir
|
|
2538
2780
|
});
|
|
2539
|
-
await
|
|
2781
|
+
await fs9.unlink(markerPath).catch(() => void 0);
|
|
2540
2782
|
} catch (preserveError) {
|
|
2541
2783
|
logger4.warn("Failed to preserve Electron runtime artifacts", {
|
|
2542
2784
|
runId: params.runId,
|
|
@@ -2545,14 +2787,14 @@ async function preserveElectronRuntimeArtifacts(params) {
|
|
|
2545
2787
|
}
|
|
2546
2788
|
}
|
|
2547
2789
|
async function scanForRuntimeDirByMtime(params) {
|
|
2548
|
-
const runtimeRoot =
|
|
2790
|
+
const runtimeRoot = path10.join(params.electronCwd, "user_data", "runtime");
|
|
2549
2791
|
try {
|
|
2550
|
-
const entries = await
|
|
2792
|
+
const entries = await fs9.readdir(runtimeRoot, { withFileTypes: true });
|
|
2551
2793
|
let bestCandidate = null;
|
|
2552
2794
|
for (const entry of entries) {
|
|
2553
2795
|
if (!entry.isDirectory()) continue;
|
|
2554
|
-
const fullPath =
|
|
2555
|
-
const stat3 = await
|
|
2796
|
+
const fullPath = path10.join(runtimeRoot, entry.name);
|
|
2797
|
+
const stat3 = await fs9.stat(fullPath);
|
|
2556
2798
|
if (stat3.mtimeMs < params.spawnAtMs) continue;
|
|
2557
2799
|
if (bestCandidate === null || stat3.mtimeMs > bestCandidate.mtimeMs) {
|
|
2558
2800
|
bestCandidate = { path: fullPath, mtimeMs: stat3.mtimeMs };
|
|
@@ -2597,15 +2839,18 @@ async function executeElectronAppAsync(params) {
|
|
|
2597
2839
|
if (params.freshSession) {
|
|
2598
2840
|
spawnArgs.push("--fresh-session");
|
|
2599
2841
|
}
|
|
2842
|
+
const { env: electronEnv, appliedNames: llmEnvOverrideNames } = applyLlmEnvOverrides({
|
|
2843
|
+
...process.env
|
|
2844
|
+
});
|
|
2845
|
+
delete electronEnv.ELECTRON_RUN_AS_NODE;
|
|
2600
2846
|
logger4.info("Spawning electron-app for local execution", {
|
|
2601
2847
|
runId: params.runId,
|
|
2602
2848
|
mode,
|
|
2603
2849
|
electronAppPath,
|
|
2604
|
-
spawnArgs
|
|
2850
|
+
spawnArgs,
|
|
2851
|
+
llmEnvOverrideNames
|
|
2605
2852
|
});
|
|
2606
|
-
const
|
|
2607
|
-
delete electronEnv.ELECTRON_RUN_AS_NODE;
|
|
2608
|
-
const electronCwd = path9.dirname(electronAppPath);
|
|
2853
|
+
const electronCwd = path10.dirname(electronAppPath);
|
|
2609
2854
|
const child = spawn(electronAppPath, spawnArgs, {
|
|
2610
2855
|
stdio: ["ignore", "pipe", "pipe"],
|
|
2611
2856
|
env: electronEnv,
|
|
@@ -2787,17 +3032,17 @@ ${executionResult.stdout}
|
|
|
2787
3032
|
STDERR:
|
|
2788
3033
|
${executionResult.stderr}`;
|
|
2789
3034
|
const sessionsDir = getStorageService().getSessionsDir();
|
|
2790
|
-
const artifactsDir2 =
|
|
2791
|
-
const generatedScriptPath2 =
|
|
2792
|
-
|
|
2793
|
-
`gen_${
|
|
3035
|
+
const artifactsDir2 = path10.join(sessionsDir, runId);
|
|
3036
|
+
const generatedScriptPath2 = path10.join(
|
|
3037
|
+
path10.dirname(inputFilePath),
|
|
3038
|
+
`gen_${path10.basename(inputFilePath)}`
|
|
2794
3039
|
);
|
|
2795
3040
|
let failedStudioResult;
|
|
2796
3041
|
try {
|
|
2797
|
-
const failedScriptRaw = await
|
|
3042
|
+
const failedScriptRaw = await fs9.readFile(generatedScriptPath2, "utf-8");
|
|
2798
3043
|
failedStudioResult = JSON.parse(failedScriptRaw);
|
|
2799
|
-
await
|
|
2800
|
-
await
|
|
3044
|
+
await fs9.copyFile(generatedScriptPath2, path10.join(artifactsDir2, "action-script.json"));
|
|
3045
|
+
await fs9.unlink(generatedScriptPath2).catch(() => {
|
|
2801
3046
|
});
|
|
2802
3047
|
} catch {
|
|
2803
3048
|
}
|
|
@@ -2826,11 +3071,11 @@ ${executionResult.stderr}`;
|
|
|
2826
3071
|
errorMessage: failureMessage
|
|
2827
3072
|
};
|
|
2828
3073
|
}
|
|
2829
|
-
const generatedScriptPath =
|
|
2830
|
-
|
|
2831
|
-
`gen_${
|
|
3074
|
+
const generatedScriptPath = path10.join(
|
|
3075
|
+
path10.dirname(inputFilePath),
|
|
3076
|
+
`gen_${path10.basename(inputFilePath)}`
|
|
2832
3077
|
);
|
|
2833
|
-
const generatedScriptRaw = await
|
|
3078
|
+
const generatedScriptRaw = await fs9.readFile(generatedScriptPath, "utf-8");
|
|
2834
3079
|
const generatedScript = JSON.parse(generatedScriptRaw);
|
|
2835
3080
|
const generatedSteps = generatedScript.steps;
|
|
2836
3081
|
if (!Array.isArray(generatedSteps)) {
|
|
@@ -2973,7 +3218,7 @@ STDOUT:
|
|
|
2973
3218
|
${executionResult.stdout}
|
|
2974
3219
|
STDERR:
|
|
2975
3220
|
${executionResult.stderr}`;
|
|
2976
|
-
const artifactsDir2 =
|
|
3221
|
+
const artifactsDir2 = path10.join(getStorageService().getSessionsDir(), runId);
|
|
2977
3222
|
storage.updateRunResult(runId, {
|
|
2978
3223
|
status: "failed",
|
|
2979
3224
|
executionTimeMs,
|
|
@@ -2991,7 +3236,7 @@ ${executionResult.stderr}`;
|
|
|
2991
3236
|
errorMessage: failureMessage
|
|
2992
3237
|
};
|
|
2993
3238
|
}
|
|
2994
|
-
const artifactsDir =
|
|
3239
|
+
const artifactsDir = path10.join(getStorageService().getSessionsDir(), runId);
|
|
2995
3240
|
const replayStudioResult = await readCloudRefsFile(inputFilePath);
|
|
2996
3241
|
const replayStudioCloudRefs = extractStudioCloudRefs(replayStudioResult);
|
|
2997
3242
|
storage.updateRunResult(runId, {
|
|
@@ -3428,7 +3673,7 @@ var PREFS_FILENAME = "preferences.json";
|
|
|
3428
3673
|
var OAUTH_SESSION_FILENAME = "oauth-session.json";
|
|
3429
3674
|
var RELEASE_MANIFEST_FILENAME = "release-manifest.json";
|
|
3430
3675
|
function getDataDir3() {
|
|
3431
|
-
return
|
|
3676
|
+
return path10.join(os4.homedir(), DATA_DIR_NAME2);
|
|
3432
3677
|
}
|
|
3433
3678
|
|
|
3434
3679
|
var cachedInstallId;
|
|
@@ -3493,9 +3738,9 @@ function isValid2(value) {
|
|
|
3493
3738
|
function readReleaseManifest2() {
|
|
3494
3739
|
if (cachedManifest2 !== void 0)
|
|
3495
3740
|
return cachedManifest2;
|
|
3496
|
-
const
|
|
3741
|
+
const path16 = MANIFEST_PATH2;
|
|
3497
3742
|
try {
|
|
3498
|
-
const raw = readFileSync(
|
|
3743
|
+
const raw = readFileSync(path16, "utf8");
|
|
3499
3744
|
const parsed = JSON.parse(raw);
|
|
3500
3745
|
cachedManifest2 = isValid2(parsed) ? parsed : DEV_MANIFEST2;
|
|
3501
3746
|
return cachedManifest2;
|
|
@@ -4274,17 +4519,17 @@ var PromptServiceClient = class {
|
|
|
4274
4519
|
* @param path - Path to validate.
|
|
4275
4520
|
* @throws GatewayError if path is not allowed.
|
|
4276
4521
|
*/
|
|
4277
|
-
validatePath(
|
|
4278
|
-
const isAllowed = ALLOWED_UPSTREAM_PREFIXES.some((prefix) =>
|
|
4522
|
+
validatePath(path16) {
|
|
4523
|
+
const isAllowed = ALLOWED_UPSTREAM_PREFIXES.some((prefix) => path16.startsWith(prefix));
|
|
4279
4524
|
if (!isAllowed) {
|
|
4280
4525
|
const logger6 = getLogger();
|
|
4281
4526
|
logger6.error("Path not in allowlist", {
|
|
4282
|
-
path:
|
|
4527
|
+
path: path16,
|
|
4283
4528
|
allowedPrefixes: ALLOWED_UPSTREAM_PREFIXES
|
|
4284
4529
|
});
|
|
4285
4530
|
throw new GatewayError({
|
|
4286
4531
|
code: "FORBIDDEN" /* FORBIDDEN */,
|
|
4287
|
-
message: `Path '${
|
|
4532
|
+
message: `Path '${path16}' is not allowed`
|
|
4288
4533
|
});
|
|
4289
4534
|
}
|
|
4290
4535
|
}
|
|
@@ -6257,178 +6502,6 @@ var CleanupSessionsInputSchema = z.object({
|
|
|
6257
6502
|
max_age_days: z.number().int().min(0).optional().describe("Maximum age of sessions to keep (in days). Sessions older than this will be deleted. Defaults to 30.")
|
|
6258
6503
|
});
|
|
6259
6504
|
var EmptyInputSchema2 = z.object({});
|
|
6260
|
-
|
|
6261
|
-
// packages/mcps/src/shared/preferences-types.ts
|
|
6262
|
-
var PreferenceKey = /* @__PURE__ */ ((PreferenceKey2) => {
|
|
6263
|
-
PreferenceKey2["AutoLogin"] = "autoLogin";
|
|
6264
|
-
PreferenceKey2["AutoSelectProject"] = "autoSelectProject";
|
|
6265
|
-
PreferenceKey2["AutoSelectLocalHost"] = "autoSelectLocalHost";
|
|
6266
|
-
PreferenceKey2["ShowElectronBrowser"] = "showElectronBrowser";
|
|
6267
|
-
PreferenceKey2["OpenTestResultsAfterRun"] = "openTestResultsAfterRun";
|
|
6268
|
-
PreferenceKey2["DefaultExecutionMode"] = "defaultExecutionMode";
|
|
6269
|
-
PreferenceKey2["SuggestRelatedUseCases"] = "suggestRelatedUseCases";
|
|
6270
|
-
PreferenceKey2["SuggestRelatedTestCases"] = "suggestRelatedTestCases";
|
|
6271
|
-
PreferenceKey2["AutoDetectChanges"] = "autoDetectChanges";
|
|
6272
|
-
PreferenceKey2["PostPRVisualWalkthrough"] = "postPRVisualWalkthrough";
|
|
6273
|
-
PreferenceKey2["AutoCreatePR"] = "autoCreatePR";
|
|
6274
|
-
PreferenceKey2["CheckForUpdates"] = "checkForUpdates";
|
|
6275
|
-
PreferenceKey2["VerboseOutput"] = "verboseOutput";
|
|
6276
|
-
PreferenceKey2["AutoUseWorktree"] = "autoUseWorktree";
|
|
6277
|
-
PreferenceKey2["AutoRebase"] = "autoRebase";
|
|
6278
|
-
PreferenceKey2["AutoCleanup"] = "autoCleanup";
|
|
6279
|
-
PreferenceKey2["AutoE2ETest"] = "autoE2ETest";
|
|
6280
|
-
PreferenceKey2["AutoResolveConflicts"] = "autoResolveConflicts";
|
|
6281
|
-
PreferenceKey2["AutoReuseValidationContext"] = "autoReuseValidationContext";
|
|
6282
|
-
PreferenceKey2["AutoRouteBuildToMuggleDo"] = "autoRouteBuildToMuggleDo";
|
|
6283
|
-
PreferenceKey2["AutoWatchPR"] = "autoWatchPR";
|
|
6284
|
-
PreferenceKey2["ReusePreparePlan"] = "reusePreparePlan";
|
|
6285
|
-
return PreferenceKey2;
|
|
6286
|
-
})(PreferenceKey || {});
|
|
6287
|
-
var PreferenceValue = /* @__PURE__ */ ((PreferenceValue2) => {
|
|
6288
|
-
PreferenceValue2["Always"] = "always";
|
|
6289
|
-
PreferenceValue2["Ask"] = "ask";
|
|
6290
|
-
PreferenceValue2["Never"] = "never";
|
|
6291
|
-
PreferenceValue2["Local"] = "local";
|
|
6292
|
-
PreferenceValue2["Remote"] = "remote";
|
|
6293
|
-
return PreferenceValue2;
|
|
6294
|
-
})(PreferenceValue || {});
|
|
6295
|
-
|
|
6296
|
-
// packages/mcps/src/shared/preferences-constants.ts
|
|
6297
|
-
var PREFERENCES_FILE_NAME = "preferences.json";
|
|
6298
|
-
var PREFERENCES_PROJECT_DIR_NAME = ".muggle-ai";
|
|
6299
|
-
var PREFERENCES_VERSION = 1;
|
|
6300
|
-
var DEFAULT_PREFERENCES = {
|
|
6301
|
-
["autoLogin" /* AutoLogin */]: "always" /* Always */,
|
|
6302
|
-
["autoSelectProject" /* AutoSelectProject */]: "always" /* Always */,
|
|
6303
|
-
["autoSelectLocalHost" /* AutoSelectLocalHost */]: "always" /* Always */,
|
|
6304
|
-
["showElectronBrowser" /* ShowElectronBrowser */]: "always" /* Always */,
|
|
6305
|
-
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: "always" /* Always */,
|
|
6306
|
-
["defaultExecutionMode" /* DefaultExecutionMode */]: "local" /* Local */,
|
|
6307
|
-
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: "always" /* Always */,
|
|
6308
|
-
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: "always" /* Always */,
|
|
6309
|
-
["autoDetectChanges" /* AutoDetectChanges */]: "always" /* Always */,
|
|
6310
|
-
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: "always" /* Always */,
|
|
6311
|
-
["autoCreatePR" /* AutoCreatePR */]: "always" /* Always */,
|
|
6312
|
-
["checkForUpdates" /* CheckForUpdates */]: "always" /* Always */,
|
|
6313
|
-
["verboseOutput" /* VerboseOutput */]: "never" /* Never */,
|
|
6314
|
-
["autoUseWorktree" /* AutoUseWorktree */]: "always" /* Always */,
|
|
6315
|
-
["autoRebase" /* AutoRebase */]: "always" /* Always */,
|
|
6316
|
-
["autoCleanup" /* AutoCleanup */]: "always" /* Always */,
|
|
6317
|
-
["autoE2ETest" /* AutoE2ETest */]: "always" /* Always */,
|
|
6318
|
-
["autoResolveConflicts" /* AutoResolveConflicts */]: "always" /* Always */,
|
|
6319
|
-
["autoReuseValidationContext" /* AutoReuseValidationContext */]: "always" /* Always */,
|
|
6320
|
-
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: "always" /* Always */,
|
|
6321
|
-
["autoWatchPR" /* AutoWatchPR */]: "always" /* Always */,
|
|
6322
|
-
["reusePreparePlan" /* ReusePreparePlan */]: "always" /* Always */
|
|
6323
|
-
};
|
|
6324
|
-
var ALWAYS_ASK_NEVER = [
|
|
6325
|
-
"always" /* Always */,
|
|
6326
|
-
"ask" /* Ask */,
|
|
6327
|
-
"never" /* Never */
|
|
6328
|
-
];
|
|
6329
|
-
var ALWAYS_ASK = [
|
|
6330
|
-
"always" /* Always */,
|
|
6331
|
-
"ask" /* Ask */
|
|
6332
|
-
];
|
|
6333
|
-
var LOCAL_REMOTE_ASK = [
|
|
6334
|
-
"local" /* Local */,
|
|
6335
|
-
"remote" /* Remote */,
|
|
6336
|
-
"ask" /* Ask */
|
|
6337
|
-
];
|
|
6338
|
-
var PREFERENCE_ALLOWED_VALUES = {
|
|
6339
|
-
["autoLogin" /* AutoLogin */]: ALWAYS_ASK_NEVER,
|
|
6340
|
-
["autoSelectProject" /* AutoSelectProject */]: ALWAYS_ASK_NEVER,
|
|
6341
|
-
["autoSelectLocalHost" /* AutoSelectLocalHost */]: ALWAYS_ASK_NEVER,
|
|
6342
|
-
["showElectronBrowser" /* ShowElectronBrowser */]: ALWAYS_ASK_NEVER,
|
|
6343
|
-
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: ALWAYS_ASK_NEVER,
|
|
6344
|
-
["defaultExecutionMode" /* DefaultExecutionMode */]: LOCAL_REMOTE_ASK,
|
|
6345
|
-
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: ALWAYS_ASK_NEVER,
|
|
6346
|
-
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: ALWAYS_ASK_NEVER,
|
|
6347
|
-
["autoDetectChanges" /* AutoDetectChanges */]: ALWAYS_ASK_NEVER,
|
|
6348
|
-
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: ALWAYS_ASK_NEVER,
|
|
6349
|
-
["autoCreatePR" /* AutoCreatePR */]: ALWAYS_ASK_NEVER,
|
|
6350
|
-
["checkForUpdates" /* CheckForUpdates */]: ALWAYS_ASK_NEVER,
|
|
6351
|
-
["verboseOutput" /* VerboseOutput */]: ALWAYS_ASK_NEVER,
|
|
6352
|
-
["autoUseWorktree" /* AutoUseWorktree */]: ALWAYS_ASK_NEVER,
|
|
6353
|
-
["autoRebase" /* AutoRebase */]: ALWAYS_ASK_NEVER,
|
|
6354
|
-
["autoCleanup" /* AutoCleanup */]: ALWAYS_ASK_NEVER,
|
|
6355
|
-
["autoE2ETest" /* AutoE2ETest */]: ALWAYS_ASK,
|
|
6356
|
-
["autoResolveConflicts" /* AutoResolveConflicts */]: ALWAYS_ASK_NEVER,
|
|
6357
|
-
["autoReuseValidationContext" /* AutoReuseValidationContext */]: ALWAYS_ASK_NEVER,
|
|
6358
|
-
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: ALWAYS_ASK_NEVER,
|
|
6359
|
-
["autoWatchPR" /* AutoWatchPR */]: ALWAYS_ASK_NEVER,
|
|
6360
|
-
["reusePreparePlan" /* ReusePreparePlan */]: ALWAYS_ASK_NEVER
|
|
6361
|
-
};
|
|
6362
|
-
var PREFERENCES_SCHEMA = {
|
|
6363
|
-
["autoLogin" /* AutoLogin */]: {
|
|
6364
|
-
description: "When a tool requires auth and saved credentials exist, reuse them without prompting"
|
|
6365
|
-
},
|
|
6366
|
-
["autoSelectProject" /* AutoSelectProject */]: {
|
|
6367
|
-
description: "When a skill needs a Muggle Test project and one was used previously in this repo, reuse it without prompting"
|
|
6368
|
-
},
|
|
6369
|
-
["autoSelectLocalHost" /* AutoSelectLocalHost */]: {
|
|
6370
|
-
description: "When running local tests, reuse the dev server URL from the previous run in this repo without prompting"
|
|
6371
|
-
},
|
|
6372
|
-
["showElectronBrowser" /* ShowElectronBrowser */]: {
|
|
6373
|
-
description: "When running local E2E tests, show the Electron browser window"
|
|
6374
|
-
},
|
|
6375
|
-
["openTestResultsAfterRun" /* OpenTestResultsAfterRun */]: {
|
|
6376
|
-
description: "After a local E2E test run completes, open the per-run results page on Muggle Test dashboard"
|
|
6377
|
-
},
|
|
6378
|
-
["defaultExecutionMode" /* DefaultExecutionMode */]: {
|
|
6379
|
-
description: "When a skill supports both local and remote test execution, which to default to"
|
|
6380
|
-
},
|
|
6381
|
-
["suggestRelatedUseCases" /* SuggestRelatedUseCases */]: {
|
|
6382
|
-
description: "After creating or running a use case, suggest related use cases to add"
|
|
6383
|
-
},
|
|
6384
|
-
["suggestRelatedTestCases" /* SuggestRelatedTestCases */]: {
|
|
6385
|
-
description: "After creating or running a test case, suggest related test cases to add"
|
|
6386
|
-
},
|
|
6387
|
-
["autoDetectChanges" /* AutoDetectChanges */]: {
|
|
6388
|
-
description: "When running muggle-test, scan local git changes and map to affected test cases"
|
|
6389
|
-
},
|
|
6390
|
-
["postPRVisualWalkthrough" /* PostPRVisualWalkthrough */]: {
|
|
6391
|
-
description: "After test results are available, post visual walkthrough comment with screenshots to the PR"
|
|
6392
|
-
},
|
|
6393
|
-
["autoCreatePR" /* AutoCreatePR */]: {
|
|
6394
|
-
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"
|
|
6395
|
-
},
|
|
6396
|
-
["checkForUpdates" /* CheckForUpdates */]: {
|
|
6397
|
-
description: "At session start, check if a newer Muggle Test version is available and notify"
|
|
6398
|
-
},
|
|
6399
|
-
["verboseOutput" /* VerboseOutput */]: {
|
|
6400
|
-
description: "Show detailed progress logs during skill and tool execution"
|
|
6401
|
-
},
|
|
6402
|
-
["autoUseWorktree" /* AutoUseWorktree */]: {
|
|
6403
|
-
description: "When starting non-trivial development work, create a git worktree to isolate the change from the current checkout"
|
|
6404
|
-
},
|
|
6405
|
-
["autoRebase" /* AutoRebase */]: {
|
|
6406
|
-
description: "Before running dev servers or E2E tests on a branch behind origin, rebase onto the default branch first"
|
|
6407
|
-
},
|
|
6408
|
-
["autoCleanup" /* AutoCleanup */]: {
|
|
6409
|
-
description: "After a PR is merged, automatically run the cleanup sequence: remove worktree, delete branches, clear local artifacts, prune [gone] branches"
|
|
6410
|
-
},
|
|
6411
|
-
["autoE2ETest" /* AutoE2ETest */]: {
|
|
6412
|
-
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)"
|
|
6413
|
-
},
|
|
6414
|
-
["autoResolveConflicts" /* AutoResolveConflicts */]: {
|
|
6415
|
-
description: "When a rebase onto the default branch hits conflicts, resolve them autonomously behind a verify-or-rollback gate instead of aborting and escalating"
|
|
6416
|
-
},
|
|
6417
|
-
["autoReuseValidationContext" /* AutoReuseValidationContext */]: {
|
|
6418
|
-
description: "When a prior session left an E2E validation context for this working tree, reuse it instead of re-asking the validation questions"
|
|
6419
|
-
},
|
|
6420
|
-
["autoRouteBuildToMuggleDo" /* AutoRouteBuildToMuggleDo */]: {
|
|
6421
|
-
description: "When a prompt looks like a build/implement/fix request, route it through the /muggle-do pipeline (requirements \u2192 build \u2192 impact \u2192 tests \u2192 E2E \u2192 PR \u2192 watcher)"
|
|
6422
|
-
},
|
|
6423
|
-
["autoWatchPR" /* AutoWatchPR */]: {
|
|
6424
|
-
description: "After a test run opens a PR, start a muggle-pr-followup watcher that polls for new reviews and hands them to /muggle-do"
|
|
6425
|
-
},
|
|
6426
|
-
["reusePreparePlan" /* ReusePreparePlan */]: {
|
|
6427
|
-
description: "Reuse the saved prepare plan for this stack (skip discovery, jump to check-running + smoke-test) instead of rediscovering from scratch"
|
|
6428
|
-
}
|
|
6429
|
-
};
|
|
6430
|
-
|
|
6431
|
-
// packages/mcps/src/mcp/local/contracts/preferences-schemas.ts
|
|
6432
6505
|
var preferenceKeyValues = Object.values(PreferenceKey);
|
|
6433
6506
|
var preferenceValueValues = Object.values(PreferenceValue);
|
|
6434
6507
|
var PreferencesSetInputSchema = z.object(
|
|
@@ -6509,9 +6582,9 @@ var TELEMETRY_DIR_NAME = "telemetry";
|
|
|
6509
6582
|
var FAILURE_EVENTS_FILE_NAME = "failure-events.jsonl";
|
|
6510
6583
|
function appendFailureEvent(record) {
|
|
6511
6584
|
try {
|
|
6512
|
-
const dir =
|
|
6585
|
+
const dir = path10.join(getDataDir(), TELEMETRY_DIR_NAME);
|
|
6513
6586
|
fs5.mkdirSync(dir, { recursive: true });
|
|
6514
|
-
const filePath =
|
|
6587
|
+
const filePath = path10.join(dir, FAILURE_EVENTS_FILE_NAME);
|
|
6515
6588
|
const full = { ts: (/* @__PURE__ */ new Date()).toISOString(), ...record };
|
|
6516
6589
|
fs5.appendFileSync(filePath, `${JSON.stringify(full)}
|
|
6517
6590
|
`, "utf-8");
|
|
@@ -6532,7 +6605,7 @@ var ProjectPreferencesReconcileOutcome = /* @__PURE__ */ ((ProjectPreferencesRec
|
|
|
6532
6605
|
|
|
6533
6606
|
// packages/mcps/src/shared/preferences-service.ts
|
|
6534
6607
|
function getGlobalPreferencesFilePath(dataDirOverride2) {
|
|
6535
|
-
return
|
|
6608
|
+
return path10.join(dataDirOverride2 ?? getDataDir(), PREFERENCES_FILE_NAME);
|
|
6536
6609
|
}
|
|
6537
6610
|
function isFirstRun(dataDirOverride2) {
|
|
6538
6611
|
return !fs5.existsSync(getGlobalPreferencesFilePath(dataDirOverride2));
|
|
@@ -6554,12 +6627,23 @@ function readPreferencesFile(filePath) {
|
|
|
6554
6627
|
}
|
|
6555
6628
|
function writePreferencesFile(filePath, prefs) {
|
|
6556
6629
|
const file = {
|
|
6630
|
+
...readRawPreferencesFile(filePath),
|
|
6557
6631
|
version: PREFERENCES_VERSION,
|
|
6558
6632
|
preferences: prefs
|
|
6559
6633
|
};
|
|
6560
6634
|
fs5.writeFileSync(filePath, `${JSON.stringify(file, null, 2)}
|
|
6561
6635
|
`, "utf-8");
|
|
6562
6636
|
}
|
|
6637
|
+
function readRawPreferencesFile(filePath) {
|
|
6638
|
+
try {
|
|
6639
|
+
if (!fs5.existsSync(filePath)) {
|
|
6640
|
+
return {};
|
|
6641
|
+
}
|
|
6642
|
+
return JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
6643
|
+
} catch {
|
|
6644
|
+
return {};
|
|
6645
|
+
}
|
|
6646
|
+
}
|
|
6563
6647
|
function resolvePreferences(dataDirOverride2) {
|
|
6564
6648
|
const saved = readPreferencesFile(getGlobalPreferencesFilePath(dataDirOverride2));
|
|
6565
6649
|
return { ...DEFAULT_PREFERENCES, ...saved };
|
|
@@ -6567,7 +6651,7 @@ function resolvePreferences(dataDirOverride2) {
|
|
|
6567
6651
|
function writePreferences2(prefs, dataDirOverride2) {
|
|
6568
6652
|
const dir = dataDirOverride2 ?? getDataDir();
|
|
6569
6653
|
fs5.mkdirSync(dir, { recursive: true });
|
|
6570
|
-
const filePath =
|
|
6654
|
+
const filePath = path10.join(dir, PREFERENCES_FILE_NAME);
|
|
6571
6655
|
const existing = readPreferencesFile(filePath);
|
|
6572
6656
|
writePreferencesFile(filePath, { ...existing, ...prefs });
|
|
6573
6657
|
}
|
|
@@ -6585,7 +6669,7 @@ function resetPreference(key, dataDirOverride2) {
|
|
|
6585
6669
|
writePreferencesFile(filePath, existing);
|
|
6586
6670
|
}
|
|
6587
6671
|
function reconcileProjectPreferences(cwd, dataDirOverride2) {
|
|
6588
|
-
const projectFilePath =
|
|
6672
|
+
const projectFilePath = path10.join(cwd, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_FILE_NAME);
|
|
6589
6673
|
const projectPreferences = readPreferencesFile(projectFilePath);
|
|
6590
6674
|
const projectKeys = Object.keys(projectPreferences);
|
|
6591
6675
|
if (projectKeys.length === 0) {
|
|
@@ -6630,10 +6714,10 @@ var MUGGLE_HOME_DISPLAY_DIR = "~/.muggle-ai";
|
|
|
6630
6714
|
|
|
6631
6715
|
// packages/mcps/src/shared/cwd-keyed-cache.ts
|
|
6632
6716
|
function resolveHomeFilePath(cache) {
|
|
6633
|
-
return
|
|
6717
|
+
return path10.join(getDataDir(), cache.fileName);
|
|
6634
6718
|
}
|
|
6635
6719
|
function resolveLegacyFilePath(cache, cwd) {
|
|
6636
|
-
return
|
|
6720
|
+
return path10.join(cwd, LEGACY_CACHE_DIR_NAME, cache.fileName);
|
|
6637
6721
|
}
|
|
6638
6722
|
function parseJsonFile(filePath) {
|
|
6639
6723
|
try {
|
|
@@ -6673,7 +6757,7 @@ function readLegacyEntry(cache, cwd) {
|
|
|
6673
6757
|
return parsed?.[cache.legacyEntryKey] ?? null;
|
|
6674
6758
|
}
|
|
6675
6759
|
function readCwdEntry(cache, cwd) {
|
|
6676
|
-
const cwdKey =
|
|
6760
|
+
const cwdKey = path10.resolve(cwd);
|
|
6677
6761
|
const entries = readHomeEntries(cache);
|
|
6678
6762
|
const homeEntry = entries[cwdKey];
|
|
6679
6763
|
if (homeEntry) {
|
|
@@ -6695,11 +6779,11 @@ function readCwdEntry(cache, cwd) {
|
|
|
6695
6779
|
}
|
|
6696
6780
|
function writeCwdEntry(cache, cwd, entry) {
|
|
6697
6781
|
const entries = readHomeEntries(cache);
|
|
6698
|
-
writeHomeEntries(cache, { ...entries, [
|
|
6782
|
+
writeHomeEntries(cache, { ...entries, [path10.resolve(cwd)]: entry });
|
|
6699
6783
|
}
|
|
6700
6784
|
function clearCwdEntry(cache, cwd) {
|
|
6701
6785
|
const entries = readHomeEntries(cache);
|
|
6702
|
-
const cwdKey =
|
|
6786
|
+
const cwdKey = path10.resolve(cwd);
|
|
6703
6787
|
if (cwdKey in entries) {
|
|
6704
6788
|
delete entries[cwdKey];
|
|
6705
6789
|
writeHomeEntries(cache, entries);
|
|
@@ -6879,11 +6963,11 @@ var runResultGetTool = {
|
|
|
6879
6963
|
`**Location:** \`${storedRunResult.artifactsDir}\``,
|
|
6880
6964
|
""
|
|
6881
6965
|
);
|
|
6882
|
-
const actionScriptPath =
|
|
6883
|
-
const resultsMdPath =
|
|
6884
|
-
const screenshotsDir =
|
|
6885
|
-
const stdoutLogPath =
|
|
6886
|
-
const stderrLogPath =
|
|
6966
|
+
const actionScriptPath = path10.join(storedRunResult.artifactsDir, "action-script.json");
|
|
6967
|
+
const resultsMdPath = path10.join(storedRunResult.artifactsDir, "results.md");
|
|
6968
|
+
const screenshotsDir = path10.join(storedRunResult.artifactsDir, "screenshots");
|
|
6969
|
+
const stdoutLogPath = path10.join(storedRunResult.artifactsDir, "stdout.log");
|
|
6970
|
+
const stderrLogPath = path10.join(storedRunResult.artifactsDir, "stderr.log");
|
|
6887
6971
|
const artifactItems = [];
|
|
6888
6972
|
if (fs5.existsSync(actionScriptPath)) {
|
|
6889
6973
|
artifactItems.push("- `action-script.json` \u2014 generated test steps");
|
|
@@ -7541,4 +7625,12 @@ var plugins_exports = {};
|
|
|
7541
7625
|
// packages/mcps/src/mcp/agents/index.ts
|
|
7542
7626
|
var agents_exports = {};
|
|
7543
7627
|
|
|
7544
|
-
|
|
7628
|
+
// packages/mcps/src/shared/watcher-lifetime-constants.ts
|
|
7629
|
+
var WATCHER_LIFETIME_UNBOUNDED_SECONDS = 0;
|
|
7630
|
+
var WATCHER_LIFETIME_SECONDS = {
|
|
7631
|
+
["1d" /* OneDay */]: 86400,
|
|
7632
|
+
["7d" /* SevenDays */]: 604800,
|
|
7633
|
+
["never" /* Never */]: WATCHER_LIFETIME_UNBOUNDED_SECONDS
|
|
7634
|
+
};
|
|
7635
|
+
|
|
7636
|
+
export { DEFAULT_PREFERENCES, EventName, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, ProjectPreferencesReconcileOutcome, ServiceName, Surface, WATCHER_LIFETIME_SECONDS, WATCHER_LIFETIME_UNBOUNDED_SECONDS, __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, getDisclosureCopy, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, hasShownDisclosure, initTelemetry, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports2 as local_exports, markDisclosureShown, mcp_exports, openBrowserUrl, performLogin, performLogout, pollDeviceCode, reconcileProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, src_exports, startDeviceCodeFlow, toolRequiresAuth, track, validatePreference, verifyFileChecksum, writePreferences2 as writePreferences };
|