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.
@@ -3864,7 +3864,7 @@ import z26 from "zod";
3864
3864
 
3865
3865
  // src/commands/handleMobbLogin.ts
3866
3866
  import chalk2 from "chalk";
3867
- import Debug6 from "debug";
3867
+ import Debug7 from "debug";
3868
3868
 
3869
3869
  // src/utils/dirname.ts
3870
3870
  import fs from "fs";
@@ -4085,10 +4085,8 @@ var errorMessages = {
4085
4085
  var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
4086
4086
 
4087
4087
  // src/features/analysis/graphql/gql.ts
4088
- import fetchOrig from "cross-fetch";
4089
- import Debug5 from "debug";
4088
+ import Debug6 from "debug";
4090
4089
  import { GraphQLClient } from "graphql-request";
4091
- import { HttpsProxyAgent } from "https-proxy-agent";
4092
4090
  import { v4 as uuidv4 } from "uuid";
4093
4091
 
4094
4092
  // src/mcp/core/Errors.ts
@@ -4118,6 +4116,71 @@ var ScanContext = {
4118
4116
  BUGSY: "BUGSY"
4119
4117
  };
4120
4118
 
4119
+ // src/utils/proxy.ts
4120
+ import fetchOrig from "cross-fetch";
4121
+ import Debug2 from "debug";
4122
+ import { HttpsProxyAgent } from "https-proxy-agent";
4123
+
4124
+ // src/utils/url.ts
4125
+ function httpToWsUrl(url) {
4126
+ const parsed = new URL(url);
4127
+ parsed.protocol = parsed.protocol === "https:" ? "wss:" : "ws:";
4128
+ return parsed.toString();
4129
+ }
4130
+
4131
+ // src/utils/proxy.ts
4132
+ var debug2 = Debug2("mobbdev:proxy");
4133
+ function getHttpProxy() {
4134
+ return process.env["HTTPS_PROXY"] || process.env["HTTP_PROXY"] || "";
4135
+ }
4136
+ function getHttpProxyOnly() {
4137
+ return process.env["HTTP_PROXY"] || "";
4138
+ }
4139
+ function getProxyAgent(url) {
4140
+ try {
4141
+ const parsedUrl = new URL(url);
4142
+ const hostname = parsedUrl.hostname.toLowerCase();
4143
+ if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
4144
+ debug2("Skipping proxy for localhost URL: %s", url);
4145
+ return void 0;
4146
+ }
4147
+ const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
4148
+ if (noProxy) {
4149
+ const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
4150
+ if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
4151
+ debug2("Skipping proxy due to NO_PROXY for: %s", url);
4152
+ return void 0;
4153
+ }
4154
+ }
4155
+ const isHttp = parsedUrl.protocol === "http:";
4156
+ const isHttps = parsedUrl.protocol === "https:";
4157
+ const proxy = isHttps ? getHttpProxy() : isHttp ? getHttpProxyOnly() : null;
4158
+ if (proxy) {
4159
+ debug2("Using proxy %s", proxy);
4160
+ debug2("Proxy agent %o", proxy);
4161
+ return new HttpsProxyAgent(proxy);
4162
+ }
4163
+ } catch (err) {
4164
+ debug2(`Skipping proxy for ${url}. Reason: ${err.message}`);
4165
+ }
4166
+ return void 0;
4167
+ }
4168
+ var fetchWithProxy = (url, options = {}) => {
4169
+ try {
4170
+ const agent = getProxyAgent(url.toString());
4171
+ if (agent) {
4172
+ return fetchOrig(url, {
4173
+ ...options,
4174
+ // @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
4175
+ agent
4176
+ });
4177
+ }
4178
+ } catch (err) {
4179
+ debug2(`Skipping proxy for ${url}. Reason: ${err.message}`);
4180
+ }
4181
+ return fetchOrig(url, options);
4182
+ };
4183
+
4121
4184
  // src/utils/subscribe/subscribe.ts
4122
4185
  import { createClient } from "graphql-ws";
4123
4186
  import WebsocketNode from "isomorphic-ws";
@@ -4146,11 +4209,11 @@ function getGraphQlHeaders(options) {
4146
4209
  }
4147
4210
 
4148
4211
  // src/utils/subscribe/subscribe.ts
