mobbdev 1.4.12 → 1.4.16

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.
@@ -1037,7 +1037,7 @@ var init_client_generates = __esm({
1037
1037
  }
1038
1038
  `;
1039
1039
  DigestVulnerabilityReportDocument = `
1040
- mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String, $fixReportId: String!, $projectId: String!, $scanSource: String!, $repoUrl: String, $reference: String, $sha: String) {
1040
+ mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String, $fixReportId: String!, $projectId: String!, $scanSource: String!, $repoUrl: String, $reference: String, $sha: String, $baselineCommit: String) {
1041
1041
  digestVulnerabilityReport(
1042
1042
  fixReportId: $fixReportId
1043
1043
  vulnerabilityReportFileName: $vulnerabilityReportFileName
@@ -1046,6 +1046,7 @@ var init_client_generates = __esm({
1046
1046
  repoUrl: $repoUrl
1047
1047
  reference: $reference
1048
1048
  sha: $sha
1049
+ baselineCommit: $baselineCommit
1049
1050
  ) {
1050
1051
  __typename
1051
1052
  ... on VulnerabilityReport {
@@ -1262,14 +1263,14 @@ var init_client_generates = __esm({
1262
1263
  GetLatestReportByRepoUrlDocument = `
1263
1264
  query GetLatestReportByRepoUrl($repoUrl: String!, $filters: fix_bool_exp = {}, $limit: Int!, $offset: Int!, $currentUserEmail: String!) {
1264
1265
  fixReport(
1265
- where: {_and: [{repo: {originalUrl: {_eq: $repoUrl}}}, {state: {_eq: Finished}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1266
+ where: {_and: [{repo: {originalUrl: {_ilike: $repoUrl}}}, {state: {_eq: Finished}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1266
1267
  order_by: {createdOn: desc}
1267
1268
  limit: 1
1268
1269
  ) {
1269
1270
  ...FixReportSummaryFields
1270
1271
  }
1271
1272
  expiredReport: fixReport(
1272
- where: {_and: [{repo: {originalUrl: {_eq: $repoUrl}}}, {state: {_eq: Expired}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1273
+ where: {_and: [{repo: {originalUrl: {_ilike: $repoUrl}}}, {state: {_eq: Expired}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1273
1274
  order_by: {createdOn: desc}
1274
1275
  limit: 1
1275
1276
  ) {
@@ -1577,7 +1578,7 @@ var init_analysis = __esm({
1577
1578
 
1578
1579
  // src/features/analysis/scm/shared/src/types/issue.ts
1579
1580
  import { z as z4 } from "zod";
1580
- var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES, VulnerabilityReportIssueRatingZ, VulnerabilityReportIssueSharedStateZ, BaseIssuePartsZ, FalsePositivePartsZ, IssuePartsWithFixZ, IssuePartsFpZ, GeneralIssueZ, IssuePartsZ, GetIssueIndexesZ, GetIssueScreenDataZ, IssueBucketZ, mapBucketTypeToCategory;
1581
+ var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES, VulnerabilityReportIssueRatingZ, VulnerabilityReportIssueSharedStateZ, BaseIssuePartsZ, FalsePositivePartsZ, UnfixablePartsZ, IssuePartsWithFixZ, IssuePartsFpZ, GeneralIssueZ, IssuePartsZ, GetIssueIndexesZ, GetIssueScreenDataZ, IssueBucketZ, mapBucketTypeToCategory;
1581
1582
  var init_issue = __esm({
1582
1583
  "src/features/analysis/scm/shared/src/types/issue.ts"() {
1583
1584
  "use strict";
@@ -1659,12 +1660,17 @@ var init_issue = __esm({
1659
1660
  return { codeDiff };
1660
1661
  })
1661
1662
  }).nullish(),
1662
- sharedState: VulnerabilityReportIssueSharedStateZ
1663
+ sharedState: VulnerabilityReportIssueSharedStateZ,
1664
+ unfixableId: z4.string().uuid().nullish()
1663
1665
  });
1664
1666
  FalsePositivePartsZ = z4.object({
1665
1667
  extraContext: z4.array(z4.object({ key: z4.string(), value: z4.string() })),
1666
1668
  fixDescription: z4.string()
1667
1669
  });
1670
+ UnfixablePartsZ = z4.object({
1671
+ extraContext: z4.array(z4.object({ key: z4.string(), value: z4.string() })),
1672
+ fixDescription: z4.string()
1673
+ });
1668
1674
  IssuePartsWithFixZ = BaseIssuePartsZ.merge(
1669
1675
  z4.object({
1670
1676
  category: z4.literal("Irrelevant" /* Irrelevant */),
@@ -1686,7 +1692,8 @@ var init_issue = __esm({
1686
1692
  z4.literal("Fixable" /* Fixable */),
1687
1693
  z4.literal("Filtered" /* Filtered */),
1688
1694
  z4.literal("Pending" /* Pending */)
1689
- ])
1695
+ ]),
1696
+ getUnfixable: UnfixablePartsZ.nullish()
1690
1697
  })
1691
1698
  );
1692
1699
  IssuePartsZ = z4.union([
@@ -2331,6 +2338,10 @@ var init_types = __esm({
2331
2338
  isDefault: z7.boolean().default(false),
2332
2339
  organizationId: z7.string().uuid(),
2333
2340
  vulnerabilityReports: z7.array(ProjectVulnerabilityReport),
2341
+ autoPrIncludeAiFixes: z7.preprocess(
2342
+ (val) => val === null || val === void 0 ? false : val,
2343
+ z7.boolean()
2344
+ ),
2334
2345
  projectIssueTypeSettings: z7.array(
2335
2346
  IssueTypeSettingZ.merge(z7.object({ id: z7.string() }))
2336
2347
  )
@@ -4431,6 +4442,18 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
4431
4442
 
4432
4443
  // src/utils/gitUtils.ts
4433
4444
  import simpleGit from "simple-git";
4445
+ var tag = (sink) => (data, msg) => {
4446
+ if (msg) {
4447
+ const sanitizedMsg = String(msg).replace(/\n|\r/g, "");
4448
+ sink(`[GIT] ${sanitizedMsg}`, data);
4449
+ } else {
4450
+ sink("[GIT]", data);
4451
+ }
4452
+ };
4453
+ var defaultLogger = {
4454
+ debug: tag(console.log),
4455
+ warn: tag(console.warn)
4456
+ };
4434
4457
 
4435
4458
  // src/utils/index.ts
4436
4459
  var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
@@ -7222,7 +7245,8 @@ var GQLClient = class {
7222
7245
  repoUrl,
7223
7246
  reference,
7224
7247
  sha,
7225
- shouldScan
7248
+ shouldScan,
7249
+ baselineCommit
7226
7250
  }) {
7227
7251
  const res = await this._clientSdk.DigestVulnerabilityReport({
7228
7252
  fixReportId,
@@ -7231,7 +7255,8 @@ var GQLClient = class {
7231
7255
  scanSource,
7232
7256
  repoUrl,
7233
7257
  reference,
7234
- sha
7258
+ sha,
7259
+ baselineCommit
7235
7260
  });
7236
7261
  if (res.digestVulnerabilityReport.__typename !== "VulnerabilityReport") {
7237
7262
  throw new Error("Digesting vulnerability report failed");
@@ -8148,7 +8173,7 @@ function getStableComputerName() {
8148
8173
  }
8149
8174
 
8150
8175
  // src/args/commands/upload_ai_blame.ts
8151
- var defaultLogger = {
8176
+ var defaultLogger2 = {
8152
8177
  info: (msg, data) => {
8153
8178
  if (data !== void 0) {
8154
8179
  console.log(msg, data);
@@ -8365,7 +8390,7 @@ async function uploadAiBlameHandler(options) {
8365
8390
  exitOnError = true,
8366
8391
  apiUrl,
8367
8392
  webAppUrl,
8368
- logger = defaultLogger
8393
+ logger = defaultLogger2
8369
8394
  } = options;
8370
8395
  const prompts = args.prompt || [];
8371
8396
  const inferences = args.inference || [];
package/dist/index.mjs CHANGED
@@ -1037,7 +1037,7 @@ var init_client_generates = __esm({
1037
1037
  }
1038
1038
  `;
1039
1039
  DigestVulnerabilityReportDocument = `
1040
- mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String, $fixReportId: String!, $projectId: String!, $scanSource: String!, $repoUrl: String, $reference: String, $sha: String) {
1040
+ mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String, $fixReportId: String!, $projectId: String!, $scanSource: String!, $repoUrl: String, $reference: String, $sha: String, $baselineCommit: String) {
1041
1041
  digestVulnerabilityReport(
1042
1042
  fixReportId: $fixReportId
1043
1043
  vulnerabilityReportFileName: $vulnerabilityReportFileName
@@ -1046,6 +1046,7 @@ var init_client_generates = __esm({
1046
1046
  repoUrl: $repoUrl
1047
1047
  reference: $reference
1048
1048
  sha: $sha
1049
+ baselineCommit: $baselineCommit
1049
1050
  ) {
1050
1051
  __typename
1051
1052
  ... on VulnerabilityReport {
@@ -1262,14 +1263,14 @@ var init_client_generates = __esm({
1262
1263
  GetLatestReportByRepoUrlDocument = `
1263
1264
  query GetLatestReportByRepoUrl($repoUrl: String!, $filters: fix_bool_exp = {}, $limit: Int!, $offset: Int!, $currentUserEmail: String!) {
1264
1265
  fixReport(
1265
- where: {_and: [{repo: {originalUrl: {_eq: $repoUrl}}}, {state: {_eq: Finished}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1266
+ where: {_and: [{repo: {originalUrl: {_ilike: $repoUrl}}}, {state: {_eq: Finished}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1266
1267
  order_by: {createdOn: desc}
1267
1268
  limit: 1
1268
1269
  ) {
1269
1270
  ...FixReportSummaryFields
1270
1271
  }
1271
1272
  expiredReport: fixReport(
1272
- where: {_and: [{repo: {originalUrl: {_eq: $repoUrl}}}, {state: {_eq: Expired}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1273
+ where: {_and: [{repo: {originalUrl: {_ilike: $repoUrl}}}, {state: {_eq: Expired}}, {vulnerabilityReport: {scanSource: {_neq: MCP}}}]}
1273
1274
  order_by: {createdOn: desc}
1274
1275
  limit: 1
1275
1276
  ) {
@@ -1364,8 +1365,8 @@ var init_client_generates = __esm({
1364
1365
 
1365
1366
  // src/features/analysis/scm/shared/src/getIssueType.ts
1366
1367
  import { z } from "zod";
1367
- function getTagTooltip(tag) {
1368
- switch (tag) {
1368
+ function getTagTooltip(tag2) {
1369
+ switch (tag2) {
1369
1370
  case "FALSE_POSITIVE":
1370
1371
  return "Issue was found to be a false positive";
1371
1372
  case "TEST_CODE":
@@ -1381,7 +1382,7 @@ function getTagTooltip(tag) {
1381
1382
  case "SUPPRESSED":
1382
1383
  return "Suppressed in the scan report";
1383
1384
  default:
1384
- return tag;
1385
+ return tag2;
1385
1386
  }
1386
1387
  }
1387
1388
  function replaceKeysWithValues(fixDescription, extraContext) {
@@ -1799,7 +1800,7 @@ var init_analysis = __esm({
1799
1800
 
1800
1801
  // src/features/analysis/scm/shared/src/types/issue.ts
1801
1802
  import { z as z9 } from "zod";
1802
- var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES, VulnerabilityReportIssueRatingZ, VulnerabilityReportIssueSharedStateZ, BaseIssuePartsZ, FalsePositivePartsZ, IssuePartsWithFixZ, IssuePartsFpZ, GeneralIssueZ, IssuePartsZ, GetIssueIndexesZ, GetIssueScreenDataZ, IssueBucketZ, mapCategoryToBucket, mapBucketTypeToCategory;
1803
+ var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES, VulnerabilityReportIssueRatingZ, VulnerabilityReportIssueSharedStateZ, BaseIssuePartsZ, FalsePositivePartsZ, UnfixablePartsZ, IssuePartsWithFixZ, IssuePartsFpZ, GeneralIssueZ, IssuePartsZ, GetIssueIndexesZ, GetIssueScreenDataZ, IssueBucketZ, mapCategoryToBucket, mapBucketTypeToCategory;
1803
1804
  var init_issue = __esm({
1804
1805
  "src/features/analysis/scm/shared/src/types/issue.ts"() {
1805
1806
  "use strict";
@@ -1881,12 +1882,17 @@ var init_issue = __esm({
1881
1882
  return { codeDiff };
1882
1883
  })
1883
1884
  }).nullish(),
1884
- sharedState: VulnerabilityReportIssueSharedStateZ
1885
+ sharedState: VulnerabilityReportIssueSharedStateZ,
1886
+ unfixableId: z9.string().uuid().nullish()
1885
1887
  });
1886
1888
  FalsePositivePartsZ = z9.object({
1887
1889
  extraContext: z9.array(z9.object({ key: z9.string(), value: z9.string() })),
1888
1890
  fixDescription: z9.string()
1889
1891
  });
1892
+ UnfixablePartsZ = z9.object({
1893
+ extraContext: z9.array(z9.object({ key: z9.string(), value: z9.string() })),
1894
+ fixDescription: z9.string()
1895
+ });
1890
1896
  IssuePartsWithFixZ = BaseIssuePartsZ.merge(
1891
1897
  z9.object({
1892
1898
  category: z9.literal("Irrelevant" /* Irrelevant */),
@@ -1908,7 +1914,8 @@ var init_issue = __esm({
1908
1914
  z9.literal("Fixable" /* Fixable */),
1909
1915
  z9.literal("Filtered" /* Filtered */),
1910
1916
  z9.literal("Pending" /* Pending */)
1911
- ])
1917
+ ]),
1918
+ getUnfixable: UnfixablePartsZ.nullish()
1912
1919
  })
1913
1920
  );
1914
1921
  IssuePartsZ = z9.union([
@@ -2376,6 +2383,10 @@ var init_types = __esm({
2376
2383
  isDefault: z11.boolean().default(false),
2377
2384
  organizationId: z11.string().uuid(),
2378
2385
  vulnerabilityReports: z11.array(ProjectVulnerabilityReport),
2386
+ autoPrIncludeAiFixes: z11.preprocess(
2387
+ (val) => val === null || val === void 0 ? false : val,
2388
+ z11.boolean()
2389
+ ),
2379
2390
  projectIssueTypeSettings: z11.array(
2380
2391
  IssueTypeSettingZ.merge(z11.object({ id: z11.string() }))
2381
2392
  )
@@ -4871,7 +4882,8 @@ var getCommitIssueDescription = ({
4871
4882
  vendor,
4872
4883
  issueType,
4873
4884
  irrelevantIssueWithTags,
4874
- fpDescription
4885
+ fpDescription,
4886
+ unfixableDescription
4875
4887
  }) => {
4876
4888
  const issueTypeString = getIssueTypeFriendlyString(issueType);
4877
4889
  let description = `The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
@@ -4887,7 +4899,7 @@ var getCommitIssueDescription = ({
4887
4899
 
4888
4900
 
4889
4901
  ## Justification
4890
- ${fpDescription ?? issueDescription[irrelevantIssueWithTags[0].tag]}
4902
+ ${fpDescription ?? unfixableDescription ?? issueDescription[irrelevantIssueWithTags[0].tag]}
4891
4903
  `;
4892
4904
  }
4893
4905
  const staticData = fixDetailsData[parseIssueTypeRes.data];
@@ -6909,25 +6921,18 @@ function getScmConfig({
6909
6921
  });
6910
6922
  const virtualDomain = filteredBrokerHosts[0]?.virtualDomain;
6911
6923
  const virtualUrl = virtualDomain ? `https://${virtualDomain}${urlObject.pathname}${urlObject.search}` : void 0;
6912
- const scmOrgConfig = filteredScmConfigs.find((scm) => scm.orgId && scm.token);
6913
- if (scmOrgConfig && includeOrgTokens) {
6914
- return {
6915
- id: scmOrgConfig.id,
6916
- accessToken: scmOrgConfig.token || void 0,
6917
- scmLibType: getScmLibTypeFromScmType(scmOrgConfig.scmType),
6918
- scmOrg: scmOrgConfig.scmOrg || void 0,
6919
- virtualUrl
6920
- };
6921
- }
6922
- const scmUserConfig = filteredScmConfigs.find(
6923
- (scm) => scm.userId && scm.token
6924
- );
6925
- if (scmUserConfig) {
6924
+ const matched = filteredScmConfigs.find((scm) => {
6925
+ if (!scm.token) return false;
6926
+ if (scm.userId) return true;
6927
+ if (scm.orgId) return includeOrgTokens;
6928
+ return false;
6929
+ });
6930
+ if (matched) {
6926
6931
  return {
6927
- id: scmUserConfig.id,
6928
- accessToken: scmUserConfig.token || void 0,
6929
- scmLibType: getScmLibTypeFromScmType(scmUserConfig.scmType),
6930
- scmOrg: scmUserConfig.scmOrg || void 0,
6932
+ id: matched.id,
6933
+ accessToken: matched.token || void 0,
6934
+ scmLibType: getScmLibTypeFromScmType(matched.scmType),
6935
+ scmOrg: matched.scmOrg || void 0,
6931
6936
  virtualUrl
6932
6937
  };
6933
6938
  }
@@ -9631,12 +9636,12 @@ function getGithubSdk(params = {}) {
9631
9636
  });
9632
9637
  },
9633
9638
  async getTagDate({
9634
- tag,
9639
+ tag: tag2,
9635
9640
  owner,
9636
9641
  repo
9637
9642
  }) {
9638
9643
  const refResponse = await octokit.rest.git.getRef({
9639
- ref: `tags/${tag}`,
9644
+ ref: `tags/${tag2}`,
9640
9645
  owner,
9641
9646
  repo
9642
9647
  });
@@ -10655,7 +10660,11 @@ var GithubSCMLib = class extends SCMLib {
10655
10660
  }
10656
10661
  const aDate = a.repoUpdatedAt ? Date.parse(a.repoUpdatedAt) : 0;
10657
10662
  const bDate = b.repoUpdatedAt ? Date.parse(b.repoUpdatedAt) : 0;
10658
- return (aDate - bDate) * sortOrder;
10663
+ const dateCmp = (aDate - bDate) * sortOrder;
10664
+ if (dateCmp !== 0) {
10665
+ return dateCmp;
10666
+ }
10667
+ return a.repoName.localeCompare(b.repoName) * sortOrder;
10659
10668
  });
10660
10669
  const limit = params.limit || 10;
10661
10670
  const offset = parseCursorSafe(params.cursor, 0);
@@ -12268,22 +12277,24 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
12268
12277
 
12269
12278
  // src/utils/gitUtils.ts
12270
12279
  import simpleGit2 from "simple-git";
12271
- var defaultLogger = {
12272
- info: (data, msg) => {
12273
- if (msg) {
12274
- const sanitizedMsg = String(msg).replace(/\n|\r/g, "");
12275
- console.log(`[GIT] ${sanitizedMsg}`, data);
12276
- } else {
12277
- console.log("[GIT]", data);
12278
- }
12280
+ var tag = (sink) => (data, msg) => {
12281
+ if (msg) {
12282
+ const sanitizedMsg = String(msg).replace(/\n|\r/g, "");
12283
+ sink(`[GIT] ${sanitizedMsg}`, data);
12284
+ } else {
12285
+ sink("[GIT]", data);
12279
12286
  }
12280
12287
  };
12288
+ var defaultLogger = {
12289
+ debug: tag(console.log),
12290
+ warn: tag(console.warn)
12291
+ };
12281
12292
  function createGitWithLogging(dirName, logger3 = defaultLogger) {
12282
12293
  return simpleGit2(dirName, {
12283
12294
  maxConcurrentProcesses: 6
12284
12295
  }).outputHandler((bin, stdout2, stderr2) => {
12285
12296
  const callID = Math.random();
12286
- logger3.info({ callID, bin }, "Start git CLI call");
12297
+ logger3.debug({ callID, bin }, "Start git CLI call");
12287
12298
  let errChunks = [];
12288
12299
  let outChunks = [];
12289
12300
  let isStdoutDone = false;
@@ -12304,7 +12315,7 @@ function createGitWithLogging(dirName, logger3 = defaultLogger) {
12304
12315
  err: `${errChunks.join("").slice(0, 200)}...`,
12305
12316
  out: `${outChunks.join("").slice(0, 200)}...`
12306
12317
  };
12307
- logger3.info(logObj, "git log output");
12318
+ logger3.debug(logObj, "git log output");
12308
12319
  stderr2.removeListener("data", onStderrData);
12309
12320
  stdout2.removeListener("data", onStdoutData);
12310
12321
  errChunks = [];
@@ -12318,11 +12329,11 @@ function createGitWithLogging(dirName, logger3 = defaultLogger) {
12318
12329
  stderr2.on("close", () => markDone("stderr"));
12319
12330
  stdout2.on("close", () => markDone("stdout"));
12320
12331
  stderr2.on("error", (error) => {
12321
- logger3.info({ callID, error: String(error) }, "git stderr stream error");
12332
+ logger3.warn({ callID, error: String(error) }, "git stderr stream error");
12322
12333
  markDone("stderr");
12323
12334
  });
12324
12335
  stdout2.on("error", (error) => {
12325
- logger3.info({ callID, error: String(error) }, "git stdout stream error");
12336
+ logger3.warn({ callID, error: String(error) }, "git stdout stream error");
12326
12337
  markDone("stdout");
12327
12338
  });
12328
12339
  });
@@ -12340,15 +12351,15 @@ import sax from "sax";
12340
12351
  var BaseStreamParser = class {
12341
12352
  constructor(parser) {
12342
12353
  __publicField(this, "currentPath", []);
12343
- parser.on("opentag", (tag) => this.onOpenTag(tag));
12354
+ parser.on("opentag", (tag2) => this.onOpenTag(tag2));
12344
12355
  parser.on("closetag", () => this.onCloseTag());
12345
12356
  parser.on("text", (text) => this.onText(text));
12346
12357
  }
12347
12358
  getPathString() {
12348
12359
  return this.currentPath.join(" > ");
12349
12360
  }
12350
- onOpenTag(tag) {
12351
- this.currentPath.push(tag.name);
12361
+ onOpenTag(tag2) {
12362
+ this.currentPath.push(tag2.name);
12352
12363
  }
12353
12364
  onCloseTag() {
12354
12365
  this.currentPath.pop();
@@ -12361,12 +12372,12 @@ var AuditMetadataParser = class extends BaseStreamParser {
12361
12372
  super(...arguments);
12362
12373
  __publicField(this, "suppressedMap", {});
12363
12374
  }
12364
- onOpenTag(tag) {
12365
- super.onOpenTag(tag);
12375
+ onOpenTag(tag2) {
12376
+ super.onOpenTag(tag2);
12366
12377
  switch (this.getPathString()) {
12367
12378
  case "Audit > IssueList > Issue":
12368
- this.suppressedMap[String(tag.attributes["instanceId"] ?? "")] = String(
12369
- tag.attributes["suppressed"] ?? ""
12379
+ this.suppressedMap[String(tag2.attributes["instanceId"] ?? "")] = String(
12380
+ tag2.attributes["suppressed"] ?? ""
12370
12381
  );
12371
12382
  break;
12372
12383
  }
@@ -12385,18 +12396,18 @@ var ReportMetadataParser = class extends BaseStreamParser {
12385
12396
  __publicField(this, "ruleId", "");
12386
12397
  __publicField(this, "groupName", "");
12387
12398
  }
12388
- onOpenTag(tag) {
12389
- super.onOpenTag(tag);
12399
+ onOpenTag(tag2) {
12400
+ super.onOpenTag(tag2);
12390
12401
  switch (this.getPathString()) {
12391
12402
  case "FVDL > EngineData > RuleInfo > Rule":
12392
- this.ruleId = String(tag.attributes["id"] ?? "");
12403
+ this.ruleId = String(tag2.attributes["id"] ?? "");
12393
12404
  break;
12394
12405
  case "FVDL > EngineData > RuleInfo > Rule > MetaInfo > Group":
12395
- this.groupName = String(tag.attributes["name"] ?? "");
12406
+ this.groupName = String(tag2.attributes["name"] ?? "");
12396
12407
  break;
12397
12408
  case "FVDL > CreatedTS":
12398
- this.createdTSDate = String(tag.attributes["date"] ?? "");
12399
- this.createdTSTime = String(tag.attributes["time"] ?? "");
12409
+ this.createdTSDate = String(tag2.attributes["date"] ?? "");
12410
+ this.createdTSTime = String(tag2.attributes["time"] ?? "");
12400
12411
  break;
12401
12412
  }
12402
12413
  }
@@ -12429,19 +12440,19 @@ var UnifiedNodePoolParser = class extends BaseStreamParser {
12429
12440
  __publicField(this, "codePoints", {});
12430
12441
  __publicField(this, "nodeId", "");
12431
12442
  }
12432
- onOpenTag(tag) {
12433
- super.onOpenTag(tag);
12443
+ onOpenTag(tag2) {
12444
+ super.onOpenTag(tag2);
12434
12445
  switch (this.getPathString()) {
12435
12446
  case "FVDL > UnifiedNodePool > Node":
12436
- this.nodeId = String(tag.attributes["id"] ?? "");
12447
+ this.nodeId = String(tag2.attributes["id"] ?? "");
12437
12448
  break;
12438
12449
  case "FVDL > UnifiedNodePool > Node > SourceLocation":
12439
12450
  this.codePoints[this.nodeId] = {
12440
- path: String(tag.attributes["path"] ?? ""),
12441
- colStart: String(tag.attributes["colStart"] ?? ""),
12442
- colEnd: String(tag.attributes["colEnd"] ?? ""),
12443
- line: String(tag.attributes["line"] ?? ""),
12444
- lineEnd: String(tag.attributes["lineEnd"] ?? "")
12451
+ path: String(tag2.attributes["path"] ?? ""),
12452
+ colStart: String(tag2.attributes["colStart"] ?? ""),
12453
+ colEnd: String(tag2.attributes["colEnd"] ?? ""),
12454
+ line: String(tag2.attributes["line"] ?? ""),
12455
+ lineEnd: String(tag2.attributes["lineEnd"] ?? "")
12445
12456
  };
12446
12457
  break;
12447
12458
  }
@@ -12463,8 +12474,8 @@ var VulnerabilityParser = class extends BaseStreamParser {
12463
12474
  this.tmpStorageFilePath = tmpStorageFilePath;
12464
12475
  this.tmpStorageFileWriter = fs5.createWriteStream(tmpStorageFilePath);
12465
12476
  }
12466
- onOpenTag(tag) {
12467
- super.onOpenTag(tag);
12477
+ onOpenTag(tag2) {
12478
+ super.onOpenTag(tag2);
12468
12479
  switch (this.getPathString()) {
12469
12480
  case "FVDL > Vulnerabilities > Vulnerability":
12470
12481
  this.isInVulnerability = true;
@@ -12473,21 +12484,21 @@ var VulnerabilityParser = class extends BaseStreamParser {
12473
12484
  this.codePoints = [];
12474
12485
  break;
12475
12486
  case "FVDL > Vulnerabilities > Vulnerability > InstanceInfo > MetaInfo > Group":
12476
- this.groupName = String(tag.attributes["name"] ?? "");
12487
+ this.groupName = String(tag2.attributes["name"] ?? "");
12477
12488
  break;
12478
12489
  }
12479
12490
  if (this.isInVulnerability) {
12480
12491
  if (this.getPathString().endsWith(" > Entry > Node > SourceLocation")) {
12481
12492
  this.codePoints.push({
12482
- path: String(tag.attributes["path"] ?? ""),
12483
- colStart: String(tag.attributes["colStart"] ?? ""),
12484
- colEnd: String(tag.attributes["colEnd"] ?? ""),
12485
- line: String(tag.attributes["line"] ?? ""),
12486
- lineEnd: String(tag.attributes["lineEnd"] ?? "")
12493
+ path: String(tag2.attributes["path"] ?? ""),
12494
+ colStart: String(tag2.attributes["colStart"] ?? ""),
12495
+ colEnd: String(tag2.attributes["colEnd"] ?? ""),
12496
+ line: String(tag2.attributes["line"] ?? ""),
12497
+ lineEnd: String(tag2.attributes["lineEnd"] ?? "")
12487
12498
  });
12488
12499
  } else if (this.getPathString().endsWith(" > Entry > NodeRef")) {
12489
12500
  this.codePoints.push({
12490
- id: String(tag.attributes["id"] ?? "")
12501
+ id: String(tag2.attributes["id"] ?? "")
12491
12502
  });
12492
12503
  }
12493
12504
  }
@@ -12964,6 +12975,12 @@ var convertToSarifCodePathPatternsOption = {
12964
12975
  type: "string",
12965
12976
  array: true
12966
12977
  };
12978
+ var baselineCommitOption = {
12979
+ describe: chalk2.bold(
12980
+ "Only report findings introduced since this commit (PR mode). The sha must be reachable from the scanned repository \u2014 unreachable baselines fail the scan loudly. Effective only when no scan file is provided."
12981
+ ),
12982
+ type: "string"
12983
+ };
12967
12984
  var pollingOption = {
12968
12985
  describe: chalk2.bold(
12969
12986
  "Use HTTP polling instead of WebSocket for status updates. Useful for proxy environments or firewalls that block WebSocket connections. Polling interval: 5 seconds, timeout: 30 minutes."
@@ -13615,7 +13632,8 @@ var GQLClient = class {
13615
13632
  repoUrl,
13616
13633
  reference,
13617
13634
  sha,
13618
- shouldScan
13635
+ shouldScan,
13636
+ baselineCommit
13619
13637
  }) {
13620
13638
  const res = await this._clientSdk.DigestVulnerabilityReport({
13621
13639
  fixReportId,
@@ -13624,7 +13642,8 @@ var GQLClient = class {
13624
13642
  scanSource,
13625
13643
  repoUrl,
13626
13644
  reference,
13627
- sha
13645
+ sha,
13646
+ baselineCommit
13628
13647
  });
13629
13648
  if (res.digestVulnerabilityReport.__typename !== "VulnerabilityReport") {
13630
13649
  throw new Error("Digesting vulnerability report failed");
@@ -16038,10 +16057,10 @@ function createFork({ args, processPath, name }, options) {
16038
16057
  });
16039
16058
  return createChildProcess({ childProcess: child, name }, options);
16040
16059
  }
16041
- function createSpawn({ args, processPath, name, cwd }, options) {
16060
+ function createSpawn({ args, processPath, name, cwd, env: env3 }, options) {
16042
16061
  const child = cp.spawn(processPath, args, {
16043
16062
  stdio: ["inherit", "pipe", "pipe", "ipc"],
16044
- env: { ...process2.env },
16063
+ env: { ...process2.env, ...env3 },
16045
16064
  cwd
16046
16065
  });
16047
16066
  return createChildProcess({ childProcess: child, name }, options);
@@ -16496,7 +16515,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
16496
16515
  createOnePr,
16497
16516
  commitDirectly,
16498
16517
  pullRequest,
16499
- polling
16518
+ polling,
16519
+ baselineCommit
16500
16520
  } = params;
16501
16521
  debug21("start %s %s", dirname, repo);
16502
16522
  const { createSpinner: createSpinner5 } = Spinner2({ ci });
@@ -16613,7 +16633,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
16613
16633
  sha,
16614
16634
  reference,
16615
16635
  shouldScan,
16616
- polling
16636
+ polling,
16637
+ // Only meaningful when opengrep is going to run (no user-supplied report).
16638
+ baselineCommit: shouldScan ? baselineCommit : void 0
16617
16639
  });
16618
16640
  uploadReportSpinner.success({ text: "\u{1F4C1} Report uploaded successfully" });
16619
16641
  const mobbSpinner = createSpinner5("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
@@ -16756,7 +16778,11 @@ async function _scan(params, { skipPrompts = false } = {}) {
16756
16778
  command,
16757
16779
  ci,
16758
16780
  shouldScan: shouldScan2,
16759
- polling
16781
+ polling,
16782
+ // shouldScan is false here (user provided a report); baseline filter
16783
+ // only applies to the opengrep code path. Drop it to keep the contract
16784
+ // honest with the CLI help text.
16785
+ baselineCommit: void 0
16760
16786
  });
16761
16787
  const res = await _zipAndUploadRepo({
16762
16788
  srcPath,
@@ -16780,7 +16806,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
16780
16806
  command,
16781
16807
  ci,
16782
16808
  shouldScan: shouldScan2,
16783
- polling
16809
+ polling,
16810
+ baselineCommit
16784
16811
  });
16785
16812
  }
16786
16813
  const mobbSpinner2 = createSpinner5("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
@@ -16875,7 +16902,8 @@ async function _digestReport({
16875
16902
  sha,
16876
16903
  reference,
16877
16904
  shouldScan,
16878
- polling
16905
+ polling,
16906
+ baselineCommit
16879
16907
  }) {
16880
16908
  const digestSpinner = createSpinner4(
16881
16909
  progressMassages.processingVulnerabilityReport
@@ -16889,7 +16917,8 @@ async function _digestReport({
16889
16917
  repoUrl,
16890
16918
  sha,
16891
16919
  reference,
16892
- shouldScan
16920
+ shouldScan,
16921
+ baselineCommit
16893
16922
  }
16894
16923
  );
16895
16924
  const callbackStates = [
@@ -17139,7 +17168,8 @@ async function analyze({
17139
17168
  createOnePr,
17140
17169
  commitDirectly,
17141
17170
  pullRequest,
17142
- polling
17171
+ polling,
17172
+ baselineCommit
17143
17173
  }, { skipPrompts = false } = {}) {
17144
17174
  !ci && await showWelcomeMessage(skipPrompts);
17145
17175
  await runAnalysis(
@@ -17158,7 +17188,8 @@ async function analyze({
17158
17188
  commitDirectly,
17159
17189
  pullRequest,
17160
17190
  createOnePr,
17161
- polling
17191
+ polling,
17192
+ baselineCommit
17162
17193
  },
17163
17194
  { skipPrompts }
17164
17195
  );
@@ -17368,9 +17399,12 @@ function analyzeBuilder(yargs2) {
17368
17399
  describe: chalk10.bold("Number of the pull request"),
17369
17400
  type: "number",
17370
17401
  demandOption: false
17371
- }).option("polling", pollingOption).example(
17402
+ }).option("polling", pollingOption).option("baseline-commit", baselineCommitOption).example(
17372
17403
  "npx mobbdev@latest analyze -r https://github.com/WebGoat/WebGoat -f <your_vulnerability_report_path>",
17373
17404
  "analyze an existing repository"
17405
+ ).example(
17406
+ "npx mobbdev@latest analyze -r https://github.com/org/repo --baseline-commit <sha>",
17407
+ "analyze only findings introduced since <sha> (PR-mode scan)"
17374
17408
  ).help();
17375
17409
  }
17376
17410
  function validateAnalyzeOptions(argv) {
@@ -19369,7 +19403,7 @@ function createLogger(config2) {
19369
19403
 
19370
19404
  // src/features/claude_code/hook_logger.ts
19371
19405
  var DD_RUM_TOKEN = true ? "pubf59c0182545bfb4c299175119f1abf9b" : "";
19372
- var CLI_VERSION = true ? "1.4.12" : "unknown";
19406
+ var CLI_VERSION = true ? "1.4.16" : "unknown";
19373
19407
  var NAMESPACE = "mobbdev-claude-code-hook-logs";
19374
19408
  var claudeCodeVersion;
19375
19409
  function buildDdTags() {
@@ -21435,8 +21469,9 @@ var McpGQLClient = class extends GQLClient {
21435
21469
  codeNodes: { path: { _in: fileFilter } }
21436
21470
  };
21437
21471
  }
21472
+ const escapedRepoUrl = repoUrl.replace(/[%_\\]/g, (c) => `\\${c}`);
21438
21473
  const resp = await this._clientSdk.GetLatestReportByRepoUrl({
21439
- repoUrl,
21474
+ repoUrl: escapedRepoUrl,
21440
21475
  limit,
21441
21476
  offset,
21442
21477
  currentUserEmail,
@@ -25920,7 +25955,7 @@ var LocalMobbFolderService = class {
25920
25955
  if (fix.vulnerabilityReportIssues.length > 0) {
25921
25956
  fix.vulnerabilityReportIssues.forEach((issue) => {
25922
25957
  if (issue.vulnerabilityReportIssueTags && issue.vulnerabilityReportIssueTags.length > 0) {
25923
- markdown += `**Tags:** ${issue.vulnerabilityReportIssueTags.map((tag) => tag.vulnerability_report_issue_tag_value).join(", ")}
25958
+ markdown += `**Tags:** ${issue.vulnerabilityReportIssueTags.map((tag2) => tag2.vulnerability_report_issue_tag_value).join(", ")}
25924
25959
 
25925
25960
  `;
25926
25961
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.4.12",
3
+ "version": "1.4.16",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.mjs",
@@ -17,10 +17,12 @@
17
17
  "test:mcp:watch": "vitest watch __tests__/mcp/",
18
18
  "test:mcp:verbose": "pnpm run build && NODE_ENV=test VERBOSE=true vitest run __tests__/mcp/",
19
19
  "test:mcp:all": "pnpm run test:unit:mcp && pnpm run test:integration:mcp && pnpm run test:e2e:mcp",
20
- "test:unit": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --exclude='**/__tests__/integration.test.ts' --exclude='**/__tests__/integration.mcp.test.ts' --exclude='**/__tests__/mcp/**'",
21
- "test:unit:ci": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --bail=1 --exclude='**/__tests__/integration.test.ts' --exclude='**/__tests__/integration.mcp.test.ts' --exclude='**/__tests__/mcp/**'",
20
+ "test:unit": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --exclude='**/__tests__/integration.test.ts' --exclude='**/__tests__/integration.mcp.test.ts' --exclude='**/__tests__/integration.baseline-commit.test.ts' --exclude='**/__tests__/mcp/**'",
21
+ "test:unit:ci": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --bail=1 --exclude='**/__tests__/integration.test.ts' --exclude='**/__tests__/integration.mcp.test.ts' --exclude='**/__tests__/integration.baseline-commit.test.ts' --exclude='**/__tests__/mcp/**'",
22
22
  "test:integration": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --sequence.concurrent=false false __tests__/integration.test.ts",
23
23
  "test:integration:ci": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --bail=1 --sequence.concurrent=false false __tests__/integration.test.ts",
24
+ "test:integration:baseline-commit": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --sequence.concurrent=false false __tests__/integration.baseline-commit.test.ts",
25
+ "test:integration:baseline-commit:proxy": "GIT_PROXY_HOST=http://tinyproxy:8888 HTTP_PROXY=http://localhost:8888 API_URL=http://app-api:8080/v1/graphql TOKEN=$(../../scripts/login_auth0.sh) vitest run --bail=1 --sequence.concurrent=false false __tests__/integration.baseline-commit.test.ts",
24
26
  "test:integration:mcp": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --sequence.concurrent=false false __tests__/integration.mcp.test.ts",
25
27
  "test:integration:mcp:ci": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest run --bail=1 --sequence.concurrent=false false __tests__/integration.mcp.test.ts",
26
28
  "test:integration:watch": "GIT_PROXY_HOST=http://tinyproxy:8888 TOKEN=$(../../scripts/login_auth0.sh) vitest watch run __tests__/integration.test.ts",
@@ -135,6 +137,7 @@
135
137
  "@typescript-eslint/parser": "7.17.0",
136
138
  "@vitest/coverage-v8": "3.2.4",
137
139
  "@vitest/ui": "3.2.4",
140
+ "dotenv-cli": "10.0.0",
138
141
  "eslint": "8.57.0",
139
142
  "eslint-plugin-graphql": "4.0.0",
140
143
  "eslint-plugin-import": "2.32.0",