mobbdev 1.0.95 → 1.0.98
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.
- package/dist/index.mjs +671 -169
- package/package.json +11 -11
package/dist/index.mjs
CHANGED
|
@@ -370,6 +370,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
370
370
|
IssueType_Enum2["DangerousFunctionOverflow"] = "DANGEROUS_FUNCTION_OVERFLOW";
|
|
371
371
|
IssueType_Enum2["DeadCodeUnusedField"] = "DEAD_CODE_UNUSED_FIELD";
|
|
372
372
|
IssueType_Enum2["DebugEnabled"] = "DEBUG_ENABLED";
|
|
373
|
+
IssueType_Enum2["DeclareVariableExplicitly"] = "DECLARE_VARIABLE_EXPLICITLY";
|
|
373
374
|
IssueType_Enum2["DefaultRightsInObjDefinition"] = "DEFAULT_RIGHTS_IN_OBJ_DEFINITION";
|
|
374
375
|
IssueType_Enum2["DeprecatedFunction"] = "DEPRECATED_FUNCTION";
|
|
375
376
|
IssueType_Enum2["DosStringBuilder"] = "DOS_STRING_BUILDER";
|
|
@@ -417,6 +418,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
417
418
|
IssueType_Enum2["NonReadonlyField"] = "NON_READONLY_FIELD";
|
|
418
419
|
IssueType_Enum2["NoEquivalenceMethod"] = "NO_EQUIVALENCE_METHOD";
|
|
419
420
|
IssueType_Enum2["NoLimitsOrThrottling"] = "NO_LIMITS_OR_THROTTLING";
|
|
421
|
+
IssueType_Enum2["NoNestedTry"] = "NO_NESTED_TRY";
|
|
420
422
|
IssueType_Enum2["NoOpOverhead"] = "NO_OP_OVERHEAD";
|
|
421
423
|
IssueType_Enum2["NoPrintStatement"] = "NO_PRINT_STATEMENT";
|
|
422
424
|
IssueType_Enum2["NoReturnInFinally"] = "NO_RETURN_IN_FINALLY";
|
|
@@ -444,6 +446,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
444
446
|
IssueType_Enum2["TrustBoundaryViolation"] = "TRUST_BOUNDARY_VIOLATION";
|
|
445
447
|
IssueType_Enum2["TypeConfusion"] = "TYPE_CONFUSION";
|
|
446
448
|
IssueType_Enum2["UncheckedLoopCondition"] = "UNCHECKED_LOOP_CONDITION";
|
|
449
|
+
IssueType_Enum2["UnnecessaryImports"] = "UNNECESSARY_IMPORTS";
|
|
447
450
|
IssueType_Enum2["UnsafeDeserialization"] = "UNSAFE_DESERIALIZATION";
|
|
448
451
|
IssueType_Enum2["UnsafeTargetBlank"] = "UNSAFE_TARGET_BLANK";
|
|
449
452
|
IssueType_Enum2["UnsafeWebThread"] = "UNSAFE_WEB_THREAD";
|
|
@@ -485,6 +488,7 @@ var Vulnerability_Report_Issue_State_Enum = /* @__PURE__ */ ((Vulnerability_Repo
|
|
|
485
488
|
Vulnerability_Report_Issue_State_Enum2["Fixed"] = "Fixed";
|
|
486
489
|
Vulnerability_Report_Issue_State_Enum2["NoFix"] = "NoFix";
|
|
487
490
|
Vulnerability_Report_Issue_State_Enum2["Pending"] = "Pending";
|
|
491
|
+
Vulnerability_Report_Issue_State_Enum2["Unfixable"] = "Unfixable";
|
|
488
492
|
Vulnerability_Report_Issue_State_Enum2["Unsupported"] = "Unsupported";
|
|
489
493
|
return Vulnerability_Report_Issue_State_Enum2;
|
|
490
494
|
})(Vulnerability_Report_Issue_State_Enum || {});
|
|
@@ -493,6 +497,7 @@ var Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((Vulnerability_Report
|
|
|
493
497
|
Vulnerability_Report_Issue_Tag_Enum3["AuxiliaryCode"] = "AUXILIARY_CODE";
|
|
494
498
|
Vulnerability_Report_Issue_Tag_Enum3["FalsePositive"] = "FALSE_POSITIVE";
|
|
495
499
|
Vulnerability_Report_Issue_Tag_Enum3["TestCode"] = "TEST_CODE";
|
|
500
|
+
Vulnerability_Report_Issue_Tag_Enum3["Unfixable"] = "UNFIXABLE";
|
|
496
501
|
Vulnerability_Report_Issue_Tag_Enum3["VendorCode"] = "VENDOR_CODE";
|
|
497
502
|
return Vulnerability_Report_Issue_Tag_Enum3;
|
|
498
503
|
})(Vulnerability_Report_Issue_Tag_Enum || {});
|
|
@@ -516,6 +521,35 @@ var Vulnerability_Severity_Enum = /* @__PURE__ */ ((Vulnerability_Severity_Enum2
|
|
|
516
521
|
Vulnerability_Severity_Enum2["Medium"] = "medium";
|
|
517
522
|
return Vulnerability_Severity_Enum2;
|
|
518
523
|
})(Vulnerability_Severity_Enum || {});
|
|
524
|
+
var FixDetailsFragmentDoc = `
|
|
525
|
+
fragment FixDetails on fix {
|
|
526
|
+
id
|
|
527
|
+
confidence
|
|
528
|
+
safeIssueType
|
|
529
|
+
severityText
|
|
530
|
+
vulnerabilityReportIssues {
|
|
531
|
+
parsedIssueType
|
|
532
|
+
parsedSeverity
|
|
533
|
+
vulnerabilityReportIssueTags {
|
|
534
|
+
vulnerability_report_issue_tag_value
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
patchAndQuestions {
|
|
538
|
+
__typename
|
|
539
|
+
... on FixData {
|
|
540
|
+
patch
|
|
541
|
+
patchOriginalEncodingBase64
|
|
542
|
+
extraContext {
|
|
543
|
+
extraContext {
|
|
544
|
+
key
|
|
545
|
+
value
|
|
546
|
+
}
|
|
547
|
+
fixDescription
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
`;
|
|
519
553
|
var MeDocument = `
|
|
520
554
|
query Me {
|
|
521
555
|
me {
|
|
@@ -714,7 +748,7 @@ var GetVulByNodesMetadataDocument = `
|
|
|
714
748
|
where: {id: {_eq: $vulnerabilityReportId}}
|
|
715
749
|
) {
|
|
716
750
|
vulnerabilityReportIssues(
|
|
717
|
-
where: {fixId: {_is_null: true}, _or: [{category: {_eq: "Irrelevant"}}, {category: {_eq: "FalsePositive"}}]}
|
|
751
|
+
where: {fixId: {_is_null: true}, _or: [{category: {_eq: "Irrelevant"}}, {category: {_eq: "FalsePositive"}}, {category: {_eq: "Filtered"}}]}
|
|
718
752
|
) {
|
|
719
753
|
id
|
|
720
754
|
safeIssueType
|
|
@@ -948,34 +982,77 @@ var AutoPrAnalysisDocument = `
|
|
|
948
982
|
var GetMcpFixesDocument = `
|
|
949
983
|
query GetMCPFixes($fixReportId: uuid!) {
|
|
950
984
|
fix(where: {fixReportId: {_eq: $fixReportId}}) {
|
|
985
|
+
...FixDetails
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
${FixDetailsFragmentDoc}`;
|
|
989
|
+
var GetLatestReportByRepoUrlDocument = `
|
|
990
|
+
query GetLatestReportByRepoUrl($repoUrl: String!, $limit: Int = 3) {
|
|
991
|
+
fixReport(
|
|
992
|
+
where: {repo: {originalUrl: {_eq: $repoUrl}}}
|
|
993
|
+
order_by: {createdOn: desc}
|
|
994
|
+
limit: 1
|
|
995
|
+
) {
|
|
951
996
|
id
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
997
|
+
createdOn
|
|
998
|
+
repo {
|
|
999
|
+
originalUrl
|
|
1000
|
+
}
|
|
1001
|
+
issueTypes
|
|
1002
|
+
fixes_aggregate(
|
|
1003
|
+
where: {vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}
|
|
1004
|
+
) {
|
|
1005
|
+
aggregate {
|
|
1006
|
+
count
|
|
960
1007
|
}
|
|
961
1008
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1009
|
+
CRITICAL: fixes_aggregate(
|
|
1010
|
+
where: {_and: [{vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}, {severityText: {_eq: "critical"}}]}
|
|
1011
|
+
) {
|
|
1012
|
+
aggregate {
|
|
1013
|
+
count
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
HIGH: fixes_aggregate(
|
|
1017
|
+
where: {_and: [{vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}, {severityText: {_eq: "high"}}]}
|
|
1018
|
+
) {
|
|
1019
|
+
aggregate {
|
|
1020
|
+
count
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
MEDIUM: fixes_aggregate(
|
|
1024
|
+
where: {_and: [{vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}, {severityText: {_eq: "medium"}}]}
|
|
1025
|
+
) {
|
|
1026
|
+
aggregate {
|
|
1027
|
+
count
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
LOW: fixes_aggregate(
|
|
1031
|
+
where: {_and: [{vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}, {severityText: {_eq: "low"}}]}
|
|
1032
|
+
) {
|
|
1033
|
+
aggregate {
|
|
1034
|
+
count
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
fixes(
|
|
1038
|
+
where: {vulnerabilityReportIssues: {category: {_eq: "Fixable"}}}
|
|
1039
|
+
order_by: {severityValue: desc}
|
|
1040
|
+
limit: $limit
|
|
1041
|
+
) {
|
|
1042
|
+
...FixDetails
|
|
1043
|
+
}
|
|
1044
|
+
vulnerabilityReport {
|
|
1045
|
+
scanDate
|
|
1046
|
+
vendor
|
|
1047
|
+
vulnerabilityReportIssues_aggregate(where: {category: {_eq: "Fixable"}}) {
|
|
1048
|
+
aggregate {
|
|
1049
|
+
count
|
|
973
1050
|
}
|
|
974
1051
|
}
|
|
975
1052
|
}
|
|
976
1053
|
}
|
|
977
1054
|
}
|
|
978
|
-
`;
|
|
1055
|
+
${FixDetailsFragmentDoc}`;
|
|
979
1056
|
var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
980
1057
|
function getSdk(client, withWrapper = defaultWrapper) {
|
|
981
1058
|
return {
|
|
@@ -1044,6 +1121,9 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
1044
1121
|
},
|
|
1045
1122
|
GetMCPFixes(variables, requestHeaders, signal) {
|
|
1046
1123
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetMcpFixesDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetMCPFixes", "query", variables);
|
|
1124
|
+
},
|
|
1125
|
+
GetLatestReportByRepoUrl(variables, requestHeaders, signal) {
|
|
1126
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetLatestReportByRepoUrlDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetLatestReportByRepoUrl", "query", variables);
|
|
1047
1127
|
}
|
|
1048
1128
|
};
|
|
1049
1129
|
}
|
|
@@ -1248,14 +1328,16 @@ var CATEGORY = {
|
|
|
1248
1328
|
Unsupported: "Unsupported",
|
|
1249
1329
|
Irrelevant: "Irrelevant",
|
|
1250
1330
|
FalsePositive: "FalsePositive",
|
|
1251
|
-
Fixable: "Fixable"
|
|
1331
|
+
Fixable: "Fixable",
|
|
1332
|
+
Filtered: "Filtered"
|
|
1252
1333
|
};
|
|
1253
1334
|
var ValidCategoriesZ = z4.union([
|
|
1254
1335
|
z4.literal(CATEGORY.NoFix),
|
|
1255
1336
|
z4.literal(CATEGORY.Unsupported),
|
|
1256
1337
|
z4.literal(CATEGORY.Irrelevant),
|
|
1257
1338
|
z4.literal(CATEGORY.FalsePositive),
|
|
1258
|
-
z4.literal(CATEGORY.Fixable)
|
|
1339
|
+
z4.literal(CATEGORY.Fixable),
|
|
1340
|
+
z4.literal(CATEGORY.Filtered)
|
|
1259
1341
|
]);
|
|
1260
1342
|
var VulnerabilityReportIssueSharedStateZ = z4.object({
|
|
1261
1343
|
id: z4.string().uuid(),
|
|
@@ -1337,7 +1419,8 @@ var GeneralIssueZ = BaseIssuePartsZ.merge(
|
|
|
1337
1419
|
category: z4.union([
|
|
1338
1420
|
z4.literal(CATEGORY.NoFix),
|
|
1339
1421
|
z4.literal(CATEGORY.Unsupported),
|
|
1340
|
-
z4.literal(CATEGORY.Fixable)
|
|
1422
|
+
z4.literal(CATEGORY.Fixable),
|
|
1423
|
+
z4.literal(CATEGORY.Filtered)
|
|
1341
1424
|
])
|
|
1342
1425
|
})
|
|
1343
1426
|
);
|
|
@@ -1367,7 +1450,8 @@ var mapCategoryToBucket = {
|
|
|
1367
1450
|
Irrelevant: "irrelevant",
|
|
1368
1451
|
NoFix: "remaining",
|
|
1369
1452
|
Unsupported: "remaining",
|
|
1370
|
-
Fixable: "fixable"
|
|
1453
|
+
Fixable: "fixable",
|
|
1454
|
+
Filtered: "remaining"
|
|
1371
1455
|
};
|
|
1372
1456
|
|
|
1373
1457
|
// src/features/analysis/scm/shared/src/types/types.ts
|
|
@@ -1482,7 +1566,10 @@ var issueTypeMap = {
|
|
|
1482
1566
|
["MISSING_WHITESPACE" /* MissingWhitespace */]: "Missing Whitespace",
|
|
1483
1567
|
["NO_PRINT_STATEMENT" /* NoPrintStatement */]: 'Python 2 "print" Statement Is Obsolete',
|
|
1484
1568
|
["NO_OP_OVERHEAD" /* NoOpOverhead */]: "Expensive Arguments in Conditional Methods",
|
|
1485
|
-
["DO_NOT_RAISE_EXCEPTION" /* DoNotRaiseException */]: "Do Not Raise Exception"
|
|
1569
|
+
["DO_NOT_RAISE_EXCEPTION" /* DoNotRaiseException */]: "Do Not Raise Exception",
|
|
1570
|
+
["DECLARE_VARIABLE_EXPLICITLY" /* DeclareVariableExplicitly */]: "Declare Variable Explicitly",
|
|
1571
|
+
["NO_NESTED_TRY" /* NoNestedTry */]: "No Nested Try",
|
|
1572
|
+
["UNNECESSARY_IMPORTS" /* UnnecessaryImports */]: "Unnecessary Imports"
|
|
1486
1573
|
};
|
|
1487
1574
|
var issueTypeZ = z5.nativeEnum(IssueType_Enum);
|
|
1488
1575
|
var getIssueTypeFriendlyString = (issueType) => {
|
|
@@ -1503,17 +1590,20 @@ function getTagTooltip(tag) {
|
|
|
1503
1590
|
case "AUTOGENERATED_CODE":
|
|
1504
1591
|
return "Code created by tools or frameworks, not manually written";
|
|
1505
1592
|
case "AUXILIARY_CODE":
|
|
1506
|
-
return "Issue found in supporting files that don
|
|
1593
|
+
return "Issue found in supporting files that don't impact core functionality";
|
|
1594
|
+
case "Filtered":
|
|
1595
|
+
return "Issue was filtered by user in the Fix Policy";
|
|
1507
1596
|
default:
|
|
1508
1597
|
return tag;
|
|
1509
1598
|
}
|
|
1510
1599
|
}
|
|
1511
1600
|
var issueDescription = {
|
|
1512
1601
|
["AUTOGENERATED_CODE" /* AutogeneratedCode */]: "The flagged code is generated automatically by tools or frameworks as part of the build or runtime process. This categorization highlights that **the issue resides in non-manual code**, which often requires tool-specific solutions or exemptions.",
|
|
1513
|
-
["AUXILIARY_CODE" /* AuxiliaryCode */]: "The flagged code is auxiliary or supporting code, such as configuration files, build scripts, or other non-application logic. This categorization indicates that the issue is not directly related to the application
|
|
1514
|
-
["FALSE_POSITIVE" /* FalsePositive */]: "The flagged code **does not represent an actual vulnerability within the application
|
|
1602
|
+
["AUXILIARY_CODE" /* AuxiliaryCode */]: "The flagged code is auxiliary or supporting code, such as configuration files, build scripts, or other non-application logic. This categorization indicates that the issue is not directly related to the application's core functionality.",
|
|
1603
|
+
["FALSE_POSITIVE" /* FalsePositive */]: "The flagged code **does not represent an actual vulnerability within the application's context.** This categorization indicates that the issue is either misidentified by the scanner or deemed irrelevant to the application's functionality.",
|
|
1515
1604
|
["TEST_CODE" /* TestCode */]: "The flagged code resides in a test-specific path or context. This categorization indicates that **it supports testing scenarios and is isolated from production use**.",
|
|
1516
|
-
["
|
|
1605
|
+
["UNFIXABLE" /* Unfixable */]: "The flagged code cannot be fixed",
|
|
1606
|
+
["VENDOR_CODE" /* VendorCode */]: "The flagged code originates from a third-party library or dependency maintained externally. This categorization suggests that **the issue lies outside the application's direct control** and should be addressed by the vendor if necessary."
|
|
1517
1607
|
};
|
|
1518
1608
|
function replaceKeysWithValues(fixDescription, extraContext) {
|
|
1519
1609
|
let result = fixDescription;
|
|
@@ -1644,7 +1734,8 @@ var ReportQueryResultZ = z7.object({
|
|
|
1644
1734
|
z7.object({
|
|
1645
1735
|
id: z7.string().uuid(),
|
|
1646
1736
|
issueType: z7.string(),
|
|
1647
|
-
issueLanguage: z7.string()
|
|
1737
|
+
issueLanguage: z7.string(),
|
|
1738
|
+
category: z7.string()
|
|
1648
1739
|
})
|
|
1649
1740
|
)
|
|
1650
1741
|
// scmSubmitFixRequests: ScmSubmitFixRequestsZ,
|
|
@@ -1769,6 +1860,7 @@ var VulnerabilityReportIssueZ = z7.object({
|
|
|
1769
1860
|
parsedSeverity: ParsedSeverityZ,
|
|
1770
1861
|
severity: z7.string(),
|
|
1771
1862
|
severityValue: z7.number(),
|
|
1863
|
+
category: z7.string(),
|
|
1772
1864
|
codeNodes: z7.array(z7.object({ path: z7.string() })),
|
|
1773
1865
|
vulnerabilityReportIssueTags: z7.array(
|
|
1774
1866
|
z7.object({
|
|
@@ -2220,7 +2312,10 @@ var fixDetailsData = {
|
|
|
2220
2312
|
["MISSING_WHITESPACE" /* MissingWhitespace */]: void 0,
|
|
2221
2313
|
["NO_PRINT_STATEMENT" /* NoPrintStatement */]: void 0,
|
|
2222
2314
|
["NO_OP_OVERHEAD" /* NoOpOverhead */]: void 0,
|
|
2223
|
-
["DO_NOT_RAISE_EXCEPTION" /* DoNotRaiseException */]: void 0
|
|
2315
|
+
["DO_NOT_RAISE_EXCEPTION" /* DoNotRaiseException */]: void 0,
|
|
2316
|
+
["DECLARE_VARIABLE_EXPLICITLY" /* DeclareVariableExplicitly */]: void 0,
|
|
2317
|
+
["UNNECESSARY_IMPORTS" /* UnnecessaryImports */]: void 0,
|
|
2318
|
+
["NO_NESTED_TRY" /* NoNestedTry */]: void 0
|
|
2224
2319
|
};
|
|
2225
2320
|
|
|
2226
2321
|
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
@@ -5429,6 +5524,92 @@ var GitService = class {
|
|
|
5429
5524
|
throw new Error(errorMessage);
|
|
5430
5525
|
}
|
|
5431
5526
|
}
|
|
5527
|
+
/**
|
|
5528
|
+
* Normalizes a Git URL to HTTPS format for various Git hosting platforms
|
|
5529
|
+
* @param url The Git URL to normalize
|
|
5530
|
+
* @returns The normalized HTTPS URL
|
|
5531
|
+
*/
|
|
5532
|
+
normalizeGitUrl(url) {
|
|
5533
|
+
let normalizedUrl = url;
|
|
5534
|
+
if (normalizedUrl.endsWith(".git")) {
|
|
5535
|
+
normalizedUrl = normalizedUrl.slice(0, -".git".length);
|
|
5536
|
+
}
|
|
5537
|
+
const sshToHttpsMappings = [
|
|
5538
|
+
// GitHub
|
|
5539
|
+
{ pattern: "git@github.com:", replacement: "https://github.com/" },
|
|
5540
|
+
// GitLab
|
|
5541
|
+
{ pattern: "git@gitlab.com:", replacement: "https://gitlab.com/" },
|
|
5542
|
+
// Bitbucket
|
|
5543
|
+
{ pattern: "git@bitbucket.org:", replacement: "https://bitbucket.org/" },
|
|
5544
|
+
// Azure DevOps (SSH format)
|
|
5545
|
+
{
|
|
5546
|
+
pattern: "git@ssh.dev.azure.com:",
|
|
5547
|
+
replacement: "https://dev.azure.com/"
|
|
5548
|
+
},
|
|
5549
|
+
// Azure DevOps (alternative SSH format)
|
|
5550
|
+
{
|
|
5551
|
+
pattern: /git@([^:]+):v3\/([^/]+)\/([^/]+)\/([^/]+)/,
|
|
5552
|
+
replacement: "https://$1/$2/_git/$4"
|
|
5553
|
+
}
|
|
5554
|
+
];
|
|
5555
|
+
for (const mapping of sshToHttpsMappings) {
|
|
5556
|
+
if (typeof mapping.pattern === "string") {
|
|
5557
|
+
if (normalizedUrl.startsWith(mapping.pattern)) {
|
|
5558
|
+
normalizedUrl = normalizedUrl.replace(
|
|
5559
|
+
mapping.pattern,
|
|
5560
|
+
mapping.replacement
|
|
5561
|
+
);
|
|
5562
|
+
break;
|
|
5563
|
+
}
|
|
5564
|
+
} else {
|
|
5565
|
+
const match = normalizedUrl.match(mapping.pattern);
|
|
5566
|
+
if (match) {
|
|
5567
|
+
normalizedUrl = normalizedUrl.replace(
|
|
5568
|
+
mapping.pattern,
|
|
5569
|
+
mapping.replacement
|
|
5570
|
+
);
|
|
5571
|
+
break;
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
return normalizedUrl;
|
|
5576
|
+
}
|
|
5577
|
+
/**
|
|
5578
|
+
* Gets all remote repository URLs (equivalent to 'git remote -v')
|
|
5579
|
+
*/
|
|
5580
|
+
async getRepoUrls() {
|
|
5581
|
+
this.log("Getting all remote repository URLs", "debug");
|
|
5582
|
+
try {
|
|
5583
|
+
const remotes = await this.git.remote(["-v"]);
|
|
5584
|
+
if (!remotes) {
|
|
5585
|
+
return {};
|
|
5586
|
+
}
|
|
5587
|
+
const remoteMap = {};
|
|
5588
|
+
remotes.split("\n").forEach((line) => {
|
|
5589
|
+
if (!line.trim()) return;
|
|
5590
|
+
const [remoteName, url, type2] = line.split(/\s+/);
|
|
5591
|
+
if (!remoteName || !url || !type2) return;
|
|
5592
|
+
if (!remoteMap[remoteName]) {
|
|
5593
|
+
remoteMap[remoteName] = { fetch: "", push: "" };
|
|
5594
|
+
}
|
|
5595
|
+
const normalizedUrl = this.normalizeGitUrl(url);
|
|
5596
|
+
const remote = remoteMap[remoteName];
|
|
5597
|
+
if (type2 === "(fetch)") {
|
|
5598
|
+
remote.fetch = normalizedUrl;
|
|
5599
|
+
} else if (type2 === "(push)") {
|
|
5600
|
+
remote.push = normalizedUrl;
|
|
5601
|
+
}
|
|
5602
|
+
});
|
|
5603
|
+
this.log("Remote repository URLs retrieved", "debug", {
|
|
5604
|
+
remotes: remoteMap
|
|
5605
|
+
});
|
|
5606
|
+
return remoteMap;
|
|
5607
|
+
} catch (error) {
|
|
5608
|
+
const errorMessage = `Failed to get remote repository URLs: ${error.message}`;
|
|
5609
|
+
this.log(errorMessage, "error", { error });
|
|
5610
|
+
throw new Error(errorMessage);
|
|
5611
|
+
}
|
|
5612
|
+
}
|
|
5432
5613
|
};
|
|
5433
5614
|
|
|
5434
5615
|
// src/features/analysis/scm/scmSubmit/index.ts
|
|
@@ -6830,7 +7011,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6830
7011
|
}
|
|
6831
7012
|
async forkRepo(repoUrl) {
|
|
6832
7013
|
this._validateAccessToken();
|
|
6833
|
-
return this.githubSdk.forkRepo({
|
|
7014
|
+
return await this.githubSdk.forkRepo({
|
|
6834
7015
|
repoUrl
|
|
6835
7016
|
});
|
|
6836
7017
|
}
|
|
@@ -6840,7 +7021,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6840
7021
|
const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
|
|
6841
7022
|
const { key_id, key } = repositoryPublicKeyResponse;
|
|
6842
7023
|
const encryptedValue = await encryptSecret(params.value, key);
|
|
6843
|
-
return this.githubSdk.createOrUpdateRepositorySecret({
|
|
7024
|
+
return await this.githubSdk.createOrUpdateRepositorySecret({
|
|
6844
7025
|
encrypted_value: encryptedValue,
|
|
6845
7026
|
secret_name: params.name,
|
|
6846
7027
|
key_id,
|
|
@@ -6859,12 +7040,12 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6859
7040
|
return { pull_request_url };
|
|
6860
7041
|
}
|
|
6861
7042
|
async validateParams() {
|
|
6862
|
-
return githubValidateParams(this.url, this.accessToken);
|
|
7043
|
+
return await githubValidateParams(this.url, this.accessToken);
|
|
6863
7044
|
}
|
|
6864
7045
|
async postPrComment(params) {
|
|
6865
7046
|
this._validateAccessTokenAndUrl();
|
|
6866
7047
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6867
|
-
return this.githubSdk.postPrComment({
|
|
7048
|
+
return await this.githubSdk.postPrComment({
|
|
6868
7049
|
...params,
|
|
6869
7050
|
owner,
|
|
6870
7051
|
repo
|
|
@@ -6873,7 +7054,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6873
7054
|
async updatePrComment(params) {
|
|
6874
7055
|
this._validateAccessTokenAndUrl();
|
|
6875
7056
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6876
|
-
return this.githubSdk.updatePrComment({
|
|
7057
|
+
return await this.githubSdk.updatePrComment({
|
|
6877
7058
|
...params,
|
|
6878
7059
|
owner,
|
|
6879
7060
|
repo
|
|
@@ -6882,7 +7063,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6882
7063
|
async deleteComment(params) {
|
|
6883
7064
|
this._validateAccessTokenAndUrl();
|
|
6884
7065
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6885
|
-
return this.githubSdk.deleteComment({
|
|
7066
|
+
return await this.githubSdk.deleteComment({
|
|
6886
7067
|
...params,
|
|
6887
7068
|
owner,
|
|
6888
7069
|
repo
|
|
@@ -6891,7 +7072,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6891
7072
|
async getPrComments(params) {
|
|
6892
7073
|
this._validateAccessTokenAndUrl();
|
|
6893
7074
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6894
|
-
return this.githubSdk.getPrComments({
|
|
7075
|
+
return await this.githubSdk.getPrComments({
|
|
6895
7076
|
per_page: 100,
|
|
6896
7077
|
...params,
|
|
6897
7078
|
owner,
|
|
@@ -6910,7 +7091,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6910
7091
|
}
|
|
6911
7092
|
async getRepoList(_scmOrg) {
|
|
6912
7093
|
this._validateAccessToken();
|
|
6913
|
-
return this.githubSdk.getGithubRepoList();
|
|
7094
|
+
return await this.githubSdk.getGithubRepoList();
|
|
6914
7095
|
}
|
|
6915
7096
|
async getBranchList() {
|
|
6916
7097
|
this._validateAccessTokenAndUrl();
|
|
@@ -6937,27 +7118,30 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6937
7118
|
return Promise.resolve(downloadUrl);
|
|
6938
7119
|
}
|
|
6939
7120
|
async _getUsernameForAuthUrl() {
|
|
6940
|
-
return this.getUsername();
|
|
7121
|
+
return await this.getUsername();
|
|
6941
7122
|
}
|
|
6942
7123
|
async getIsRemoteBranch(branch) {
|
|
6943
7124
|
this._validateUrl();
|
|
6944
|
-
return this.githubSdk.getGithubIsRemoteBranch({
|
|
7125
|
+
return await this.githubSdk.getGithubIsRemoteBranch({
|
|
7126
|
+
branch,
|
|
7127
|
+
repoUrl: this.url
|
|
7128
|
+
});
|
|
6945
7129
|
}
|
|
6946
7130
|
async getUserHasAccessToRepo() {
|
|
6947
7131
|
this._validateAccessTokenAndUrl();
|
|
6948
7132
|
const username = await this.getUsername();
|
|
6949
|
-
return this.githubSdk.getGithubIsUserCollaborator({
|
|
7133
|
+
return await this.githubSdk.getGithubIsUserCollaborator({
|
|
6950
7134
|
repoUrl: this.url,
|
|
6951
7135
|
username
|
|
6952
7136
|
});
|
|
6953
7137
|
}
|
|
6954
7138
|
async getUsername() {
|
|
6955
7139
|
this._validateAccessToken();
|
|
6956
|
-
return this.githubSdk.getGithubUsername();
|
|
7140
|
+
return await this.githubSdk.getGithubUsername();
|
|
6957
7141
|
}
|
|
6958
7142
|
async getSubmitRequestStatus(scmSubmitRequestId) {
|
|
6959
7143
|
this._validateAccessTokenAndUrl();
|
|
6960
|
-
return this.githubSdk.getGithubPullRequestStatus({
|
|
7144
|
+
return await this.githubSdk.getGithubPullRequestStatus({
|
|
6961
7145
|
repoUrl: this.url,
|
|
6962
7146
|
prNumber: Number(scmSubmitRequestId)
|
|
6963
7147
|
});
|
|
@@ -6980,7 +7164,10 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
6980
7164
|
}
|
|
6981
7165
|
async getReferenceData(ref) {
|
|
6982
7166
|
this._validateUrl();
|
|
6983
|
-
return this.githubSdk.getGithubReferenceData({
|
|
7167
|
+
return await this.githubSdk.getGithubReferenceData({
|
|
7168
|
+
ref,
|
|
7169
|
+
gitHubUrl: this.url
|
|
7170
|
+
});
|
|
6984
7171
|
}
|
|
6985
7172
|
async getPrComment(commentId) {
|
|
6986
7173
|
this._validateUrl();
|
|
@@ -7049,7 +7236,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
7049
7236
|
}) {
|
|
7050
7237
|
this._validateAccessTokenAndUrl();
|
|
7051
7238
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7052
|
-
return this.githubSdk.deleteGeneralPrComment({
|
|
7239
|
+
return await this.githubSdk.deleteGeneralPrComment({
|
|
7053
7240
|
owner,
|
|
7054
7241
|
repo,
|
|
7055
7242
|
comment_id: commentId
|
|
@@ -8817,31 +9004,33 @@ async function addFixCommentsForPr({
|
|
|
8817
9004
|
|
|
8818
9005
|
${contextString}` : description2;
|
|
8819
9006
|
}
|
|
8820
|
-
return
|
|
8821
|
-
(
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
9007
|
+
return await Promise.all(
|
|
9008
|
+
vulnerabilityReportIssue.codeNodes.map(
|
|
9009
|
+
async (vulnerabilityReportIssueCodeNode) => {
|
|
9010
|
+
return await postIssueComment({
|
|
9011
|
+
vulnerabilityReportIssueCodeNode: {
|
|
9012
|
+
path: vulnerabilityReportIssueCodeNode.path,
|
|
9013
|
+
startLine: vulnerabilityReportIssueCodeNode.startLine,
|
|
9014
|
+
vulnerabilityReportIssue: {
|
|
9015
|
+
fixId: "",
|
|
9016
|
+
safeIssueType: vulnerabilityReportIssue.safeIssueType,
|
|
9017
|
+
vulnerabilityReportIssueTags: vulnerabilityReportIssue.vulnerabilityReportIssueTags,
|
|
9018
|
+
category: vulnerabilityReportIssue.category
|
|
9019
|
+
},
|
|
9020
|
+
vulnerabilityReportIssueId: vulnerabilityReportIssue.id
|
|
8831
9021
|
},
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
}
|
|
9022
|
+
projectId,
|
|
9023
|
+
analysisId,
|
|
9024
|
+
organizationId,
|
|
9025
|
+
fixesById,
|
|
9026
|
+
scm,
|
|
9027
|
+
pullRequest,
|
|
9028
|
+
scanner,
|
|
9029
|
+
commitSha,
|
|
9030
|
+
fpDescription
|
|
9031
|
+
});
|
|
9032
|
+
}
|
|
9033
|
+
)
|
|
8845
9034
|
);
|
|
8846
9035
|
}
|
|
8847
9036
|
),
|
|
@@ -11306,6 +11495,30 @@ var McpGQLClient = class {
|
|
|
11306
11495
|
return null;
|
|
11307
11496
|
}
|
|
11308
11497
|
}
|
|
11498
|
+
async getLatestReportByRepoUrl(repoUrl, limit) {
|
|
11499
|
+
try {
|
|
11500
|
+
logDebug("GraphQL: Calling GetLatestReportByRepoUrl query", {
|
|
11501
|
+
repoUrl,
|
|
11502
|
+
limit
|
|
11503
|
+
});
|
|
11504
|
+
const res = await this.clientSdk.GetLatestReportByRepoUrl({
|
|
11505
|
+
repoUrl,
|
|
11506
|
+
limit
|
|
11507
|
+
});
|
|
11508
|
+
logInfo("GraphQL: GetLatestReportByRepoUrl successful", {
|
|
11509
|
+
result: res,
|
|
11510
|
+
reportCount: res.fixReport?.length || 0
|
|
11511
|
+
});
|
|
11512
|
+
return res.fixReport?.[0] || null;
|
|
11513
|
+
} catch (e) {
|
|
11514
|
+
logError("GraphQL: GetLatestReportByRepoUrl failed", {
|
|
11515
|
+
error: e,
|
|
11516
|
+
repoUrl,
|
|
11517
|
+
...this.getErrorContext()
|
|
11518
|
+
});
|
|
11519
|
+
throw e;
|
|
11520
|
+
}
|
|
11521
|
+
}
|
|
11309
11522
|
};
|
|
11310
11523
|
async function openBrowser(url) {
|
|
11311
11524
|
const now = Date.now();
|
|
@@ -11478,21 +11691,12 @@ var McpServer = class {
|
|
|
11478
11691
|
}
|
|
11479
11692
|
async handleListToolsRequest(request) {
|
|
11480
11693
|
logInfo("Received list_tools request", { params: request.params });
|
|
11481
|
-
|
|
11482
|
-
await getMcpGQLClient();
|
|
11483
|
-
} catch (error) {
|
|
11484
|
-
logError("Failed to get MCPGQLClient", { error });
|
|
11485
|
-
const authError = new Error(
|
|
11486
|
-
"Please authorize this client by visiting: https://mobb.ai"
|
|
11487
|
-
);
|
|
11488
|
-
authError.name = "AuthorizationRequired";
|
|
11489
|
-
throw authError;
|
|
11490
|
-
}
|
|
11694
|
+
void getMcpGQLClient();
|
|
11491
11695
|
const tools = this.toolRegistry.getAllTools();
|
|
11492
|
-
|
|
11696
|
+
const response = {
|
|
11493
11697
|
tools: tools.map((tool) => ({
|
|
11494
11698
|
name: tool.name,
|
|
11495
|
-
display_name: tool.name,
|
|
11699
|
+
display_name: tool.display_name || tool.name,
|
|
11496
11700
|
description: tool.description || "",
|
|
11497
11701
|
inputSchema: {
|
|
11498
11702
|
type: "object",
|
|
@@ -11501,6 +11705,8 @@ var McpServer = class {
|
|
|
11501
11705
|
}
|
|
11502
11706
|
}))
|
|
11503
11707
|
};
|
|
11708
|
+
logInfo("Returning list_tools response", { response });
|
|
11709
|
+
return response;
|
|
11504
11710
|
}
|
|
11505
11711
|
async handleCallToolRequest(request) {
|
|
11506
11712
|
const { name, arguments: args } = request.params;
|
|
@@ -11571,6 +11777,9 @@ var McpServer = class {
|
|
|
11571
11777
|
}
|
|
11572
11778
|
};
|
|
11573
11779
|
|
|
11780
|
+
// src/mcp/tools/checkForAvailableFixes/AvailableFixesTool.ts
|
|
11781
|
+
import { z as z32 } from "zod";
|
|
11782
|
+
|
|
11574
11783
|
// src/mcp/services/PathValidation.ts
|
|
11575
11784
|
import fs9 from "fs";
|
|
11576
11785
|
import path11 from "path";
|
|
@@ -11616,6 +11825,369 @@ var PathValidation = class {
|
|
|
11616
11825
|
}
|
|
11617
11826
|
};
|
|
11618
11827
|
|
|
11828
|
+
// src/mcp/tools/base/BaseTool.ts
|
|
11829
|
+
import { z as z31 } from "zod";
|
|
11830
|
+
var BaseTool = class {
|
|
11831
|
+
getDefinition() {
|
|
11832
|
+
return {
|
|
11833
|
+
name: this.name,
|
|
11834
|
+
display_name: this.displayName,
|
|
11835
|
+
description: this.description,
|
|
11836
|
+
inputSchema: {
|
|
11837
|
+
type: "object",
|
|
11838
|
+
properties: {
|
|
11839
|
+
path: {
|
|
11840
|
+
type: "string",
|
|
11841
|
+
description: "The path to the local git repository"
|
|
11842
|
+
}
|
|
11843
|
+
},
|
|
11844
|
+
required: ["path"]
|
|
11845
|
+
}
|
|
11846
|
+
};
|
|
11847
|
+
}
|
|
11848
|
+
async execute(args) {
|
|
11849
|
+
logInfo(`Executing tool: ${this.name}`, { args });
|
|
11850
|
+
const validatedArgs = this.validateInput(args);
|
|
11851
|
+
logDebug(`Tool ${this.name} input validation successful`, {
|
|
11852
|
+
validatedArgs
|
|
11853
|
+
});
|
|
11854
|
+
await this.validateAdditional(validatedArgs);
|
|
11855
|
+
try {
|
|
11856
|
+
const result = await this.executeInternal(validatedArgs);
|
|
11857
|
+
logInfo(`Tool ${this.name} executed successfully`);
|
|
11858
|
+
return result;
|
|
11859
|
+
} catch (error) {
|
|
11860
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
11861
|
+
logError(`Tool ${this.name} execution failed: ${errorMessage}`, {
|
|
11862
|
+
error,
|
|
11863
|
+
args
|
|
11864
|
+
});
|
|
11865
|
+
return this.createErrorResponse(errorMessage);
|
|
11866
|
+
}
|
|
11867
|
+
}
|
|
11868
|
+
validateInput(args) {
|
|
11869
|
+
try {
|
|
11870
|
+
return this.inputSchema.parse(args);
|
|
11871
|
+
} catch (error) {
|
|
11872
|
+
if (error instanceof z31.ZodError) {
|
|
11873
|
+
const errorDetails = error.errors.map((e) => {
|
|
11874
|
+
const fieldPath = e.path.length > 0 ? e.path.join(".") : "root";
|
|
11875
|
+
const message = e.message === "Required" ? `Missing required parameter '${fieldPath}'` : `Invalid value for '${fieldPath}': ${e.message}`;
|
|
11876
|
+
return message;
|
|
11877
|
+
});
|
|
11878
|
+
const errorMessage = `Invalid arguments: ${errorDetails.join(", ")}`;
|
|
11879
|
+
throw new Error(errorMessage);
|
|
11880
|
+
}
|
|
11881
|
+
throw error;
|
|
11882
|
+
}
|
|
11883
|
+
}
|
|
11884
|
+
/**
|
|
11885
|
+
* Additional validation that should bubble up as MCP errors
|
|
11886
|
+
* Override this method in subclasses to add custom validation
|
|
11887
|
+
*/
|
|
11888
|
+
async validateAdditional(_validatedArgs) {
|
|
11889
|
+
}
|
|
11890
|
+
createSuccessResponse(text) {
|
|
11891
|
+
return {
|
|
11892
|
+
content: [
|
|
11893
|
+
{
|
|
11894
|
+
type: "text",
|
|
11895
|
+
text
|
|
11896
|
+
}
|
|
11897
|
+
]
|
|
11898
|
+
};
|
|
11899
|
+
}
|
|
11900
|
+
createErrorResponse(error) {
|
|
11901
|
+
return {
|
|
11902
|
+
content: [
|
|
11903
|
+
{
|
|
11904
|
+
type: "text",
|
|
11905
|
+
text: error
|
|
11906
|
+
}
|
|
11907
|
+
]
|
|
11908
|
+
};
|
|
11909
|
+
}
|
|
11910
|
+
};
|
|
11911
|
+
|
|
11912
|
+
// src/mcp/tools/base/prompts.ts
|
|
11913
|
+
function frienlyType(s) {
|
|
11914
|
+
const withoutUnderscores = s.replace(/_/g, " ");
|
|
11915
|
+
const result = withoutUnderscores.replace(/([a-z])([A-Z])/g, "$1 $2");
|
|
11916
|
+
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
11917
|
+
}
|
|
11918
|
+
var applyFixesPrompt = (fixes) => {
|
|
11919
|
+
const fixList = fixes.map((fix) => {
|
|
11920
|
+
const vulnerabilityType = frienlyType(fix.safeIssueType);
|
|
11921
|
+
const vulnerabilityDescription = fix.patchAndQuestions?.__typename === "FixData" ? fix.patchAndQuestions.extraContext?.fixDescription : void 0;
|
|
11922
|
+
const patch = fix.patchAndQuestions?.__typename === "FixData" ? fix.patchAndQuestions.patch : void 0;
|
|
11923
|
+
return {
|
|
11924
|
+
vulnerabilityType,
|
|
11925
|
+
vulnerabilityDescription,
|
|
11926
|
+
patch
|
|
11927
|
+
};
|
|
11928
|
+
});
|
|
11929
|
+
return `## CRITICAL INSTRUCTIONS - READ CAREFULLY
|
|
11930
|
+
|
|
11931
|
+
You are an AI code assistant tasked with applying security vulnerability fixes. Follow these instructions EXACTLY:
|
|
11932
|
+
|
|
11933
|
+
### 1. IMMEDIATE ACTION REQUIRED
|
|
11934
|
+
- **DO NOT ask for permission** - Apply the patches immediately
|
|
11935
|
+
- **DO NOT explain first** - Apply the patch, then explain what you did
|
|
11936
|
+
- **DO NOT modify any other code** - Only apply the exact changes shown in each patch
|
|
11937
|
+
|
|
11938
|
+
### 2. HOW TO APPLY EACH PATCH
|
|
11939
|
+
For each fix below:
|
|
11940
|
+
1. **Identify the target file** from the patch header (e.g., \`src/database/queries.js\`)
|
|
11941
|
+
2. **Locate the exact lines** shown in the patch context
|
|
11942
|
+
3. **Remove lines** that start with \`-\` (minus sign)
|
|
11943
|
+
4. **Add lines** that start with \`+\` (plus sign)
|
|
11944
|
+
5. **Keep unchanged lines** exactly as they are (lines without +/- prefix)
|
|
11945
|
+
6. **Preserve indentation and formatting** exactly as shown
|
|
11946
|
+
|
|
11947
|
+
### 3. PATCH FORMAT EXPLANATION
|
|
11948
|
+
- \`@@\` lines show line numbers and context
|
|
11949
|
+
- Lines starting with \`-\` should be REMOVED
|
|
11950
|
+
- Lines starting with \`+\` should be ADDED
|
|
11951
|
+
- Lines with no prefix should remain UNCHANGED
|
|
11952
|
+
- The patch shows surrounding context to help you locate the right place
|
|
11953
|
+
|
|
11954
|
+
### 4. VALIDATION STEPS
|
|
11955
|
+
After applying each patch:
|
|
11956
|
+
1. Verify the file syntax is correct
|
|
11957
|
+
2. Ensure no unrelated code was modified
|
|
11958
|
+
3. Confirm the vulnerability is addressed
|
|
11959
|
+
|
|
11960
|
+
### 5. ERROR HANDLING
|
|
11961
|
+
If you cannot apply a patch:
|
|
11962
|
+
1. Explain specifically what went wrong
|
|
11963
|
+
2. Show the current state of the target lines
|
|
11964
|
+
3. Ask for clarification on the specific issue
|
|
11965
|
+
|
|
11966
|
+
---
|
|
11967
|
+
|
|
11968
|
+
# SECURITY FIXES TO APPLY
|
|
11969
|
+
|
|
11970
|
+
${fixList.map(
|
|
11971
|
+
(fix, index) => `
|
|
11972
|
+
## Fix ${index + 1}: ${fix.vulnerabilityType}
|
|
11973
|
+
|
|
11974
|
+
**\u{1F3AF} Target:** Apply this patch to fix a ${fix.vulnerabilityType.toLowerCase()} vulnerability
|
|
11975
|
+
|
|
11976
|
+
**\u{1F4DD} Description:** ${fix.vulnerabilityDescription || "Security vulnerability fix"}
|
|
11977
|
+
|
|
11978
|
+
**\u{1F527} Action Required:** Apply the following patch exactly as shown
|
|
11979
|
+
|
|
11980
|
+
**\u{1F4C1} Patch to Apply:**
|
|
11981
|
+
\`\`\`diff
|
|
11982
|
+
${fix.patch || "No patch available"}
|
|
11983
|
+
\`\`\`
|
|
11984
|
+
|
|
11985
|
+
**\u2705 Expected Result:** The vulnerability will be fixed and the code will be more secure
|
|
11986
|
+
|
|
11987
|
+
---`
|
|
11988
|
+
).join("\n")}
|
|
11989
|
+
|
|
11990
|
+
## FINAL REMINDER
|
|
11991
|
+
- Apply ALL patches above in order
|
|
11992
|
+
- Do NOT ask for permission
|
|
11993
|
+
- Explain what you did AFTER applying the patches
|
|
11994
|
+
- If any patch fails, continue with the others and report issues at the end
|
|
11995
|
+
`;
|
|
11996
|
+
};
|
|
11997
|
+
|
|
11998
|
+
// src/mcp/tools/checkForAvailableFixes/helpers/AvailableFixesResponsePrompts.ts
|
|
11999
|
+
var noReportFoundPrompt = `\u{1F50D} **MOBB SECURITY SCAN STATUS**
|
|
12000
|
+
|
|
12001
|
+
## No Vulnerability Report Found
|
|
12002
|
+
|
|
12003
|
+
We were unable to find a previous vulnerability report for this repository. This could be due to several reasons:
|
|
12004
|
+
|
|
12005
|
+
### \u{1F4CB} Possible Reasons
|
|
12006
|
+
- This is a new repository that hasn't been scanned yet
|
|
12007
|
+
- The repository URL might not match our records
|
|
12008
|
+
- The repository might be private or not accessible
|
|
12009
|
+
- Previous scans might have been deleted or expired
|
|
12010
|
+
|
|
12011
|
+
### \u{1F3AF} Recommended Actions
|
|
12012
|
+
1. **Run a new security scan** to analyze your codebase
|
|
12013
|
+
- Use the \`fix_vulnerabilities\` tool to start a fresh scan
|
|
12014
|
+
- This will analyze your current code for security issues
|
|
12015
|
+
|
|
12016
|
+
2. **Verify repository access**
|
|
12017
|
+
- Ensure the repository is properly connected to Mobb
|
|
12018
|
+
- Check that you have the necessary permissions
|
|
12019
|
+
|
|
12020
|
+
3. **Check repository URL**
|
|
12021
|
+
- Confirm the repository URL matches your remote origin
|
|
12022
|
+
- Verify the URL format is correct (e.g., https://github.com/org/repo)
|
|
12023
|
+
|
|
12024
|
+
### \u{1F680} Next Steps
|
|
12025
|
+
To get started with security scanning:
|
|
12026
|
+
1. Run \`fix_vulnerabilities\` to perform a new scan
|
|
12027
|
+
2. Review the results and apply any suggested fixes
|
|
12028
|
+
3. Set up regular scanning to maintain security
|
|
12029
|
+
|
|
12030
|
+
### \u{1F4A1} Additional Information
|
|
12031
|
+
- New scans typically take a few minutes to complete
|
|
12032
|
+
- You'll receive detailed results including:
|
|
12033
|
+
- Vulnerability types and severities
|
|
12034
|
+
- Specific code locations
|
|
12035
|
+
- Recommended fixes
|
|
12036
|
+
- Security best practices
|
|
12037
|
+
|
|
12038
|
+
For assistance, please:
|
|
12039
|
+
- Visit our documentation at https://docs.mobb.ai
|
|
12040
|
+
- Contact support at support@mobb.ai`;
|
|
12041
|
+
var noFixesFoundPrompt = `\u{1F50D} **MOBB SECURITY SCAN STATUS**
|
|
12042
|
+
|
|
12043
|
+
## No Available Fixes Found
|
|
12044
|
+
|
|
12045
|
+
We've analyzed your repository but found no automated fixes available at this time.
|
|
12046
|
+
`;
|
|
12047
|
+
var fixesFoundPrompt = (fixReport) => {
|
|
12048
|
+
if (fixReport.fixes_aggregate.aggregate?.count === 0) {
|
|
12049
|
+
return noFixesFoundPrompt;
|
|
12050
|
+
}
|
|
12051
|
+
const totalFixes = fixReport.fixes_aggregate.aggregate?.count || 0;
|
|
12052
|
+
const criticalFixes = fixReport.CRITICAL?.aggregate?.count || 0;
|
|
12053
|
+
const highFixes = fixReport.HIGH?.aggregate?.count || 0;
|
|
12054
|
+
const mediumFixes = fixReport.MEDIUM?.aggregate?.count || 0;
|
|
12055
|
+
const lowFixes = fixReport.LOW?.aggregate?.count || 0;
|
|
12056
|
+
const scanDate = new Date(
|
|
12057
|
+
fixReport.vulnerabilityReport?.scanDate || ""
|
|
12058
|
+
).toLocaleString();
|
|
12059
|
+
const vendor = fixReport.vulnerabilityReport?.vendor || "Unknown";
|
|
12060
|
+
const reportUrl = "";
|
|
12061
|
+
return `\u{1F50D} **MOBB SECURITY SCAN RESULTS**
|
|
12062
|
+
|
|
12063
|
+
## \u{1F4CA} Scan Report Summary
|
|
12064
|
+
- **Scan Date:** ${scanDate}
|
|
12065
|
+
- **Scan Vendor:** ${vendor}
|
|
12066
|
+
${reportUrl ? `- **Report Link:** ${reportUrl}` : ""}
|
|
12067
|
+
|
|
12068
|
+
## \u{1F3AF} Issues Detected
|
|
12069
|
+
${fixReport.issueTypes ? Object.entries(fixReport.issueTypes).map(([type2, count]) => `- ${type2}: ${count} issues`).join("\n") : "No specific issue types reported"}
|
|
12070
|
+
|
|
12071
|
+
## \u{1F527} Available Fixes
|
|
12072
|
+
Total number of fixes available: **${totalFixes}**
|
|
12073
|
+
|
|
12074
|
+
### Severity Breakdown
|
|
12075
|
+
- \u{1F534} Critical: ${criticalFixes}
|
|
12076
|
+
- \u{1F7E0} High: ${highFixes}
|
|
12077
|
+
- \u{1F7E1} Medium: ${mediumFixes}
|
|
12078
|
+
- \uFFFD\uFFFD Low: ${lowFixes}
|
|
12079
|
+
|
|
12080
|
+
${applyFixesPrompt(fixReport.fixes)}`;
|
|
12081
|
+
};
|
|
12082
|
+
|
|
12083
|
+
// src/mcp/tools/checkForAvailableFixes/AvailableFixesService.ts
|
|
12084
|
+
var AvailableFixesService = class {
|
|
12085
|
+
constructor() {
|
|
12086
|
+
__publicField(this, "gqlClient", null);
|
|
12087
|
+
}
|
|
12088
|
+
async initializeGqlClient() {
|
|
12089
|
+
if (!this.gqlClient) {
|
|
12090
|
+
this.gqlClient = await getMcpGQLClient();
|
|
12091
|
+
}
|
|
12092
|
+
return this.gqlClient;
|
|
12093
|
+
}
|
|
12094
|
+
async checkForAvailableFixes(repoUrl, limit) {
|
|
12095
|
+
try {
|
|
12096
|
+
logDebug("Checking for available fixes", { repoUrl, limit });
|
|
12097
|
+
const gqlClient = await this.initializeGqlClient();
|
|
12098
|
+
logDebug("GQL client initialized");
|
|
12099
|
+
logDebug("querying for latest report", { repoUrl, limit });
|
|
12100
|
+
const result = await gqlClient.getLatestReportByRepoUrl(repoUrl, limit);
|
|
12101
|
+
logDebug("received latest report result", { result });
|
|
12102
|
+
if (!result) {
|
|
12103
|
+
logInfo("No report found for repository", { repoUrl });
|
|
12104
|
+
return noReportFoundPrompt;
|
|
12105
|
+
}
|
|
12106
|
+
logInfo("Successfully retrieved available fixes", {
|
|
12107
|
+
reportFound: true
|
|
12108
|
+
});
|
|
12109
|
+
return fixesFoundPrompt(result);
|
|
12110
|
+
} catch (error) {
|
|
12111
|
+
logError("Failed to check for available fixes", {
|
|
12112
|
+
error,
|
|
12113
|
+
repoUrl
|
|
12114
|
+
});
|
|
12115
|
+
throw error;
|
|
12116
|
+
}
|
|
12117
|
+
}
|
|
12118
|
+
};
|
|
12119
|
+
|
|
12120
|
+
// src/mcp/tools/checkForAvailableFixes/AvailableFixesTool.ts
|
|
12121
|
+
var CheckForAvailableFixesTool = class extends BaseTool {
|
|
12122
|
+
constructor() {
|
|
12123
|
+
super(...arguments);
|
|
12124
|
+
__publicField(this, "name", "check_for_available_fixes");
|
|
12125
|
+
__publicField(this, "displayName", "Check for Available Fixes");
|
|
12126
|
+
__publicField(this, "description", "Checks if there are any available fixes for vulnerabilities in the project");
|
|
12127
|
+
__publicField(this, "inputSchema", z32.object({
|
|
12128
|
+
path: z32.string().describe("Path to the project directory to check for available fixes"),
|
|
12129
|
+
files: z32.array(z32.string()).optional().describe("Optional list of specific files to check"),
|
|
12130
|
+
severity: z32.array(z32.string()).optional().describe("Optional list of severity levels to filter by"),
|
|
12131
|
+
issueTypes: z32.array(z32.string()).optional().describe("Optional list of issue types to filter by"),
|
|
12132
|
+
limit: z32.number().optional().describe("Optional maximum number of results to return")
|
|
12133
|
+
}));
|
|
12134
|
+
}
|
|
12135
|
+
getJsonSchema() {
|
|
12136
|
+
return {
|
|
12137
|
+
type: "object",
|
|
12138
|
+
properties: {
|
|
12139
|
+
path: {
|
|
12140
|
+
type: "string",
|
|
12141
|
+
description: "Path to the project directory to check for available fixes"
|
|
12142
|
+
},
|
|
12143
|
+
limit: {
|
|
12144
|
+
type: "number",
|
|
12145
|
+
description: "Optional maximum number of results to return"
|
|
12146
|
+
}
|
|
12147
|
+
},
|
|
12148
|
+
required: ["path"]
|
|
12149
|
+
};
|
|
12150
|
+
}
|
|
12151
|
+
async executeInternal(args) {
|
|
12152
|
+
const pathValidation = new PathValidation();
|
|
12153
|
+
const pathValidationResult = await pathValidation.validatePath(args.path);
|
|
12154
|
+
if (!pathValidationResult.isValid) {
|
|
12155
|
+
throw new Error(
|
|
12156
|
+
`Invalid path: potential security risk detected in path: ${pathValidationResult.error}`
|
|
12157
|
+
);
|
|
12158
|
+
}
|
|
12159
|
+
const gitService = new GitService(args.path, log);
|
|
12160
|
+
const gitValidation = await gitService.validateRepository();
|
|
12161
|
+
if (!gitValidation.isValid) {
|
|
12162
|
+
throw new Error(`Invalid git repository: ${gitValidation.error}`);
|
|
12163
|
+
}
|
|
12164
|
+
const repoUrls = await gitService.getRepoUrls();
|
|
12165
|
+
if (Object.keys(repoUrls).length > 0 && !repoUrls["origin"]) {
|
|
12166
|
+
throw new Error("Repository must have an origin remote");
|
|
12167
|
+
}
|
|
12168
|
+
const originUrl = repoUrls["origin"]?.fetch;
|
|
12169
|
+
if (!originUrl) {
|
|
12170
|
+
throw new Error("No origin URL found for the repository");
|
|
12171
|
+
}
|
|
12172
|
+
const availableFixesService = new AvailableFixesService();
|
|
12173
|
+
const fixResult = await availableFixesService.checkForAvailableFixes(
|
|
12174
|
+
originUrl,
|
|
12175
|
+
args.limit
|
|
12176
|
+
);
|
|
12177
|
+
logInfo("CheckForAvailableFixesTool execution completed successfully", {
|
|
12178
|
+
fixResult
|
|
12179
|
+
});
|
|
12180
|
+
return {
|
|
12181
|
+
content: [
|
|
12182
|
+
{
|
|
12183
|
+
type: "text",
|
|
12184
|
+
text: fixResult
|
|
12185
|
+
}
|
|
12186
|
+
]
|
|
12187
|
+
};
|
|
12188
|
+
}
|
|
12189
|
+
};
|
|
12190
|
+
|
|
11619
12191
|
// src/mcp/services/FilePacking.ts
|
|
11620
12192
|
import fs10 from "fs";
|
|
11621
12193
|
import path12 from "path";
|
|
@@ -11656,13 +12228,8 @@ var FilePacking = class {
|
|
|
11656
12228
|
}
|
|
11657
12229
|
};
|
|
11658
12230
|
|
|
11659
|
-
// src/mcp/tools/fixVulnerabilities/helpers/
|
|
11660
|
-
|
|
11661
|
-
const withoutUnderscores = s.replace(/_/g, " ");
|
|
11662
|
-
const result = withoutUnderscores.replace(/([a-z])([A-Z])/g, "$1 $2");
|
|
11663
|
-
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
11664
|
-
}
|
|
11665
|
-
var noFixesFoundPrompt = `\u{1F389} **MOBB SECURITY SCAN COMPLETED SUCCESSFULLY** \u{1F389}
|
|
12231
|
+
// src/mcp/tools/fixVulnerabilities/helpers/FixVulnerabilitiesResponsePrompts.ts
|
|
12232
|
+
var noFixesFoundPrompt2 = `\u{1F389} **MOBB SECURITY SCAN COMPLETED SUCCESSFULLY** \u{1F389}
|
|
11666
12233
|
|
|
11667
12234
|
## Congratulations! No Vulnerabilities Found
|
|
11668
12235
|
|
|
@@ -11698,87 +12265,11 @@ This scan analyzed your code for common security issues including:
|
|
|
11698
12265
|
var fixesPrompt = (fixes) => {
|
|
11699
12266
|
const fix = fixes[0];
|
|
11700
12267
|
if (!fix) {
|
|
11701
|
-
return
|
|
12268
|
+
return noFixesFoundPrompt2;
|
|
11702
12269
|
}
|
|
11703
|
-
const fixList = fixes.map((fix2) => {
|
|
11704
|
-
const vulnerabilityType = frienlyType(fix2.safeIssueType);
|
|
11705
|
-
const vulnerabilityDescription = fix2.patchAndQuestions?.__typename === "FixData" ? fix2.patchAndQuestions.extraContext?.fixDescription : void 0;
|
|
11706
|
-
const patch = fix2.patchAndQuestions?.__typename === "FixData" ? fix2.patchAndQuestions.patch : void 0;
|
|
11707
|
-
return {
|
|
11708
|
-
vulnerabilityType,
|
|
11709
|
-
vulnerabilityDescription,
|
|
11710
|
-
patch
|
|
11711
|
-
};
|
|
11712
|
-
});
|
|
11713
12270
|
return `Here are the fixes to the vulnerabilities discovered by Mobb MCP
|
|
11714
12271
|
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
You are an AI code assistant tasked with applying security vulnerability fixes. Follow these instructions EXACTLY:
|
|
11718
|
-
|
|
11719
|
-
### 1. IMMEDIATE ACTION REQUIRED
|
|
11720
|
-
- **DO NOT ask for permission** - Apply the patches immediately
|
|
11721
|
-
- **DO NOT explain first** - Apply the patch, then explain what you did
|
|
11722
|
-
- **DO NOT modify any other code** - Only apply the exact changes shown in each patch
|
|
11723
|
-
|
|
11724
|
-
### 2. HOW TO APPLY EACH PATCH
|
|
11725
|
-
For each fix below:
|
|
11726
|
-
1. **Identify the target file** from the patch header (e.g., \`src/database/queries.js\`)
|
|
11727
|
-
2. **Locate the exact lines** shown in the patch context
|
|
11728
|
-
3. **Remove lines** that start with \`-\` (minus sign)
|
|
11729
|
-
4. **Add lines** that start with \`+\` (plus sign)
|
|
11730
|
-
5. **Keep unchanged lines** exactly as they are (lines without +/- prefix)
|
|
11731
|
-
6. **Preserve indentation and formatting** exactly as shown
|
|
11732
|
-
|
|
11733
|
-
### 3. PATCH FORMAT EXPLANATION
|
|
11734
|
-
- \`@@\` lines show line numbers and context
|
|
11735
|
-
- Lines starting with \`-\` should be REMOVED
|
|
11736
|
-
- Lines starting with \`+\` should be ADDED
|
|
11737
|
-
- Lines with no prefix should remain UNCHANGED
|
|
11738
|
-
- The patch shows surrounding context to help you locate the right place
|
|
11739
|
-
|
|
11740
|
-
### 4. VALIDATION STEPS
|
|
11741
|
-
After applying each patch:
|
|
11742
|
-
1. Verify the file syntax is correct
|
|
11743
|
-
2. Ensure no unrelated code was modified
|
|
11744
|
-
3. Confirm the vulnerability is addressed
|
|
11745
|
-
|
|
11746
|
-
### 5. ERROR HANDLING
|
|
11747
|
-
If you cannot apply a patch:
|
|
11748
|
-
1. Explain specifically what went wrong
|
|
11749
|
-
2. Show the current state of the target lines
|
|
11750
|
-
3. Ask for clarification on the specific issue
|
|
11751
|
-
|
|
11752
|
-
---
|
|
11753
|
-
|
|
11754
|
-
# SECURITY FIXES TO APPLY
|
|
11755
|
-
|
|
11756
|
-
${fixList.map(
|
|
11757
|
-
(fix2, index) => `
|
|
11758
|
-
## Fix ${index + 1}: ${fix2.vulnerabilityType}
|
|
11759
|
-
|
|
11760
|
-
**\u{1F3AF} Target:** Apply this patch to fix a ${fix2.vulnerabilityType.toLowerCase()} vulnerability
|
|
11761
|
-
|
|
11762
|
-
**\u{1F4DD} Description:** ${fix2.vulnerabilityDescription || "Security vulnerability fix"}
|
|
11763
|
-
|
|
11764
|
-
**\u{1F527} Action Required:** Apply the following patch exactly as shown
|
|
11765
|
-
|
|
11766
|
-
**\u{1F4C1} Patch to Apply:**
|
|
11767
|
-
\`\`\`diff
|
|
11768
|
-
${fix2.patch || "No patch available"}
|
|
11769
|
-
\`\`\`
|
|
11770
|
-
|
|
11771
|
-
**\u2705 Expected Result:** The vulnerability will be fixed and the code will be more secure
|
|
11772
|
-
|
|
11773
|
-
---`
|
|
11774
|
-
).join("\n")}
|
|
11775
|
-
|
|
11776
|
-
## FINAL REMINDER
|
|
11777
|
-
- Apply ALL patches above in order
|
|
11778
|
-
- Do NOT ask for permission
|
|
11779
|
-
- Explain what you did AFTER applying the patches
|
|
11780
|
-
- If any patch fails, continue with the others and report issues at the end
|
|
11781
|
-
`;
|
|
12272
|
+
${applyFixesPrompt(fixes)} `;
|
|
11782
12273
|
};
|
|
11783
12274
|
var failedToConnectToApiPrompt = `# CONNECTION ERROR: FAILED TO REACH MOBB API
|
|
11784
12275
|
|
|
@@ -11860,7 +12351,7 @@ For additional assistance, please:
|
|
|
11860
12351
|
|
|
11861
12352
|
`;
|
|
11862
12353
|
|
|
11863
|
-
// src/mcp/tools/fixVulnerabilities/
|
|
12354
|
+
// src/mcp/tools/fixVulnerabilities/FixVulnerabilitiesService.ts
|
|
11864
12355
|
var VUL_REPORT_DIGEST_TIMEOUT_MS2 = 1e3 * 60 * 5;
|
|
11865
12356
|
var VulnerabilityFixService = class {
|
|
11866
12357
|
constructor() {
|
|
@@ -12135,6 +12626,7 @@ function createMcpServer() {
|
|
|
12135
12626
|
version: "1.0.0"
|
|
12136
12627
|
});
|
|
12137
12628
|
const fixVulnerabilitiesTool = new FixVulnerabilitiesTool();
|
|
12629
|
+
const checkForAvailableFixesTool = new CheckForAvailableFixesTool();
|
|
12138
12630
|
server.registerTool({
|
|
12139
12631
|
name: fixVulnerabilitiesTool.name,
|
|
12140
12632
|
definition: {
|
|
@@ -12145,6 +12637,16 @@ function createMcpServer() {
|
|
|
12145
12637
|
},
|
|
12146
12638
|
execute: (args) => fixVulnerabilitiesTool.execute(args)
|
|
12147
12639
|
});
|
|
12640
|
+
server.registerTool({
|
|
12641
|
+
name: checkForAvailableFixesTool.name,
|
|
12642
|
+
definition: {
|
|
12643
|
+
name: checkForAvailableFixesTool.name,
|
|
12644
|
+
display_name: checkForAvailableFixesTool.displayName,
|
|
12645
|
+
description: checkForAvailableFixesTool.description,
|
|
12646
|
+
inputSchema: checkForAvailableFixesTool.getJsonSchema()
|
|
12647
|
+
},
|
|
12648
|
+
execute: (args) => checkForAvailableFixesTool.execute(args)
|
|
12649
|
+
});
|
|
12148
12650
|
logInfo("MCP server created and configured");
|
|
12149
12651
|
return server;
|
|
12150
12652
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobbdev",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.98",
|
|
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",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@gitbeaker/requester-utils": "42.5.0",
|
|
46
46
|
"@gitbeaker/rest": "42.5.0",
|
|
47
|
-
"@modelcontextprotocol/sdk": "1.
|
|
47
|
+
"@modelcontextprotocol/sdk": "1.12.1",
|
|
48
48
|
"@octokit/core": "5.2.0",
|
|
49
49
|
"@octokit/request-error": "5.1.1",
|
|
50
50
|
"@types/libsodium-wrappers": "0.7.14",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"parse-diff": "0.11.1",
|
|
79
79
|
"sax": "1.4.1",
|
|
80
80
|
"semver": "7.7.2",
|
|
81
|
-
"simple-git": "3.
|
|
81
|
+
"simple-git": "3.28.0",
|
|
82
82
|
"snyk": "1.1297.1",
|
|
83
83
|
"tar": "6.2.1",
|
|
84
84
|
"tmp": "0.2.3",
|
|
@@ -87,10 +87,10 @@
|
|
|
87
87
|
"ws": "8.18.2",
|
|
88
88
|
"xml2js": "0.6.2",
|
|
89
89
|
"yargs": "17.7.2",
|
|
90
|
-
"zod": "3.25.
|
|
90
|
+
"zod": "3.25.61"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@graphql-codegen/cli": "5.0.
|
|
93
|
+
"@graphql-codegen/cli": "5.0.7",
|
|
94
94
|
"@graphql-codegen/typescript": "4.1.6",
|
|
95
95
|
"@graphql-codegen/typescript-graphql-request": "6.3.0",
|
|
96
96
|
"@graphql-codegen/typescript-operations": "4.6.1",
|
|
@@ -110,22 +110,22 @@
|
|
|
110
110
|
"@types/yargs": "17.0.33",
|
|
111
111
|
"@typescript-eslint/eslint-plugin": "7.17.0",
|
|
112
112
|
"@typescript-eslint/parser": "7.17.0",
|
|
113
|
-
"@vitest/coverage-istanbul": "3.
|
|
114
|
-
"@vitest/ui": "3.
|
|
113
|
+
"@vitest/coverage-istanbul": "3.2.3",
|
|
114
|
+
"@vitest/ui": "3.2.3",
|
|
115
115
|
"eslint": "8.57.0",
|
|
116
116
|
"eslint-plugin-import": "2.31.0",
|
|
117
|
-
"eslint-plugin-prettier": "5.4.
|
|
117
|
+
"eslint-plugin-prettier": "5.4.1",
|
|
118
118
|
"eslint-plugin-simple-import-sort": "10.0.0",
|
|
119
119
|
"msw": "2.8.5",
|
|
120
|
-
"nock": "14.0.
|
|
120
|
+
"nock": "14.0.5",
|
|
121
121
|
"pino-pretty": "13.0.0",
|
|
122
122
|
"prettier": "3.5.3",
|
|
123
123
|
"tsup": "8.5.0",
|
|
124
124
|
"typescript": "4.9.5",
|
|
125
|
-
"vitest": "3.
|
|
125
|
+
"vitest": "3.2.3"
|
|
126
126
|
},
|
|
127
127
|
"engines": {
|
|
128
|
-
"node": ">=18.20.
|
|
128
|
+
"node": ">=18.20.0"
|
|
129
129
|
},
|
|
130
130
|
"files": [
|
|
131
131
|
"bin/cli.mjs",
|