mobbdev 1.4.62 → 1.4.66

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.
@@ -261,6 +261,7 @@ var init_client_generates = __esm({
261
261
  Scan_Source_Enum2["CiJenkins"] = "CI_JENKINS";
262
262
  Scan_Source_Enum2["CiUnknown"] = "CI_UNKNOWN";
263
263
  Scan_Source_Enum2["Cli"] = "CLI";
264
+ Scan_Source_Enum2["GithubPrCheck"] = "GITHUB_PR_CHECK";
264
265
  Scan_Source_Enum2["Mcp"] = "MCP";
265
266
  Scan_Source_Enum2["WebUiCheckmarxIntegration"] = "WEB_UI_CHECKMARX_INTEGRATION";
266
267
  Scan_Source_Enum2["WebUiFixOwnCode"] = "WEB_UI_FIX_OWN_CODE";
@@ -1484,6 +1485,11 @@ var init_analysis = __esm({
1484
1485
  createdOn: z3.string(),
1485
1486
  state: z3.enum(Fix_Report_State_Enum),
1486
1487
  isFixEnabled: z3.boolean().nullish(),
1488
+ // When this report's fixes expire(d). Nullish because the column is, and
1489
+ // because the issue screen reads it only to date the "fixes expired"
1490
+ // messaging — a missing date degrades to the undated wording rather than
1491
+ // failing the parse (MOBB-3769).
1492
+ expirationOn: z3.string().nullish(),
1487
1493
  repo: z3.object({
1488
1494
  name: z3.string().nullable(),
1489
1495
  originalUrl: z3.string(),
@@ -1578,7 +1584,10 @@ var init_issue = __esm({
1578
1584
  })
1579
1585
  }).transform(async ({ sourceCodeFile }) => {
1580
1586
  const { url } = sourceCodeFile.signedFile;
1581
- const sourceCodeRes = await fetch(url);
1587
+ const sourceCodeRes = await fetch(url).catch(() => null);
1588
+ if (!sourceCodeRes?.ok) {
1589
+ return null;
1590
+ }
1582
1591
  if (Number(sourceCodeRes.headers.get("Content-Length")) > MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES) {
1583
1592
  return null;
1584
1593
  }
@@ -1589,16 +1598,40 @@ var init_issue = __esm({
1589
1598
  })
1590
1599
  ).transform((nodes) => nodes.filter((node) => node !== null)),
1591
1600
  fix: FixPartsForFixScreenZ.nullish(),
1601
+ // Null when the diff cannot actually be read, not merely when the row is
1602
+ // absent. The `vulnerability_report_issue_node_diff_file_id` column outlives
1603
+ // the object it points at — only code-node rows are GC'd — and `getFile`
1604
+ // signs a URL without checking existence, so a fixes-expired report hands
1605
+ // back a perfectly valid URL for an object the lifecycle already swept.
1606
+ //
1607
+ // Treating the row as proof of the object put an empty box under "The issue
1608
+ // was reported in the following locations:", because the renderer took the
1609
+ // diff branch and had nothing to draw. Collapsing to null falls back to the
1610
+ // locations list, which is the honest thing to show. Same rule as the
1611
+ // snippet reader: an id is not evidence a file exists.
1592
1612
  vulnerabilityReportIssueNodeDiffFile: z4.object({
1593
1613
  signedFile: z4.object({
1594
1614
  url: z4.string()
1595
- }).transform(async ({ url }) => {
1596
- const codeDiff = await fetch(url).then((res) => res.text());
1597
- return { codeDiff };
1598
1615
  })
1599
- }).nullish(),
1616
+ }).nullish().transform(async (nodeDiffFile) => {
1617
+ if (!nodeDiffFile) {
1618
+ return nodeDiffFile;
1619
+ }
1620
+ const response = await fetch(nodeDiffFile.signedFile.url).catch(
1621
+ () => null
1622
+ );
1623
+ if (!response?.ok) {
1624
+ return null;
1625
+ }
1626
+ return { signedFile: { codeDiff: await response.text() } };
1627
+ }),
1600
1628
  sharedState: VulnerabilityReportIssueSharedStateZ,
1601
- unfixableId: z4.guid().nullish()
1629
+ unfixableId: z4.guid().nullish(),
1630
+ // The DB link to the fix, which outlives the fix's S3 artifacts. Non-null
1631
+ // means "this issue had a fix" even when `fix` above is absent because the
1632
+ // report's fixes expired, and that distinction is what keeps such an issue
1633
+ // from being rendered as if it were never fixable (MOBB-3769).
1634
+ fixId: z4.guid().nullish()
1602
1635
  });
1603
1636
  FalsePositivePartsZ = z4.object({
1604
1637
  extraContext: z4.array(z4.object({ key: z4.string(), value: z4.string() })),
@@ -1618,7 +1651,13 @@ var init_issue = __esm({
1618
1651
  z4.object({
1619
1652
  category: z4.literal("FalsePositive" /* FalsePositive */),
1620
1653
  fpId: z4.guid(),
1621
- getFalsePositive: FalsePositivePartsZ
1654
+ // Nullish, like getUnfixable on GeneralIssueZ, because the explanation can
1655
+ // genuinely be absent: the analyzer's pickle dies with the report's fixes,
1656
+ // and issues processed before the persistent store existed (MOBB-3768)
1657
+ // have nothing to fall back to. This used to be required, so the
1658
+ // resolver's error member failed the parse and took down the entire issue
1659
+ // screen instead of rendering one "explanation unavailable" accordion.
1660
+ getFalsePositive: FalsePositivePartsZ.nullish()
1622
1661
  }).shape
1623
1662
  );
1624
1663
  GeneralIssueZ = BaseIssuePartsZ.extend(
@@ -2001,6 +2040,10 @@ var init_types = __esm({
2001
2040
  severityText: z7.enum(Vulnerability_Severity_Enum),
2002
2041
  vulnerabilityReportIssues: z7.array(
2003
2042
  z7.object({
2043
+ // The row's reroute target once fixes expire: a fix's own page cannot
2044
+ // render without its S3 patch, so the fixable bucket points the row
2045
+ // at this issue instead (MOBB-3769).
2046
+ id: z7.guid(),
2004
2047
  issueType: z7.string(),
2005
2048
  issueLanguage: z7.string(),
2006
2049
  sharedState: IssueSharedStateZ2
@@ -2145,7 +2188,11 @@ var init_types = __esm({
2145
2188
  email: z7.string()
2146
2189
  }).nullable(),
2147
2190
  state: z7.enum(Fix_Report_State_Enum),
2148
- expirationOn: z7.string()
2191
+ expirationOn: z7.string(),
2192
+ // Whether this org has fixes at all. Scan-only reports hit the same
2193
+ // expiry date as every other report, so the list needs this to avoid
2194
+ // badging them for fixes they never had (MOBB-3769).
2195
+ isFixEnabled: z7.boolean()
2149
2196
  })
2150
2197
  });
2151
2198
  GetProjectsQueryZ = z7.object({
package/dist/index.mjs CHANGED
@@ -261,6 +261,7 @@ var init_client_generates = __esm({
261
261
  Scan_Source_Enum2["CiJenkins"] = "CI_JENKINS";
262
262
  Scan_Source_Enum2["CiUnknown"] = "CI_UNKNOWN";
263
263
  Scan_Source_Enum2["Cli"] = "CLI";
264
+ Scan_Source_Enum2["GithubPrCheck"] = "GITHUB_PR_CHECK";
264
265
  Scan_Source_Enum2["Mcp"] = "MCP";
265
266
  Scan_Source_Enum2["WebUiCheckmarxIntegration"] = "WEB_UI_CHECKMARX_INTEGRATION";
266
267
  Scan_Source_Enum2["WebUiFixOwnCode"] = "WEB_UI_FIX_OWN_CODE";
@@ -1589,6 +1590,11 @@ var init_analysis = __esm({
1589
1590
  createdOn: z4.string(),
1590
1591
  state: z4.enum(Fix_Report_State_Enum),
1591
1592
  isFixEnabled: z4.boolean().nullish(),
1593
+ // When this report's fixes expire(d). Nullish because the column is, and
1594
+ // because the issue screen reads it only to date the "fixes expired"
1595
+ // messaging — a missing date degrades to the undated wording rather than
1596
+ // failing the parse (MOBB-3769).
1597
+ expirationOn: z4.string().nullish(),
1592
1598
  repo: z4.object({
1593
1599
  name: z4.string().nullable(),
1594
1600
  originalUrl: z4.string(),
@@ -1683,7 +1689,10 @@ var init_issue = __esm({
1683
1689
  })
1684
1690
  }).transform(async ({ sourceCodeFile }) => {
1685
1691
  const { url } = sourceCodeFile.signedFile;
1686
- const sourceCodeRes = await fetch(url);
1692
+ const sourceCodeRes = await fetch(url).catch(() => null);
1693
+ if (!sourceCodeRes?.ok) {
1694
+ return null;
1695
+ }
1687
1696
  if (Number(sourceCodeRes.headers.get("Content-Length")) > MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES) {
1688
1697
  return null;
1689
1698
  }
@@ -1694,16 +1703,40 @@ var init_issue = __esm({
1694
1703
  })
1695
1704
  ).transform((nodes) => nodes.filter((node) => node !== null)),
1696
1705
  fix: FixPartsForFixScreenZ.nullish(),
1706
+ // Null when the diff cannot actually be read, not merely when the row is
1707
+ // absent. The `vulnerability_report_issue_node_diff_file_id` column outlives
1708
+ // the object it points at — only code-node rows are GC'd — and `getFile`
1709
+ // signs a URL without checking existence, so a fixes-expired report hands
1710
+ // back a perfectly valid URL for an object the lifecycle already swept.
1711
+ //
1712
+ // Treating the row as proof of the object put an empty box under "The issue
1713
+ // was reported in the following locations:", because the renderer took the
1714
+ // diff branch and had nothing to draw. Collapsing to null falls back to the
1715
+ // locations list, which is the honest thing to show. Same rule as the
1716
+ // snippet reader: an id is not evidence a file exists.
1697
1717
  vulnerabilityReportIssueNodeDiffFile: z5.object({
1698
1718
  signedFile: z5.object({
1699
1719
  url: z5.string()
1700
- }).transform(async ({ url }) => {
1701
- const codeDiff = await fetch(url).then((res) => res.text());
1702
- return { codeDiff };
1703
1720
  })
1704
- }).nullish(),
1721
+ }).nullish().transform(async (nodeDiffFile) => {
1722
+ if (!nodeDiffFile) {
1723
+ return nodeDiffFile;
1724
+ }
1725
+ const response = await fetch(nodeDiffFile.signedFile.url).catch(
1726
+ () => null
1727
+ );
1728
+ if (!response?.ok) {
1729
+ return null;
1730
+ }
1731
+ return { signedFile: { codeDiff: await response.text() } };
1732
+ }),
1705
1733
  sharedState: VulnerabilityReportIssueSharedStateZ,
1706
- unfixableId: z5.guid().nullish()
1734
+ unfixableId: z5.guid().nullish(),
1735
+ // The DB link to the fix, which outlives the fix's S3 artifacts. Non-null
1736
+ // means "this issue had a fix" even when `fix` above is absent because the
1737
+ // report's fixes expired, and that distinction is what keeps such an issue
1738
+ // from being rendered as if it were never fixable (MOBB-3769).
1739
+ fixId: z5.guid().nullish()
1707
1740
  });
1708
1741
  FalsePositivePartsZ = z5.object({
1709
1742
  extraContext: z5.array(z5.object({ key: z5.string(), value: z5.string() })),
@@ -1723,7 +1756,13 @@ var init_issue = __esm({
1723
1756
  z5.object({
1724
1757
  category: z5.literal("FalsePositive" /* FalsePositive */),
1725
1758
  fpId: z5.guid(),
1726
- getFalsePositive: FalsePositivePartsZ
1759
+ // Nullish, like getUnfixable on GeneralIssueZ, because the explanation can
1760
+ // genuinely be absent: the analyzer's pickle dies with the report's fixes,
1761
+ // and issues processed before the persistent store existed (MOBB-3768)
1762
+ // have nothing to fall back to. This used to be required, so the
1763
+ // resolver's error member failed the parse and took down the entire issue
1764
+ // screen instead of rendering one "explanation unavailable" accordion.
1765
+ getFalsePositive: FalsePositivePartsZ.nullish()
1727
1766
  }).shape
1728
1767
  );
1729
1768
  GeneralIssueZ = BaseIssuePartsZ.extend(
@@ -2048,6 +2087,10 @@ var init_types = __esm({
2048
2087
  severityText: z7.enum(Vulnerability_Severity_Enum),
2049
2088
  vulnerabilityReportIssues: z7.array(
2050
2089
  z7.object({
2090
+ // The row's reroute target once fixes expire: a fix's own page cannot
2091
+ // render without its S3 patch, so the fixable bucket points the row
2092
+ // at this issue instead (MOBB-3769).
2093
+ id: z7.guid(),
2051
2094
  issueType: z7.string(),
2052
2095
  issueLanguage: z7.string(),
2053
2096
  sharedState: IssueSharedStateZ2
@@ -2192,7 +2235,11 @@ var init_types = __esm({
2192
2235
  email: z7.string()
2193
2236
  }).nullable(),
2194
2237
  state: z7.enum(Fix_Report_State_Enum),
2195
- expirationOn: z7.string()
2238
+ expirationOn: z7.string(),
2239
+ // Whether this org has fixes at all. Scan-only reports hit the same
2240
+ // expiry date as every other report, so the list needs this to avoid
2241
+ // badging them for fixes they never had (MOBB-3769).
2242
+ isFixEnabled: z7.boolean()
2196
2243
  })
2197
2244
  });
2198
2245
  GetProjectsQueryZ = z7.object({
@@ -7725,7 +7772,12 @@ function getGithubSdk(params = {}) {
7725
7772
  repoOwner: repo.owner.login,
7726
7773
  repoLanguages: repo.language ? [repo.language] : [],
7727
7774
  repoIsPublic: !repo.private,
7728
- repoUpdatedAt: repo.updated_at
7775
+ repoUpdatedAt: repo.updated_at,
7776
+ // GitHub already returns this on /user/repos; it was simply never mapped.
7777
+ // PR-check enablement registers a webhook, which needs repo admin, so a
7778
+ // picker without it can only offer every repository and let the customer
7779
+ // discover by failing.
7780
+ repoIsAdmin: repo.permissions ? repo.permissions.admin === true : void 0
7729
7781
  }));
7730
7782
  return {
7731
7783
  items,
@@ -18562,7 +18614,7 @@ function createLogger(config2) {
18562
18614
 
18563
18615
  // src/features/claude_code/hook_logger.ts
18564
18616
  var DD_RUM_TOKEN = true ? "pubf59c0182545bfb4c299175119f1abf9b" : "";
18565
- var CLI_VERSION = true ? "1.4.62" : "unknown";
18617
+ var CLI_VERSION = true ? "1.4.66" : "unknown";
18566
18618
  var NAMESPACE = "mobbdev-claude-code-hook-logs";
18567
18619
  var claudeCodeVersion;
18568
18620
  function buildDdTags() {
@@ -23741,7 +23793,7 @@ All tools require authentication via the Mobb API. The tools will handle authent
23741
23793
 
23742
23794
  Common scenarios:
23743
23795
  - **No fixes found**: Repository has no vulnerabilities or they're not fixable
23744
- - **Report expired**: Previous scan is too old, need to rescan
23796
+ - **Fixes expired**: The previous scan's fixes have aged out \u2014 rescan to get new ones (the findings themselves stay viewable in the web app)
23745
23797
  - **No report found**: No previous scan exists, run scan_and_fix_vulnerabilities
23746
23798
  - **Authentication required**: User needs to authenticate with Mobb
23747
23799
 
@@ -24251,18 +24303,19 @@ var expiredReportPrompt = ({
24251
24303
  lastReportDate
24252
24304
  }) => `\u{1F50D} **MOBB SECURITY SCAN STATUS**
24253
24305
 
24254
- ## Out-of-Date Vulnerability Report
24306
+ ## Fixes Have Expired
24255
24307
 
24256
- Your most recent vulnerability report for this repository **expired on ${lastReportDate}** and is no longer available for fetching automated fixes.
24308
+ The fixes from your most recent vulnerability report for this repository **expired on ${lastReportDate}**, so there are no automated fixes left to fetch.
24257
24309
 
24258
24310
  ### \u{1F4CB} Why Did This Happen?
24259
- - Reports are automatically purged after a retention period for security and storage optimization.
24260
- - No new scans have been run since the last report expired.
24311
+ - Fixes are kept for a limited window after an analysis (extendable), and this one has passed.
24312
+ - The findings themselves have not gone anywhere: the report is still viewable in the Mobb web app, with every issue, location and severity intact.
24313
+ - No new scans have been run since those fixes expired.
24261
24314
 
24262
24315
  ### \u{1F3AF} Recommended Actions
24263
- 1. **Run a fresh security scan** to generate an up-to-date vulnerability report.
24316
+ 1. **Run a fresh security scan** to generate new fixes for the current code.
24264
24317
  - Use the \`${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES}\` tool.
24265
- 2. **Verify repository access** if scans fail to run or the repository has moved.
24318
+ 2. **Open the existing report in the web app** if you need the findings themselves \u2014 for an audit, a compliance review, or to see what was reported.
24266
24319
  3. **Review your CI/CD pipeline** to ensure regular scans are triggered.
24267
24320
 
24268
24321
  For more help:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.4.62",
3
+ "version": "1.4.66",
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",