mobbdev 1.1.17 → 1.1.21

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.
@@ -51,18 +51,26 @@ declare const PromptItemZ: z.ZodObject<{
51
51
  name: string;
52
52
  parameters: string;
53
53
  result: string;
54
- rawArguments?: string | undefined;
55
54
  accepted?: boolean | undefined;
55
+ rawArguments?: string | undefined;
56
56
  }, {
57
57
  name: string;
58
58
  parameters: string;
59
59
  result: string;
60
- rawArguments?: string | undefined;
61
60
  accepted?: boolean | undefined;
61
+ rawArguments?: string | undefined;
62
62
  }>>;
63
63
  }, "strip", z.ZodTypeAny, {
64
64
  type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
65
+ tool?: {
66
+ name: string;
67
+ parameters: string;
68
+ result: string;
69
+ accepted?: boolean | undefined;
70
+ rawArguments?: string | undefined;
71
+ } | undefined;
65
72
  date?: Date | undefined;
73
+ text?: string | undefined;
66
74
  attachedFiles?: {
67
75
  relativePath: string;
68
76
  startLine?: number | undefined;
@@ -71,17 +79,17 @@ declare const PromptItemZ: z.ZodObject<{
71
79
  inputCount: number;
72
80
  outputCount: number;
73
81
  } | undefined;
74
- text?: string | undefined;
82
+ }, {
83
+ type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
75
84
  tool?: {
76
85
  name: string;
77
86
  parameters: string;
78
87
  result: string;
79
- rawArguments?: string | undefined;
80
88
  accepted?: boolean | undefined;
89
+ rawArguments?: string | undefined;
81
90
  } | undefined;
82
- }, {
83
- type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
84
91
  date?: Date | undefined;
92
+ text?: string | undefined;
85
93
  attachedFiles?: {
86
94
  relativePath: string;
87
95
  startLine?: number | undefined;
@@ -90,14 +98,6 @@ declare const PromptItemZ: z.ZodObject<{
90
98
  inputCount: number;
91
99
  outputCount: number;
92
100
  } | undefined;
93
- text?: string | undefined;
94
- tool?: {
95
- name: string;
96
- parameters: string;
97
- result: string;
98
- rawArguments?: string | undefined;
99
- accepted?: boolean | undefined;
100
- } | undefined;
101
101
  }>;
102
102
  type PromptItem = z.infer<typeof PromptItemZ>;
103
103
  declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
@@ -134,18 +134,26 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
134
134
  name: string;
135
135
  parameters: string;
136
136
  result: string;
137
- rawArguments?: string | undefined;
138
137
  accepted?: boolean | undefined;
138
+ rawArguments?: string | undefined;
139
139
  }, {
140
140
  name: string;
141
141
  parameters: string;
142
142
  result: string;
143
- rawArguments?: string | undefined;
144
143
  accepted?: boolean | undefined;
144
+ rawArguments?: string | undefined;
145
145
  }>>;
146
146
  }, "strip", z.ZodTypeAny, {
147
147
  type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
148
+ tool?: {
149
+ name: string;
150
+ parameters: string;
151
+ result: string;
152
+ accepted?: boolean | undefined;
153
+ rawArguments?: string | undefined;
154
+ } | undefined;
148
155
  date?: Date | undefined;
156
+ text?: string | undefined;
149
157
  attachedFiles?: {
150
158
  relativePath: string;
151
159
  startLine?: number | undefined;
@@ -154,17 +162,17 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
154
162
  inputCount: number;
155
163
  outputCount: number;
156
164
  } | undefined;
157
- text?: string | undefined;
165
+ }, {
166
+ type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
158
167
  tool?: {
159
168
  name: string;
160
169
  parameters: string;
161
170
  result: string;
162
- rawArguments?: string | undefined;
163
171
  accepted?: boolean | undefined;
172
+ rawArguments?: string | undefined;
164
173
  } | undefined;
165
- }, {
166
- type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
167
174
  date?: Date | undefined;
175
+ text?: string | undefined;
168
176
  attachedFiles?: {
169
177
  relativePath: string;
170
178
  startLine?: number | undefined;
@@ -173,14 +181,6 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
173
181
  inputCount: number;
174
182
  outputCount: number;
175
183
  } | undefined;
176
- text?: string | undefined;
177
- tool?: {
178
- name: string;
179
- parameters: string;
180
- result: string;
181
- rawArguments?: string | undefined;
182
- accepted?: boolean | undefined;
183
- } | undefined;
184
184
  }>, "many">;
185
185
  type PromptItemArray = z.infer<typeof PromptItemArrayZ>;
