mobbdev 1.1.26 → 1.1.28

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.
@@ -16,6 +16,10 @@ type SanitizationCounts = {
16
16
  };
17
17
  };
18
18
 
19
+ type Logger = {
20
+ info: (msg: string, data?: unknown) => void;
21
+ error: (msg: string, data?: unknown) => void;
22
+ };
19
23
  declare const PromptItemZ: z.ZodObject<{
20
24
  type: z.ZodEnum<["USER_PROMPT", "AI_RESPONSE", "TOOL_EXECUTION", "AI_THINKING"]>;
21
25
  attachedFiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -210,7 +214,17 @@ declare function uploadAiBlameHandlerFromExtension(args: {
210
214
  responseTime: string;
211
215
  blameType?: AiBlameInferenceType;
212
216
  sessionId?: string;
217
+ apiUrl?: string;
218
+ webAppUrl?: string;
213
219
  }): Promise<UploadAiBlameResult>;
214
- declare function uploadAiBlameHandler(args: UploadAiBlameOptions, exitOnError?: boolean): Promise<void>;
220
+ type UploadAiBlameHandlerOptions = {
221
+ args: UploadAiBlameOptions;
222
+ exitOnError?: boolean;
223
+ apiUrl?: string;
224
+ webAppUrl?: string;
225
+ logger?: Logger;
226
+ };
227
+ declare function uploadAiBlameHandler(options: UploadAiBlameHandlerOptions): Promise<void>;
228
+ declare function uploadAiBlameCommandHandler(args: UploadAiBlameOptions): Promise<void>;
215
229
 
216
- export { type PromptItem, type PromptItemArray, type UploadAiBlameOptions, type UploadAiBlameResult, uploadAiBlameBuilder, uploadAiBlameHandler, uploadAiBlameHandlerFromExtension };
230
+ export { type PromptItem, type PromptItemArray, type UploadAiBlameOptions, type UploadAiBlameResult, uploadAiBlameBuilder, uploadAiBlameCommandHandler, uploadAiBlameHandler, uploadAiBlameHandlerFromExtension };
@@ -4734,6 +4734,11 @@ var GQLClient = class {
4734
4734
  debug6(`init with ${args}`);
4735
4735
  this._auth = args;
4736
4736
  this._apiUrl = args.apiUrl || API_URL;
4737
+ debug6(
4738
+ "GQLClient constructor: resolved apiUrl=%s (from param: %s)",
4739
+ this._apiUrl,
4740
+ args.apiUrl || "fallback to API_URL constant"
4741
+ );
4737
4742
  this._client = new GraphQLClient(this._apiUrl, {
4738
4743
  headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
4739
4744
  Authorization: `Bearer ${args.token}`
@@ -5100,6 +5105,18 @@ var GQLClient = class {
5100
5105
  }
5101
5106
  };
5102
5107
 
5108
+ // src/mcp/services/types.ts
5109
+ function buildLoginUrl(baseUrl, loginId, hostname2, context) {
5110
+ const url = new URL(`${baseUrl}/${loginId}`);
5111
+ url.searchParams.set("hostname", hostname2);
5112
+ url.searchParams.set("trigger", context.trigger);
5113
+ url.searchParams.set("source", context.source);
5114
+ if (context.ide) {
5115
+ url.searchParams.set("ide", context.ide);
5116
+ }
5117
+ return url.toString();
5118
+ }
5119
+
5103
5120
  // src/utils/ConfigStoreService.ts
5104
5121
  import Configstore from "configstore";
5105
5122
  function createConfigStore(defaultValues = { apiToken: "" }) {
@@ -5132,6 +5149,11 @@ async function getAuthenticatedGQLClient({
5132
5149
  apiUrl,
5133
5150
  webAppUrl
5134
5151
  }) {
5152
+ debug7(
5153
+ "getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
5154
+ apiUrl || "undefined",
5155
+ webAppUrl || "undefined"
5156
+ );
5135
5157
  let gqlClient = new GQLClient({
5136
5158
  apiKey: inputApiKey || configStore.get("apiToken") || "",
5137
5159
  type: "apiKey",
@@ -5150,10 +5172,18 @@ async function handleMobbLogin({
5150
5172
  apiKey,
5151
5173
  skipPrompts,
5152
5174
  apiUrl,
5153
- webAppUrl
5175
+ webAppUrl,
5176
+ loginContext
5154
5177
  }) {
5155
5178
  const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
5156
5179
  const resolvedApiUrl = apiUrl || API_URL;
5180
+ debug7(
5181
+ "handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
5182
+ resolvedApiUrl,
5183
+ apiUrl || "fallback",
5184
+ resolvedWebAppUrl,
5185
+ webAppUrl || "fallback"
5186
+ );
5157
5187
  const { createSpinner } = Spinner({ ci: skipPrompts });
5158
5188
  const isConnected = await inGqlClient.verifyApiConnection();
5159
5189
  if (!isConnected) {
@@ -5195,7 +5225,8 @@ async function handleMobbLogin({
5195
5225
  const loginId = await inGqlClient.createCliLogin({
5196
5226
  publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
5197
5227
  });
5198
- const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
5228
+ const webLoginUrl = `${resolvedWebAppUrl}/cli-login`;
5229
+ const browserUrl = loginContext ? buildLoginUrl(webLoginUrl, loginId, os.hostname(), loginContext) : `${webLoginUrl}/${loginId}?hostname=${os.hostname()}`;
5199
5230
  !skipPrompts && console.log(
5200
5231
  `If the page does not open automatically, kindly access it through ${browserUrl}.`
5201
5232
  );
@@ -5433,6 +5464,22 @@ async function sanitizeDataWithCounts(obj) {
5433
5464
  }
5434
5465
 
5435
5466
  // src/args/commands/upload_ai_blame.ts
5467
+ var defaultLogger = {
5468
+ info: (msg, data) => {
5469
+ if (data !== void 0) {
5470
+ console.log(msg, data);
5471
+ } else {
5472
+ console.log(msg);
5473
+ }
5474
+ },
5475
+ error: (msg, data) => {
5476
+ if (data !== void 0) {
5477
+ console.error(msg, data);
5478
+ } else {
5479
+ console.error(msg);
5480
+ }
5481
+ }
5482
+ };
5436
5483
  var PromptItemZ = z26.object({
5437
5484
  type: z26.enum(["USER_PROMPT", "AI_RESPONSE", "TOOL_EXECUTION", "AI_THINKING"]),
5438
5485
  attachedFiles: z26.array(
@@ -5548,7 +5595,12 @@ async function uploadAiBlameHandlerFromExtension(args) {
5548
5595
  if (args.sessionId) {
5549
5596
  uploadArgs.sessionId.push(args.sessionId);
5550
5597
  }
5551
- await uploadAiBlameHandler(uploadArgs, false);
5598
+ await uploadAiBlameHandler({
5599
+ args: uploadArgs,
5600
+ exitOnError: false,
5601
+ apiUrl: args.apiUrl,
5602
+ webAppUrl: args.webAppUrl
5603
+ });
5552
5604
  });
5553
5605
  });
5554
5606
  return {
@@ -5558,7 +5610,14 @@ async function uploadAiBlameHandlerFromExtension(args) {
5558
5610
  inferenceUUID
5559
5611
  };
5560
5612
  }
5561
- async function uploadAiBlameHandler(args, exitOnError = true) {
5613
+ async function uploadAiBlameHandler(options) {
5614
+ const {
5615
+ args,
5616
+ exitOnError = true,
5617
+ apiUrl,
5618
+ webAppUrl,
5619
+ logger = defaultLogger
5620
+ } = options;
5562
5621
  const prompts = args.prompt || [];
5563
5622
  const inferences = args.inference || [];
5564
5623
  const models = args.model || [];
@@ -5568,7 +5627,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5568
5627
  const sessionIds = args.sessionId || args["session-id"] || [];
5569
5628
  if (prompts.length !== inferences.length) {
5570
5629
  const errorMsg = "prompt and inference must have the same number of entries";
5571
- console.error(chalk3.red(errorMsg));
5630
+ logger.error(chalk3.red(errorMsg));
5572
5631
  if (exitOnError) {
5573
5632
  process.exit(1);
5574
5633
  }
@@ -5587,7 +5646,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5587
5646
  ]);
5588
5647
  } catch {
5589
5648
  const errorMsg = `File not found for session ${i + 1}`;
5590
- console.error(chalk3.red(errorMsg));
5649
+ logger.error(chalk3.red(errorMsg));
5591
5650
  if (exitOnError) {
5592
5651
  process.exit(1);
5593
5652
  }
@@ -5606,7 +5665,9 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5606
5665
  });
5607
5666
  }
5608
5667
  const authenticatedClient = await getAuthenticatedGQLClient({
5609
- isSkipPrompts: true
5668
+ isSkipPrompts: true,
5669
+ apiUrl,
5670
+ webAppUrl
5610
5671
  });
5611
5672
  const initSessions = sessions.map(
5612
5673
  ({ sessionId: _sessionId, ...rest }) => rest
@@ -5617,7 +5678,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5617
5678
  const uploadSessions = initRes.uploadAIBlameInferencesInit?.uploadSessions ?? [];
5618
5679
  if (uploadSessions.length !== sessions.length) {
5619
5680
  const errorMsg = "Init failed to return expected number of sessions";
5620
- console.error(chalk3.red(errorMsg));
5681
+ logger.error(chalk3.red(errorMsg));
5621
5682
  if (exitOnError) {
5622
5683
  process.exit(1);
5623
5684
  }
@@ -5659,22 +5720,41 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5659
5720
  sessionId: s.sessionId
5660
5721
  };
5661
5722
  });
5662
- const finRes = await authenticatedClient.finalizeAIBlameInferencesUploadRaw({
5663
- sessions: finalizeSessions
5664
- });
5665
- const status = finRes?.finalizeAIBlameInferencesUpload?.status;
5666
- if (status !== "OK") {
5667
- const errorMsg = finRes?.finalizeAIBlameInferencesUpload?.error || "unknown error";
5668
- console.error(chalk3.red(errorMsg));
5669
- if (exitOnError) {
5670
- process.exit(1);
5723
+ try {
5724
+ logger.info(
5725
+ `[UPLOAD] Calling finalizeAIBlameInferencesUploadRaw with ${finalizeSessions.length} sessions`
5726
+ );
5727
+ const finRes = await authenticatedClient.finalizeAIBlameInferencesUploadRaw(
5728
+ {
5729
+ sessions: finalizeSessions
5730
+ }
5731
+ );
5732
+ logger.info("[UPLOAD] Finalize response:", JSON.stringify(finRes, null, 2));
5733
+ const status = finRes?.finalizeAIBlameInferencesUpload?.status;
5734
+ if (status !== "OK") {
5735
+ const errorMsg = finRes?.finalizeAIBlameInferencesUpload?.error || "unknown error";
5736
+ logger.error(
5737
+ chalk3.red(
5738
+ `[UPLOAD] Finalize failed with status: ${status}, error: ${errorMsg}`
5739
+ )
5740
+ );
5741
+ if (exitOnError) {
5742
+ process.exit(1);
5743
+ }
5744
+ throw new Error(errorMsg);
5671
5745
  }
5672
- throw new Error(errorMsg);
5746
+ logger.info(chalk3.green("[UPLOAD] AI Blame uploads finalized successfully"));
5747
+ } catch (error) {
5748
+ logger.error("[UPLOAD] Finalize threw error:", error);
5749
+ throw error;
5673
5750
  }
5674
- console.log(chalk3.green("AI Blame uploads finalized successfully"));
5751
+ }
5752
+ async function uploadAiBlameCommandHandler(args) {
5753
+ await uploadAiBlameHandler({ args });
5675
5754
  }
5676
5755
  export {
5677
5756
  uploadAiBlameBuilder,
5757
+ uploadAiBlameCommandHandler,
5678
5758
  uploadAiBlameHandler,
5679
5759
  uploadAiBlameHandlerFromExtension
5680
5760
  };
package/dist/index.mjs CHANGED
@@ -11034,6 +11034,11 @@ var GQLClient = class {
11034
11034
  debug6(`init with ${args}`);
11035
11035
  this._auth = args;
11036
11036
  this._apiUrl = args.apiUrl || API_URL;
11037
+ debug6(
11038
+ "GQLClient constructor: resolved apiUrl=%s (from param: %s)",
11039
+ this._apiUrl,
11040
+ args.apiUrl || "fallback to API_URL constant"
11041
+ );
11037
11042
  this._client = new GraphQLClient(this._apiUrl, {
11038
11043
  headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
11039
11044
  Authorization: `Bearer ${args.token}`
@@ -11400,6 +11405,38 @@ var GQLClient = class {
11400
11405
  }
11401
11406
  };
11402
11407
 
11408
+ // src/mcp/services/types.ts
11409
+ function detectIDE() {
11410
+ const env3 = process.env;
11411
+ if (env3["CURSOR_TRACE_ID"] || env3["CURSOR_SESSION_ID"]) return "cursor";
11412
+ if (env3["WINDSURF_IPC_HOOK"] || env3["WINDSURF_PID"]) return "windsurf";
11413
+ if (env3["CLAUDE_DESKTOP"] || env3["ANTHROPIC_CLAUDE"]) return "claude";
11414
+ if (env3["WEBSTORM_VM_OPTIONS"] || env3["IDEA_VM_OPTIONS"] || env3["JETBRAINS_IDE"])
11415
+ return "webstorm";
11416
+ if (env3["VSCODE_IPC_HOOK"] || env3["VSCODE_PID"]) return "vscode";
11417
+ const termProgram = env3["TERM_PROGRAM"]?.toLowerCase();
11418
+ if (termProgram === "windsurf") return "windsurf";
11419
+ if (termProgram === "vscode") return "vscode";
11420
+ return void 0;
11421
+ }
11422
+ function createMcpLoginContext(trigger) {
11423
+ return {
11424
+ trigger,
11425
+ source: "mcp",
11426
+ ide: detectIDE()
11427
+ };
11428
+ }
11429
+ function buildLoginUrl(baseUrl, loginId, hostname2, context) {
11430
+ const url = new URL(`${baseUrl}/${loginId}`);
11431
+ url.searchParams.set("hostname", hostname2);
11432
+ url.searchParams.set("trigger", context.trigger);
11433
+ url.searchParams.set("source", context.source);
11434
+ if (context.ide) {
11435
+ url.searchParams.set("ide", context.ide);
11436
+ }
11437
+ return url.toString();
11438
+ }
11439
+
11403
11440
  // src/utils/ConfigStoreService.ts
11404
11441
  import Configstore from "configstore";
11405
11442
  function createConfigStore(defaultValues = { apiToken: "" }) {
@@ -11432,6 +11469,11 @@ async function getAuthenticatedGQLClient({
11432
11469
  apiUrl,
11433
11470
  webAppUrl
11434
11471
  }) {
11472
+ debug7(
11473
+ "getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
11474
+ apiUrl || "undefined",
11475
+ webAppUrl || "undefined"
11476
+ );
11435
11477
  let gqlClient = new GQLClient({
11436
11478
  apiKey: inputApiKey || configStore.get("apiToken") || "",
11437
11479
  type: "apiKey",
@@ -11450,10 +11492,18 @@ async function handleMobbLogin({
11450
11492
  apiKey,
11451
11493
  skipPrompts,
11452
11494
  apiUrl,
11453
- webAppUrl
11495
+ webAppUrl,
11496
+ loginContext
11454
11497
  }) {
11455
11498
  const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
11456
11499
  const resolvedApiUrl = apiUrl || API_URL;
11500
+ debug7(
11501
+ "handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
11502
+ resolvedApiUrl,
11503
+ apiUrl || "fallback",
11504
+ resolvedWebAppUrl,
11505
+ webAppUrl || "fallback"
11506
+ );
11457
11507
  const { createSpinner: createSpinner5 } = Spinner({ ci: skipPrompts });
11458
11508
  const isConnected = await inGqlClient.verifyApiConnection();
11459
11509
  if (!isConnected) {
@@ -11495,7 +11545,8 @@ async function handleMobbLogin({
11495
11545
  const loginId = await inGqlClient.createCliLogin({
11496
11546
  publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
11497
11547
  });
11498
- const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
11548
+ const webLoginUrl = `${resolvedWebAppUrl}/cli-login`;
11549
+ const browserUrl = loginContext ? buildLoginUrl(webLoginUrl, loginId, os.hostname(), loginContext) : `${webLoginUrl}/${loginId}?hostname=${os.hostname()}`;
11499
11550
  !skipPrompts && console.log(
11500
11551
  `If the page does not open automatically, kindly access it through ${browserUrl}.`
11501
11552
  );
@@ -13767,6 +13818,22 @@ async function sanitizeDataWithCounts(obj) {
13767
13818
  }
13768
13819
 
13769
13820
  // src/args/commands/upload_ai_blame.ts
13821
+ var defaultLogger2 = {
13822
+ info: (msg, data) => {
13823
+ if (data !== void 0) {
13824
+ console.log(msg, data);
13825
+ } else {
13826
+ console.log(msg);
13827
+ }
13828
+ },
13829
+ error: (msg, data) => {
13830
+ if (data !== void 0) {
13831
+ console.error(msg, data);
13832
+ } else {
13833
+ console.error(msg);
13834
+ }
13835
+ }
13836
+ };
13770
13837
  var PromptItemZ = z31.object({
13771
13838
  type: z31.enum(["USER_PROMPT", "AI_RESPONSE", "TOOL_EXECUTION", "AI_THINKING"]),
13772
13839
  attachedFiles: z31.array(
@@ -13882,7 +13949,12 @@ async function uploadAiBlameHandlerFromExtension(args) {
13882
13949
  if (args.sessionId) {
13883
13950
  uploadArgs.sessionId.push(args.sessionId);
13884
13951
  }
13885
- await uploadAiBlameHandler(uploadArgs, false);
13952
+ await uploadAiBlameHandler({
13953
+ args: uploadArgs,
13954
+ exitOnError: false,
13955
+ apiUrl: args.apiUrl,
13956
+ webAppUrl: args.webAppUrl
13957
+ });
13886
13958
  });
13887
13959
  });
13888
13960
  return {
@@ -13892,7 +13964,14 @@ async function uploadAiBlameHandlerFromExtension(args) {
13892
13964
  inferenceUUID
13893
13965
  };
13894
13966
  }
13895
- async function uploadAiBlameHandler(args, exitOnError = true) {
13967
+ async function uploadAiBlameHandler(options) {
13968
+ const {
13969
+ args,
13970
+ exitOnError = true,
13971
+ apiUrl,
13972
+ webAppUrl,
13973
+ logger: logger2 = defaultLogger2
13974
+ } = options;
13896
13975
  const prompts = args.prompt || [];
13897
13976
  const inferences = args.inference || [];
13898
13977
  const models = args.model || [];
@@ -13902,7 +13981,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13902
13981
  const sessionIds = args.sessionId || args["session-id"] || [];
13903
13982
  if (prompts.length !== inferences.length) {
13904
13983
  const errorMsg = "prompt and inference must have the same number of entries";
13905
- console.error(chalk9.red(errorMsg));
13984
+ logger2.error(chalk9.red(errorMsg));
13906
13985
  if (exitOnError) {
13907
13986
  process.exit(1);
13908
13987
  }
@@ -13921,7 +14000,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13921
14000
  ]);
13922
14001
  } catch {
13923
14002
  const errorMsg = `File not found for session ${i + 1}`;
13924
- console.error(chalk9.red(errorMsg));
14003
+ logger2.error(chalk9.red(errorMsg));
13925
14004
  if (exitOnError) {
13926
14005
  process.exit(1);
13927
14006
  }
@@ -13940,7 +14019,9 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13940
14019
  });
13941
14020
  }
13942
14021
  const authenticatedClient = await getAuthenticatedGQLClient({
13943
- isSkipPrompts: true
14022
+ isSkipPrompts: true,
14023
+ apiUrl,
14024
+ webAppUrl
13944
14025
  });
13945
14026
  const initSessions = sessions.map(
13946
14027
  ({ sessionId: _sessionId, ...rest }) => rest
@@ -13951,7 +14032,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13951
14032
  const uploadSessions = initRes.uploadAIBlameInferencesInit?.uploadSessions ?? [];
13952
14033
  if (uploadSessions.length !== sessions.length) {
13953
14034
  const errorMsg = "Init failed to return expected number of sessions";
13954
- console.error(chalk9.red(errorMsg));
14035
+ logger2.error(chalk9.red(errorMsg));
13955
14036
  if (exitOnError) {
13956
14037
  process.exit(1);
13957
14038
  }
@@ -13993,19 +14074,37 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13993
14074
  sessionId: s.sessionId
13994
14075
  };
13995
14076
  });
13996
- const finRes = await authenticatedClient.finalizeAIBlameInferencesUploadRaw({
13997
- sessions: finalizeSessions
13998
- });
13999
- const status = finRes?.finalizeAIBlameInferencesUpload?.status;
14000
- if (status !== "OK") {
14001
- const errorMsg = finRes?.finalizeAIBlameInferencesUpload?.error || "unknown error";
14002
- console.error(chalk9.red(errorMsg));
14003
- if (exitOnError) {
14004
- process.exit(1);
14077
+ try {
14078
+ logger2.info(
14079
+ `[UPLOAD] Calling finalizeAIBlameInferencesUploadRaw with ${finalizeSessions.length} sessions`
14080
+ );
14081
+ const finRes = await authenticatedClient.finalizeAIBlameInferencesUploadRaw(
14082
+ {
14083
+ sessions: finalizeSessions
14084
+ }
14085
+ );
14086
+ logger2.info("[UPLOAD] Finalize response:", JSON.stringify(finRes, null, 2));
14087
+ const status = finRes?.finalizeAIBlameInferencesUpload?.status;
14088
+ if (status !== "OK") {
14089
+ const errorMsg = finRes?.finalizeAIBlameInferencesUpload?.error || "unknown error";
14090
+ logger2.error(
14091
+ chalk9.red(
14092
+ `[UPLOAD] Finalize failed with status: ${status}, error: ${errorMsg}`
14093
+ )
14094
+ );
14095
+ if (exitOnError) {
14096
+ process.exit(1);
14097
+ }
14098
+ throw new Error(errorMsg);
14005
14099
  }
14006
- throw new Error(errorMsg);
14100
+ logger2.info(chalk9.green("[UPLOAD] AI Blame uploads finalized successfully"));
14101
+ } catch (error) {
14102
+ logger2.error("[UPLOAD] Finalize threw error:", error);
14103
+ throw error;
14007
14104
  }
14008
- console.log(chalk9.green("AI Blame uploads finalized successfully"));
14105
+ }
14106
+ async function uploadAiBlameCommandHandler(args) {
14107
+ await uploadAiBlameHandler({ args });
14009
14108
  }
14010
14109
 
14011
14110
  // src/features/claude_code/transcript_parser.ts
@@ -14263,7 +14362,8 @@ async function processAndUploadHookData() {
14263
14362
  model: result.tracePayload.model,
14264
14363
  tool: result.tracePayload.tool,
14265
14364
  responseTime: result.tracePayload.responseTime,
14266
- blameType: "CHAT" /* Chat */
14365
+ blameType: "CHAT" /* Chat */,
14366
+ sessionId: result.hookData.session_id
14267
14367
  });
14268
14368
  uploadSuccess = true;
14269
14369
  } catch (error) {
@@ -14776,9 +14876,10 @@ var McpAuthService = class {
14776
14876
  /**
14777
14877
  * Handles the complete authentication flow
14778
14878
  * @param isBackgoundCall Whether this is called from tools context
14879
+ * @param loginContext Context information about who triggered the login
14779
14880
  * @returns Authenticated API token
14780
14881
  */
14781
- async authenticate(isBackgoundCall = false) {
14882
+ async authenticate(isBackgoundCall = false, loginContext) {
14782
14883
  const { publicKey, privateKey } = crypto2.generateKeyPairSync("rsa", {
14783
14884
  modulusLength: 2048
14784
14885
  });
@@ -14791,7 +14892,7 @@ var McpAuthService = class {
14791
14892
  }
14792
14893
  logDebug(`cli login created ${loginId}`);
14793
14894
  const webLoginUrl = `${WEB_APP_URL}/mvs-login`;
14794
- const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os4.hostname()}`;
14895
+ const browserUrl = loginContext ? buildLoginUrl(webLoginUrl, loginId, os4.hostname(), loginContext) : `${webLoginUrl}/${loginId}?hostname=${os4.hostname()}`;
14795
14896
  await this.openBrowser(browserUrl, isBackgoundCall);
14796
14897
  logDebug(`waiting for login to complete`);
14797
14898
  let newApiToken = null;
@@ -15465,7 +15566,8 @@ var McpGQLClient = class {
15465
15566
  }
15466
15567
  };
15467
15568
  async function createAuthenticatedMcpGQLClient({
15468
- isBackgroundCall = false
15569
+ isBackgroundCall = false,
15570
+ loginContext
15469
15571
  } = {}) {
15470
15572
  logDebug("[GraphQL] Getting config", {
15471
15573
  apiToken: configStore.get("apiToken")
@@ -15486,7 +15588,10 @@ async function createAuthenticatedMcpGQLClient({
15486
15588
  return initialClient;
15487
15589
  }
15488
15590
  const authService = new McpAuthService(initialClient);
15489
- const newApiToken = await authService.authenticate(isBackgroundCall);
15591
+ const newApiToken = await authService.authenticate(
15592
+ isBackgroundCall,
15593
+ loginContext
15594
+ );
15490
15595
  configStore.set("apiToken", newApiToken);
15491
15596
  return new McpGQLClient({ apiKey: newApiToken, type: "apiKey" });
15492
15597
  }
@@ -18430,7 +18535,10 @@ var BaseTool = class {
18430
18535
  async execute(args) {
18431
18536
  if (this.hasAuthentication) {
18432
18537
  logDebug(`Authenticating tool: ${this.name}`, { args });
18433
- const mcpGqlClient = await createAuthenticatedMcpGQLClient();
18538
+ const loginContext = createMcpLoginContext(this.name);
18539
+ const mcpGqlClient = await createAuthenticatedMcpGQLClient({
18540
+ loginContext
18541
+ });
18434
18542
  const userInfo2 = await mcpGqlClient.getUserInfo();
18435
18543
  logDebug("User authenticated successfully", { userInfo: userInfo2 });
18436
18544
  }
@@ -21664,7 +21772,8 @@ var _CheckForNewAvailableFixesService = class _CheckForNewAvailableFixesService
21664
21772
  logInfo(`[${scanContext}] Reset service state for new path`, { path: path22 });
21665
21773
  }
21666
21774
  try {
21667
- this.gqlClient = await createAuthenticatedMcpGQLClient();
21775
+ const loginContext = createMcpLoginContext("check_new_fixes");
21776
+ this.gqlClient = await createAuthenticatedMcpGQLClient({ loginContext });
21668
21777
  } catch (error) {
21669
21778
  const errorMessage = error.message;
21670
21779
  if (errorMessage.includes("Authentication failed") || errorMessage.includes("access-denied") || errorMessage.includes("Authentication hook unauthorized")) {
@@ -21916,7 +22025,8 @@ var _FetchAvailableFixesService = class _FetchAvailableFixesService {
21916
22025
  }
21917
22026
  async initializeGqlClient() {
21918
22027
  if (!this.gqlClient) {
21919
- this.gqlClient = await createAuthenticatedMcpGQLClient();
22028
+ const loginContext = createMcpLoginContext("fetch_fixes");
22029
+ this.gqlClient = await createAuthenticatedMcpGQLClient({ loginContext });
21920
22030
  }
21921
22031
  return this.gqlClient;
21922
22032
  }
@@ -22313,7 +22423,8 @@ var _ScanAndFixVulnerabilitiesService = class _ScanAndFixVulnerabilitiesService
22313
22423
  }
22314
22424
  }
22315
22425
  async initializeGqlClient() {
22316
- const gqlClient = await createAuthenticatedMcpGQLClient();
22426
+ const loginContext = createMcpLoginContext("scan_vulnerabilities");
22427
+ const gqlClient = await createAuthenticatedMcpGQLClient({ loginContext });
22317
22428
  const isConnected = await gqlClient.verifyApiConnection();
22318
22429
  if (!isConnected) {
22319
22430
  throw new ApiConnectionError(
@@ -22746,7 +22857,7 @@ var parseArgs = async (args) => {
22746
22857
  "Upload AI Blame inference artifacts (prompt + inference) and finalize them."
22747
22858
  ),
22748
22859
  uploadAiBlameBuilder,
22749
- uploadAiBlameHandler
22860
+ uploadAiBlameCommandHandler
22750
22861
  ).command(
22751
22862
  mobbCliCommand.claudeCodeInstallHook,
22752
22863
  chalk12.bold("Install Claude Code hooks for data collection."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.1.26",
3
+ "version": "1.1.28",
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",