4149
- var DEFAULT_API_URL2 = "https://api.mobb.ai/v1/graphql";
4212
+ var DEFAULT_API_URL2 = "wss://api.mobb.ai/v1/graphql";
4150
4213
  var SUBSCRIPTION_TIMEOUT_MS = 30 * 60 * 1e3;
4151
4214
  function createWSClient(options) {
4152
- const url = options.url || (process.env["API_URL"] || DEFAULT_API_URL2).replace("http", "ws");
4153
- const websocketImpl = options.websocket || (typeof WebSocket !== "undefined" ? WebSocket : WebsocketNode);
4215
+ const url = options.url || (process.env["API_URL"] ? httpToWsUrl(process.env["API_URL"]) : DEFAULT_API_URL2);
4216
+ const websocketImpl = options.websocket || WebsocketNode;
4154
4217
  const CustomWebSocket = options.proxyAgent ? (
4155
4218
  // biome-ignore lint/suspicious/noExplicitAny: Dynamic WebSocket extension requires any cast for cross-platform compatibility
4156
4219
  class extends websocketImpl {
@@ -6169,7 +6232,7 @@ var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
6169
6232
  init_env();
6170
6233
  import querystring from "querystring";
6171
6234
  import * as api from "azure-devops-node-api";
6172
- import Debug2 from "debug";
6235
+ import Debug3 from "debug";
6173
6236
  import { z as z18 } from "zod";
6174
6237
 
6175
6238
  // src/features/analysis/scm/ado/validation.ts
@@ -6208,7 +6271,7 @@ var accountsZ = z17.object({
6208
6271
  });
6209
6272
 
6210
6273
  // src/features/analysis/scm/ado/utils.ts
6211
- var debug2 = Debug2("mobbdev:scm:ado");
6274
+ var debug3 = Debug3("mobbdev:scm:ado");
6212
6275
 
6213
6276
  // src/features/analysis/scm/ado/AdoSCMLib.ts
6214
6277
  import { setTimeout as setTimeout2 } from "timers/promises";
@@ -6220,7 +6283,7 @@ init_GitService();
6220
6283
  import querystring2 from "querystring";
6221
6284
  import * as bitbucketPkgNode from "bitbucket";
6222
6285
  import bitbucketPkg from "bitbucket";
6223
- import Debug3 from "debug";
6286
+ import Debug4 from "debug";
6224
6287
  import { z as z20 } from "zod";
6225
6288
 
6226
6289
  // src/features/analysis/scm/bitbucket/validation.ts
@@ -6232,7 +6295,7 @@ var BitbucketAuthResultZ = z19.object({
6232
6295
  });
6233
6296
 
6234
6297
  // src/features/analysis/scm/bitbucket/bitbucket.ts
6235
- var debug3 = Debug3("scm:bitbucket");
6298
+ var debug4 = Debug4("scm:bitbucket");
6236
6299
  var BITBUCKET_HOSTNAME = "bitbucket.org";
6237
6300
  var TokenExpiredErrorZ = z20.object({
6238
6301
  status: z20.number(),
@@ -6283,7 +6346,7 @@ import {
6283
6346
  AccessLevel,
6284
6347
  Gitlab
6285
6348
  } from "@gitbeaker/rest";
6286
- import Debug4 from "debug";
6349
+ import Debug5 from "debug";
6287
6350
  import pLimit from "p-limit";
6288
6351
  import {
6289
6352
  Agent,
@@ -6293,7 +6356,7 @@ import {
6293
6356
 
6294
6357
  // src/utils/contextLogger.ts
6295
6358
  import debugModule from "debug";
6296
- var debug4 = debugModule("mobb:shared");
6359
+ var debug5 = debugModule("mobb:shared");
6297
6360
 
6298
6361
  // src/features/analysis/scm/gitlab/gitlab.ts
6299
6362
  init_env();
@@ -6307,7 +6370,7 @@ var GitlabAuthResultZ = z23.object({
6307
6370
  });
6308
6371
 
6309
6372
  // src/features/analysis/scm/gitlab/gitlab.ts
6310
- var debug5 = Debug4("scm:gitlab");
6373
+ var debug6 = Debug5("scm:gitlab");
6311
6374
 
6312
6375
  // src/features/analysis/scm/gitlab/GitlabSCMLib.ts
6313
6376
  init_client_generates();
@@ -6381,63 +6444,19 @@ var GetVulByNodesMetadataZ = z25.object({
6381
6444
  });
6382
6445
 
6383
6446
  // src/features/analysis/graphql/gql.ts
6384
- var debug6 = Debug5("mobbdev:gql");
6447
+ var debug7 = Debug6("mobbdev:gql");
6385
6448
  var API_KEY_HEADER_NAME = "x-mobb-key";
6386
6449
  var REPORT_STATE_CHECK_DELAY = 5 * 1e3;
6387
- function getProxyAgent(url) {
6388
- try {
6389
- const parsedUrl = new URL(url);
6390
- const hostname = parsedUrl.hostname.toLowerCase();
6391
- if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
6392
- debug6("Skipping proxy for localhost URL: %s", url);
6393
- return void 0;
6394
- }
6395
- const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
6396
- if (noProxy) {
6397
- const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
6398
- if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
6399
- debug6("Skipping proxy due to NO_PROXY for: %s", url);
6400
- return void 0;
6401
- }
6402
- }
6403
- const isHttp = parsedUrl.protocol === "http:";
6404
- const isHttps = parsedUrl.protocol === "https:";
6405
- const proxy = isHttps ? HTTPS_PROXY || HTTP_PROXY : isHttp ? HTTP_PROXY : null;
6406
- if (proxy) {
6407
- debug6("Using proxy %s", proxy);
6408
- debug6("Proxy agent %o", proxy);
6409
- return new HttpsProxyAgent(proxy);
6410
- }
6411
- } catch (err) {
6412
- debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
6413
- }
6414
- return void 0;
6415
- }
6416
- var fetchWithProxy = (url, options = {}) => {
6417
- try {
6418
- const agent = getProxyAgent(url.toString());
6419
- if (agent) {
6420
- return fetchOrig(url, {
6421
- ...options,
6422
- // @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
6423
- agent
6424
- });
6425
- }
6426
- } catch (err) {
6427
- debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
6428
- }
6429
- return fetchOrig(url, options);
6430
- };
6431
6450
  var GQLClient = class {
6432
6451
  constructor(args) {
6433
6452
  __publicField(this, "_client");
6434
6453
  __publicField(this, "_clientSdk");
6435
6454
  __publicField(this, "_apiUrl");
6436
6455
  __publicField(this, "_auth");
6437
- debug6(`init with ${args}`);
6456
+ debug7(`init with ${args}`);
6438
6457
  this._auth = args;
6439
6458
  this._apiUrl = args.apiUrl || API_URL;
6440
- debug6(
6459
+ debug7(
6441
6460
  "GQLClient constructor: resolved apiUrl=%s (from param: %s)",
6442
6461
  this._apiUrl,
6443
6462
  args.apiUrl || "fallback to API_URL constant"
@@ -6449,7 +6468,7 @@ var GQLClient = class {
6449
6468
  fetch: fetchWithProxy,
6450
6469
  requestMiddleware: (request) => {
6451
6470
  const requestId = uuidv4();
6452
- debug6(
6471
+ debug7(
6453
6472
  `sending API request with id: ${requestId} and with request: ${request.body}`
6454
6473
  );
6455
6474
  return {
@@ -6486,7 +6505,7 @@ var GQLClient = class {
6486
6505
  await this.getUserInfo();
6487
6506
  } catch (e) {
6488
6507
  if (e?.toString().startsWith("FetchError")) {
6489
- debug6("verify connection failed %o", e);
6508
+ debug7("verify connection failed %o", e);
6490
6509
  return false;
6491
6510
  }
6492
6511
  }
@@ -6498,7 +6517,7 @@ var GQLClient = class {
6498
6517
  try {
6499
6518
  info = await this.getUserInfo();
6500
6519
  } catch (e) {
6501
- debug6("verify token failed %o", e);
6520
+ debug7("verify token failed %o", e);
6502
6521
  return false;
6503
6522
  }
6504
6523
  return info?.email || true;
@@ -6559,7 +6578,7 @@ var GQLClient = class {
6559
6578
  try {
6560
6579
  await this._clientSdk.CreateCommunityUser();
6561
6580
  } catch (e) {
6562
- debug6("create community user failed %o", e);
6581
+ debug7("create community user failed %o", e);
6563
6582
  }
6564
6583
  }
6565
6584
  async updateScmToken(args) {
@@ -6739,11 +6758,13 @@ var GQLClient = class {
6739
6758
  this._auth.type === "apiKey" ? {
6740
6759
  apiKey: this._auth.apiKey,
6741
6760
  type: "apiKey",
6761
+ url: httpToWsUrl(this._apiUrl),
6742
6762
  timeoutInMs: params.timeoutInMs,
6743
6763
  proxyAgent: getProxyAgent(this._apiUrl)
6744
6764
  } : {
6745
6765
  token: this._auth.token,
6746
6766
  type: "token",
6767
+ url: httpToWsUrl(this._apiUrl),
6747
6768
  timeoutInMs: params.timeoutInMs,
6748
6769
  proxyAgent: getProxyAgent(this._apiUrl)
6749
6770
  }
@@ -6756,7 +6777,7 @@ var GQLClient = class {
6756
6777
  const startTime = Date.now();
6757
6778
  const maxDuration = timeoutInMs ?? 30 * 60 * 1e3;
6758
6779
  const pollingIntervalSec = REPORT_STATE_CHECK_DELAY / 1e3;
6759
- debug6(
6780
+ debug7(
6760
6781
  `[pollForAnalysisState] Starting polling for analysis ${analysisId}, target states: ${callbackStates.join(", ")}, interval: ${pollingIntervalSec}s`
6761
6782
  );
6762
6783
  let isPolling = true;
@@ -6765,7 +6786,7 @@ var GQLClient = class {
6765
6786
  pollCount++;
6766
6787
  const elapsedSec = Math.round((Date.now() - startTime) / 1e3);
6767
6788
  if (Date.now() - startTime > maxDuration) {
6768
- debug6(
6789
+ debug7(
6769
6790
  `[pollForAnalysisState] Timeout expired after ${pollCount} polls (${elapsedSec}s)`
6770
6791
  );
6771
6792
  throw new ReportDigestError(
@@ -6773,20 +6794,20 @@ var GQLClient = class {
6773
6794
  `Analysis timed out after ${Math.round(maxDuration / 6e4)} minutes. Please try again or check the Mobb platform for status.`
6774
6795
  );
6775
6796
  }
6776
- debug6(
6797
+ debug7(
6777
6798
  `[pollForAnalysisState] Poll #${pollCount} (elapsed: ${elapsedSec}s) - fetching analysis state...`
6778
6799
  );
6779
6800
  const analysis = await this.getAnalysis(analysisId);
6780
- debug6(
6801
+ debug7(
6781
6802
  `[pollForAnalysisState] Poll #${pollCount} - current state: ${analysis.state}`
6782
6803
  );
6783
6804
  if (!analysis.state || analysis.state === "Failed" /* Failed */) {
6784
6805
  const errorMessage = analysis.failReason || `Analysis failed with id: ${analysis.id}`;
6785
- debug6(`[pollForAnalysisState] Analysis failed: ${errorMessage}`);
6806
+ debug7(`[pollForAnalysisState] Analysis failed: ${errorMessage}`);
6786
6807
  throw new ReportDigestError(errorMessage, analysis.failReason ?? "");
6787
6808
  }
6788
6809
  if (callbackStates.includes(analysis.state)) {
6789
- debug6(
6810
+ debug7(
6790
6811
  `[pollForAnalysisState] Target state reached: ${analysis.state} after ${pollCount} polls (${elapsedSec}s)`
6791
6812
  );
6792
6813
  await callback(analysis.id);
@@ -6799,7 +6820,7 @@ var GQLClient = class {
6799
6820
  }
6800
6821
  };
6801
6822
  }
6802
- debug6(
6823
+ debug7(
6803
6824
  `[pollForAnalysisState] State ${analysis.state} not in target states, waiting ${pollingIntervalSec}s before next poll...`
6804
6825
  );
6805
6826
  await sleep(REPORT_STATE_CHECK_DELAY);
@@ -7068,7 +7089,7 @@ var AuthManager = class {
7068
7089
  };
7069
7090
 
7070
7091
  // src/commands/handleMobbLogin.ts
7071
- var debug7 = Debug6("mobbdev:commands");
7092
+ var debug8 = Debug7("mobbdev:commands");
7072
7093
  var LOGIN_MAX_WAIT2 = 10 * 60 * 1e3;
7073
7094
  var LOGIN_CHECK_DELAY2 = 5 * 1e3;
7074
7095
  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, ${chalk2.bgBlue(
@@ -7080,7 +7101,7 @@ async function getAuthenticatedGQLClient({
7080
7101
  apiUrl,
7081
7102
  webAppUrl
7082
7103
  }) {
7083
- debug7(
7104
+ debug8(
7084
7105
  "getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
7085
7106
  apiUrl || "undefined",
7086
7107
  webAppUrl || "undefined"
@@ -7103,7 +7124,7 @@ async function handleMobbLogin({
7103
7124
  webAppUrl,
7104
7125
  loginContext
7105
7126
  }) {
7106
- debug7(
7127
+ debug8(
7107
7128
  "handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
7108
7129
  apiUrl || "fallback",
7109
7130
  apiUrl || "fallback",
@@ -7122,7 +7143,7 @@ async function handleMobbLogin({
7122
7143
  return authManager.getGQLClient();
7123
7144
  }
7124
7145
  } catch (error) {
7125
- debug7("Authentication check failed:", error);
7146
+ debug8("Authentication check failed:", error);
7126
7147
  }
7127
7148
  if (apiKey) {
7128
7149
  createSpinner().start().error({
@@ -7174,9 +7195,9 @@ init_GitService();
7174
7195
  init_urlParser2();
7175
7196
 
7176
7197
  // src/features/analysis/upload-file.ts
7177
- import Debug7 from "debug";
7198
+ import Debug8 from "debug";
7178
7199
  import fetch3, { File, fileFrom, FormData } from "node-fetch";
7179
- var debug8 = Debug7("mobbdev:upload-file");
7200
+ var debug9 = Debug8("mobbdev:upload-file");
7180
7201
  async function uploadFile({
7181
7202
  file,
7182
7203
  url,
@@ -7189,9 +7210,9 @@ async function uploadFile({
7189
7210
  logInfo(`FileUpload: upload file start ${url}`);
7190
7211
  logInfo(`FileUpload: upload fields`, uploadFields);
7191
7212
  logInfo(`FileUpload: upload key ${uploadKey}`);
7192
- debug8("upload file start %s", url);
7193
- debug8("upload fields %o", uploadFields);
7194
- debug8("upload key %s", uploadKey);
7213
+ debug9("upload file start %s", url);
7214
+ debug9("upload fields %o", uploadFields);
7215
+ debug9("upload key %s", uploadKey);
7195
7216
  const form = new FormData();
7196
7217
  Object.entries(uploadFields).forEach(([key, value]) => {
7197
7218
  form.append(key, value);
@@ -7200,11 +7221,11 @@ async function uploadFile({
7200
7221
  form.append("key", uploadKey);
7201
7222
  }
7202
7223
  if (typeof file === "string") {
7203
- debug8("upload file from path %s", file);
7224
+ debug9("upload file from path %s", file);
7204
7225
  logInfo(`FileUpload: upload file from path ${file}`);
7205
7226
  form.append("file", await fileFrom(file));
7206
7227
  } else {
7207
- debug8("upload file from buffer");
7228
+ debug9("upload file from buffer");
7208
7229
  logInfo(`FileUpload: upload file from buffer`);
7209
7230
  form.append("file", new File([new Uint8Array(file)], "file"));
7210
7231
  }
@@ -7215,11 +7236,11 @@ async function uploadFile({
7215
7236
  agent
7216
7237
  });
7217
7238
  if (!response.ok) {
7218
- debug8("error from S3 %s %s", response.body, response.status);
7239
+ debug9("error from S3 %s %s", response.body, response.status);
7219
7240
  logInfo(`FileUpload: error from S3 ${response.body} ${response.status}`);
7220
7241
  throw new Error(`Failed to upload the file: ${response.status}`);
7221
7242
  }
7222
- debug8("upload file done");
7243
+ debug9("upload file done");
7223
7244
  logInfo(`FileUpload: upload file done`);
7224
7245
  }
7225
7246