@muggleai/works 5.15.0-staging.105 → 5.15.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.
@@ -11,6 +11,7 @@
11
11
  "production": {
12
12
  "promptServiceBaseUrl": "https://promptservice.muggle-ai.com",
13
13
  "uiBaseUrl": "https://www.muggle-ai.com/muggleTestV0",
14
+ "dashboardBaseUrl": "https://www.muggle-ai.com/muggleTestV0/dashboard/projects",
14
15
  "auth0Domain": "login.muggle-ai.com",
15
16
  "auth0ClientId": "UgG5UjoyLksxMciWWKqVpwfWrJ4rFvtT",
16
17
  "auth0Audience": "https://muggleai.us.auth0.com/api/v2/",
@@ -19,6 +20,7 @@
19
20
  "staging": {
20
21
  "promptServiceBaseUrl": "https://staging.promptservice.muggle-ai.com",
21
22
  "uiBaseUrl": "https://staging.muggle-ai.com/muggleTestV0",
23
+ "dashboardBaseUrl": "https://staging.muggle-ai.com/muggleTestV0/dashboard/projects",
22
24
  "auth0Domain": "login.staging.muggle-ai.com",
23
25
  "auth0ClientId": "C6rmJN3FeX3EuGZdY8qbHpbJVRadxsly",
24
26
  "auth0Audience": "https://staging-muggleai.us.auth0.com/api/v2/",
@@ -27,6 +29,7 @@
27
29
  "dev": {
28
30
  "promptServiceBaseUrl": "http://localhost:5050",
29
31
  "uiBaseUrl": "http://localhost:3999/muggleTestV0",
32
+ "dashboardBaseUrl": "http://localhost:3999/muggleTestV0/dashboard/projects",
30
33
  "auth0Domain": "dev-po4mxmz0rd8a0w8w.us.auth0.com",
31
34
  "auth0ClientId": "GBvkMdTbCI80XJXnJ90MmbEvXwcWGUtw",
32
35
  "auth0Audience": "https://dev-po4mxmz0rd8a0w8w.us.auth0.com/api/v2/",
@@ -1,4 +1,4 @@
1
- import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getActiveRuntimeTarget, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, reconcileProjectPreferences, getDataDir, PREFERENCES_FILE_NAME, isFirstRun, writePreferences, DEFAULT_PREFERENCES, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, getElectronAppSignedFromVersion, getReleaseSignerIdentityUri, verifyFileChecksum, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, assertDeviceCodeClientProvisioned, performLogin, toolRequiresAuth, getCallerCredentials, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-J6VC26BI.js';
1
+ import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getActiveRuntimeTarget, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, reconcileProjectPreferences, getDataDir, PREFERENCES_FILE_NAME, isFirstRun, writePreferences, DEFAULT_PREFERENCES, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, getElectronAppSignedFromVersion, getReleaseSignerIdentityUri, verifyFileChecksum, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, assertDeviceCodeClientProvisioned, performLogin, toolRequiresAuth, getCallerCredentials, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-VQZLKLAY.js';
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { v4 } from 'uuid';
@@ -753,7 +753,7 @@ async function resolveGsScreenshotUrls(report, opts) {
753
753
  if (gsUrls.length === 0) {
754
754
  return report;
755
755
  }
756
- const mcps = await import('./src-HWRBSSUF.js');
756
+ const mcps = await import('./src-EHF3T2T2.js');
757
757
  const credentials = await mcps.getCallerCredentialsAsync();
758
758
  if (!credentials.bearerToken && !credentials.apiKey) {
759
759
  stderrWrite(
@@ -806,8 +806,8 @@ var withSentinel = (s) => s ? `${REPORT_SECTION_SENTINEL}
806
806
  ${s}` : s;
807
807
  async function resolveDashboardBaseUrl(stderrWrite) {
808
808
  try {
809
- const mcps = await import('./src-HWRBSSUF.js');
810
- return `${mcps.resolveActiveProfile().uiBaseUrl}/dashboard/projects`;
809
+ const mcps = await import('./src-EHF3T2T2.js');
810
+ return mcps.resolveActiveProfile().dashboardBaseUrl;
811
811
  } catch (err) {
812
812
  stderrWrite(
813
813
  `build-pr-section: could not resolve the runtime target, linking to production: ${errMsg2(err)}
@@ -952,7 +952,37 @@ var TestResultStatus = /* @__PURE__ */ ((TestResultStatus2) => {
952
952
  })(TestResultStatus || {});
953
953
 
954
954
  // packages/mcps/src/mcp/local/services/stored-auth-target.ts
955
+ function decodeJwtPayload(token) {
956
+ try {
957
+ const parts = token.split(".");
958
+ if (parts.length !== 3) {
959
+ return null;
960
+ }
961
+ const payload = parts[1];
962
+ const decoded = Buffer.from(payload, "base64url").toString("utf-8");
963
+ return JSON.parse(decoded);
964
+ } catch {
965
+ return null;
966
+ }
967
+ }
968
+ function extractJwtIssuer(token) {
969
+ const payload = decodeJwtPayload(token);
970
+ if (!payload || typeof payload.iss !== "string") {
971
+ return null;
972
+ }
973
+ return payload.iss;
974
+ }
975
+ function normalizeIssuerHost(issuer) {
976
+ return issuer.replace(/^https:\/\//, "").replace(/\/$/, "");
977
+ }
955
978
  function isStoredAuthForRuntimeTarget(params) {
979
+ if (params.tokenIssuer && params.expectedAuth0Domain) {
980
+ const issuerHost = normalizeIssuerHost(params.tokenIssuer);
981
+ const expectedHost = normalizeIssuerHost(params.expectedAuth0Domain);
982
+ if (issuerHost !== expectedHost) {
983
+ return false;
984
+ }
985
+ }
956
986
  if (!params.storedRuntimeTarget) {
957
987
  return params.activeRuntimeTarget === "production" /* Production */;
958
988
  }
@@ -1033,23 +1063,23 @@ var AuthService = class {
1033
1063
  });
1034
1064
  throw new Error(`Failed to start device code flow: ${response.status} ${errorText}`);
1035
1065
  }
1036
- const data = await response.json();
1066
+ const deviceCodeResponse = await response.json();
1037
1067
  logger6.info("Device code flow started", {
1038
- userCode: data.user_code,
1039
- verificationUri: data.verification_uri,
1040
- expiresIn: data.expires_in
1068
+ userCode: deviceCodeResponse.user_code,
1069
+ verificationUri: deviceCodeResponse.verification_uri,
1070
+ expiresIn: deviceCodeResponse.expires_in
1041
1071
  });
1042
1072
  this.storePendingDeviceCode({
1043
- deviceCode: data.device_code,
1044
- userCode: data.user_code,
1045
- expiresAt: new Date(Date.now() + data.expires_in * 1e3).toISOString()
1073
+ deviceCode: deviceCodeResponse.device_code,
1074
+ userCode: deviceCodeResponse.user_code,
1075
+ expiresAt: new Date(Date.now() + deviceCodeResponse.expires_in * 1e3).toISOString()
1046
1076
  });
1047
- let browserUrl = data.verification_uri_complete;
1077
+ let browserUrl = deviceCodeResponse.verification_uri_complete;
1048
1078
  if (options?.forceNewSession) {
1049
1079
  this.logout();
1050
1080
  const logoutUrl = new URL(`https://${domain}/v2/logout`);
1051
1081
  logoutUrl.searchParams.set("client_id", clientId);
1052
- logoutUrl.searchParams.set("returnTo", data.verification_uri_complete);
1082
+ logoutUrl.searchParams.set("returnTo", deviceCodeResponse.verification_uri_complete);
1053
1083
  browserUrl = logoutUrl.toString();
1054
1084
  logger6.info("Force new session: cleared local token, opening logout-redirect URL", {
1055
1085
  logoutUrl: browserUrl
@@ -1067,12 +1097,12 @@ var AuthService = class {
1067
1097
  });
1068
1098
  }
1069
1099
  return {
1070
- deviceCode: data.device_code,
1071
- userCode: data.user_code,
1072
- verificationUri: data.verification_uri,
1073
- verificationUriComplete: data.verification_uri_complete,
1074
- expiresIn: data.expires_in,
1075
- interval: data.interval,
1100
+ deviceCode: deviceCodeResponse.device_code,
1101
+ userCode: deviceCodeResponse.user_code,
1102
+ verificationUri: deviceCodeResponse.verification_uri,
1103
+ verificationUriComplete: deviceCodeResponse.verification_uri_complete,
1104
+ expiresIn: deviceCodeResponse.expires_in,
1105
+ interval: deviceCodeResponse.interval,
1076
1106
  browserOpened: browserOpenResult.opened,
1077
1107
  browserOpenError: browserOpenResult.error
1078
1108
  };
@@ -1103,15 +1133,15 @@ var AuthService = class {
1103
1133
  }
1104
1134
  try {
1105
1135
  const content = fs6.readFileSync(this.pendingDeviceCodePath, "utf-8");
1106
- const data = JSON.parse(content);
1136
+ const pendingDeviceCodeData = JSON.parse(content);
1107
1137
  const now = /* @__PURE__ */ new Date();
1108
- const expiresAt = new Date(data.expiresAt);
1138
+ const expiresAt = new Date(pendingDeviceCodeData.expiresAt);
1109
1139
  if (now >= expiresAt) {
1110
1140
  logger6.debug("Pending device code expired");
1111
1141
  this.clearPendingDeviceCode();
1112
1142
  return null;
1113
1143
  }
1114
- return data.deviceCode;
1144
+ return pendingDeviceCodeData.deviceCode;
1115
1145
  } catch (error) {
1116
1146
  logger6.warn("Failed to read pending device code", {
1117
1147
  error: error instanceof Error ? error.message : String(error)
@@ -1238,9 +1268,9 @@ var AuthService = class {
1238
1268
  pollIntervalMs
1239
1269
  });
1240
1270
  while (Date.now() - startedAt < timeoutMs) {
1241
- const result = await this.pollDeviceCode(params.deviceCode);
1242
- if (result.status !== "pending" /* Pending */) {
1243
- return result;
1271
+ const pollResult = await this.pollDeviceCode(params.deviceCode);
1272
+ if (pollResult.status !== "pending" /* Pending */) {
1273
+ return pollResult;
1244
1274
  }
1245
1275
  const remainingMs = timeoutMs - (Date.now() - startedAt);
1246
1276
  if (remainingMs <= 0) {
@@ -1272,8 +1302,8 @@ var AuthService = class {
1272
1302
  logger6.warn("Failed to get user info", { status: response.status });
1273
1303
  return {};
1274
1304
  }
1275
- const data = await response.json();
1276
- return data;
1305
+ const userInfoData = await response.json();
1306
+ return userInfoData;
1277
1307
  } catch (error) {
1278
1308
  logger6.warn("User info request failed", {
1279
1309
  error: error instanceof Error ? error.message : String(error)
@@ -1319,13 +1349,20 @@ var AuthService = class {
1319
1349
  const content = fs6.readFileSync(this.oauthSessionFilePath, "utf-8");
1320
1350
  const storedAuth = JSON.parse(content);
1321
1351
  const activeRuntimeTarget = getActiveRuntimeTarget();
1352
+ const config = getConfig();
1353
+ const expectedAuth0Domain = config.localQa.auth0.domain;
1354
+ const tokenIssuer = extractJwtIssuer(storedAuth.accessToken);
1322
1355
  if (!isStoredAuthForRuntimeTarget({
1323
1356
  storedRuntimeTarget: storedAuth.runtimeTarget,
1324
- activeRuntimeTarget
1357
+ activeRuntimeTarget,
1358
+ tokenIssuer,
1359
+ expectedAuth0Domain
1325
1360
  })) {
1326
1361
  logger6.warn("Ignoring stored auth issued for a different runtime target", {
1327
1362
  storedRuntimeTarget: storedAuth.runtimeTarget ?? "unrecorded",
1328
- activeRuntimeTarget
1363
+ activeRuntimeTarget,
1364
+ tokenIssuer: tokenIssuer ?? "undecodable",
1365
+ expectedAuth0Domain
1329
1366
  });
1330
1367
  return null;
1331
1368
  }
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { runCli } from './chunk-GMNAD3B6.js';
3
- import './chunk-J6VC26BI.js';
2
+ import { runCli } from './chunk-FK7XVMVA.js';
3
+ import './chunk-VQZLKLAY.js';
4
4
 
5
5
  // src/cli/main.ts
6
6
  runCli().catch((error) => {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-GMNAD3B6.js';
2
- export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-J6VC26BI.js';
1
+ export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-FK7XVMVA.js';
2
+ export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-VQZLKLAY.js';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "release": "5.13.1",
3
- "buildId": "run-105-1",
4
- "commitSha": "a9e7e8cbb77fd8f9bb3f6c93f55a7b1509705c84",
5
- "buildTime": "2026-09-08T23:57:01Z",
3
+ "buildId": "run-107-1",
4
+ "commitSha": "04bc87307c2df4dd098aa15befb19a3734923306",
5
+ "buildTime": "2026-09-09T01:10:17Z",
6
6
  "serviceName": "muggle-ai-works-mcp"
7
7
  }
@@ -1 +1 @@
1
- export { DEFAULT_PREFERENCES, ElectronAppReleaseStream, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, ProjectPreferencesReconcileOutcome, RuntimeTarget, WATCHER_LIFETIME_SECONDS, WATCHER_LIFETIME_UNBOUNDED_SECONDS, assertDeviceCodeClientProvisioned, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getActiveElectronAppReleaseStream, getActiveRuntimeTarget, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppReleaseTagPrefix, getElectronAppSignedFromVersion, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getReleaseSignerIdentityUri, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, reconcileProjectPreferences, resetConfig, resetLogger, resetPreference, resolveActiveProfile, resolveActiveReleaseStream, resolveActiveReleaseTagPrefix, resolveElectronAppPathOrNull, resolvePreferences, resolveRuntimeTarget, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-J6VC26BI.js';
1
+ export { DEFAULT_PREFERENCES, ElectronAppReleaseStream, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, ProjectPreferencesReconcileOutcome, RuntimeTarget, WATCHER_LIFETIME_SECONDS, WATCHER_LIFETIME_UNBOUNDED_SECONDS, assertDeviceCodeClientProvisioned, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getActiveElectronAppReleaseStream, getActiveRuntimeTarget, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppReleaseTagPrefix, getElectronAppSignedFromVersion, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getReleaseSignerIdentityUri, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, reconcileProjectPreferences, resetConfig, resetLogger, resetPreference, resolveActiveProfile, resolveActiveReleaseStream, resolveActiveReleaseTagPrefix, resolveElectronAppPathOrNull, resolvePreferences, resolveRuntimeTarget, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-VQZLKLAY.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@muggleai/works",
3
3
  "mcpName": "io.github.multiplex-ai/muggle",
4
- "version": "5.15.0-staging.105",
4
+ "version": "5.15.0",
5
5
  "description": "Ship quality products with AI-powered E2E acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -53,7 +53,7 @@
53
53
  "muggleConfig": {
54
54
  "electronAppVersion": "1.10.3",
55
55
  "downloadBaseUrl": "https://github.com/multiplex-ai/muggle-ai-works/releases/download",
56
- "runtimeTargetDefault": "staging",
56
+ "runtimeTargetDefault": "production",
57
57
  "checksumsByStream": {
58
58
  "production": {
59
59
  "win32-x64": "58e2238b1609ceff65b836b4b724b1c4c341d737a15debaa8a71af21b70bc436",