mobbdev 1.0.180 → 1.0.182

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.
Files changed (2) hide show
  1. package/dist/index.mjs +175 -19
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -10604,7 +10604,9 @@ var GQLClient = class {
10604
10604
  `The user with email:${email} is not associated with any organization`
10605
10605
  );
10606
10606
  }
10607
- const organization = orgAndProjectRes.user?.at(0)?.userOrganizationsAndUserOrganizationRoles.map((org) => org.organization).filter(
10607
+ const organization = orgAndProjectRes.user?.at(0)?.userOrganizationsAndUserOrganizationRoles.map(
10608
+ (org) => org.organization
10609
+ ).filter(
10608
10610
  (org) => userDefinedOrganizationId ? org.id === userDefinedOrganizationId : true
10609
10611
  )?.at(0);
10610
10612
  if (!organization) {
@@ -12354,15 +12356,111 @@ import {
12354
12356
 
12355
12357
  // src/mcp/Logger.ts
12356
12358
  import Configstore3 from "configstore";
12359
+
12360
+ // src/mcp/services/WorkspaceService.ts
12361
+ var WorkspaceService = class {
12362
+ /**
12363
+ * Sets a known workspace path that was discovered through successful validation
12364
+ * @param path The validated workspace path to store
12365
+ */
12366
+ static setKnownWorkspacePath(path17) {
12367
+ this.knownWorkspacePath = path17;
12368
+ }
12369
+ /**
12370
+ * Gets the known workspace path that was previously validated
12371
+ * @returns The known workspace path or undefined if none stored
12372
+ */
12373
+ static getKnownWorkspacePath() {
12374
+ return this.knownWorkspacePath;
12375
+ }
12376
+ /**
12377
+ * Gets the workspace folder path from known path or environment variables
12378
+ * @returns The workspace folder path or undefined if none found
12379
+ */
12380
+ static getWorkspaceFolderPath() {
12381
+ if (this.knownWorkspacePath) {
12382
+ return this.knownWorkspacePath;
12383
+ }
12384
+ const workspaceEnvVars = [
12385
+ "WORKSPACE_FOLDER_PATHS",
12386
+ // Cursor IDE
12387
+ "PWD",
12388
+ // Claude Code and general shell
12389
+ "WORKSPACE_ROOT",
12390
+ // Generic workspace root
12391
+ "PROJECT_ROOT"
12392
+ // Generic project root
12393
+ ];
12394
+ for (const envVar of workspaceEnvVars) {
12395
+ const value = process.env[envVar];
12396
+ if (value?.trim()) {
12397
+ return value.trim();
12398
+ }
12399
+ }
12400
+ return void 0;
12401
+ }
12402
+ ///this should be deleted, use instead the host detection from the McpUsageService
12403
+ /**
12404
+ * Detects the IDE/editor host based on environment variables
12405
+ * @returns The detected IDE host
12406
+ */
12407
+ static getHost() {
12408
+ if (process.env["WORKSPACE_FOLDER_PATHS"]) {
12409
+ return "CURSOR";
12410
+ }
12411
+ if (process.env["VSCODE_IPC_HOOK"] || process.env["VSCODE_PID"] || process.env["TERM_PROGRAM"] === "vscode") {
12412
+ return "VSCODE";
12413
+ }
12414
+ if (process.env["WINDSURF_IPC_HOOK"] || process.env["WINDSURF_PID"] || process.env["TERM_PROGRAM"] === "windsurf") {
12415
+ return "WINDSURF";
12416
+ }
12417
+ if (process.env["CLAUDE_DESKTOP"] || process.env["ANTHROPIC_CLAUDE"]) {
12418
+ return "CLAUDE";
12419
+ }
12420
+ if (process.env["WEBSTORM_VM_OPTIONS"] || process.env["IDEA_VM_OPTIONS"] || process.env["JETBRAINS_IDE"]) {
12421
+ return "WEBSTORM";
12422
+ }
12423
+ return "UNKNOWN";
12424
+ }
12425
+ };
12426
+ __publicField(WorkspaceService, "knownWorkspacePath");
12427
+
12428
+ // src/mcp/Logger.ts
12357
12429
  var MAX_LOGS_SIZE = 1e3;
12358
12430
  var Logger = class {
12359
12431
  constructor() {
12360
12432
  __publicField(this, "mobbConfigStore");
12361
- __publicField(this, "path");
12362
- this.path = process.env["WORKSPACE_FOLDER_PATHS"] || "unknown";
12433
+ __publicField(this, "host");
12434
+ __publicField(this, "unknownPathSuffix");
12435
+ __publicField(this, "lastKnownPath", null);
12436
+ this.host = WorkspaceService.getHost();
12437
+ this.unknownPathSuffix = Math.floor(1e3 + Math.random() * 9e3).toString();
12363
12438
  this.mobbConfigStore = new Configstore3("mobb-logs", {});
12364
12439
  this.mobbConfigStore.set("version", packageJson.version);
12365
12440
  }
12441
+ /**
12442
+ * Gets the current log path, fetching workspace path dynamically
12443
+ */
12444
+ getCurrentLogPath() {
12445
+ const workspacePath = WorkspaceService.getWorkspaceFolderPath();
12446
+ if (workspacePath) {
12447
+ return `${this.host}:${workspacePath}`;
12448
+ }
12449
+ return `${this.host}:unknown-${this.unknownPathSuffix}`;
12450
+ }
12451
+ /**
12452
+ * Migrates logs from unknown path to known workspace path
12453
+ */
12454
+ migrateLogs(fromPath, toPath) {
12455
+ const existingLogs = this.mobbConfigStore.get(fromPath) || [];
12456
+ const targetLogs = this.mobbConfigStore.get(toPath) || [];
12457
+ if (existingLogs.length > 0) {
12458
+ const combinedLogs = [...targetLogs, ...existingLogs];
12459
+ const finalLogs = combinedLogs.slice(-MAX_LOGS_SIZE);
12460
+ this.mobbConfigStore.set(toPath, finalLogs);
12461
+ this.mobbConfigStore.delete(fromPath);
12462
+ }
12463
+ }
12366
12464
  /**
12367
12465
  * Log a message to the console.
12368
12466
  * @param message - The message to log.
@@ -12370,17 +12468,27 @@ var Logger = class {
12370
12468
  * @param data - The data to log.
12371
12469
  */
12372
12470
  log(message, level = "info", data) {
12471
+ const currentPath = this.getCurrentLogPath();
12472
+ const workspacePath = WorkspaceService.getWorkspaceFolderPath();
12473
+ if (workspacePath && this.lastKnownPath !== workspacePath) {
12474
+ const unknownPath = `${this.host}:unknown-${this.unknownPathSuffix}`;
12475
+ const knownPath = `${this.host}:${workspacePath}`;
12476
+ if (this.lastKnownPath === null || this.lastKnownPath.includes("unknown-")) {
12477
+ this.migrateLogs(unknownPath, knownPath);
12478
+ }
12479
+ this.lastKnownPath = workspacePath;
12480
+ }
12373
12481
  const logMessage = {
12374
12482
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12375
12483
  level,
12376
12484
  message,
12377
12485
  data
12378
12486
  };
12379
- const logs = this.mobbConfigStore.get(this.path) || [];
12487
+ const logs = this.mobbConfigStore.get(currentPath) || [];
12380
12488
  if (logs.length >= MAX_LOGS_SIZE) {
12381
12489
  logs.shift();
12382
12490
  }
12383
- this.mobbConfigStore.set(this.path, [...logs, logMessage]);
12491
+ this.mobbConfigStore.set(currentPath, [...logs, logMessage]);
12384
12492
  }
12385
12493
  };
12386
12494
  var logger = new Logger();
@@ -13475,6 +13583,12 @@ var McpUsageService = class {
13475
13583
  }
13476
13584
  }
13477
13585
  startPeriodicTracking() {
13586
+ if (!this.hasOrganizationId()) {
13587
+ logDebug(
13588
+ `[UsageService] Not starting periodic tracking - organization ID not available`
13589
+ );
13590
+ return;
13591
+ }
13478
13592
  logDebug(`[UsageService] Starting periodic tracking for mcps`, {});
13479
13593
  this.intervalId = setInterval(async () => {
13480
13594
  logDebug(`[UsageService] Triggering periodic usage service`, {
@@ -13509,6 +13623,10 @@ var McpUsageService = class {
13509
13623
  }
13510
13624
  return "";
13511
13625
  }
13626
+ hasOrganizationId() {
13627
+ const organizationId = configStore.get("GOV-ORG-ID") || "";
13628
+ return !!organizationId;
13629
+ }
13512
13630
  createUsageData(mcpHostId, organizationId, status) {
13513
13631
  const { user, mcps } = getHostInfo();
13514
13632
  return {
@@ -13670,6 +13788,12 @@ var McpServer = class {
13670
13788
  }
13671
13789
  async trackServerUsage(action, signalOrError) {
13672
13790
  try {
13791
+ if (!mcpUsageService.hasOrganizationId()) {
13792
+ logDebug(
13793
+ `[McpServer] Skipping ${action} usage tracking - organization ID not available`
13794
+ );
13795
+ return;
13796
+ }
13673
13797
  if (action === "start") {
13674
13798
  await mcpUsageService.trackServerStart();
13675
13799
  }
@@ -13849,17 +13973,15 @@ var McpServer = class {
13849
13973
  logError("Failed to connect to the API, skipping background scan");
13850
13974
  return;
13851
13975
  }
13852
- if (process.env["WORKSPACE_FOLDER_PATHS"]) {
13853
- logDebug("WORKSPACE_FOLDER_PATHS is set", {
13854
- WORKSPACE_FOLDER_PATHS: process.env["WORKSPACE_FOLDER_PATHS"]
13855
- });
13976
+ const workspacePath = WorkspaceService.getWorkspaceFolderPath();
13977
+ if (workspacePath) {
13856
13978
  try {
13857
13979
  const checkForNewAvailableFixesTool = this.toolRegistry.getTool(
13858
13980
  MCP_TOOL_CHECK_FOR_NEW_AVAILABLE_FIXES
13859
13981
  );
13860
13982
  logInfo("Triggering periodic scan for new available fixes");
13861
13983
  checkForNewAvailableFixesTool.triggerScan({
13862
- path: process.env["WORKSPACE_FOLDER_PATHS"],
13984
+ path: workspacePath,
13863
13985
  gqlClient
13864
13986
  });
13865
13987
  } catch (error) {
@@ -14017,14 +14139,19 @@ async function validatePath(inputPath) {
14017
14139
  inputPath = inputPath.slice(1);
14018
14140
  }
14019
14141
  if (inputPath === "." || inputPath === "./") {
14020
- if (process.env["WORKSPACE_FOLDER_PATHS"]) {
14142
+ const workspaceFolderPath = WorkspaceService.getWorkspaceFolderPath();
14143
+ if (workspaceFolderPath) {
14021
14144
  logDebug("Fallback to workspace folder path", {
14022
14145
  inputPath,
14023
- workspaceFolderPaths: process.env["WORKSPACE_FOLDER_PATHS"]
14146
+ workspaceFolderPaths: [workspaceFolderPath]
14147
+ });
14148
+ WorkspaceService.setKnownWorkspacePath(workspaceFolderPath);
14149
+ logDebug("Stored workspace folder path as known path", {
14150
+ workspaceFolderPath
14024
14151
  });
14025
14152
  return {
14026
14153
  isValid: true,
14027
- path: process.env["WORKSPACE_FOLDER_PATHS"]
14154
+ path: workspaceFolderPath
14028
14155
  };
14029
14156
  } else {
14030
14157
  const error = `"." is not a valid path, please provide a full localpath to the repository`;
@@ -14066,6 +14193,8 @@ async function validatePath(inputPath) {
14066
14193
  try {
14067
14194
  await fs11.promises.access(inputPath);
14068
14195
  logDebug("Path exists and is accessible", { inputPath });
14196
+ WorkspaceService.setKnownWorkspacePath(inputPath);
14197
+ logDebug("Stored validated path in WorkspaceService", { inputPath });
14069
14198
  return { isValid: true, path: inputPath };
14070
14199
  } catch (error) {
14071
14200
  const errorMessage = `Path does not exist or is not accessible: ${inputPath}`;
@@ -14178,7 +14307,15 @@ To retrieve the available fixes, use one of these approaches:
14178
14307
 
14179
14308
  **\u{1F4CB} Valid offset range:** 0 to ${Math.max(0, totalCount - 1)}
14180
14309
 
14181
- To fetch the fixes, run the \`${currentTool}\` tool again with the corrected parameters.
14310
+ ### \u26A0\uFE0F CRITICAL INSTRUCTION FOR AI AGENTS \u26A0\uFE0F
14311
+
14312
+ **DO NOT AUTOMATICALLY FETCH FIXES WITHOUT EXPLICIT USER REQUEST**
14313
+
14314
+ - **DO NOT** run the \`${currentTool}\` tool again on your own
14315
+ - **ONLY** fetch fixes if the user explicitly asks for them
14316
+ - **WAIT** for the user to specifically request fixes before proceeding
14317
+
14318
+ If the user wants to fetch the fixes, they should explicitly ask you to run the \`${currentTool}\` tool again with the corrected parameters.
14182
14319
  `;
14183
14320
  var applyFixesPrompt = ({
14184
14321
  fixes,
@@ -14300,12 +14437,23 @@ ${hasMore ? `---
14300
14437
 
14301
14438
  You have viewed ${shownCount} out of ${totalCount} available fixes.
14302
14439
 
14303
- To fetch additional fixes, run the \`${currentTool}\` tool again with the following parameters:
14440
+ ### \u26A0\uFE0F CRITICAL INSTRUCTION FOR AI AGENTS \u26A0\uFE0F
14441
+
14442
+ **DO NOT AUTOMATICALLY FETCH ADDITIONAL FIXES WITHOUT EXPLICIT USER REQUEST**
14443
+
14444
+ - **DO NOT** run the \`${currentTool}\` tool again on your own
14445
+ - **DO NOT** automatically retrieve more fixes
14446
+ - **ONLY** fetch additional fixes if the user explicitly asks for them
14447
+ - **WAIT** for the user to specifically request more fixes before proceeding
14448
+
14449
+ ### How Users Can Request Additional Fixes
14450
+
14451
+ If the user wants to see more fixes, they should explicitly ask you to run the \`${currentTool}\` tool again with the following parameters:
14304
14452
 
14305
14453
  - **offset**: ${nextOffset} _(start index for the next batch)_
14306
14454
  - **limit**: <number_of_fixes_to_return> _(optional \u2013 default is ${MCP_DEFAULT_LIMIT})_
14307
14455
 
14308
- If you omit both **offset** and **limit**, the command will automatically return the next ${MCP_DEFAULT_LIMIT} fixes.
14456
+ If they omit both **offset** and **limit**, the command will automatically return the next ${MCP_DEFAULT_LIMIT} fixes.
14309
14457
  ` : ""}
14310
14458
  `;
14311
14459
  };
@@ -14346,7 +14494,7 @@ var expiredReportPrompt = ({
14346
14494
  Your most recent vulnerability report for this repository **expired on ${lastReportDate}** and is no longer available for fetching automated fixes.
14347
14495
 
14348
14496
  ### \u{1F4CB} Why Did This Happen?
14349
- - Reports are automatically purged after a retention period for security and storage optimisation.
14497
+ - Reports are automatically purged after a retention period for security and storage optimization.
14350
14498
  - No new scans have been run since the last report expired.
14351
14499
 
14352
14500
  ### \u{1F3AF} Recommended Actions
@@ -14427,13 +14575,21 @@ This will scan up to the specified number of recently changed files.
14427
14575
 
14428
14576
  ### \u{1F504} Running a Fresh Scan
14429
14577
 
14430
- To perform a **rescan** of your repository (fetching a brand-new vulnerability report and updated fixes), include the additional parameter:
14578
+ ### \u26A0\uFE0F CRITICAL INSTRUCTION FOR AI AGENTS \u26A0\uFE0F
14579
+
14580
+ **DO NOT AUTOMATICALLY RUN RESCANS WITHOUT EXPLICIT USER REQUEST**
14581
+
14582
+ - **DO NOT** run rescans on your own
14583
+ - **ONLY** perform rescans if the user explicitly asks for them
14584
+ - **WAIT** for the user to specifically request a rescan before proceeding
14585
+
14586
+ If the user wants to perform a **rescan** of their repository (fetching a brand-new vulnerability report and updated fixes), they should explicitly ask you to include the additional parameter:
14431
14587
 
14432
14588
  - **rescan**: true
14433
14589
 
14434
14590
  This will start a new analysis, discard any cached results.
14435
14591
 
14436
- \u26A0\uFE0F *Note:* A full rescan may take longer to complete than simply fetching additional fixes because your repository is re-uploaded and re-analyzed from scratch.
14592
+ \u26A0\uFE0F *Note:* A full rescan may take longer to complete than simply fetching additional fixes because the repository is re-uploaded and re-analyzed from scratch.
14437
14593
  `;
14438
14594
  var noFixesFoundPrompt = ({
14439
14595
  scannedFiles
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.0.180",
3
+ "version": "1.0.182",
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",