mobbdev 1.2.28 → 1.2.29
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/args/commands/upload_ai_blame.mjs +106 -85
- package/dist/index.mjs +180 -174
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3908,7 +3908,7 @@ ${rootContent}`;
|
|
|
3908
3908
|
});
|
|
3909
3909
|
|
|
3910
3910
|
// src/index.ts
|
|
3911
|
-
import
|
|
3911
|
+
import Debug20 from "debug";
|
|
3912
3912
|
import { hideBin } from "yargs/helpers";
|
|
3913
3913
|
|
|
3914
3914
|
// src/args/yargs.ts
|
|
@@ -11469,7 +11469,7 @@ import path9 from "path";
|
|
|
11469
11469
|
import { env as env2 } from "process";
|
|
11470
11470
|
import { pipeline } from "stream/promises";
|
|
11471
11471
|
import chalk6 from "chalk";
|
|
11472
|
-
import
|
|
11472
|
+
import Debug19 from "debug";
|
|
11473
11473
|
import extract from "extract-zip";
|
|
11474
11474
|
import { createSpinner as createSpinner4 } from "nanospinner";
|
|
11475
11475
|
import fetch4 from "node-fetch";
|
|
@@ -11479,7 +11479,7 @@ import { z as z29 } from "zod";
|
|
|
11479
11479
|
|
|
11480
11480
|
// src/commands/handleMobbLogin.ts
|
|
11481
11481
|
import chalk3 from "chalk";
|
|
11482
|
-
import
|
|
11482
|
+
import Debug7 from "debug";
|
|
11483
11483
|
|
|
11484
11484
|
// src/commands/AuthManager.ts
|
|
11485
11485
|
import crypto from "crypto";
|
|
@@ -11487,10 +11487,8 @@ import os from "os";
|
|
|
11487
11487
|
import open from "open";
|
|
11488
11488
|
|
|
11489
11489
|
// src/features/analysis/graphql/gql.ts
|
|
11490
|
-
import
|
|
11491
|
-
import Debug5 from "debug";
|
|
11490
|
+
import Debug6 from "debug";
|
|
11492
11491
|
import { GraphQLClient } from "graphql-request";
|
|
11493
|
-
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
11494
11492
|
import { v4 as uuidv4 } from "uuid";
|
|
11495
11493
|
|
|
11496
11494
|
// src/mcp/core/Errors.ts
|
|
@@ -11565,6 +11563,71 @@ var _ReportDigestError = class _ReportDigestError extends Error {
|
|
|
11565
11563
|
__publicField(_ReportDigestError, "defaultMessage", "\u{1F575}\uFE0F\u200D\u2642\uFE0F Digesting report failed. Please verify that the file provided is of a valid supported report format.");
|
|
11566
11564
|
var ReportDigestError = _ReportDigestError;
|
|
11567
11565
|
|
|
11566
|
+
// src/utils/proxy.ts
|
|
11567
|
+
import fetchOrig from "cross-fetch";
|
|
11568
|
+
import Debug5 from "debug";
|
|
11569
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
11570
|
+
|
|
11571
|
+
// src/utils/url.ts
|
|
11572
|
+
function httpToWsUrl(url) {
|
|
11573
|
+
const parsed = new URL(url);
|
|
11574
|
+
parsed.protocol = parsed.protocol === "https:" ? "wss:" : "ws:";
|
|
11575
|
+
return parsed.toString();
|
|
11576
|
+
}
|
|
11577
|
+
|
|
11578
|
+
// src/utils/proxy.ts
|
|
11579
|
+
var debug6 = Debug5("mobbdev:proxy");
|
|
11580
|
+
function getHttpProxy() {
|
|
11581
|
+
return process.env["HTTPS_PROXY"] || process.env["HTTP_PROXY"] || "";
|
|
11582
|
+
}
|
|
11583
|
+
function getHttpProxyOnly() {
|
|
11584
|
+
return process.env["HTTP_PROXY"] || "";
|
|
11585
|
+
}
|
|
11586
|
+
function getProxyAgent(url) {
|
|
11587
|
+
try {
|
|
11588
|
+
const parsedUrl = new URL(url);
|
|
11589
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
11590
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
|
|
11591
|
+
debug6("Skipping proxy for localhost URL: %s", url);
|
|
11592
|
+
return void 0;
|
|
11593
|
+
}
|
|
11594
|
+
const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
|
|
11595
|
+
if (noProxy) {
|
|
11596
|
+
const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
|
|
11597
|
+
if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
|
|
11598
|
+
debug6("Skipping proxy due to NO_PROXY for: %s", url);
|
|
11599
|
+
return void 0;
|
|
11600
|
+
}
|
|
11601
|
+
}
|
|
11602
|
+
const isHttp = parsedUrl.protocol === "http:";
|
|
11603
|
+
const isHttps = parsedUrl.protocol === "https:";
|
|
11604
|
+
const proxy = isHttps ? getHttpProxy() : isHttp ? getHttpProxyOnly() : null;
|
|
11605
|
+
if (proxy) {
|
|
11606
|
+
debug6("Using proxy %s", proxy);
|
|
11607
|
+
debug6("Proxy agent %o", proxy);
|
|
11608
|
+
return new HttpsProxyAgent(proxy);
|
|
11609
|
+
}
|
|
11610
|
+
} catch (err) {
|
|
11611
|
+
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
11612
|
+
}
|
|
11613
|
+
return void 0;
|
|
11614
|
+
}
|
|
11615
|
+
var fetchWithProxy = (url, options = {}) => {
|
|
11616
|
+
try {
|
|
11617
|
+
const agent = getProxyAgent(url.toString());
|
|
11618
|
+
if (agent) {
|
|
11619
|
+
return fetchOrig(url, {
|
|
11620
|
+
...options,
|
|
11621
|
+
// @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
|
|
11622
|
+
agent
|
|
11623
|
+
});
|
|
11624
|
+
}
|
|
11625
|
+
} catch (err) {
|
|
11626
|
+
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
11627
|
+
}
|
|
11628
|
+
return fetchOrig(url, options);
|
|
11629
|
+
};
|
|
11630
|
+
|
|
11568
11631
|
// src/utils/subscribe/subscribe.ts
|
|
11569
11632
|
import { createClient } from "graphql-ws";
|
|
11570
11633
|
import WebsocketNode from "isomorphic-ws";
|
|
@@ -11593,11 +11656,11 @@ function getGraphQlHeaders(options) {
|
|
|
11593
11656
|
}
|
|
11594
11657
|
|
|
11595
11658
|
// src/utils/subscribe/subscribe.ts
|
|
11596
|
-
var DEFAULT_API_URL2 = "
|
|
11659
|
+
var DEFAULT_API_URL2 = "wss://api.mobb.ai/v1/graphql";
|
|
11597
11660
|
var SUBSCRIPTION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
11598
11661
|
function createWSClient(options) {
|
|
11599
|
-
const url = options.url || (process.env["API_URL"]
|
|
11600
|
-
const websocketImpl = options.websocket ||
|
|
11662
|
+
const url = options.url || (process.env["API_URL"] ? httpToWsUrl(process.env["API_URL"]) : DEFAULT_API_URL2);
|
|
11663
|
+
const websocketImpl = options.websocket || WebsocketNode;
|
|
11601
11664
|
const CustomWebSocket = options.proxyAgent ? (
|
|
11602
11665
|
// biome-ignore lint/suspicious/noExplicitAny: Dynamic WebSocket extension requires any cast for cross-platform compatibility
|
|
11603
11666
|
class extends websocketImpl {
|
|
@@ -11761,63 +11824,19 @@ var GetVulByNodesMetadataZ = z25.object({
|
|
|
11761
11824
|
});
|
|
11762
11825
|
|
|
11763
11826
|
// src/features/analysis/graphql/gql.ts
|
|
11764
|
-
var
|
|
11827
|
+
var debug7 = Debug6("mobbdev:gql");
|
|
11765
11828
|
var API_KEY_HEADER_NAME = "x-mobb-key";
|
|
11766
11829
|
var REPORT_STATE_CHECK_DELAY = 5 * 1e3;
|
|
11767
|
-
function getProxyAgent(url) {
|
|
11768
|
-
try {
|
|
11769
|
-
const parsedUrl = new URL(url);
|
|
11770
|
-
const hostname = parsedUrl.hostname.toLowerCase();
|
|
11771
|
-
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
|
|
11772
|
-
debug6("Skipping proxy for localhost URL: %s", url);
|
|
11773
|
-
return void 0;
|
|
11774
|
-
}
|
|
11775
|
-
const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
|
|
11776
|
-
if (noProxy) {
|
|
11777
|
-
const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
|
|
11778
|
-
if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
|
|
11779
|
-
debug6("Skipping proxy due to NO_PROXY for: %s", url);
|
|
11780
|
-
return void 0;
|
|
11781
|
-
}
|
|
11782
|
-
}
|
|
11783
|
-
const isHttp = parsedUrl.protocol === "http:";
|
|
11784
|
-
const isHttps = parsedUrl.protocol === "https:";
|
|
11785
|
-
const proxy = isHttps ? HTTPS_PROXY || HTTP_PROXY : isHttp ? HTTP_PROXY : null;
|
|
11786
|
-
if (proxy) {
|
|
11787
|
-
debug6("Using proxy %s", proxy);
|
|
11788
|
-
debug6("Proxy agent %o", proxy);
|
|
11789
|
-
return new HttpsProxyAgent(proxy);
|
|
11790
|
-
}
|
|
11791
|
-
} catch (err) {
|
|
11792
|
-
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
11793
|
-
}
|
|
11794
|
-
return void 0;
|
|
11795
|
-
}
|
|
11796
|
-
var fetchWithProxy = (url, options = {}) => {
|
|
11797
|
-
try {
|
|
11798
|
-
const agent = getProxyAgent(url.toString());
|
|
11799
|
-
if (agent) {
|
|
11800
|
-
return fetchOrig(url, {
|
|
11801
|
-
...options,
|
|
11802
|
-
// @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
|
|
11803
|
-
agent
|
|
11804
|
-
});
|
|
11805
|
-
}
|
|
11806
|
-
} catch (err) {
|
|
11807
|
-
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
11808
|
-
}
|
|
11809
|
-
return fetchOrig(url, options);
|
|
11810
|
-
};
|
|
11811
11830
|
var GQLClient = class {
|
|
11812
11831
|
constructor(args) {
|
|
11813
11832
|
__publicField(this, "_client");
|
|
11814
11833
|
__publicField(this, "_clientSdk");
|
|
11815
11834
|
__publicField(this, "_apiUrl");
|
|
11816
11835
|
__publicField(this, "_auth");
|
|
11817
|
-
|
|
11836
|
+
debug7(`init with ${args}`);
|
|
11818
11837
|
this._auth = args;
|
|
11819
11838
|
this._apiUrl = args.apiUrl || API_URL;
|
|
11820
|
-
|
|
11839
|
+
debug7(
|
|
11821
11840
|
"GQLClient constructor: resolved apiUrl=%s (from param: %s)",
|
|
11822
11841
|
this._apiUrl,
|
|
11823
11842
|
args.apiUrl || "fallback to API_URL constant"
|
|
@@ -11829,7 +11848,7 @@ var GQLClient = class {
|
|
|
11829
11848
|
fetch: fetchWithProxy,
|
|
11830
11849
|
requestMiddleware: (request) => {
|
|
11831
11850
|
const requestId = uuidv4();
|
|
11832
|
-
|
|
11851
|
+
debug7(
|
|
11833
11852
|
`sending API request with id: ${requestId} and with request: ${request.body}`
|
|
11834
11853
|
);
|
|
11835
11854
|
return {
|
|
@@ -11866,7 +11885,7 @@ var GQLClient = class {
|
|
|
11866
11885
|
await this.getUserInfo();
|
|
11867
11886
|
} catch (e) {
|
|
11868
11887
|
if (e?.toString().startsWith("FetchError")) {
|
|
11869
|
-
|
|
11888
|
+
debug7("verify connection failed %o", e);
|
|
11870
11889
|
return false;
|
|
11871
11890
|
}
|
|
11872
11891
|
}
|
|
@@ -11878,7 +11897,7 @@ var GQLClient = class {
|
|
|
11878
11897
|
try {
|
|
11879
11898
|
info = await this.getUserInfo();
|
|
11880
11899
|
} catch (e) {
|
|
11881
|
-
|
|
11900
|
+
debug7("verify token failed %o", e);
|
|
11882
11901
|
return false;
|
|
11883
11902
|
}
|
|
11884
11903
|
return info?.email || true;
|
|
@@ -11939,7 +11958,7 @@ var GQLClient = class {
|
|
|
11939
11958
|
try {
|
|
11940
11959
|
await this._clientSdk.CreateCommunityUser();
|
|
11941
11960
|
} catch (e) {
|
|
11942
|
-
|
|
11961
|
+
debug7("create community user failed %o", e);
|
|
11943
11962
|
}
|
|
11944
11963
|
}
|
|
11945
11964
|
async updateScmToken(args) {
|
|
@@ -12119,11 +12138,13 @@ var GQLClient = class {
|
|
|
12119
12138
|
this._auth.type === "apiKey" ? {
|
|
12120
12139
|
apiKey: this._auth.apiKey,
|
|
12121
12140
|
type: "apiKey",
|
|
12141
|
+
url: httpToWsUrl(this._apiUrl),
|
|
12122
12142
|
timeoutInMs: params.timeoutInMs,
|
|
12123
12143
|
proxyAgent: getProxyAgent(this._apiUrl)
|
|
12124
12144
|
} : {
|
|
12125
12145
|
token: this._auth.token,
|
|
12126
12146
|
type: "token",
|
|
12147
|
+
url: httpToWsUrl(this._apiUrl),
|
|
12127
12148
|
timeoutInMs: params.timeoutInMs,
|
|
12128
12149
|
proxyAgent: getProxyAgent(this._apiUrl)
|
|
12129
12150
|
}
|
|
@@ -12136,7 +12157,7 @@ var GQLClient = class {
|
|
|
12136
12157
|
const startTime = Date.now();
|
|
12137
12158
|
const maxDuration = timeoutInMs ?? 30 * 60 * 1e3;
|
|
12138
12159
|
const pollingIntervalSec = REPORT_STATE_CHECK_DELAY / 1e3;
|
|
12139
|
-
|
|
12160
|
+
debug7(
|
|
12140
12161
|
`[pollForAnalysisState] Starting polling for analysis ${analysisId}, target states: ${callbackStates.join(", ")}, interval: ${pollingIntervalSec}s`
|
|
12141
12162
|
);
|
|
12142
12163
|
let isPolling = true;
|
|
@@ -12145,7 +12166,7 @@ var GQLClient = class {
|
|
|
12145
12166
|
pollCount++;
|
|
12146
12167
|
const elapsedSec = Math.round((Date.now() - startTime) / 1e3);
|
|
12147
12168
|
if (Date.now() - startTime > maxDuration) {
|
|
12148
|
-
|
|
12169
|
+
debug7(
|
|
12149
12170
|
`[pollForAnalysisState] Timeout expired after ${pollCount} polls (${elapsedSec}s)`
|
|
12150
12171
|
);
|
|
12151
12172
|
throw new ReportDigestError(
|
|
@@ -12153,20 +12174,20 @@ var GQLClient = class {
|
|
|
12153
12174
|
`Analysis timed out after ${Math.round(maxDuration / 6e4)} minutes. Please try again or check the Mobb platform for status.`
|
|
12154
12175
|
);
|
|
12155
12176
|
}
|
|
12156
|
-
|
|
12177
|
+
debug7(
|
|
12157
12178
|
`[pollForAnalysisState] Poll #${pollCount} (elapsed: ${elapsedSec}s) - fetching analysis state...`
|
|
12158
12179
|
);
|
|
12159
12180
|
const analysis = await this.getAnalysis(analysisId);
|
|
12160
|
-
|
|
12181
|
+
debug7(
|
|
12161
12182
|
`[pollForAnalysisState] Poll #${pollCount} - current state: ${analysis.state}`
|
|
12162
12183
|
);
|
|
12163
12184
|
if (!analysis.state || analysis.state === "Failed" /* Failed */) {
|
|
12164
12185
|
const errorMessage = analysis.failReason || `Analysis failed with id: ${analysis.id}`;
|
|
12165
|
-
|
|
12186
|
+
debug7(`[pollForAnalysisState] Analysis failed: ${errorMessage}`);
|
|
12166
12187
|
throw new ReportDigestError(errorMessage, analysis.failReason ?? "");
|
|
12167
12188
|
}
|
|
12168
12189
|
if (callbackStates.includes(analysis.state)) {
|
|
12169
|
-
|
|
12190
|
+
debug7(
|
|
12170
12191
|
`[pollForAnalysisState] Target state reached: ${analysis.state} after ${pollCount} polls (${elapsedSec}s)`
|
|
12171
12192
|
);
|
|
12172
12193
|
await callback(analysis.id);
|
|
@@ -12179,7 +12200,7 @@ var GQLClient = class {
|
|
|
12179
12200
|
}
|
|
12180
12201
|
};
|
|
12181
12202
|
}
|
|
12182
|
-
|
|
12203
|
+
debug7(
|
|
12183
12204
|
`[pollForAnalysisState] State ${analysis.state} not in target states, waiting ${pollingIntervalSec}s before next poll...`
|
|
12184
12205
|
);
|
|
12185
12206
|
await sleep(REPORT_STATE_CHECK_DELAY);
|
|
@@ -12468,7 +12489,7 @@ var AuthManager = class {
|
|
|
12468
12489
|
};
|
|
12469
12490
|
|
|
12470
12491
|
// src/commands/handleMobbLogin.ts
|
|
12471
|
-
var
|
|
12492
|
+
var debug8 = Debug7("mobbdev:commands");
|
|
12472
12493
|
var LOGIN_MAX_WAIT2 = 10 * 60 * 1e3;
|
|
12473
12494
|
var LOGIN_CHECK_DELAY2 = 5 * 1e3;
|
|
12474
12495
|
var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk3.bgBlue(
|
|
@@ -12480,7 +12501,7 @@ async function getAuthenticatedGQLClient({
|
|
|
12480
12501
|
apiUrl,
|
|
12481
12502
|
webAppUrl
|
|
12482
12503
|
}) {
|
|
12483
|
-
|
|
12504
|
+
debug8(
|
|
12484
12505
|
"getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
|
|
12485
12506
|
apiUrl || "undefined",
|
|
12486
12507
|
webAppUrl || "undefined"
|
|
@@ -12503,7 +12524,7 @@ async function handleMobbLogin({
|
|
|
12503
12524
|
webAppUrl,
|
|
12504
12525
|
loginContext
|
|
12505
12526
|
}) {
|
|
12506
|
-
|
|
12527
|
+
debug8(
|
|
12507
12528
|
"handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
|
|
12508
12529
|
apiUrl || "fallback",
|
|
12509
12530
|
apiUrl || "fallback",
|
|
@@ -12522,7 +12543,7 @@ async function handleMobbLogin({
|
|
|
12522
12543
|
return authManager.getGQLClient();
|
|
12523
12544
|
}
|
|
12524
12545
|
} catch (error) {
|
|
12525
|
-
|
|
12546
|
+
debug8("Authentication check failed:", error);
|
|
12526
12547
|
}
|
|
12527
12548
|
if (apiKey) {
|
|
12528
12549
|
createSpinner5().start().error({
|
|
@@ -12569,10 +12590,10 @@ async function handleMobbLogin({
|
|
|
12569
12590
|
}
|
|
12570
12591
|
|
|
12571
12592
|
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
12572
|
-
import
|
|
12593
|
+
import Debug11 from "debug";
|
|
12573
12594
|
|
|
12574
12595
|
// src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
|
|
12575
|
-
import
|
|
12596
|
+
import Debug10 from "debug";
|
|
12576
12597
|
import parseDiff from "parse-diff";
|
|
12577
12598
|
import { z as z27 } from "zod";
|
|
12578
12599
|
|
|
@@ -12584,9 +12605,9 @@ function keyBy(array, keyBy2) {
|
|
|
12584
12605
|
}
|
|
12585
12606
|
|
|
12586
12607
|
// src/features/analysis/utils/send_report.ts
|
|
12587
|
-
import
|
|
12608
|
+
import Debug8 from "debug";
|
|
12588
12609
|
init_client_generates();
|
|
12589
|
-
var
|
|
12610
|
+
var debug9 = Debug8("mobbdev:index");
|
|
12590
12611
|
async function sendReport({
|
|
12591
12612
|
spinner,
|
|
12592
12613
|
submitVulnerabilityReportVariables,
|
|
@@ -12598,7 +12619,7 @@ async function sendReport({
|
|
|
12598
12619
|
submitVulnerabilityReportVariables
|
|
12599
12620
|
);
|
|
12600
12621
|
if (submitRes.submitVulnerabilityReport.__typename !== "VulnerabilityReport") {
|
|
12601
|
-
|
|
12622
|
+
debug9("error submit vul report %s", submitRes);
|
|
12602
12623
|
throw new Error("\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed");
|
|
12603
12624
|
}
|
|
12604
12625
|
spinner.update({ text: progressMassages.processingVulnerabilityReport });
|
|
@@ -12610,7 +12631,7 @@ async function sendReport({
|
|
|
12610
12631
|
"Finished" /* Finished */
|
|
12611
12632
|
];
|
|
12612
12633
|
if (polling) {
|
|
12613
|
-
|
|
12634
|
+
debug9("[sendReport] Using POLLING mode for analysis state updates");
|
|
12614
12635
|
await gqlClient.pollForAnalysisState({
|
|
12615
12636
|
analysisId: submitRes.submitVulnerabilityReport.fixReportId,
|
|
12616
12637
|
callback,
|
|
@@ -12618,7 +12639,7 @@ async function sendReport({
|
|
|
12618
12639
|
timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
|
|
12619
12640
|
});
|
|
12620
12641
|
} else {
|
|
12621
|
-
|
|
12642
|
+
debug9("[sendReport] Using WEBSOCKET mode for analysis state updates");
|
|
12622
12643
|
await gqlClient.subscribeToAnalysis({
|
|
12623
12644
|
subscribeToAnalysisParams: {
|
|
12624
12645
|
analysisId: submitRes.submitVulnerabilityReport.fixReportId
|
|
@@ -12661,10 +12682,10 @@ var scannerToFriendlyString = {
|
|
|
12661
12682
|
};
|
|
12662
12683
|
|
|
12663
12684
|
// src/features/analysis/add_fix_comments_for_pr/utils/buildCommentBody.ts
|
|
12664
|
-
import
|
|
12685
|
+
import Debug9 from "debug";
|
|
12665
12686
|
import { z as z26 } from "zod";
|
|
12666
12687
|
init_client_generates();
|
|
12667
|
-
var
|
|
12688
|
+
var debug10 = Debug9("mobbdev:handle-finished-analysis");
|
|
12668
12689
|
var getCommitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
12669
12690
|
function buildFixCommentBody({
|
|
12670
12691
|
fix,
|
|
@@ -12723,7 +12744,7 @@ function buildFixCommentBody({
|
|
|
12723
12744
|
safeIssueType: z26.nativeEnum(IssueType_Enum)
|
|
12724
12745
|
}).safeParse(fix);
|
|
12725
12746
|
if (!validFixParseRes.success) {
|
|
12726
|
-
|
|
12747
|
+
debug10(
|
|
12727
12748
|
`fix ${fixId} has custom issue type or language, therefore the commit description will not be added`,
|
|
12728
12749
|
validFixParseRes.error
|
|
12729
12750
|
);
|
|
@@ -12787,7 +12808,7 @@ ${issuePageLink}`;
|
|
|
12787
12808
|
}
|
|
12788
12809
|
|
|
12789
12810
|
// src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
|
|
12790
|
-
var
|
|
12811
|
+
var debug11 = Debug10("mobbdev:handle-finished-analysis");
|
|
12791
12812
|
function calculateRanges(integers) {
|
|
12792
12813
|
if (integers.length === 0) {
|
|
12793
12814
|
return [];
|
|
@@ -12821,7 +12842,7 @@ function deleteAllPreviousComments({
|
|
|
12821
12842
|
try {
|
|
12822
12843
|
return scm.deleteComment({ comment_id: comment.id });
|
|
12823
12844
|
} catch (e) {
|
|
12824
|
-
|
|
12845
|
+
debug11("delete comment failed %s", e);
|
|
12825
12846
|
return Promise.resolve();
|
|
12826
12847
|
}
|
|
12827
12848
|
});
|
|
@@ -12837,7 +12858,7 @@ function deleteAllPreviousGeneralPrComments(params) {
|
|
|
12837
12858
|
try {
|
|
12838
12859
|
return scm.deleteGeneralPrComment({ commentId: comment.id });
|
|
12839
12860
|
} catch (e) {
|
|
12840
|
-
|
|
12861
|
+
debug11("delete comment failed %s", e);
|
|
12841
12862
|
return Promise.resolve();
|
|
12842
12863
|
}
|
|
12843
12864
|
});
|
|
@@ -12981,7 +13002,7 @@ async function postAnalysisInsightComment(params) {
|
|
|
12981
13002
|
fixablePrVuls,
|
|
12982
13003
|
nonFixablePrVuls
|
|
12983
13004
|
} = prVulenrabilities;
|
|
12984
|
-
|
|
13005
|
+
debug11({
|
|
12985
13006
|
fixablePrVuls,
|
|
12986
13007
|
nonFixablePrVuls,
|
|
12987
13008
|
vulnerabilitiesOutsidePr,
|
|
@@ -13036,7 +13057,7 @@ ${contactUsMarkdown}`;
|
|
|
13036
13057
|
}
|
|
13037
13058
|
|
|
13038
13059
|
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
13039
|
-
var
|
|
13060
|
+
var debug12 = Debug11("mobbdev:handle-finished-analysis");
|
|
13040
13061
|
async function addFixCommentsForPr({
|
|
13041
13062
|
analysisId,
|
|
13042
13063
|
scm: _scm,
|
|
@@ -13048,7 +13069,7 @@ async function addFixCommentsForPr({
|
|
|
13048
13069
|
}
|
|
13049
13070
|
const scm = _scm;
|
|
13050
13071
|
const getAnalysisRes = await gqlClient.getAnalysis(analysisId);
|
|
13051
|
-
|
|
13072
|
+
debug12("getAnalysis %o", getAnalysisRes);
|
|
13052
13073
|
const {
|
|
13053
13074
|
vulnerabilityReport: {
|
|
13054
13075
|
projectId,
|
|
@@ -13158,8 +13179,8 @@ ${contextString}` : description;
|
|
|
13158
13179
|
|
|
13159
13180
|
// src/features/analysis/auto_pr_handler.ts
|
|
13160
13181
|
init_client_generates();
|
|
13161
|
-
import
|
|
13162
|
-
var
|
|
13182
|
+
import Debug12 from "debug";
|
|
13183
|
+
var debug13 = Debug12("mobbdev:handleAutoPr");
|
|
13163
13184
|
async function handleAutoPr(params) {
|
|
13164
13185
|
const {
|
|
13165
13186
|
gqlClient,
|
|
@@ -13180,7 +13201,7 @@ async function handleAutoPr(params) {
|
|
|
13180
13201
|
prId,
|
|
13181
13202
|
prStrategy: createOnePr ? "CONDENSE" /* Condense */ : "SPREAD" /* Spread */
|
|
13182
13203
|
});
|
|
13183
|
-
|
|
13204
|
+
debug13("auto pr analysis res %o", autoPrAnalysisRes);
|
|
13184
13205
|
if (autoPrAnalysisRes.autoPrAnalysis?.__typename === "AutoPrError") {
|
|
13185
13206
|
createAutoPrSpinner.error({
|
|
13186
13207
|
text: `\u{1F504} Automatic pull request failed - ${autoPrAnalysisRes.autoPrAnalysis.error}`
|
|
@@ -13202,14 +13223,14 @@ async function handleAutoPr(params) {
|
|
|
13202
13223
|
};
|
|
13203
13224
|
const callbackStates = ["Finished" /* Finished */];
|
|
13204
13225
|
if (polling) {
|
|
13205
|
-
|
|
13226
|
+
debug13("[handleAutoPr] Using POLLING mode for analysis state updates");
|
|
13206
13227
|
return await gqlClient.pollForAnalysisState({
|
|
13207
13228
|
analysisId,
|
|
13208
13229
|
callback,
|
|
13209
13230
|
callbackStates
|
|
13210
13231
|
});
|
|
13211
13232
|
} else {
|
|
13212
|
-
|
|
13233
|
+
debug13("[handleAutoPr] Using WEBSOCKET mode for analysis state updates");
|
|
13213
13234
|
return await gqlClient.subscribeToAnalysis({
|
|
13214
13235
|
subscribeToAnalysisParams: {
|
|
13215
13236
|
analysisId
|
|
@@ -13222,15 +13243,15 @@ async function handleAutoPr(params) {
|
|
|
13222
13243
|
|
|
13223
13244
|
// src/features/analysis/git.ts
|
|
13224
13245
|
init_GitService();
|
|
13225
|
-
import
|
|
13226
|
-
var
|
|
13246
|
+
import Debug13 from "debug";
|
|
13247
|
+
var debug14 = Debug13("mobbdev:git");
|
|
13227
13248
|
async function getGitInfo(srcDirPath) {
|
|
13228
|
-
|
|
13249
|
+
debug14("getting git info for %s", srcDirPath);
|
|
13229
13250
|
const gitService = new GitService(srcDirPath);
|
|
13230
13251
|
try {
|
|
13231
13252
|
const validationResult = await gitService.validateRepository();
|
|
13232
13253
|
if (!validationResult.isValid) {
|
|
13233
|
-
|
|
13254
|
+
debug14("folder is not a git repo");
|
|
13234
13255
|
return {
|
|
13235
13256
|
success: false,
|
|
13236
13257
|
hash: void 0,
|
|
@@ -13245,9 +13266,9 @@ async function getGitInfo(srcDirPath) {
|
|
|
13245
13266
|
};
|
|
13246
13267
|
} catch (e) {
|
|
13247
13268
|
if (e instanceof Error) {
|
|
13248
|
-
|
|
13269
|
+
debug14("failed to run git %o", e);
|
|
13249
13270
|
if (e.message.includes(" spawn ")) {
|
|
13250
|
-
|
|
13271
|
+
debug14("git cli not installed");
|
|
13251
13272
|
} else {
|
|
13252
13273
|
throw e;
|
|
13253
13274
|
}
|
|
@@ -13261,13 +13282,13 @@ init_configs();
|
|
|
13261
13282
|
import fs9 from "fs";
|
|
13262
13283
|
import path7 from "path";
|
|
13263
13284
|
import AdmZip from "adm-zip";
|
|
13264
|
-
import
|
|
13285
|
+
import Debug14 from "debug";
|
|
13265
13286
|
import { globby } from "globby";
|
|
13266
13287
|
import { isBinary as isBinary2 } from "istextorbinary";
|
|
13267
13288
|
import { simpleGit as simpleGit3 } from "simple-git";
|
|
13268
13289
|
import { parseStringPromise } from "xml2js";
|
|
13269
13290
|
import { z as z28 } from "zod";
|
|
13270
|
-
var
|
|
13291
|
+
var debug15 = Debug14("mobbdev:pack");
|
|
13271
13292
|
var FPR_SOURCE_CODE_FILE_MAPPING_SCHEMA = z28.object({
|
|
13272
13293
|
properties: z28.object({
|
|
13273
13294
|
entry: z28.array(
|
|
@@ -13289,7 +13310,7 @@ function getManifestFilesSuffixes() {
|
|
|
13289
13310
|
return ["package.json", "pom.xml"];
|
|
13290
13311
|
}
|
|
13291
13312
|
async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
13292
|
-
|
|
13313
|
+
debug15("pack folder %s", srcDirPath);
|
|
13293
13314
|
let git = void 0;
|
|
13294
13315
|
try {
|
|
13295
13316
|
git = simpleGit3({
|
|
@@ -13299,13 +13320,13 @@ async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
|
13299
13320
|
});
|
|
13300
13321
|
await git.status();
|
|
13301
13322
|
} catch (e) {
|
|
13302
|
-
|
|
13323
|
+
debug15("failed to run git %o", e);
|
|
13303
13324
|
git = void 0;
|
|
13304
13325
|
if (e instanceof Error) {
|
|
13305
13326
|
if (e.message.includes(" spawn ")) {
|
|
13306
|
-
|
|
13327
|
+
debug15("git cli not installed");
|
|
13307
13328
|
} else if (e.message.includes("not a git repository")) {
|
|
13308
|
-
|
|
13329
|
+
debug15("folder is not a git repo");
|
|
13309
13330
|
} else {
|
|
13310
13331
|
throw e;
|
|
13311
13332
|
}
|
|
@@ -13320,9 +13341,9 @@ async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
|
13320
13341
|
followSymbolicLinks: false,
|
|
13321
13342
|
dot: true
|
|
13322
13343
|
});
|
|
13323
|
-
|
|
13344
|
+
debug15("files found %d", filepaths.length);
|
|
13324
13345
|
const zip = new AdmZip();
|
|
13325
|
-
|
|
13346
|
+
debug15("compressing files");
|
|
13326
13347
|
for (const filepath of filepaths) {
|
|
13327
13348
|
const absFilepath = path7.join(srcDirPath, filepath.toString());
|
|
13328
13349
|
if (!isIncludeAllFiles) {
|
|
@@ -13331,12 +13352,12 @@ async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
|
13331
13352
|
absFilepath.toString().replaceAll(path7.win32.sep, path7.posix.sep),
|
|
13332
13353
|
vulnFiles
|
|
13333
13354
|
)) {
|
|
13334
|
-
|
|
13355
|
+
debug15("ignoring %s because it is not a vulnerability file", filepath);
|
|
13335
13356
|
continue;
|
|
13336
13357
|
}
|
|
13337
13358
|
}
|
|
13338
13359
|
if (fs9.lstatSync(absFilepath).size > MCP_MAX_FILE_SIZE) {
|
|
13339
|
-
|
|
13360
|
+
debug15("ignoring %s because the size is > 5MB", filepath);
|
|
13340
13361
|
continue;
|
|
13341
13362
|
}
|
|
13342
13363
|
let data;
|
|
@@ -13350,16 +13371,16 @@ async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
|
13350
13371
|
data = fs9.readFileSync(absFilepath);
|
|
13351
13372
|
}
|
|
13352
13373
|
if (isBinary2(null, data)) {
|
|
13353
|
-
|
|
13374
|
+
debug15("ignoring %s because is seems to be a binary file", filepath);
|
|
13354
13375
|
continue;
|
|
13355
13376
|
}
|
|
13356
13377
|
zip.addFile(filepath.toString(), data);
|
|
13357
13378
|
}
|
|
13358
|
-
|
|
13379
|
+
debug15("get zip file buffer");
|
|
13359
13380
|
return zip.toBuffer();
|
|
13360
13381
|
}
|
|
13361
13382
|
async function repackFpr(fprPath) {
|
|
13362
|
-
|
|
13383
|
+
debug15("repack fpr file %s", fprPath);
|
|
13363
13384
|
const zipIn = new AdmZip(fprPath);
|
|
13364
13385
|
const zipOut = new AdmZip();
|
|
13365
13386
|
const mappingXML = zipIn.readAsText("src-archive/index.xml", "utf-8");
|
|
@@ -13374,7 +13395,7 @@ async function repackFpr(fprPath) {
|
|
|
13374
13395
|
zipOut.addFile(realPath, buf);
|
|
13375
13396
|
}
|
|
13376
13397
|
}
|
|
13377
|
-
|
|
13398
|
+
debug15("get repacked zip file buffer");
|
|
13378
13399
|
return zipOut.toBuffer();
|
|
13379
13400
|
}
|
|
13380
13401
|
|
|
@@ -13445,7 +13466,7 @@ async function snykArticlePrompt() {
|
|
|
13445
13466
|
// src/features/analysis/scanners/checkmarx.ts
|
|
13446
13467
|
import { createRequire } from "module";
|
|
13447
13468
|
import chalk4 from "chalk";
|
|
13448
|
-
import
|
|
13469
|
+
import Debug16 from "debug";
|
|
13449
13470
|
import { existsSync } from "fs";
|
|
13450
13471
|
import { createSpinner as createSpinner2 } from "nanospinner";
|
|
13451
13472
|
import { type } from "os";
|
|
@@ -13457,7 +13478,7 @@ var cxOperatingSystemSupportMessage = `Your operating system does not support ch
|
|
|
13457
13478
|
|
|
13458
13479
|
// src/utils/child_process.ts
|
|
13459
13480
|
import cp from "child_process";
|
|
13460
|
-
import
|
|
13481
|
+
import Debug15 from "debug";
|
|
13461
13482
|
import * as process2 from "process";
|
|
13462
13483
|
function createFork({ args, processPath, name }, options) {
|
|
13463
13484
|
const child = cp.fork(processPath, args, {
|
|
@@ -13475,16 +13496,16 @@ function createSpawn({ args, processPath, name, cwd }, options) {
|
|
|
13475
13496
|
return createChildProcess({ childProcess: child, name }, options);
|
|
13476
13497
|
}
|
|
13477
13498
|
function createChildProcess({ childProcess, name }, options) {
|
|
13478
|
-
const
|
|
13499
|
+
const debug21 = Debug15(`mobbdev:${name}`);
|
|
13479
13500
|
const { display } = options;
|
|
13480
13501
|
return new Promise((resolve, reject) => {
|
|
13481
13502
|
let out = "";
|
|
13482
13503
|
const onData = (chunk) => {
|
|
13483
|
-
|
|
13504
|
+
debug21(`chunk received from ${name} std ${chunk}`);
|
|
13484
13505
|
out += chunk;
|
|
13485
13506
|
};
|
|
13486
13507
|
if (!childProcess?.stdout || !childProcess?.stderr) {
|
|
13487
|
-
|
|
13508
|
+
debug21(`unable to fork ${name}`);
|
|
13488
13509
|
reject(new Error(`unable to fork ${name}`));
|
|
13489
13510
|
}
|
|
13490
13511
|
childProcess.stdout?.on("data", onData);
|
|
@@ -13494,18 +13515,18 @@ function createChildProcess({ childProcess, name }, options) {
|
|
|
13494
13515
|
childProcess.stderr?.pipe(process2.stderr);
|
|
13495
13516
|
}
|
|
13496
13517
|
childProcess.on("exit", (code) => {
|
|
13497
|
-
|
|
13518
|
+
debug21(`${name} exit code ${code}`);
|
|
13498
13519
|
resolve({ message: out, code });
|
|
13499
13520
|
});
|
|
13500
13521
|
childProcess.on("error", (err) => {
|
|
13501
|
-
|
|
13522
|
+
debug21(`${name} error %o`, err);
|
|
13502
13523
|
reject(err);
|
|
13503
13524
|
});
|
|
13504
13525
|
});
|
|
13505
13526
|
}
|
|
13506
13527
|
|
|
13507
13528
|
// src/features/analysis/scanners/checkmarx.ts
|
|
13508
|
-
var
|
|
13529
|
+
var debug16 = Debug16("mobbdev:checkmarx");
|
|
13509
13530
|
var moduleUrl;
|
|
13510
13531
|
if (typeof __filename !== "undefined") {
|
|
13511
13532
|
moduleUrl = __filename;
|
|
@@ -13564,14 +13585,14 @@ function validateCheckmarxInstallation() {
|
|
|
13564
13585
|
existsSync(getCheckmarxPath());
|
|
13565
13586
|
}
|
|
13566
13587
|
async function forkCheckmarx(args, { display }) {
|
|
13567
|
-
|
|
13588
|
+
debug16("fork checkmarx with args %o %s", args.join(" "), display);
|
|
13568
13589
|
return createSpawn(
|
|
13569
13590
|
{ args, processPath: getCheckmarxPath(), name: "checkmarx" },
|
|
13570
13591
|
{ display }
|
|
13571
13592
|
);
|
|
13572
13593
|
}
|
|
13573
13594
|
async function getCheckmarxReport({ reportPath, repositoryRoot, branch, projectName }, { skipPrompts = false }) {
|
|
13574
|
-
|
|
13595
|
+
debug16("get checkmarx report start %s %s", reportPath, repositoryRoot);
|
|
13575
13596
|
const { code: loginCode } = await forkCheckmarx(VALIDATE_COMMAND, {
|
|
13576
13597
|
display: false
|
|
13577
13598
|
});
|
|
@@ -13639,10 +13660,10 @@ async function validateCheckamxCredentials() {
|
|
|
13639
13660
|
// src/features/analysis/scanners/snyk.ts
|
|
13640
13661
|
import { createRequire as createRequire2 } from "module";
|
|
13641
13662
|
import chalk5 from "chalk";
|
|
13642
|
-
import
|
|
13663
|
+
import Debug17 from "debug";
|
|
13643
13664
|
import { createSpinner as createSpinner3 } from "nanospinner";
|
|
13644
13665
|
import open2 from "open";
|
|
13645
|
-
var
|
|
13666
|
+
var debug17 = Debug17("mobbdev:snyk");
|
|
13646
13667
|
var moduleUrl2;
|
|
13647
13668
|
if (typeof __filename !== "undefined") {
|
|
13648
13669
|
moduleUrl2 = __filename;
|
|
@@ -13664,13 +13685,13 @@ if (typeof __filename !== "undefined") {
|
|
|
13664
13685
|
var costumeRequire2 = createRequire2(moduleUrl2);
|
|
13665
13686
|
var SNYK_PATH = costumeRequire2.resolve("snyk/bin/snyk");
|
|
13666
13687
|
var SNYK_ARTICLE_URL = "https://docs.snyk.io/scan-using-snyk/snyk-code/configure-snyk-code#enable-snyk-code";
|
|
13667
|
-
|
|
13688
|
+
debug17("snyk executable path %s", SNYK_PATH);
|
|
13668
13689
|
async function forkSnyk(args, { display }) {
|
|
13669
|
-
|
|
13690
|
+
debug17("fork snyk with args %o %s", args, display);
|
|
13670
13691
|
return createFork({ args, processPath: SNYK_PATH, name: "snyk" }, { display });
|
|
13671
13692
|
}
|
|
13672
13693
|
async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
13673
|
-
|
|
13694
|
+
debug17("get snyk report start %s %s", reportPath, repoRoot);
|
|
13674
13695
|
const config2 = await forkSnyk(["config"], { display: false });
|
|
13675
13696
|
const { message: configMessage } = config2;
|
|
13676
13697
|
if (!configMessage.includes("api: ")) {
|
|
@@ -13684,7 +13705,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
13684
13705
|
snykLoginSpinner.update({
|
|
13685
13706
|
text: "\u{1F513} Waiting for Snyk login to complete"
|
|
13686
13707
|
});
|
|
13687
|
-
|
|
13708
|
+
debug17("no token in the config %s", config2);
|
|
13688
13709
|
await forkSnyk(["auth"], { display: true });
|
|
13689
13710
|
snykLoginSpinner.success({ text: "\u{1F513} Login to Snyk Successful" });
|
|
13690
13711
|
}
|
|
@@ -13694,12 +13715,12 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
13694
13715
|
{ display: true }
|
|
13695
13716
|
);
|
|
13696
13717
|
if (scanOutput.includes("Snyk Code is not supported for org")) {
|
|
13697
|
-
|
|
13718
|
+
debug17("snyk code is not enabled %s", scanOutput);
|
|
13698
13719
|
snykSpinner.error({ text: "\u{1F50D} Snyk configuration needed" });
|
|
13699
13720
|
const answer = await snykArticlePrompt();
|
|
13700
|
-
|
|
13721
|
+
debug17("answer %s", answer);
|
|
13701
13722
|
if (answer) {
|
|
13702
|
-
|
|
13723
|
+
debug17("opening the browser");
|
|
13703
13724
|
await open2(SNYK_ARTICLE_URL);
|
|
13704
13725
|
}
|
|
13705
13726
|
console.log(
|
|
@@ -13717,9 +13738,9 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
13717
13738
|
init_client_generates();
|
|
13718
13739
|
|
|
13719
13740
|
// src/features/analysis/upload-file.ts
|
|
13720
|
-
import
|
|
13741
|
+
import Debug18 from "debug";
|
|
13721
13742
|
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
13722
|
-
var
|
|
13743
|
+
var debug18 = Debug18("mobbdev:upload-file");
|
|
13723
13744
|
async function uploadFile({
|
|
13724
13745
|
file,
|
|
13725
13746
|
url,
|
|
@@ -13732,9 +13753,9 @@ async function uploadFile({
|
|
|
13732
13753
|
logInfo2(`FileUpload: upload file start ${url}`);
|
|
13733
13754
|
logInfo2(`FileUpload: upload fields`, uploadFields);
|
|
13734
13755
|
logInfo2(`FileUpload: upload key ${uploadKey}`);
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13756
|
+
debug18("upload file start %s", url);
|
|
13757
|
+
debug18("upload fields %o", uploadFields);
|
|
13758
|
+
debug18("upload key %s", uploadKey);
|
|
13738
13759
|
const form = new FormData();
|
|
13739
13760
|
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
13740
13761
|
form.append(key, value);
|
|
@@ -13743,11 +13764,11 @@ async function uploadFile({
|
|
|
13743
13764
|
form.append("key", uploadKey);
|
|
13744
13765
|
}
|
|
13745
13766
|
if (typeof file === "string") {
|
|
13746
|
-
|
|
13767
|
+
debug18("upload file from path %s", file);
|
|
13747
13768
|
logInfo2(`FileUpload: upload file from path ${file}`);
|
|
13748
13769
|
form.append("file", await fileFrom(file));
|
|
13749
13770
|
} else {
|
|
13750
|
-
|
|
13771
|
+
debug18("upload file from buffer");
|
|
13751
13772
|
logInfo2(`FileUpload: upload file from buffer`);
|
|
13752
13773
|
form.append("file", new File([new Uint8Array(file)], "file"));
|
|
13753
13774
|
}
|
|
@@ -13758,11 +13779,11 @@ async function uploadFile({
|
|
|
13758
13779
|
agent
|
|
13759
13780
|
});
|
|
13760
13781
|
if (!response.ok) {
|
|
13761
|
-
|
|
13782
|
+
debug18("error from S3 %s %s", response.body, response.status);
|
|
13762
13783
|
logInfo2(`FileUpload: error from S3 ${response.body} ${response.status}`);
|
|
13763
13784
|
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
13764
13785
|
}
|
|
13765
|
-
|
|
13786
|
+
debug18("upload file done");
|
|
13766
13787
|
logInfo2(`FileUpload: upload file done`);
|
|
13767
13788
|
}
|
|
13768
13789
|
|
|
@@ -13797,9 +13818,9 @@ async function downloadRepo({
|
|
|
13797
13818
|
}) {
|
|
13798
13819
|
const { createSpinner: createSpinner5 } = Spinner2({ ci });
|
|
13799
13820
|
const repoSpinner = createSpinner5("\u{1F4BE} Downloading Repo").start();
|
|
13800
|
-
|
|
13821
|
+
debug19("download repo %s %s %s", repoUrl, dirname);
|
|
13801
13822
|
const zipFilePath = path9.join(dirname, "repo.zip");
|
|
13802
|
-
|
|
13823
|
+
debug19("download URL: %s auth headers: %o", downloadUrl, authHeaders);
|
|
13803
13824
|
const response = await fetch4(downloadUrl, {
|
|
13804
13825
|
method: "GET",
|
|
13805
13826
|
headers: {
|
|
@@ -13807,7 +13828,7 @@ async function downloadRepo({
|
|
|
13807
13828
|
}
|
|
13808
13829
|
});
|
|
13809
13830
|
if (!response.ok) {
|
|
13810
|
-
|
|
13831
|
+
debug19("SCM zipball request failed %s %s", response.body, response.status);
|
|
13811
13832
|
repoSpinner.error({ text: "\u{1F4BE} Repo download failed" });
|
|
13812
13833
|
throw new Error(`Can't access ${chalk6.bold(repoUrl)}`);
|
|
13813
13834
|
}
|
|
@@ -13821,7 +13842,7 @@ async function downloadRepo({
|
|
|
13821
13842
|
if (!repoRoot) {
|
|
13822
13843
|
throw new Error("Repo root not found");
|
|
13823
13844
|
}
|
|
13824
|
-
|
|
13845
|
+
debug19("repo root %s", repoRoot);
|
|
13825
13846
|
repoSpinner.success({ text: "\u{1F4BE} Repo downloaded successfully" });
|
|
13826
13847
|
return path9.join(dirname, repoRoot);
|
|
13827
13848
|
}
|
|
@@ -13830,7 +13851,7 @@ var getReportUrl = ({
|
|
|
13830
13851
|
projectId,
|
|
13831
13852
|
fixReportId
|
|
13832
13853
|
}) => `${WEB_APP_URL}/organization/${organizationId}/project/${projectId}/report/${fixReportId}`;
|
|
13833
|
-
var
|
|
13854
|
+
var debug19 = Debug19("mobbdev:index");
|
|
13834
13855
|
async function runAnalysis(params, options) {
|
|
13835
13856
|
const tmpObj = tmp2.dirSync({
|
|
13836
13857
|
unsafeCleanup: true
|
|
@@ -13976,7 +13997,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
13976
13997
|
pullRequest,
|
|
13977
13998
|
polling
|
|
13978
13999
|
} = params;
|
|
13979
|
-
|
|
14000
|
+
debug19("start %s %s", dirname, repo);
|
|
13980
14001
|
const { createSpinner: createSpinner5 } = Spinner2({ ci });
|
|
13981
14002
|
skipPrompts = skipPrompts || ci;
|
|
13982
14003
|
const gqlClient = await getAuthenticatedGQLClient({
|
|
@@ -14045,8 +14066,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
14045
14066
|
);
|
|
14046
14067
|
}
|
|
14047
14068
|
const { sha } = getReferenceDataRes.gitReference;
|
|
14048
|
-
|
|
14049
|
-
|
|
14069
|
+
debug19("project id %s", projectId);
|
|
14070
|
+
debug19("default branch %s", reference);
|
|
14050
14071
|
if (command === "scan") {
|
|
14051
14072
|
reportPath = await getReport(
|
|
14052
14073
|
{
|
|
@@ -14374,7 +14395,7 @@ async function _digestReport({
|
|
|
14374
14395
|
text: progressMassages.processingVulnerabilityReportSuccess
|
|
14375
14396
|
});
|
|
14376
14397
|
if (polling) {
|
|
14377
|
-
|
|
14398
|
+
debug19(
|
|
14378
14399
|
"[_digestReport] Using POLLING mode for analysis state updates (--polling flag enabled)"
|
|
14379
14400
|
);
|
|
14380
14401
|
console.log(
|
|
@@ -14389,7 +14410,7 @@ async function _digestReport({
|
|
|
14389
14410
|
timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
|
|
14390
14411
|
});
|
|
14391
14412
|
} else {
|
|
14392
|
-
|
|
14413
|
+
debug19(
|
|
14393
14414
|
"[_digestReport] Using WEBSOCKET mode for analysis state updates (default)"
|
|
14394
14415
|
);
|
|
14395
14416
|
console.log(
|
|
@@ -14453,7 +14474,7 @@ async function waitForAnaysisAndReviewPr({
|
|
|
14453
14474
|
});
|
|
14454
14475
|
};
|
|
14455
14476
|
if (polling) {
|
|
14456
|
-
|
|
14477
|
+
debug19(
|
|
14457
14478
|
"[waitForAnaysisAndReviewPr] Using POLLING mode for analysis state updates"
|
|
14458
14479
|
);
|
|
14459
14480
|
console.log(
|
|
@@ -14467,7 +14488,7 @@ async function waitForAnaysisAndReviewPr({
|
|
|
14467
14488
|
callbackStates: ["Finished" /* Finished */]
|
|
14468
14489
|
});
|
|
14469
14490
|
} else {
|
|
14470
|
-
|
|
14491
|
+
debug19(
|
|
14471
14492
|
"[waitForAnaysisAndReviewPr] Using WEBSOCKET mode for analysis state updates"
|
|
14472
14493
|
);
|
|
14473
14494
|
console.log(
|
|
@@ -16091,7 +16112,6 @@ var log = logger.log.bind(logger);
|
|
|
16091
16112
|
// src/mcp/services/McpGQLClient.ts
|
|
16092
16113
|
import crypto3 from "crypto";
|
|
16093
16114
|
import { GraphQLClient as GraphQLClient2 } from "graphql-request";
|
|
16094
|
-
import { HttpsProxyAgent as HttpsProxyAgent2 } from "https-proxy-agent";
|
|
16095
16115
|
import { v4 as uuidv42 } from "uuid";
|
|
16096
16116
|
init_client_generates();
|
|
16097
16117
|
init_configs();
|
|
@@ -16306,23 +16326,6 @@ var McpAuthService = class {
|
|
|
16306
16326
|
};
|
|
16307
16327
|
|
|
16308
16328
|
// src/mcp/services/McpGQLClient.ts
|
|
16309
|
-
function getProxyAgent2(url) {
|
|
16310
|
-
try {
|
|
16311
|
-
const parsedUrl = new URL(url);
|
|
16312
|
-
const isHttp = parsedUrl.protocol === "http:";
|
|
16313
|
-
const isHttps = parsedUrl.protocol === "https:";
|
|
16314
|
-
const proxy = isHttps ? HTTPS_PROXY || HTTP_PROXY : isHttp ? HTTP_PROXY : null;
|
|
16315
|
-
if (proxy) {
|
|
16316
|
-
logDebug("[GraphQL] Using proxy for websocket subscriptions", { proxy });
|
|
16317
|
-
return new HttpsProxyAgent2(proxy);
|
|
16318
|
-
}
|
|
16319
|
-
} catch (err) {
|
|
16320
|
-
logDebug(`[GraphQL] Skipping proxy for ${url}`, {
|
|
16321
|
-
error: err.message
|
|
16322
|
-
});
|
|
16323
|
-
}
|
|
16324
|
-
return void 0;
|
|
16325
|
-
}
|
|
16326
16329
|
var McpGQLClient = class {
|
|
16327
16330
|
constructor(args) {
|
|
16328
16331
|
__publicField(this, "client");
|
|
@@ -16339,6 +16342,7 @@ var McpGQLClient = class {
|
|
|
16339
16342
|
headers: args.type === "apiKey" ? { [MCP_API_KEY_HEADER_NAME]: args.apiKey || "" } : {
|
|
16340
16343
|
Authorization: `Bearer ${args.token}`
|
|
16341
16344
|
},
|
|
16345
|
+
fetch: fetchWithProxy,
|
|
16342
16346
|
requestMiddleware: (request) => {
|
|
16343
16347
|
const requestId = uuidv42();
|
|
16344
16348
|
return {
|
|
@@ -16521,13 +16525,15 @@ var McpGQLClient = class {
|
|
|
16521
16525
|
this._auth.type === "apiKey" ? {
|
|
16522
16526
|
apiKey: this._auth.apiKey,
|
|
16523
16527
|
type: "apiKey",
|
|
16528
|
+
url: httpToWsUrl(this.apiUrl),
|
|
16524
16529
|
timeoutInMs: params.timeoutInMs,
|
|
16525
|
-
proxyAgent:
|
|
16530
|
+
proxyAgent: getProxyAgent(this.apiUrl)
|
|
16526
16531
|
} : {
|
|
16527
16532
|
token: this._auth.token,
|
|
16528
16533
|
type: "token",
|
|
16534
|
+
url: httpToWsUrl(this.apiUrl),
|
|
16529
16535
|
timeoutInMs: params.timeoutInMs,
|
|
16530
|
-
proxyAgent:
|
|
16536
|
+
proxyAgent: getProxyAgent(this.apiUrl)
|
|
16531
16537
|
}
|
|
16532
16538
|
);
|
|
16533
16539
|
}
|
|
@@ -24720,13 +24726,13 @@ var parseArgs = async (args) => {
|
|
|
24720
24726
|
};
|
|
24721
24727
|
|
|
24722
24728
|
// src/index.ts
|
|
24723
|
-
var
|
|
24729
|
+
var debug20 = Debug20("mobbdev:index");
|
|
24724
24730
|
async function run() {
|
|
24725
24731
|
return parseArgs(hideBin(process.argv));
|
|
24726
24732
|
}
|
|
24727
24733
|
(async () => {
|
|
24728
24734
|
try {
|
|
24729
|
-
|
|
24735
|
+
debug20("Bugsy CLI v%s running...", packageJson.version);
|
|
24730
24736
|
await run();
|
|
24731
24737
|
process.exit(0);
|
|
24732
24738
|
} catch (err) {
|