mobbdev 1.0.108 → 1.0.110

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 (2) hide show
  1. package/dist/index.mjs +175 -112
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -707,6 +707,7 @@ var GetAnalysisSubscriptionDocument = `
707
707
  analysis: fixReport_by_pk(id: $analysisId) {
708
708
  id
709
709
  state
710
+ failReason
710
711
  }
711
712
  }
712
713
  `;
@@ -715,6 +716,7 @@ var GetAnalysisDocument = `
715
716
  analysis: fixReport_by_pk(id: $analysisId) {
716
717
  id
717
718
  state
719
+ failReason
718
720
  repo {
719
721
  commitSha
720
722
  pullRequest
@@ -1094,6 +1096,13 @@ var GetReportFixesDocument = `
1094
1096
  }
1095
1097
  }
1096
1098
  ${FixReportSummaryFieldsFragmentDoc}`;
1099
+ var UpdateDownloadedFixDataDocument = `
1100
+ mutation updateDownloadedFixData($fixIds: [String!]!, $source: FixDownloadSource!) {
1101
+ updateDownloadedFixData(fixIds: $fixIds, source: $source) {
1102
+ status
1103
+ }
1104
+ }
1105
+ `;
1097
1106
  var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
1098
1107
  function getSdk(client, withWrapper = defaultWrapper) {
1099
1108
  return {
@@ -1165,6 +1174,9 @@ function getSdk(client, withWrapper = defaultWrapper) {
1165
1174
  },
1166
1175
  GetReportFixes(variables, requestHeaders, signal) {
1167
1176
  return withWrapper((wrappedRequestHeaders) => client.request({ document: GetReportFixesDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetReportFixes", "query", variables);
1177
+ },
1178
+ updateDownloadedFixData(variables, requestHeaders, signal) {
1179
+ return withWrapper((wrappedRequestHeaders) => client.request({ document: UpdateDownloadedFixDataDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "updateDownloadedFixData", "mutation", variables);
1168
1180
  }
1169
1181
  };
1170
1182
  }
@@ -1597,9 +1609,9 @@ function getParsedFalsePositiveMessage(data) {
1597
1609
  const containsTemplate = extraContext.some(
1598
1610
  (context) => fixDescription.includes(`\${${context.key}}`)
1599
1611
  );
1600
- const description2 = containsTemplate ? replaceKeysWithValues(fixDescription, extraContext) : fixDescription;
1612
+ const description = containsTemplate ? replaceKeysWithValues(fixDescription, extraContext) : fixDescription;
1601
1613
  const contextString = containsTemplate ? null : `\`\`\`${extraContext.map(({ value }) => value).join(" ")} \`\`\``;
1602
- return { description: description2, contextString };
1614
+ return { description, contextString };
1603
1615
  }
1604
1616
 
1605
1617
  // src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
