@muggleai/works 5.10.0 → 5.11.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.
Files changed (136) hide show
  1. package/dist/{chunk-OCLMXAVJ.js → chunk-MSPMXBO5.js} +418 -326
  2. package/dist/{chunk-7NC2DJTK.js → chunk-WUMAJOBT.js} +9 -4
  3. package/dist/cli.js +2 -2
  4. package/dist/index.js +2 -2
  5. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  6. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  7. package/dist/plugin/agents/test-prepare-runner.md +3 -1
  8. package/dist/plugin/agents/visual-walkthrough-builder.md +12 -5
  9. package/dist/plugin/commands/mtest.md +1 -1
  10. package/dist/plugin/hooks/README.md +15 -3
  11. package/dist/plugin/hooks/hooks.json +79 -0
  12. package/dist/plugin/scripts/guardrail-classify-gate.sh +23 -0
  13. package/dist/plugin/scripts/guardrail-debug-path-gate.sh +41 -0
  14. package/dist/plugin/scripts/guardrail-pr-terminal.sh +6 -2
  15. package/dist/plugin/scripts/guardrail-record-stage-read.sh +21 -0
  16. package/dist/plugin/scripts/guardrail-record-stage-signals.sh +23 -0
  17. package/dist/plugin/scripts/guardrail-record-tests.sh +11 -4
  18. package/dist/plugin/scripts/guardrail-report-format.sh +9 -5
  19. package/dist/plugin/scripts/guardrail-skill-stages.sh +35 -0
  20. package/dist/plugin/scripts/guardrail-stage-gate.sh +43 -0
  21. package/dist/plugin/scripts/guardrail-walkthrough-gate.sh +41 -0
  22. package/dist/plugin/scripts/guardrails.mjs +428 -35
  23. package/dist/plugin/scripts/pr-watch-events.sh +116 -0
  24. package/dist/plugin/scripts/pr-watch-guards.sh +8 -2
  25. package/dist/plugin/scripts/pr-watch-loop.sh +254 -0
  26. package/dist/plugin/scripts/reconcile-stale-watchers.sh +66 -18
  27. package/dist/plugin/scripts/sign-body.sh +88 -0
  28. package/dist/plugin/skills/CLAUDE.md +16 -0
  29. package/dist/plugin/skills/_shared/post-merge-cleanup.md +83 -3
  30. package/dist/plugin/skills/_shared/pr-followup-helpers/loop-signature.md +6 -8
  31. package/dist/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +10 -18
  32. package/dist/plugin/skills/_shared/vcs/CLAUDE.md +1 -0
  33. package/dist/plugin/skills/_shared/vcs/github/pr-edit.md +3 -2
  34. package/dist/plugin/skills/_shared/vcs/github/reply-line-comment.md +3 -2
  35. package/dist/plugin/skills/_shared/vcs/github/top-level-comment.md +3 -2
  36. package/dist/plugin/skills/_shared/vcs/gitlab/mr-create.md +4 -1
  37. package/dist/plugin/skills/_shared/vcs/gitlab/mr-edit.md +4 -1
  38. package/dist/plugin/skills/_shared/vcs/gitlab/mr-note.md +4 -1
  39. package/dist/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +4 -1
  40. package/dist/plugin/skills/_shared/vcs/post-signature.md +23 -12
  41. package/dist/plugin/skills/do/open-prs/forward.md +2 -2
  42. package/dist/plugin/skills/do/per-comment-replies.md +2 -15
  43. package/dist/plugin/skills/muggle-browser-task/SKILL.md +1 -1
  44. package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -1
  45. package/dist/plugin/skills/muggle-pr-followup/SKILL.md +6 -3
  46. package/dist/plugin/skills/muggle-pr-followup/adopt.md +60 -0
  47. package/dist/plugin/skills/muggle-pr-followup/arm-watcher.md +10 -14
  48. package/dist/plugin/skills/muggle-pr-followup/auto-track.md +2 -0
  49. package/dist/plugin/skills/muggle-pr-followup/evals/evals.json +63 -1
  50. package/dist/plugin/skills/muggle-pr-followup/output-templates/help.md +11 -1
  51. package/dist/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +1 -7
  52. package/dist/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +1 -4
  53. package/dist/plugin/skills/muggle-pr-followup/reconcile.md +32 -6
  54. package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +18 -0
  55. package/dist/plugin/skills/muggle-preferences/preference-gates/watcherLifetime.md +23 -0
  56. package/dist/plugin/skills/muggle-test/SKILL.md +22 -2
  57. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +3 -0
  58. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +19 -12
  59. package/dist/plugin/skills/muggle-test-prepare/steps/confirm-recipe.md +56 -0
  60. package/dist/plugin/skills/muggle-test-prepare/steps/derive-service-graph.md +51 -0
  61. package/dist/plugin/skills/muggle-test-prepare/steps/e2e-instructions.md +13 -2
  62. package/dist/plugin/skills/muggle-test-prepare/steps/identify-services.md +4 -2
  63. package/dist/plugin/skills/muggle-test-prepare/steps/readiness-report.md +3 -1
  64. package/dist/plugin/skills/muggle-test-prepare/steps/record-resolution.md +32 -0
  65. package/dist/plugin/skills/muggle-test-prepare/steps/replay-or-learn.md +20 -0
  66. package/dist/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +4 -2
  67. package/dist/plugin/skills/muggle-test-prepare/steps/smoke-test.md +5 -1
  68. package/dist/plugin/skills/muggle-test-prepare/steps/start-services.md +3 -1
  69. package/dist/release-manifest.json +4 -4
  70. package/dist/src-B5OTAZKM.js +1 -0
  71. package/package.json +7 -6
  72. package/plugin/.claude-plugin/plugin.json +1 -1
  73. package/plugin/.cursor-plugin/plugin.json +1 -1
  74. package/plugin/agents/test-prepare-runner.md +3 -1
  75. package/plugin/agents/visual-walkthrough-builder.md +12 -5
  76. package/plugin/commands/mtest.md +1 -1
  77. package/plugin/hooks/README.md +15 -3
  78. package/plugin/hooks/hooks.json +79 -0
  79. package/plugin/scripts/guardrail-classify-gate.sh +23 -0
  80. package/plugin/scripts/guardrail-debug-path-gate.sh +41 -0
  81. package/plugin/scripts/guardrail-pr-terminal.sh +6 -2
  82. package/plugin/scripts/guardrail-record-stage-read.sh +21 -0
  83. package/plugin/scripts/guardrail-record-stage-signals.sh +23 -0
  84. package/plugin/scripts/guardrail-record-tests.sh +11 -4
  85. package/plugin/scripts/guardrail-report-format.sh +9 -5
  86. package/plugin/scripts/guardrail-skill-stages.sh +35 -0
  87. package/plugin/scripts/guardrail-stage-gate.sh +43 -0
  88. package/plugin/scripts/guardrail-walkthrough-gate.sh +41 -0
  89. package/plugin/scripts/guardrails.mjs +428 -35
  90. package/plugin/scripts/pr-watch-events.sh +116 -0
  91. package/plugin/scripts/pr-watch-guards.sh +8 -2
  92. package/plugin/scripts/pr-watch-loop.sh +254 -0
  93. package/plugin/scripts/reconcile-stale-watchers.sh +66 -18
  94. package/plugin/scripts/sign-body.sh +88 -0
  95. package/plugin/skills/CLAUDE.md +16 -0
  96. package/plugin/skills/_shared/post-merge-cleanup.md +83 -3
  97. package/plugin/skills/_shared/pr-followup-helpers/loop-signature.md +6 -8
  98. package/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +10 -18
  99. package/plugin/skills/_shared/vcs/CLAUDE.md +1 -0
  100. package/plugin/skills/_shared/vcs/github/pr-edit.md +3 -2
  101. package/plugin/skills/_shared/vcs/github/reply-line-comment.md +3 -2
  102. package/plugin/skills/_shared/vcs/github/top-level-comment.md +3 -2
  103. package/plugin/skills/_shared/vcs/gitlab/mr-create.md +4 -1
  104. package/plugin/skills/_shared/vcs/gitlab/mr-edit.md +4 -1
  105. package/plugin/skills/_shared/vcs/gitlab/mr-note.md +4 -1
  106. package/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +4 -1
  107. package/plugin/skills/_shared/vcs/post-signature.md +23 -12
  108. package/plugin/skills/do/open-prs/forward.md +2 -2
  109. package/plugin/skills/do/per-comment-replies.md +2 -15
  110. package/plugin/skills/muggle-browser-task/SKILL.md +1 -1
  111. package/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -1
  112. package/plugin/skills/muggle-pr-followup/SKILL.md +6 -3
  113. package/plugin/skills/muggle-pr-followup/adopt.md +60 -0
  114. package/plugin/skills/muggle-pr-followup/arm-watcher.md +10 -14
  115. package/plugin/skills/muggle-pr-followup/auto-track.md +2 -0
  116. package/plugin/skills/muggle-pr-followup/evals/evals.json +63 -1
  117. package/plugin/skills/muggle-pr-followup/output-templates/help.md +11 -1
  118. package/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +1 -7
  119. package/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +1 -4
  120. package/plugin/skills/muggle-pr-followup/reconcile.md +32 -6
  121. package/plugin/skills/muggle-pr-followup/state-schemas.md +18 -0
  122. package/plugin/skills/muggle-preferences/preference-gates/watcherLifetime.md +23 -0
  123. package/plugin/skills/muggle-test/SKILL.md +22 -2
  124. package/plugin/skills/muggle-test-feature-local/SKILL.md +3 -0
  125. package/plugin/skills/muggle-test-prepare/SKILL.md +19 -12
  126. package/plugin/skills/muggle-test-prepare/steps/confirm-recipe.md +56 -0
  127. package/plugin/skills/muggle-test-prepare/steps/derive-service-graph.md +51 -0
  128. package/plugin/skills/muggle-test-prepare/steps/e2e-instructions.md +13 -2
  129. package/plugin/skills/muggle-test-prepare/steps/identify-services.md +4 -2
  130. package/plugin/skills/muggle-test-prepare/steps/readiness-report.md +3 -1
  131. package/plugin/skills/muggle-test-prepare/steps/record-resolution.md +32 -0
  132. package/plugin/skills/muggle-test-prepare/steps/replay-or-learn.md +20 -0
  133. package/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +4 -2
  134. package/plugin/skills/muggle-test-prepare/steps/smoke-test.md +5 -1
  135. package/plugin/skills/muggle-test-prepare/steps/start-services.md +3 -1
  136. 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 path9 from 'path';
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 fs8 from 'fs/promises';
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 path9.join(os4.homedir(), DATA_DIR_NAME);
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 = path9.dirname(currentFilePath);
166
- if (currentDir.includes(path9.join("dist", "shared"))) {
167
- return path9.resolve(currentDir, "..", "..");
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 path9.resolve(currentDir, "..");
172
+ return path10.resolve(currentDir, "..");
171
173
  }