186
186
  type UploadAiBlameOptions = {
@@ -1118,6 +1118,31 @@ var GetUserMvsAutoFixDocument = `
1118
1118
  }
1119
1119
  }
1120
1120
  `;
1121
+ var StreamBlameAiAnalysisRequestsDocument = `
1122
+ subscription streamBlameAiAnalysisRequests($requestIds: [uuid!]!) {
1123
+ blame_ai_analysis_request(where: {id: {_in: $requestIds}}) {
1124
+ id
1125
+ state
1126
+ commitId
1127
+ organizationId
1128
+ createdOn
1129
+ }
1130
+ }
1131
+ `;
1132
+ var StreamCommitBlameRequestsDocument = `
1133
+ subscription streamCommitBlameRequests($requestIds: [uuid!]!) {
1134
+ commit_blame_request(where: {id: {_in: $requestIds}}) {
1135
+ id
1136
+ state
1137
+ organizationId
1138
+ repositoryUrl
1139
+ commitSha
1140
+ createdOn
1141
+ completedOn
1142
+ error
1143
+ }
1144
+ }
1145
+ `;
1121
1146
  var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
1122
1147
  function getSdk(client, withWrapper = defaultWrapper) {
1123
1148
  return {
@@ -1216,6 +1241,12 @@ function getSdk(client, withWrapper = defaultWrapper) {
1216
1241
  },
1217
1242
  GetUserMvsAutoFix(variables, requestHeaders, signal) {
1218
1243
  return withWrapper((wrappedRequestHeaders) => client.request({ document: GetUserMvsAutoFixDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetUserMvsAutoFix", "query", variables);
1244
+ },
1245
+ streamBlameAiAnalysisRequests(variables, requestHeaders, signal) {
1246
+ return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamBlameAiAnalysisRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamBlameAiAnalysisRequests", "subscription", variables);
1247
+ },
1248
+ streamCommitBlameRequests(variables, requestHeaders, signal) {
1249
+ return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamCommitBlameRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamCommitBlameRequests", "subscription", variables);
1219
1250
  }
1220
1251
  };
1221
1252
  }
@@ -2172,6 +2203,7 @@ function getDirName() {
2172
2203
  var debug = Debug("mobbdev:constants");
2173
2204
  dotenv.config({ path: path2.join(getModuleRootDir(), ".env") });
2174
2205
  var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
2206
+ var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
2175
2207
  var scmFriendlyText = {
2176
2208
  ["Ado" /* Ado */]: "Azure DevOps",
2177
2209
  ["Bitbucket" /* Bitbucket */]: "Bitbucket",
@@ -2198,13 +2230,16 @@ var scannerToVulnerabilityReportVendorEnum = {
2198
2230
  };
2199
2231
  var SupportedScannersZ = z8.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
2200
2232
  var envVariablesSchema = z8.object({
2201
- WEB_APP_URL: z8.string(),
2202
- API_URL: z8.string(),
2203
- HASURA_ACCESS_KEY: z8.string(),
2204
- LOCAL_GRAPHQL_ENDPOINT: z8.string(),
2233
+ // These have safe defaults for production - the VS Code extension passes explicit URLs
2234
+ WEB_APP_URL: z8.string().optional().default(DEFAULT_WEB_APP_URL),
2235
+ API_URL: z8.string().optional().default(DEFAULT_API_URL),
2236
+ // These are only needed for local development with Hasura
2237
+ HASURA_ACCESS_KEY: z8.string().optional().default(""),
2238
+ LOCAL_GRAPHQL_ENDPOINT: z8.string().optional().default(""),
2239
+ // Proxy settings
2205
2240
  HTTP_PROXY: z8.string().optional().default(""),
2206
2241
  HTTPS_PROXY: z8.string().optional().default("")
2207
- }).required();
2242
+ });
2208
2243
  var envVariables = envVariablesSchema.parse(process.env);
2209
2244
  debug("config %o", envVariables);
2210
2245
  var WEB_APP_URL = envVariables.WEB_APP_URL;
@@ -2399,75 +2434,78 @@ function createWSClient(options) {
2399
2434
  }
2400
2435
  });
2401
2436
  }
2402
- function subscribe(query, variables, callback, wsClientOptions) {
2403
- return new Promise((resolve, reject) => {
2404
- let timer = null;
2405
- let settled = false;
2406
- const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
2407
- const client = createWSClient(wsClientOptions);
2408
- let unsubscribe = () => {
2409
- return;
2410
- };
2411
- function cleanup() {
2437
+ function subscribeStream(query, variables, handlers, wsClientOptions) {
2438
+ let timer = null;
2439
+ const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
2440
+ const client = createWSClient(wsClientOptions);
2441
+ let unsub = null;
2442
+ let settled = false;
2443
+ const cleanup = () => {
2444
+ if (unsub) {
2412
2445
  try {
2413
- unsubscribe();
2446
+ unsub();
2414
2447
  } catch {
2415
2448
  }
2416
- if (timer) {
2417
- clearTimeout(timer);
2418
- timer = null;
2419
- }
2449
+ unsub = null;
2420
2450
  }
2421
- function finalizeResolve(data) {
2422
- if (settled) {
2451
+ if (timer) {
2452
+ clearTimeout(timer);
2453
+ timer = null;
2454
+ }
2455
+ };
2456
+ const finalizeError = (error) => {
2457
+ if (settled) {
2458
+ return;
2459
+ }
2460
+ settled = true;
2461
+ cleanup();
2462
+ handlers.error(error);
2463
+ };
2464
+ unsub = client.subscribe(
2465
+ { query, variables },
2466
+ {
2467
+ next: (payload) => {
2468
+ if (settled) {
2469
+ return;
2470
+ }
2471
+ if (!payload.data) {
2472
+ finalizeError(
2473
+ new Error(
2474
+ `Broken data object from graphQL subscribe: ${JSON.stringify(
2475
+ payload
2476
+ )} for query: ${query}`
2477
+ )
2478
+ );
2479
+ return;
2480
+ }
2481
+ handlers.next(payload.data);
2482
+ },
2483
+ error: (error) => {
2484
+ finalizeError(error);
2485
+ },
2486
+ complete: () => {
2423
2487
  return;
2424
2488
  }
2425
- settled = true;
2426
- cleanup();
2427
- resolve(data);
2428
2489
  }
2429
- function finalizeReject(error) {
2490
+ );
2491
+ if (typeof timeoutInMs === "number") {
2492
+ timer = setTimeout(() => {
2493
+ finalizeError(
2494
+ new Error(
2495
+ `Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
2496
+ )
2497
+ );
2498
+ }, timeoutInMs);
2499
+ }
2500
+ return {
2501
+ unsubscribe: () => {
2430
2502
  if (settled) {
2431
2503
  return;
2432
2504
  }
2433
2505
  settled = true;
2434
2506
  cleanup();
2435
- reject(error);
2436
2507
  }
2437
- unsubscribe = client.subscribe(
2438
- { query, variables },
2439
- {
2440
- next: (data) => {
2441
- if (!data.data) {
2442
- finalizeReject(
2443
- new Error(
2444
- `Broken data object from graphQL subscribe: ${JSON.stringify(
2445
- data
2446
- )} for query: ${query}`
2447
- )
2448
- );
2449
- } else {
2450
- callback(finalizeResolve, finalizeReject, data.data);
2451
- }
2452
- },
2453
- error: (error) => {
2454
- finalizeReject(error);
2455
- },
2456
- complete: () => {
2457
- return;
2458
- }
2459
- }
2460
- );
2461
- if (typeof timeoutInMs === "number") {
2462
- timer = setTimeout(() => {
2463
- finalizeReject(
2464
- new Error(
2465
- `Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
2466
- )
2467
- );
2468
- }, timeoutInMs);
2469
- }
2470
- });
2508
+ };
2471
2509
  }
2472
2510
 
2473
2511
  // src/features/analysis/scm/utils/index.ts
@@ -4688,10 +4726,12 @@ var GQLClient = class {
4688
4726
  constructor(args) {
4689
4727
  __publicField(this, "_client");
4690
4728
  __publicField(this, "_clientSdk");
4729
+ __publicField(this, "_apiUrl");
4691
4730
  __publicField(this, "_auth");
4692
4731
  debug6(`init with ${args}`);
4693
4732
  this._auth = args;
4694
- this._client = new GraphQLClient(API_URL, {
4733
+ this._apiUrl = args.apiUrl || API_URL;
4734
+ this._client = new GraphQLClient(this._apiUrl, {
4695
4735
  headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
4696
4736
  Authorization: `Bearer ${args.token}`
4697
4737
  },
@@ -4956,32 +4996,47 @@ var GQLClient = class {
4956
4996
  }
4957
4997
  async subscribeToAnalysis(params) {
4958
4998
  const { callbackStates } = params;
4959
- return subscribe(
4960
- GetAnalysisSubscriptionDocument,
4961
- params.subscribeToAnalysisParams,
4962
- async (resolve, reject, data) => {
4963
- if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
4964
- const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
4965
- reject(
4966
- new ReportDigestError(errorMessage, data.analysis?.failReason ?? "")
4967
- );
4968
- return;
4969
- }
4970
- if (callbackStates.includes(data.analysis?.state)) {
4971
- await params.callback(data.analysis.id);
4972
- resolve(data);
4973
- }
4974
- },
4975
- this._auth.type === "apiKey" ? {
4976
- apiKey: this._auth.apiKey,
4977
- type: "apiKey",
4978
- timeoutInMs: params.timeoutInMs,
4979
- proxyAgent: getProxyAgent(API_URL)
4980
- } : {
4981
- token: this._auth.token,
4982
- type: "token",
4983
- timeoutInMs: params.timeoutInMs,
4984
- proxyAgent: getProxyAgent(API_URL)
4999
+ return new Promise(
5000
+ (resolve, reject) => {
5001
+ const subscription = subscribeStream(
5002
+ GetAnalysisSubscriptionDocument,
5003
+ params.subscribeToAnalysisParams,
5004
+ {
5005
+ next: async (data) => {
5006
+ if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
5007
+ const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
5008
+ subscription.unsubscribe();
5009
+ reject(
5010
+ new ReportDigestError(
5011
+ errorMessage,
5012
+ data.analysis?.failReason ?? ""
5013
+ )
5014
+ );
5015
+ return;
5016
+ }
5017
+ if (callbackStates.includes(data.analysis?.state)) {
5018
+ await params.callback(data.analysis.id);
5019
+ subscription.unsubscribe();
5020
+ resolve(data);
5021
+ }
5022
+ },
5023
+ error: (error) => {
5024
+ subscription.unsubscribe();
5025
+ reject(error);
5026
+ }
5027
+ },
5028
+ this._auth.type === "apiKey" ? {
5029
+ apiKey: this._auth.apiKey,
5030
+ type: "apiKey",
5031
+ timeoutInMs: params.timeoutInMs,
5032
+ proxyAgent: getProxyAgent(this._apiUrl)
5033
+ } : {
5034
+ token: this._auth.token,
5035
+ type: "token",
5036
+ timeoutInMs: params.timeoutInMs,
5037
+ proxyAgent: getProxyAgent(this._apiUrl)
5038
+ }
5039
+ );
4985
5040
  }
4986
5041
  );
4987
5042
  }
@@ -5065,29 +5120,37 @@ var configStore = getConfigStore();
5065
5120
  var debug7 = Debug6("mobbdev:commands");
5066
5121
  var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
5067
5122
  var LOGIN_CHECK_DELAY = 5 * 1e3;
5068
- var webLoginUrl = `${WEB_APP_URL}/cli-login`;
5069
5123
  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(
5070
5124
  "press any key to continue"
5071
5125
  )};`;
5072
5126
  async function getAuthenticatedGQLClient({
5073
5127
  inputApiKey = "",
5074
- isSkipPrompts = true
5128
+ isSkipPrompts = true,
5129
+ apiUrl,
5130
+ webAppUrl
5075
5131
  }) {
5076
5132
  let gqlClient = new GQLClient({
5077
5133
  apiKey: inputApiKey || configStore.get("apiToken") || "",
5078
- type: "apiKey"
5134
+ type: "apiKey",
5135
+ apiUrl
5079
5136
  });
5080
5137
  gqlClient = await handleMobbLogin({
5081
5138
  inGqlClient: gqlClient,
5082
- skipPrompts: isSkipPrompts
5139
+ skipPrompts: isSkipPrompts,
5140
+ apiUrl,
5141
+ webAppUrl
5083
5142
  });
5084
5143
  return gqlClient;
5085
5144
  }
5086
5145
  async function handleMobbLogin({
5087
5146
  inGqlClient,
5088
5147
  apiKey,
5089
- skipPrompts
5148
+ skipPrompts,
5149
+ apiUrl,
5150
+ webAppUrl
5090
5151
  }) {
5152
+ const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
5153
+ const resolvedApiUrl = apiUrl || API_URL;
5091
5154
  const { createSpinner } = Spinner({ ci: skipPrompts });
5092
5155
  const isConnected = await inGqlClient.verifyApiConnection();
5093
5156
  if (!isConnected) {
@@ -5129,7 +5192,7 @@ async function handleMobbLogin({
5129
5192
  const loginId = await inGqlClient.createCliLogin({
5130
5193
  publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
5131
5194
  });
5132
- const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os.hostname()}`;
5195
+ const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
5133
5196
  !skipPrompts && console.log(
5134
5197
  `If the page does not open automatically, kindly access it through ${browserUrl}.`
5135
5198
  );
@@ -5154,7 +5217,11 @@ async function handleMobbLogin({
5154
5217
  });
5155
5218
  throw new CliError();
5156
5219
  }
5157
- const newGqlClient = new GQLClient({ apiKey: newApiToken, type: "apiKey" });
5220
+ const newGqlClient = new GQLClient({
5221
+ apiKey: newApiToken,
5222
+ type: "apiKey",
5223
+ apiUrl: resolvedApiUrl
5224
+ });
5158
5225
  const loginSuccess = await newGqlClient.validateUserToken();
5159
5226
  if (loginSuccess) {
5160
5227
  debug7(`set api token ${newApiToken}`);
@@ -5242,42 +5309,36 @@ var openRedaction = new OpenRedaction({
5242
5309
  "VISA_NUMBER",
5243
5310
  "VISA_MRZ",
5244
5311
  "TAX_ID",
5245
- // Financial Data
5312
+ // Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
5246
5313
  "CREDIT_CARD",
5247
5314
  "IBAN",
5248
5315
  "BANK_ACCOUNT_UK",
5249
5316
  "ROUTING_NUMBER_US",
5250
- "SWIFT_BIC",
5251
5317
  "CARD_TRACK1_DATA",
5252
5318
  "CARD_TRACK2_DATA",
5253
5319
  "CARD_EXPIRY",
5254
5320
  "CARD_AUTH_CODE",
5255
- // Cryptocurrency
5256
- "BITCOIN_ADDRESS",
5321
+ // Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
5257
5322
  "ETHEREUM_ADDRESS",
5258
5323
  "LITECOIN_ADDRESS",
5259
5324
  "CARDANO_ADDRESS",
5260
5325
  "SOLANA_ADDRESS",
5261
5326
  "MONERO_ADDRESS",
5262
5327
  "RIPPLE_ADDRESS",
5263
- // Medical Data
5328
+ // Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
5264
5329
  "NHS_NUMBER",
5265
5330
  "MEDICAL_RECORD_NUMBER",
5266
5331
  "AUSTRALIAN_MEDICARE",
5267
5332
  "HEALTH_PLAN_NUMBER",
5268
- "PRESCRIPTION_NUMBER",
5269
5333
  "PATIENT_ID",
5270
- // Communications
5334
+ // Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
5271
5335
  "PHONE_US",
5272
5336
  "PHONE_UK",
5273
5337
  "PHONE_UK_MOBILE",
5274
5338
  "PHONE_INTERNATIONAL",
5275
5339
  "PHONE_LINE_NUMBER",
5276
- "EMERGENCY_CONTACT",
5277
5340
  "ADDRESS_STREET",
5278
- "ADDRESS_PO_BOX",
5279
5341
  "POSTCODE_UK",
5280
- "ZIP_CODE_US",
5281
5342
  // Network & Technical
5282
5343
  "IPV4",
5283
5344
  "IPV6",
package/dist/index.mjs CHANGED
@@ -842,16 +842,7 @@ var init_GitService = __esm({
842
842
  this.git.revparse(["HEAD"]),
843
843
  this.git.revparse(["--abbrev-ref", "HEAD"])
844
844
  ]);
845
- let normalizedRepoUrl = repoUrl.value || "";
846
- if (normalizedRepoUrl.endsWith(".git")) {
847
- normalizedRepoUrl = normalizedRepoUrl.slice(0, -".git".length);
848
- }
849
- if (normalizedRepoUrl.startsWith("git@github.com:")) {
850
- normalizedRepoUrl = normalizedRepoUrl.replace(
851
- "git@github.com:",
852
- "https://github.com/"
853
- );
854
- }
845
+ const normalizedRepoUrl = repoUrl.value ? this.normalizeGitUrl(repoUrl.value) : "";
855
846
  this.log("[GitService] Git repository information retrieved", "debug", {
856
847
  repoUrl: normalizedRepoUrl,
857
848
  hash,
@@ -1147,6 +1138,9 @@ var init_GitService = __esm({
1147
1138
  }
1148
1139
  }
1149
1140
  }
1141
+ if (normalizedUrl.startsWith("https://") || normalizedUrl.startsWith("http://")) {
1142
+ normalizedUrl = normalizedUrl.replace(/^(https?:\/\/)([^@/]+@)/, "$1");
1143
+ }
1150
1144
  return normalizedUrl;
1151
1145
  }
1152
1146
  /**
@@ -2377,6 +2371,31 @@ var GetUserMvsAutoFixDocument = `
2377
2371
  }
2378
2372
  }
2379
2373
  `;
2374
+ var StreamBlameAiAnalysisRequestsDocument = `
2375
+ subscription streamBlameAiAnalysisRequests($requestIds: [uuid!]!) {
2376
+ blame_ai_analysis_request(where: {id: {_in: $requestIds}}) {
2377
+ id
2378
+ state
2379
+ commitId
2380
+ organizationId
2381
+ createdOn
2382
+ }
2383
+ }
2384
+ `;
2385
+ var StreamCommitBlameRequestsDocument = `
2386
+ subscription streamCommitBlameRequests($requestIds: [uuid!]!) {
2387
+ commit_blame_request(where: {id: {_in: $requestIds}}) {
2388
+ id
2389
+ state
2390
+ organizationId
2391
+ repositoryUrl
2392
+ commitSha
2393
+ createdOn
2394
+ completedOn
2395
+ error
2396
+ }
2397
+ }
2398
+ `;
2380
2399
  var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
2381
2400
  function getSdk(client, withWrapper = defaultWrapper) {
2382
2401
  return {
@@ -2475,6 +2494,12 @@ function getSdk(client, withWrapper = defaultWrapper) {
2475
2494
  },
2476
2495
  GetUserMvsAutoFix(variables, requestHeaders, signal) {
2477
2496
  return withWrapper((wrappedRequestHeaders) => client.request({ document: GetUserMvsAutoFixDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetUserMvsAutoFix", "query", variables);
2497
+ },
2498
+ streamBlameAiAnalysisRequests(variables, requestHeaders, signal) {
2499
+ return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamBlameAiAnalysisRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamBlameAiAnalysisRequests", "subscription", variables);
2500
+ },
2501
+ streamCommitBlameRequests(variables, requestHeaders, signal) {
2502
+ return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamCommitBlameRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamCommitBlameRequests", "subscription", variables);
2478
2503
  }
2479
2504
  };
2480
2505
  }
@@ -8463,6 +8488,16 @@ function getGithubSdk(params = {}) {
8463
8488
  }
8464
8489
 
8465
8490
  // src/features/analysis/scm/github/GithubSCMLib.ts
8491
+ function determinePrStatus(state, isDraft) {
8492
+ switch (state) {
8493
+ case "CLOSED":
8494
+ return "CLOSED" /* Closed */;
8495
+ case "MERGED":
8496
+ return "MERGED" /* Merged */;
8497
+ case "OPEN":
8498
+ return isDraft ? "DRAFT" /* Draft */ : "ACTIVE" /* Active */;
8499
+ }
8500
+ }
8466
8501
  var GithubSCMLib = class extends SCMLib {
8467
8502
  // we don't always need a url, what's important is that we have an access token
8468
8503
  constructor(url, accessToken, scmOrg) {
@@ -8910,12 +8945,7 @@ var GithubSCMLib = class extends SCMLib {
8910
8945
  if (!pr) {
8911
8946
  throw new Error(`Pull request #${prNumber} not found`);
8912
8947
  }
8913
- let prStatus = "ACTIVE" /* Active */;
8914
- if (pr.state === "CLOSED") {
8915
- prStatus = pr.mergedAt ? "MERGED" /* Merged */ : "CLOSED" /* Closed */;
8916
- } else if (pr.isDraft) {
8917
- prStatus = "DRAFT" /* Draft */;
8918
- }
8948
+ const prStatus = determinePrStatus(pr.state, pr.isDraft);
8919
8949
  const firstCommit = pr.commits.nodes[0];
8920
8950
  const firstCommitDate = firstCommit ? new Date(
8921
8951
  firstCommit.commit.author?.date || firstCommit.commit.committedDate || pr.createdAt
@@ -10360,6 +10390,7 @@ import { z as z24 } from "zod";
10360
10390
  var debug5 = Debug4("mobbdev:constants");
10361
10391
  dotenv.config({ path: path6.join(getModuleRootDir(), ".env") });
10362
10392
  var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
10393
+ var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
10363
10394
  var scmFriendlyText = {
10364
10395
  ["Ado" /* Ado */]: "Azure DevOps",
10365
10396
  ["Bitbucket" /* Bitbucket */]: "Bitbucket",
@@ -10386,13 +10417,16 @@ var scannerToVulnerabilityReportVendorEnum = {
10386
10417
  };
10387
10418
  var SupportedScannersZ = z24.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
10388
10419
  var envVariablesSchema = z24.object({
10389
- WEB_APP_URL: z24.string(),
10390
- API_URL: z24.string(),
10391
- HASURA_ACCESS_KEY: z24.string(),
10392
- LOCAL_GRAPHQL_ENDPOINT: z24.string(),
10420
+ // These have safe defaults for production - the VS Code extension passes explicit URLs
10421
+ WEB_APP_URL: z24.string().optional().default(DEFAULT_WEB_APP_URL),
10422
+ API_URL: z24.string().optional().default(DEFAULT_API_URL),
10423
+ // These are only needed for local development with Hasura
10424
+ HASURA_ACCESS_KEY: z24.string().optional().default(""),
10425
+ LOCAL_GRAPHQL_ENDPOINT: z24.string().optional().default(""),
10426
+ // Proxy settings
10393
10427
  HTTP_PROXY: z24.string().optional().default(""),
10394
10428
  HTTPS_PROXY: z24.string().optional().default("")
10395
- }).required();
10429
+ });
10396
10430
  var envVariables = envVariablesSchema.parse(process.env);
10397
10431
  debug5("config %o", envVariables);
10398
10432
  var mobbAscii = `
@@ -10445,9 +10479,9 @@ var errorMessages = {
10445
10479
  )} is needed if you're adding an SCM token`
10446
10480
  };
10447
10481
  var progressMassages = {
10448
- processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
10449
- processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
10450
- processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
10482
+ processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report processed successfully",
10483
+ processingVulnerabilityReport: "\u2699\uFE0F Processing vulnerability report",
10484
+ processingVulnerabilityReportFailed: "\u2699\uFE0F Error Processing vulnerability report"
10451
10485
  };
10452
10486
  var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
10453
10487
 
@@ -10773,75 +10807,78 @@ function createWSClient(options) {
10773
10807
  }
10774
10808
  });
10775
10809
  }
10776
- function subscribe(query, variables, callback, wsClientOptions) {
10777
- return new Promise((resolve, reject) => {
10778
- let timer = null;
10779
- let settled = false;
10780
- const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
10781
- const client = createWSClient(wsClientOptions);
10782
- let unsubscribe = () => {
10783
- return;
10784
- };
10785
- function cleanup() {
10810
+ function subscribeStream(query, variables, handlers, wsClientOptions) {
10811
+ let timer = null;
10812
+ const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
10813
+ const client = createWSClient(wsClientOptions);
10814
+ let unsub = null;
10815
+ let settled = false;
10816
+ const cleanup = () => {
10817
+ if (unsub) {
10786
10818
  try {
10787
- unsubscribe();
10819
+ unsub();
10788
10820
  } catch {
10789
10821
  }
10790
- if (timer) {
10791
- clearTimeout(timer);
10792
- timer = null;
10793
- }
10822
+ unsub = null;
10794
10823
  }
10795
- function finalizeResolve(data) {
10796
- if (settled) {
10824
+ if (timer) {
10825
+ clearTimeout(timer);
10826
+ timer = null;
10827
+ }
10828
+ };
10829
+ const finalizeError = (error) => {
10830
+ if (settled) {
10831
+ return;
10832
+ }
10833
+ settled = true;
10834
+ cleanup();
10835
+ handlers.error(error);
10836
+ };
10837
+ unsub = client.subscribe(
10838
+ { query, variables },
10839
+ {
10840
+ next: (payload) => {
10841
+ if (settled) {
10842
+ return;
10843
+ }
10844
+ if (!payload.data) {
10845
+ finalizeError(
10846
+ new Error(
10847
+ `Broken data object from graphQL subscribe: ${JSON.stringify(
10848
+ payload
10849
+ )} for query: ${query}`
10850
+ )
10851
+ );
10852
+ return;
10853
+ }
10854
+ handlers.next(payload.data);
10855
+ },
10856
+ error: (error) => {
10857
+ finalizeError(error);
10858
+ },
10859
+ complete: () => {
10797
10860
  return;
10798
10861
  }
10799
- settled = true;
10800
- cleanup();
10801
- resolve(data);
10802
10862
  }
10803
- function finalizeReject(error) {
10863
+ );
10864
+ if (typeof timeoutInMs === "number") {
10865
+ timer = setTimeout(() => {
10866
+ finalizeError(
10867
+ new Error(
10868
+ `Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
10869
+ )
10870
+ );
10871
+ }, timeoutInMs);
10872
+ }
10873
+ return {
10874
+ unsubscribe: () => {
10804
10875
  if (settled) {
10805
10876
  return;
10806
10877
  }
10807
10878
  settled = true;
10808
10879
  cleanup();
10809
- reject(error);
10810
10880
  }
10811
- unsubscribe = client.subscribe(
10812
- { query, variables },
10813
- {
10814
- next: (data) => {
10815
- if (!data.data) {
10816
- finalizeReject(
10817
- new Error(
10818
- `Broken data object from graphQL subscribe: ${JSON.stringify(
10819
- data
10820
- )} for query: ${query}`
10821
- )
10822
- );
10823
- } else {
10824
- callback(finalizeResolve, finalizeReject, data.data);
10825
- }
10826
- },
10827
- error: (error) => {
10828
- finalizeReject(error);
10829
- },
10830
- complete: () => {
10831
- return;
10832
- }
10833
- }
10834
- );
10835
- if (typeof timeoutInMs === "number") {
10836
- timer = setTimeout(() => {
10837
- finalizeReject(
10838
- new Error(
10839
- `Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
10840
- )
10841
- );
10842
- }, timeoutInMs);
10843
- }
10844
- });
10881
+ };
10845
10882
  }
10846
10883
 
10847
10884
  // src/features/analysis/graphql/types.ts
@@ -10944,10 +10981,12 @@ var GQLClient = class {
10944
10981
  constructor(args) {
10945
10982
  __publicField(this, "_client");
10946
10983
  __publicField(this, "_clientSdk");
10984
+ __publicField(this, "_apiUrl");
10947
10985
  __publicField(this, "_auth");
10948
10986
  debug6(`init with ${args}`);
10949
10987
  this._auth = args;
10950
- this._client = new GraphQLClient(API_URL, {
10988
+ this._apiUrl = args.apiUrl || API_URL;
10989
+ this._client = new GraphQLClient(this._apiUrl, {
10951
10990
  headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
10952
10991
  Authorization: `Bearer ${args.token}`
10953
10992
  },
@@ -11212,32 +11251,47 @@ var GQLClient = class {
11212
11251
  }
11213
11252
  async subscribeToAnalysis(params) {
11214
11253
  const { callbackStates } = params;
11215
- return subscribe(
11216
- GetAnalysisSubscriptionDocument,
11217
- params.subscribeToAnalysisParams,
11218
- async (resolve, reject, data) => {
11219
- if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
11220
- const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
11221
- reject(
11222
- new ReportDigestError(errorMessage, data.analysis?.failReason ?? "")
11223
- );
11224
- return;
11225
- }
11226
- if (callbackStates.includes(data.analysis?.state)) {
11227
- await params.callback(data.analysis.id);
11228
- resolve(data);
11229
- }
11230
- },
11231
- this._auth.type === "apiKey" ? {
11232
- apiKey: this._auth.apiKey,
11233
- type: "apiKey",
11234
- timeoutInMs: params.timeoutInMs,
11235
- proxyAgent: getProxyAgent(API_URL)
11236
- } : {
11237
- token: this._auth.token,
11238
- type: "token",
11239
- timeoutInMs: params.timeoutInMs,
11240
- proxyAgent: getProxyAgent(API_URL)
11254
+ return new Promise(
11255
+ (resolve, reject) => {
11256
+ const subscription = subscribeStream(
11257
+ GetAnalysisSubscriptionDocument,
11258
+ params.subscribeToAnalysisParams,
11259
+ {
11260
+ next: async (data) => {
11261
+ if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
11262
+ const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
11263
+ subscription.unsubscribe();
11264
+ reject(
11265
+ new ReportDigestError(
11266
+ errorMessage,
11267
+ data.analysis?.failReason ?? ""
11268
+ )
11269
+ );
11270
+ return;
11271
+ }
11272
+ if (callbackStates.includes(data.analysis?.state)) {
11273
+ await params.callback(data.analysis.id);
11274
+ subscription.unsubscribe();
11275
+ resolve(data);
11276
+ }
11277
+ },
11278
+ error: (error) => {
11279
+ subscription.unsubscribe();
11280
+ reject(error);
11281
+ }
11282
+ },
11283
+ this._auth.type === "apiKey" ? {
11284
+ apiKey: this._auth.apiKey,
11285
+ type: "apiKey",
11286
+ timeoutInMs: params.timeoutInMs,
11287
+ proxyAgent: getProxyAgent(this._apiUrl)
11288
+ } : {
11289
+ token: this._auth.token,
11290
+ type: "token",
11291
+ timeoutInMs: params.timeoutInMs,
11292
+ proxyAgent: getProxyAgent(this._apiUrl)
11293
+ }
11294
+ );
11241
11295
  }
11242
11296
  );
11243
11297
  }
@@ -11321,29 +11375,37 @@ var configStore = getConfigStore();
11321
11375
  var debug7 = Debug6("mobbdev:commands");
11322
11376
  var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
11323
11377
  var LOGIN_CHECK_DELAY = 5 * 1e3;
11324
- var webLoginUrl = `${WEB_APP_URL}/cli-login`;
11325
11378
  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(
11326
11379
  "press any key to continue"
11327
11380
  )};`;
11328
11381
  async function getAuthenticatedGQLClient({
11329
11382
  inputApiKey = "",
11330
- isSkipPrompts = true
11383
+ isSkipPrompts = true,
11384
+ apiUrl,
11385
+ webAppUrl
11331
11386
  }) {
11332
11387
  let gqlClient = new GQLClient({
11333
11388
  apiKey: inputApiKey || configStore.get("apiToken") || "",
11334
- type: "apiKey"
11389
+ type: "apiKey",
11390
+ apiUrl
11335
11391
  });
11336
11392
  gqlClient = await handleMobbLogin({
11337
11393
  inGqlClient: gqlClient,
11338
- skipPrompts: isSkipPrompts
11394
+ skipPrompts: isSkipPrompts,
11395
+ apiUrl,
11396
+ webAppUrl
11339
11397
  });
11340
11398
  return gqlClient;
11341
11399
  }
11342
11400
  async function handleMobbLogin({
11343
11401
  inGqlClient,
11344
11402
  apiKey,
11345
- skipPrompts
11403
+ skipPrompts,
11404
+ apiUrl,
11405
+ webAppUrl
11346
11406
  }) {
11407
+ const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
11408
+ const resolvedApiUrl = apiUrl || API_URL;
11347
11409
  const { createSpinner: createSpinner5 } = Spinner({ ci: skipPrompts });
11348
11410
  const isConnected = await inGqlClient.verifyApiConnection();
11349
11411
  if (!isConnected) {
@@ -11385,7 +11447,7 @@ async function handleMobbLogin({
11385
11447
  const loginId = await inGqlClient.createCliLogin({
11386
11448
  publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
11387
11449
  });
11388
- const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os.hostname()}`;
11450
+ const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
11389
11451
  !skipPrompts && console.log(
11390
11452
  `If the page does not open automatically, kindly access it through ${browserUrl}.`
11391
11453
  );
@@ -11410,7 +11472,11 @@ async function handleMobbLogin({
11410
11472
  });
11411
11473
  throw new CliError();
11412
11474
  }
11413
- const newGqlClient = new GQLClient({ apiKey: newApiToken, type: "apiKey" });
11475
+ const newGqlClient = new GQLClient({
11476
+ apiKey: newApiToken,
11477
+ type: "apiKey",
11478
+ apiUrl: resolvedApiUrl
11479
+ });
11414
11480
  const loginSuccess = await newGqlClient.validateUserToken();
11415
11481
  if (loginSuccess) {
11416
11482
  debug7(`set api token ${newApiToken}`);
@@ -13532,42 +13598,36 @@ var openRedaction = new OpenRedaction({
13532
13598
  "VISA_NUMBER",
13533
13599
  "VISA_MRZ",
13534
13600
  "TAX_ID",
13535
- // Financial Data
13601
+ // Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
13536
13602
  "CREDIT_CARD",
13537
13603
  "IBAN",
13538
13604
  "BANK_ACCOUNT_UK",
13539
13605
  "ROUTING_NUMBER_US",
13540
- "SWIFT_BIC",
13541
13606
  "CARD_TRACK1_DATA",
13542
13607
  "CARD_TRACK2_DATA",
13543
13608
  "CARD_EXPIRY",
13544
13609
  "CARD_AUTH_CODE",
13545
- // Cryptocurrency
13546
- "BITCOIN_ADDRESS",
13610
+ // Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
13547
13611
  "ETHEREUM_ADDRESS",
13548
13612
  "LITECOIN_ADDRESS",
13549
13613
  "CARDANO_ADDRESS",
13550
13614
  "SOLANA_ADDRESS",
13551
13615
  "MONERO_ADDRESS",
13552
13616
  "RIPPLE_ADDRESS",
13553
- // Medical Data
13617
+ // Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
13554
13618
  "NHS_NUMBER",
13555
13619
  "MEDICAL_RECORD_NUMBER",
13556
13620
  "AUSTRALIAN_MEDICARE",
13557
13621
  "HEALTH_PLAN_NUMBER",
13558
- "PRESCRIPTION_NUMBER",
13559
13622
  "PATIENT_ID",
13560
- // Communications
13623
+ // Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
13561
13624
  "PHONE_US",
13562
13625
  "PHONE_UK",
13563
13626
  "PHONE_UK_MOBILE",
13564
13627
  "PHONE_INTERNATIONAL",
13565
13628
  "PHONE_LINE_NUMBER",
13566
- "EMERGENCY_CONTACT",
13567
13629
  "ADDRESS_STREET",
13568
- "ADDRESS_PO_BOX",
13569
13630
  "POSTCODE_UK",
13570
- "ZIP_CODE_US",
13571
13631
  // Network & Technical
13572
13632
  "IPV4",
13573
13633
  "IPV6",
@@ -14751,8 +14811,8 @@ var McpAuthService = class {
14751
14811
  throw new CliLoginError("Error: createCliLogin failed");
14752
14812
  }
14753
14813
  logDebug(`cli login created ${loginId}`);
14754
- const webLoginUrl2 = `${WEB_APP_URL}/mvs-login`;
14755
- const browserUrl = `${webLoginUrl2}/${loginId}?hostname=${os4.hostname()}`;
14814
+ const webLoginUrl = `${WEB_APP_URL}/mvs-login`;
14815
+ const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os4.hostname()}`;
14756
14816
  await this.openBrowser(browserUrl, isBackgoundCall);
14757
14817
  logDebug(`waiting for login to complete`);
14758
14818
  let newApiToken = null;
@@ -14941,54 +15001,77 @@ var McpGQLClient = class {
14941
15001
  params: params.subscribeToAnalysisParams
14942
15002
  });
14943
15003
  const { callbackStates } = params;
14944
- const result = await subscribe(
14945
- GetAnalysisSubscriptionDocument,
14946
- params.subscribeToAnalysisParams,
14947
- async (resolve, reject, data) => {
14948
- logDebug(
14949
- `[${scanContext}] GraphQL: GetAnalysis subscription data received ${data.analysis?.state}`,
14950
- { data }
14951
- );
14952
- if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
14953
- const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
14954
- logError(`[${scanContext}] GraphQL: Analysis failed`, {
14955
- analysisId: data.analysis?.id,
14956
- state: data.analysis?.state,
14957
- failReason: data.analysis?.failReason,
14958
- ...this.getErrorContext()
14959
- });
14960
- reject(new Error(errorMessage));
14961
- return;
14962
- }
14963
- if (callbackStates.includes(data.analysis?.state)) {
14964
- logDebug(
14965
- `[${scanContext}] GraphQL: Analysis state matches callback states: ${data.analysis.state}`,
14966
- {
14967
- analysisId: data.analysis.id,
14968
- state: data.analysis.state,
14969
- callbackStates
15004
+ return new Promise(
15005
+ (resolve, reject) => {
15006
+ const subscription = subscribeStream(
15007
+ GetAnalysisSubscriptionDocument,
15008
+ params.subscribeToAnalysisParams,
15009
+ {
15010
+ next: async (data) => {
15011
+ logDebug(
15012
+ `[${scanContext}] GraphQL: GetAnalysis subscription data received ${data.analysis?.state}`,
15013
+ { data }
15014
+ );
15015
+ if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
15016
+ const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
15017
+ logError(`[${scanContext}] GraphQL: Analysis failed`, {
15018
+ analysisId: data.analysis?.id,
15019
+ state: data.analysis?.state,
15020
+ failReason: data.analysis?.failReason,
15021
+ ...this.getErrorContext()
15022
+ });
15023
+ subscription.unsubscribe();
15024
+ reject(new Error(errorMessage));
15025
+ return;
15026
+ }
15027
+ if (callbackStates.includes(data.analysis?.state)) {
15028
+ logDebug(
15029
+ `[${scanContext}] GraphQL: Analysis state matches callback states: ${data.analysis.state}`,
15030
+ {
15031
+ analysisId: data.analysis.id,
15032
+ state: data.analysis.state,
15033
+ callbackStates
15034
+ }
15035
+ );
15036
+ await params.callback(data.analysis.id);
15037
+ subscription.unsubscribe();
15038
+ logDebug(
15039
+ `[${scanContext}] GraphQL: GetAnalysis subscription completed`,
15040
+ {
15041
+ analysisId: data.analysis.id,
15042
+ state: data.analysis.state
15043
+ }
15044
+ );
15045
+ resolve(data);
15046
+ }
15047
+ },
15048
+ error: (error) => {
15049
+ logError(
15050
+ `[${scanContext}] GraphQL: GetAnalysis subscription failed`,
15051
+ {
15052
+ error,
15053
+ params: params.subscribeToAnalysisParams,
15054
+ ...this.getErrorContext()
15055
+ }
15056
+ );
15057
+ subscription.unsubscribe();
15058
+ reject(error);
14970
15059
  }
14971
- );
14972
- await params.callback(data.analysis.id);
14973
- resolve(data);
14974
- }
14975
- },
14976
- this._auth.type === "apiKey" ? {
14977
- apiKey: this._auth.apiKey,
14978
- type: "apiKey",
14979
- timeoutInMs: params.timeoutInMs,
14980
- proxyAgent: getProxyAgent2(this.apiUrl)
14981
- } : {
14982
- token: this._auth.token,
14983
- type: "token",
14984
- timeoutInMs: params.timeoutInMs,
14985
- proxyAgent: getProxyAgent2(this.apiUrl)
15060
+ },
15061
+ this._auth.type === "apiKey" ? {
15062
+ apiKey: this._auth.apiKey,
15063
+ type: "apiKey",
15064
+ timeoutInMs: params.timeoutInMs,
15065
+ proxyAgent: getProxyAgent2(this.apiUrl)
15066
+ } : {
15067
+ token: this._auth.token,
15068
+ type: "token",
15069
+ timeoutInMs: params.timeoutInMs,
15070
+ proxyAgent: getProxyAgent2(this.apiUrl)
15071
+ }
15072
+ );
14986
15073
  }
14987
15074
  );
14988
- logDebug(`[${scanContext}] GraphQL: GetAnalysis subscription completed`, {
14989
- result
14990
- });
14991
- return result;
14992
15075
  } catch (e) {
14993
15076
  logError(`[${scanContext}] GraphQL: GetAnalysis subscription failed`, {
14994
15077
  error: e,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.1.17",
3
+ "version": "1.1.21",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.mjs",