@@ -1625,7 +1637,7 @@ var getCommitDescription = ({
1625
1637
  irrelevantIssueWithTags
1626
1638
  }) => {
1627
1639
  const issueTypeString = getIssueTypeFriendlyString(issueType);
1628
- let description2 = `This change fixes a **${severity} severity** (${severityToEmoji[severity]}) **${issueTypeString}** issue reported by **${capitalizeFirstLetter(
1640
+ let description = `This change fixes a **${severity} severity** (${severityToEmoji[severity]}) **${issueTypeString}** issue reported by **${capitalizeFirstLetter(
1629
1641
  vendor
1630
1642
  )}**.
1631
1643
 
@@ -1633,7 +1645,7 @@ var getCommitDescription = ({
1633
1645
  const parseIssueTypeRes = z2.nativeEnum(IssueType_Enum).safeParse(issueType);
1634
1646
  if (issueType && parseIssueTypeRes.success) {
1635
1647
  if (irrelevantIssueWithTags?.[0]?.tag) {
1636
- description2 += `
1648
+ description += `
1637
1649
  > [!tip]
1638
1650
  > This issue was found to be irrelevant to your project - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
1639
1651
  > Mobb recommends to ignore this issue, however fix is available if you think differently.
@@ -1645,7 +1657,7 @@ ${issueDescription[irrelevantIssueWithTags[0].tag]}
1645
1657
  }
1646
1658
  const staticData = fixDetailsData[parseIssueTypeRes.data];
1647
1659
  if (staticData) {
1648
- description2 += `## Issue description
1660
+ description += `## Issue description
1649
1661
  ${staticData.issueDescription}
1650
1662
 
1651
1663
  ## Fix instructions
@@ -1653,16 +1665,16 @@ ${staticData.fixInstructions}
1653
1665
  `;
1654
1666
  }
1655
1667
  }
1656
- description2 += `
1668
+ description += `
1657
1669
  ${guidances.map(({ guidance }) => `## Additional actions required
1658
1670
  ${guidance}
1659
1671
  `).join("")}
1660
1672
  `;
1661
1673
  if (fixUrl) {
1662
- description2 += `
1674
+ description += `
1663
1675
  [More info and fix customization are available in the Mobb platform](${fixUrl})`;
1664
1676
  }
1665
- return description2;
1677
+ return description;
1666
1678
  };
1667
1679
  var getCommitIssueDescription = ({
1668
1680
  vendor,
@@ -1671,12 +1683,12 @@ var getCommitIssueDescription = ({
1671
1683
  fpDescription
1672
1684
  }) => {
1673
1685
  const issueTypeString = getIssueTypeFriendlyString(issueType);
1674
- let description2 = `The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
1686
+ let description = `The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
1675
1687
  `;
1676
1688
  const parseIssueTypeRes = z2.nativeEnum(IssueType_Enum).safeParse(issueType);
1677
1689
  if (issueType && parseIssueTypeRes.success) {
1678
1690
  if (irrelevantIssueWithTags?.[0]?.tag) {
1679
- description2 = `
1691
+ description = `
1680
1692
  > [!tip]
1681
1693
  > The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
1682
1694
  > ${issueTypeString} - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
@@ -1689,12 +1701,12 @@ ${fpDescription ?? issueDescription[irrelevantIssueWithTags[0].tag]}
1689
1701
  }
1690
1702
  const staticData = fixDetailsData[parseIssueTypeRes.data];
1691
1703
  if (staticData) {
1692
- description2 += `## Issue description
1704
+ description += `## Issue description
1693
1705
  ${staticData.issueDescription}
1694
1706
  `;
1695
1707
  }
1696
1708
  }
1697
- return description2;
1709
+ return description;
1698
1710
  };
1699
1711
 
1700
1712
  // src/features/analysis/scm/shared/src/guidances.ts
@@ -2917,15 +2929,22 @@ var openRedirect2 = {
2917
2929
  description: () => "",
2918
2930
  guidance: () => ""
2919
2931
  },
2920
- allowlist: {
2921
- content: () => "Allowed domains/paths",
2922
- description: () => description,
2932
+ domainAllowlist: {
2933
+ content: () => "Allowed domains names",
2934
+ description: () => "please provide a coma separated list of allowed domains names (example.com, example.org, etc.)",
2935
+ guidance: () => ""
2936
+ },
2937
+ pathAllowlist: {
2938
+ content: () => "Allowed paths (URIs)",
2939
+ description: () => "please provide a coma separated list of allowed path (/health, /api/v1/health, etc.)",
2940
+ guidance: () => ""
2941
+ },
2942
+ includeProtocolValidation: {
2943
+ content: () => "Should HTTP or HTTPS protocol be enforced?",
2944
+ description: () => "please indicate if the protocol should be enforced",
2923
2945
  guidance: () => ""
2924
2946
  }
2925
2947
  };
2926
- var description = `- *If external*, provide a coma separated list of allowed domains.
2927
-  
2928
- - *If internal*, provide a coma seperated list of allowed paths`;
2929
2948
 
2930
2949
  // src/features/analysis/scm/shared/src/storedQuestionData/js/pt.ts
2931
2950
  var pt3 = {
@@ -3674,6 +3693,7 @@ var ReportQueryResultZ = z11.object({
3674
3693
  createdOn: z11.string(),
3675
3694
  expirationOn: z11.string().nullable(),
3676
3695
  state: z11.nativeEnum(Fix_Report_State_Enum),
3696
+ failReason: z11.string().nullable(),
3677
3697
  fixes: z11.array(
3678
3698
  z11.object({
3679
3699
  id: z11.string().uuid(),
@@ -4683,11 +4703,11 @@ async function adoValidateParams({
4683
4703
  console.log("adoValidateParams error", e);
4684
4704
  const error = e;
4685
4705
  const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
4686
- const description2 = error.description || `${e}`;
4687
- if (code === 401 || code === 403 || description2.includes("401") || description2.includes("403")) {
4706
+ const description = error.description || `${e}`;
4707
+ if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
4688
4708
  throw new InvalidAccessTokenError(`invalid ADO access token`);
4689
4709
  }
4690
- if (code === 404 || description2.includes("404") || description2.includes("Not Found")) {
4710
+ if (code === 404 || description.includes("404") || description.includes("Not Found")) {
4691
4711
  throw new InvalidRepoUrlError(`invalid ADO repo URL ${url}`);
4692
4712
  }
4693
4713
  console.log("adoValidateParams error", e);
@@ -7411,11 +7431,11 @@ async function gitlabValidateParams({
7411
7431
  } catch (e) {
7412
7432
  const error = e;
7413
7433
  const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
7414
- const description2 = error.description || `${e}`;
7415
- if (code === 401 || code === 403 || description2.includes("401") || description2.includes("403")) {
7434
+ const description = error.description || `${e}`;
7435
+ if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
7416
7436
  throw new InvalidAccessTokenError(`invalid gitlab access token`);
7417
7437
  }
7418
- if (code === 404 || description2.includes("404") || description2.includes("Not Found")) {
7438
+ if (code === 404 || description.includes("404") || description.includes("Not Found")) {
7419
7439
  throw new InvalidRepoUrlError(`invalid gitlab repo URL: ${url}`);
7420
7440
  }
7421
7441
  console.log("gitlabValidateParams error", e);
@@ -8569,6 +8589,84 @@ import open2 from "open";
8569
8589
  import tmp2 from "tmp";
8570
8590
  import { z as z29 } from "zod";
8571
8591
 
8592
+ // src/mcp/core/Errors.ts
8593
+ var ApiConnectionError = class extends Error {
8594
+ constructor(message = "Failed to connect to the API") {
8595
+ super(message);
8596
+ this.name = "ApiConnectionError";
8597
+ }
8598
+ };
8599
+ var CliLoginError = class extends Error {
8600
+ constructor(message = "CLI login failed") {
8601
+ super(message);
8602
+ this.name = "CliLoginError";
8603
+ }
8604
+ };
8605
+ var AuthenticationError = class extends Error {
8606
+ constructor(message = "Authentication failed") {
8607
+ super(message);
8608
+ this.name = "AuthenticationError";
8609
+ }
8610
+ };
8611
+ var NoFilesError = class extends Error {
8612
+ constructor(message = "No files to fix") {
8613
+ super(message);
8614
+ this.name = "NoFilesError";
8615
+ }
8616
+ };
8617
+ var GqlClientError = class extends Error {
8618
+ constructor(message = "GraphQL client not initialized") {
8619
+ super(message);
8620
+ this.name = "GqlClientError";
8621
+ }
8622
+ };
8623
+ var FileProcessingError = class extends Error {
8624
+ constructor(message) {
8625
+ super(message);
8626
+ this.name = "FileProcessingError";
8627
+ }
8628
+ };
8629
+ var ReportInitializationError = class extends Error {
8630
+ constructor(message) {
8631
+ super(message);
8632
+ this.name = "ReportInitializationError";
8633
+ }
8634
+ };
8635
+ var FileUploadError = class extends Error {
8636
+ constructor(message) {
8637
+ super(message);
8638
+ this.name = "FileUploadError";
8639
+ }
8640
+ };
8641
+ var ScanError = class extends Error {
8642
+ constructor(message) {
8643
+ super(message);
8644
+ this.name = "ScanError";
8645
+ }
8646
+ };
8647
+ var FailedToGetApiTokenError = class extends Error {
8648
+ constructor(message) {
8649
+ super(message);
8650
+ this.name = "FailedToGetApiTokenError";
8651
+ }
8652
+ };
8653
+ var _ReportDigestError = class _ReportDigestError extends Error {
8654
+ constructor(message, failReason) {
8655
+ super(message);
8656
+ this.failReason = failReason;
8657
+ this.name = "ReportDigestError";
8658
+ this.failReason = failReason;
8659
+ }
8660
+ getDisplayMessage() {
8661
+ if (this.failReason?.trim()) {
8662
+ return `\u{1F575}\uFE0F\u200D\u2642\uFE0F Digesting report failed. ${this.failReason}`;
8663
+ }
8664
+ return _ReportDigestError.defaultMessage;
8665
+ }
8666
+ };
8667
+ __publicField(_ReportDigestError, "defaultMessage", "\u{1F575}\uFE0F\u200D\u2642\uFE0F Digesting report failed. Please verify that the file provided is of a valid supported report format.");
8668
+ var ReportDigestError = _ReportDigestError;
8669
+
8572
8670
  // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
8573
8671
  import Debug8 from "debug";
8574
8672
 
@@ -9092,10 +9190,10 @@ async function addFixCommentsForPr({
9092
9190
  const parsedFpRes = await FalsePositivePartsZ.parseAsync(
9093
9191
  fpRes?.getFalsePositive
9094
9192
  );
9095
- const { description: description2, contextString } = getParsedFalsePositiveMessage(parsedFpRes);
9096
- fpDescription = contextString ? `${description2}
9193
+ const { description, contextString } = getParsedFalsePositiveMessage(parsedFpRes);
9194
+ fpDescription = contextString ? `${description}
9097
9195
 
9098
- ${contextString}` : description2;
9196
+ ${contextString}` : description;
9099
9197
  }
9100
9198
  return await Promise.all(
9101
9199
  vulnerabilityReportIssue.codeNodes.map(
@@ -9674,7 +9772,10 @@ var GQLClient = class {
9674
9772
  params.subscribeToAnalysisParams,
9675
9773
  async (resolve, reject, data) => {
9676
9774
  if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
9677
- reject(new Error(`Analysis failed with id: ${data.analysis?.id}`));
9775
+ const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
9776
+ reject(
9777
+ new ReportDigestError(errorMessage, data.analysis?.failReason ?? "")
9778
+ );
9678
9779
  return;
9679
9780
  }
9680
9781
  if (callbackStates.includes(data.analysis?.state)) {
@@ -10785,23 +10886,19 @@ async function _digestReport({
10785
10886
  shouldScan
10786
10887
  }
10787
10888
  );
10788
- try {
10789
- await gqlClient.subscribeToAnalysis({
10790
- subscribeToAnalysisParams: {
10791
- analysisId: fixReportId
10792
- },
10793
- callback: () => digestSpinner.update({
10794
- text: progressMassages.processingVulnerabilityReportSuccess
10795
- }),
10796
- callbackStates: [
10797
- "Digested" /* Digested */,
10798
- "Finished" /* Finished */
10799
- ],
10800
- timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
10801
- });
10802
- } catch (e) {
10803
- throw new Error(progressMassages.processingVulnerabilityReportFailed);
10804
- }
10889
+ await gqlClient.subscribeToAnalysis({
10890
+ subscribeToAnalysisParams: {
10891
+ analysisId: fixReportId
10892
+ },
10893
+ callback: () => digestSpinner.update({
10894
+ text: progressMassages.processingVulnerabilityReportSuccess
10895
+ }),
10896
+ callbackStates: [
10897
+ "Digested" /* Digested */,
10898
+ "Finished" /* Finished */
10899
+ ],
10900
+ timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
10901
+ });
10805
10902
  const vulnFiles = await gqlClient.getVulnerabilityReportPaths(
10806
10903
  vulnerabilityReportId
10807
10904
  );
@@ -10810,8 +10907,9 @@ async function _digestReport({
10810
10907
  });
10811
10908
  return vulnFiles;
10812
10909
  } catch (e) {
10910
+ const errorMessage = e instanceof ReportDigestError ? e.getDisplayMessage() : ReportDigestError.defaultMessage;
10813
10911
  digestSpinner.error({
10814
- text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Digesting report failed. Please verify that the file provided is of a valid supported report format."
10912
+ text: errorMessage
10815
10913
  });
10816
10914
  throw e;
10817
10915
  }
@@ -11331,70 +11429,6 @@ import Configstore3 from "configstore";
11331
11429
  import { GraphQLClient as GraphQLClient2 } from "graphql-request";
11332
11430
  import open4 from "open";
11333
11431
  import { v4 as uuidv42 } from "uuid";
11334
-
11335
- // src/mcp/core/Errors.ts
11336
- var ApiConnectionError = class extends Error {
11337
- constructor(message = "Failed to connect to the API") {
11338
- super(message);
11339
- this.name = "ApiConnectionError";
11340
- }
11341
- };
11342
- var CliLoginError = class extends Error {
11343
- constructor(message = "CLI login failed") {
11344
- super(message);
11345
- this.name = "CliLoginError";
11346
- }
11347
- };
11348
- var AuthenticationError = class extends Error {
11349
- constructor(message = "Authentication failed") {
11350
- super(message);
11351
- this.name = "AuthenticationError";
11352
- }
11353
- };
11354
- var NoFilesError = class extends Error {
11355
- constructor(message = "No files to fix") {
11356
- super(message);
11357
- this.name = "NoFilesError";
11358
- }
11359
- };
11360
- var GqlClientError = class extends Error {
11361
- constructor(message = "GraphQL client not initialized") {
11362
- super(message);
11363
- this.name = "GqlClientError";
11364
- }
11365
- };
11366
- var FileProcessingError = class extends Error {
11367
- constructor(message) {
11368
- super(message);
11369
- this.name = "FileProcessingError";
11370
- }
11371
- };
11372
- var ReportInitializationError = class extends Error {
11373
- constructor(message) {
11374
- super(message);
11375
- this.name = "ReportInitializationError";
11376
- }
11377
- };
11378
- var FileUploadError = class extends Error {
11379
- constructor(message) {
11380
- super(message);
11381
- this.name = "FileUploadError";
11382
- }
11383
- };
11384
- var ScanError = class extends Error {
11385
- constructor(message) {
11386
- super(message);
11387
- this.name = "ScanError";
11388
- }
11389
- };
11390
- var FailedToGetApiTokenError = class extends Error {
11391
- constructor(message) {
11392
- super(message);
11393
- this.name = "FailedToGetApiTokenError";
11394
- }
11395
- };
11396
-
11397
- // src/mcp/services/McpGQLClient.ts
11398
11432
  var mobbConfigStore = new Configstore3(packageJson.name, { apiToken: "" });
11399
11433
  var McpGQLClient = class {
11400
11434
  constructor(args) {
@@ -11512,12 +11546,14 @@ var McpGQLClient = class {
11512
11546
  async (resolve, reject, data) => {
11513
11547
  logDebug("GraphQL: GetAnalysis subscription data received", { data });
11514
11548
  if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
11549
+ const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
11515
11550
  logError("GraphQL: Analysis failed", {
11516
11551
  analysisId: data.analysis?.id,
11517
11552
  state: data.analysis?.state,
11553
+ failReason: data.analysis?.failReason,
11518
11554
  ...this.getErrorContext()
11519
11555
  });
11520
- reject(new Error(`Analysis failed with id: ${data.analysis?.id}`));
11556
+ reject(new Error(errorMessage));
11521
11557
  return;
11522
11558
  }
11523
11559
  if (callbackStates.includes(data.analysis?.state)) {
@@ -11553,7 +11589,16 @@ var McpGQLClient = class {
11553
11589
  }
11554
11590
  async getProjectId() {
11555
11591
  try {
11556
- const projectName = "MCP Scans";
11592
+ const me = await this.getUserInfo();
11593
+ if (!me) {
11594
+ throw new Error("User not found");
11595
+ }
11596
+ const userEmail = me.email;
11597
+ if (!userEmail) {
11598
+ throw new Error("User email not found");
11599
+ }
11600
+ const shortEmailHash = crypto2.createHash("sha256").update(userEmail).digest("hex").slice(0, 8).toUpperCase();
11601
+ const projectName = `MCP Scans ${shortEmailHash}`;
11557
11602
  logDebug("GraphQL: Calling getOrgAndProjectId query", { projectName });
11558
11603
  const getOrgAndProjectIdResult = await this.clientSdk.getOrgAndProjectId({
11559
11604
  filters: {},
@@ -11638,6 +11683,20 @@ var McpGQLClient = class {
11638
11683
  return null;
11639
11684
  }
11640
11685
  }
11686
+ async _updateFixesArchiveState(fixIds) {
11687
+ if (fixIds.length > 0) {
11688
+ const resUpdate = await this.clientSdk.updateDownloadedFixData({
11689
+ fixIds,
11690
+ source: "MCP" /* Mcp */
11691
+ });
11692
+ logInfo("GraphQL: updateFixesArchiveState successful", {
11693
+ result: resUpdate,
11694
+ fixIds
11695
+ });
11696
+ } else {
11697
+ logInfo("GraphQL: No fixes found");
11698
+ }
11699
+ }
11641
11700
  async getLatestReportByRepoUrl({
11642
11701
  repoUrl,
11643
11702
  limit = 3,
@@ -11658,6 +11717,8 @@ var McpGQLClient = class {
11658
11717
  result: res,
11659
11718
  reportCount: res.fixReport?.length || 0
11660
11719
  });
11720
+ const fixIds = res.fixReport?.[0]?.fixes?.map((fix) => fix.id) || [];
11721
+ await this._updateFixesArchiveState(fixIds);
11661
11722
  return {
11662
11723
  fixReport: res.fixReport?.[0] || null,
11663
11724
  expiredReport: res.expiredReport?.[0] || null
@@ -11708,6 +11769,8 @@ var McpGQLClient = class {
11708
11769
  if (res.fixReport.length === 0) {
11709
11770
  return null;
11710
11771
  }
11772
+ const fixIds = res.fixReport?.[0]?.fixes?.map((fix) => fix.id) || [];
11773
+ await this._updateFixesArchiveState(fixIds);
11711
11774
  return {
11712
11775
  fixes: res.fixReport?.[0]?.fixes || [],
11713
11776
  totalCount: res.fixReport?.[0]?.filteredFixesCount?.aggregate?.count || 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.0.108",
3
+ "version": "1.0.110",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.js",