172
- if (currentDir.includes(path9.join("src", "shared"))) {
173
- return path9.resolve(currentDir, "..", "..");
174
+ if (currentDir.includes(path10.join("src", "shared"))) {
175
+ return path10.resolve(currentDir, "..", "..");
174
176
  }
175
- return path9.dirname(currentDir);
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 = path9.join(packageRoot, "package.json");
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 = path9.join(getDataDir2(), ELECTRON_APP_DIR, version);
247
+ const baseDir = path10.join(getDataDir2(), ELECTRON_APP_DIR, version);
246
248
  let binaryPath;
247
249
  switch (platformName) {
248
250
  case "darwin":
249
- binaryPath = path9.join(baseDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
251
+ binaryPath = path10.join(baseDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
250
252
  break;
251
253
  case "win32":
252
- binaryPath = path9.join(baseDir, "MuggleAI.exe");
254
+ binaryPath = path10.join(baseDir, "MuggleAI.exe");
253
255
  break;
254
256
  case "linux":
255
- binaryPath = path9.join(baseDir, "MuggleAI");
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 = path9.join(homeDir, "Applications", "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
273
+ binaryPath = path10.join(homeDir, "Applications", "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
272
274
  break;
273
275
  case "win32":
274
- binaryPath = path9.join(homeDir, "AppData", "Local", "Programs", "MuggleAI", "MuggleAI.exe");
276
+ binaryPath = path10.join(homeDir, "AppData", "Local", "Programs", "MuggleAI", "MuggleAI.exe");
275
277
  break;
276
278
  case "linux":
277
- binaryPath = path9.join(homeDir, ".local", "share", "muggle-ai", "MuggleAI");
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 = path9.resolve(packageRoot, "..", "web-service", "dist", "src", "index.js");
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: path9.join(dataDir, "sessions"),
396
- projectsDir: path9.join(dataDir, "projects"),
397
- tempDir: path9.join(dataDir, "temp"),
398
- apiKeyFilePath: path9.join(dataDir, API_KEY_FILE),
399
- oauthSessionFilePath: path9.join(dataDir, "oauth-session.json"),
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: path9.join(dataDir, "web-service.pid"),
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 = path9.join(getDataDir2(), VERSION_OVERRIDE_FILE);
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 = path9.join(getDataDir2(), VERSION_OVERRIDE_FILE);
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 path9.join(getDataDir2(), ELECTRON_APP_DIR, resolvedVersion);
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: path9.basename(filePath)
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: path9.basename(filePath),
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: path9.basename(filePath),
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: path9.basename(filePath),
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 path9.join(getDataDir(), API_KEY_FILE2);
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 = path9.join(
854
- path9.dirname(config.localQa.oauthSessionFilePath),
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 = path9.dirname(this.pendingDeviceCodePath);
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 = path9.dirname(this.oauthSessionFilePath);
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 = path9.dirname(this.oauthSessionFilePath);
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 = path9.join(this.sessionsDir, sessionId);
1404
+ const sessionDir = path10.join(this.sessionsDir, sessionId);
1403
1405
  if (!fs5.existsSync(sessionDir)) {
1404
1406
  fs5.mkdirSync(sessionDir, { recursive: true });
1405
- fs5.mkdirSync(path9.join(sessionDir, "screenshots"), { recursive: true });
1406
- fs5.mkdirSync(path9.join(sessionDir, "logs"), { recursive: true });
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 = path9.join(sessionDir, "metadata.json");
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 = path9.join(this.sessionsDir, sessionId, "metadata.json");
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 = path9.join(this.sessionsDir, entry);
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 = path9.join(this.sessionsDir, "current");
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 path9.basename(target);
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 = path9.join(this.sessionsDir, "current");
1480
- const targetPath = path9.join(this.sessionsDir, sessionId);
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 = path9.join(sessionDir, "screenshots", filename);
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 = path9.join(sessionDir, "results.md");
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 = path9.join(this.sessionsDir, sessionId, "results.md");
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 = path9.join(sessionDir, "results.md");
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 = path9.join(sessionDir, "results.md");
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 = path9.join(this.sessionsDir, sessionId);
1637
- const resultsPath = path9.join(sessionDir, "results.md");
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 = path9.join(this.sessionsDir, sessionId);
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 path9.join(this.sessionsDir, sessionId);
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 = path9.join(this.sessionsDir, sessionId);
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 = path9.join(this.sessionsDir, "current");
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 = path9.join(dataDir, "run-results");
1801
- this.testScriptsDir = path9.join(dataDir, "test-scripts");
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(path9.join(this.runResultsDir, file), "utf-8");
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 = path9.join(this.runResultsDir, `${runId}.json`);
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 = path9.join(this.runResultsDir, `${result.id}.json`);
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(path9.join(this.testScriptsDir, file), "utf-8");
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 = path9.join(this.testScriptsDir, `${testScriptId}.json`);
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 = path9.join(this.testScriptsDir, `${script.id}.json`);
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 path9.join(getDataDir(), LOCK_FILE_NAME);
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 = path9.resolve(cwd);
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 fs8.readFile(lockFilePath(), "utf-8");
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 fs8.writeFile(lockFilePath(), JSON.stringify(state2, null, 2), "utf-8");
2437
+ await fs9.writeFile(lockFilePath(), JSON.stringify(state2, null, 2), "utf-8");
2196
2438
  }
2197
2439
  async function deleteStateFile() {
2198
2440
  try {
2199
- await fs8.unlink(lockFilePath());
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 fs8.mkdir(path9.dirname(modifyLockPath()), { recursive: true });
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 fs8.open(modifyPath, "wx");
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 fs8.stat(modifyPath);
2456
+ const stat3 = await fs9.stat(modifyPath);
2215
2457
  if (Date.now() - stat3.mtimeMs > MODIFY_LOCK_STALE_MS) {
2216
- await fs8.unlink(modifyPath).catch(() => void 0);
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 fs8.unlink(modifyPath).catch(() => void 0);
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 = path9.join(
2369
- path9.dirname(inputFilePath),
2370
- `cloudrefs_${path9.basename(inputFilePath)}`
2610
+ const cloudRefsPath = path10.join(
2611
+ path10.dirname(inputFilePath),
2612
+ `cloudrefs_${path10.basename(inputFilePath)}`
2371
2613
  );
2372
2614
  try {
2373
- return JSON.parse(await fs8.readFile(cloudRefsPath, "utf-8"));
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 = path9.dirname(fileURLToPath(currentFileUrl));
2634
+ const currentDir = path10.dirname(fileURLToPath(currentFileUrl));
2393
2635
  const candidatePaths = [
2394
- path9.resolve(currentDir, "../../../package.json"),
2395
- path9.resolve(currentDir, "../package.json"),
2396
- path9.resolve(currentDir, "../../package.json")
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 fs8.readFile(candidatePath, "utf-8");
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 = path9.join(config.localQa.dataDir, "temp");
2447
- await fs8.mkdir(tempDir, { recursive: true });
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 = path9.join(tempDir, params.filename);
2453
- await fs8.writeFile(filePath, JSON.stringify(params.data, null, 2));
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 fs8.unlink(filePath);
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 = path9.join(sessionsDir, params.runId);
2468
- const actionScriptPath = path9.join(artifactsDir, "action-script.json");
2469
- await fs8.mkdir(artifactsDir, { recursive: true });
2470
- await fs8.copyFile(params.generatedScriptPath, actionScriptPath);
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 fs8.unlink(params.generatedScriptPath);
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 = path9.join(sessionsDir, params.runId);
2481
- await fs8.mkdir(artifactsDir, { recursive: true });
2482
- const stdoutPath = path9.join(artifactsDir, "stdout.log");
2483
- const stderrPath = path9.join(artifactsDir, "stderr.log");
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
- fs8.writeFile(stdoutPath, params.stdout, "utf-8"),
2486
- fs8.writeFile(stderrPath, params.stderr, "utf-8")
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 = path9.join(tempDir, `${params.runId}_runtime_dir.txt`);
2738
+ const markerPath = path10.join(tempDir, `${params.runId}_runtime_dir.txt`);
2497
2739
  let runtimeDir = null;
2498
2740
  try {
2499
- const marker = await fs8.readFile(markerPath, "utf-8");
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 fs8.access(runtimeDir);
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 fs8.unlink(markerPath).catch(() => void 0);
2769
+ await fs9.unlink(markerPath).catch(() => void 0);
2528
2770
  return;
2529
2771
  }
2530
2772
  const storage = getStorageService();
2531
- const destDir = path9.join(storage.getSessionsDir(), params.runId, "electron-runtime");
2532
- await fs8.mkdir(destDir, { recursive: true });
2533
- await fs8.cp(runtimeDir, destDir, { recursive: true });
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 fs8.unlink(markerPath).catch(() => void 0);
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 = path9.join(params.electronCwd, "user_data", "runtime");
2790
+ const runtimeRoot = path10.join(params.electronCwd, "user_data", "runtime");
2549
2791
  try {
2550
- const entries = await fs8.readdir(runtimeRoot, { withFileTypes: true });
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 = path9.join(runtimeRoot, entry.name);
2555
- const stat3 = await fs8.stat(fullPath);
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 electronEnv = { ...process.env };
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 = path9.join(sessionsDir, runId);
2791
- const generatedScriptPath2 = path9.join(
2792
- path9.dirname(inputFilePath),
2793
- `gen_${path9.basename(inputFilePath)}`
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 fs8.readFile(generatedScriptPath2, "utf-8");
3042
+ const failedScriptRaw = await fs9.readFile(generatedScriptPath2, "utf-8");
2798
3043
  failedStudioResult = JSON.parse(failedScriptRaw);
2799
- await fs8.copyFile(generatedScriptPath2, path9.join(artifactsDir2, "action-script.json"));
2800
- await fs8.unlink(generatedScriptPath2).catch(() => {
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 = path9.join(
2830
- path9.dirname(inputFilePath),
2831
- `gen_${path9.basename(inputFilePath)}`
3074
+ const generatedScriptPath = path10.join(
3075
+ path10.dirname(inputFilePath),
3076
+ `gen_${path10.basename(inputFilePath)}`
2832
3077
  );
2833
- const generatedScriptRaw = await fs8.readFile(generatedScriptPath, "utf-8");
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 = path9.join(getStorageService().getSessionsDir(), runId);
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 = path9.join(getStorageService().getSessionsDir(), runId);
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 path9.join(os4.homedir(), DATA_DIR_NAME2);
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 path15 = MANIFEST_PATH2;
3741
+ const path16 = MANIFEST_PATH2;
3497
3742
  try {
3498
- const raw = readFileSync(path15, "utf8");
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(path15) {
4278
- const isAllowed = ALLOWED_UPSTREAM_PREFIXES.some((prefix) => path15.startsWith(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: path15,
4527
+ path: path16,
4283
4528
  allowedPrefixes: ALLOWED_UPSTREAM_PREFIXES
4284
4529
  });
4285
4530
  throw new GatewayError({
4286
4531
  code: "FORBIDDEN" /* FORBIDDEN */,
4287
- message: `Path '${path15}' is not allowed`
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 = path9.join(getDataDir(), TELEMETRY_DIR_NAME);
6585
+ const dir = path10.join(getDataDir(), TELEMETRY_DIR_NAME);
6513
6586
  fs5.mkdirSync(dir, { recursive: true });
6514
- const filePath = path9.join(dir, FAILURE_EVENTS_FILE_NAME);
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 path9.join(dataDirOverride2 ?? getDataDir(), PREFERENCES_FILE_NAME);
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 = path9.join(dir, PREFERENCES_FILE_NAME);
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 = path9.join(cwd, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_FILE_NAME);
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 path9.join(getDataDir(), cache.fileName);
6717
+ return path10.join(getDataDir(), cache.fileName);
6634
6718
  }
6635
6719
  function resolveLegacyFilePath(cache, cwd) {
6636
- return path9.join(cwd, LEGACY_CACHE_DIR_NAME, cache.fileName);
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 = path9.resolve(cwd);
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, [path9.resolve(cwd)]: entry });
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 = path9.resolve(cwd);
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 = path9.join(storedRunResult.artifactsDir, "action-script.json");
6883
- const resultsMdPath = path9.join(storedRunResult.artifactsDir, "results.md");
6884
- const screenshotsDir = path9.join(storedRunResult.artifactsDir, "screenshots");
6885
- const stdoutLogPath = path9.join(storedRunResult.artifactsDir, "stdout.log");
6886
- const stderrLogPath = path9.join(storedRunResult.artifactsDir, "stderr.log");
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
- export { DEFAULT_PREFERENCES, EventName, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, ProjectPreferencesReconcileOutcome, 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, 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 };
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 };