mobbdev 1.1.1 → 1.1.3

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.
@@ -92,7 +92,6 @@ var init_GitService = __esm({
92
92
  import fsPromises2 from "fs/promises";
93
93
  import path6 from "path";
94
94
  import chalk3 from "chalk";
95
- import Configstore2 from "configstore";
96
95
  import { withFile } from "tmp-promise";
97
96
  import z26 from "zod";
98
97
 
@@ -100,7 +99,6 @@ import z26 from "zod";
100
99
  import crypto from "crypto";
101
100
  import os from "os";
102
101
  import chalk2 from "chalk";
103
- import Configstore from "configstore";
104
102
  import Debug7 from "debug";
105
103
  import open from "open";
106
104
 
@@ -2111,6 +2109,7 @@ function getDirName() {
2111
2109
  // src/constants.ts
2112
2110
  var debug = Debug("mobbdev:constants");
2113
2111
  dotenv.config({ path: path2.join(getModuleRootDir(), ".env") });
2112
+ var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
2114
2113
  var scmFriendlyText = {
2115
2114
  ["Ado" /* Ado */]: "Azure DevOps",
2116
2115
  ["Bitbucket" /* Bitbucket */]: "Bitbucket",
@@ -4408,7 +4407,7 @@ import Debug5 from "debug";
4408
4407
  import { createClient } from "graphql-ws";
4409
4408
  import { HttpsProxyAgent } from "https-proxy-agent";
4410
4409
  import WebSocket from "ws";
4411
- var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
4410
+ var DEFAULT_API_URL2 = "https://api.mobb.ai/v1/graphql";
4412
4411
  var debug6 = Debug5("mobbdev:subscribe");
4413
4412
  var SUBSCRIPTION_TIMEOUT_MS = 30 * 60 * 1e3;
4414
4413
  function createWSClient(options) {
@@ -4444,7 +4443,7 @@ function subscribe(query, variables, callback, wsClientOptions) {
4444
4443
  return new Promise((resolve, reject) => {
4445
4444
  let timer = null;
4446
4445
  const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
4447
- const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL;
4446
+ const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL2;
4448
4447
  const client = createWSClient({
4449
4448
  ...wsClientOptions,
4450
4449
  websocket: WebSocket,
@@ -4950,6 +4949,25 @@ var GQLClient = class {
4950
4949
  }
4951
4950
  };
4952
4951
 
4952
+ // src/utils/ConfigStoreService.ts
4953
+ import Configstore from "configstore";
4954
+ function createConfigStore(defaultValues = { apiToken: "" }) {
4955
+ const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL;
4956
+ let domain = "";
4957
+ try {
4958
+ const url = new URL(API_URL2);
4959
+ domain = url.hostname;
4960
+ } catch (e) {
4961
+ domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
4962
+ }
4963
+ const sanitizedDomain = domain.replace(/\./g, "_");
4964
+ return new Configstore(`mobbdev-${sanitizedDomain}`, defaultValues);
4965
+ }
4966
+ function getConfigStore() {
4967
+ return createConfigStore();
4968
+ }
4969
+ var configStore = getConfigStore();
4970
+
4953
4971
  // src/commands/handleMobbLogin.ts
4954
4972
  var debug8 = Debug7("mobbdev:commands");
4955
4973
  var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
@@ -4958,7 +4976,20 @@ var webLoginUrl = `${WEB_APP_URL}/cli-login`;
4958
4976
  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(
4959
4977
  "press any key to continue"
4960
4978
  )};`;
4961
- var config2 = new Configstore(packageJson.name, { apiToken: "" });
4979
+ async function getAuthenticatedGQLClient({
4980
+ inputApiKey = "",
4981
+ isSkipPrompts = true
4982
+ }) {
4983
+ let gqlClient = new GQLClient({
4984
+ apiKey: inputApiKey || configStore.get("apiToken") || "",
4985
+ type: "apiKey"
4986
+ });
4987
+ gqlClient = await handleMobbLogin({
4988
+ inGqlClient: gqlClient,
4989
+ skipPrompts: isSkipPrompts
4990
+ });
4991
+ return gqlClient;
4992
+ }
4962
4993
  async function handleMobbLogin({
4963
4994
  inGqlClient,
4964
4995
  apiKey,
@@ -5034,7 +5065,7 @@ async function handleMobbLogin({
5034
5065
  const loginSuccess = await newGqlClient.validateUserToken();
5035
5066
  if (loginSuccess) {
5036
5067
  debug8(`set api token ${newApiToken}`);
5037
- config2.set("apiToken", newApiToken);
5068
+ configStore.set("apiToken", newApiToken);
5038
5069
  loginSpinner.success({
5039
5070
  text: `\u{1F513} Login to Mobb successful! ${typeof loginSpinner === "string" ? `Logged in as ${loginSuccess}` : ""}`
5040
5071
  });
@@ -5184,18 +5215,6 @@ async function uploadAiBlameHandlerFromExtension(args) {
5184
5215
  });
5185
5216
  });
5186
5217
  }
5187
- var config3 = new Configstore2(packageJson.name, { apiToken: "" });
5188
- async function getAuthenticatedGQLClientForIdeExtension() {
5189
- let gqlClient = new GQLClient({
5190
- apiKey: config3.get("apiToken") ?? "",
5191
- type: "apiKey"
5192
- });
5193
- gqlClient = await handleMobbLogin({
5194
- inGqlClient: gqlClient,
5195
- skipPrompts: true
5196
- });
5197
- return gqlClient;
5198
- }
5199
5218
  async function uploadAiBlameHandler(args, exitOnError = true) {
5200
5219
  const prompts = args.prompt || [];
5201
5220
  const inferences = args.inference || [];
@@ -5238,7 +5257,9 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5238
5257
  blameType: blameTypes[i] || "CHAT" /* Chat */
5239
5258
  });
5240
5259
  }
5241
- const authenticatedClient = await getAuthenticatedGQLClientForIdeExtension();
5260
+ const authenticatedClient = await getAuthenticatedGQLClient({
5261
+ isSkipPrompts: true
5262
+ });
5242
5263
  const initRes = await authenticatedClient.uploadAIBlameInferencesInitRaw({
5243
5264
  sessions
5244
5265
  });
@@ -5299,7 +5320,6 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
5299
5320
  console.log(chalk3.green("AI Blame uploads finalized successfully"));
5300
5321
  }
5301
5322
  export {
5302
- getAuthenticatedGQLClientForIdeExtension,
5303
5323
  uploadAiBlameBuilder,
5304
5324
  uploadAiBlameHandler,
5305
5325
  uploadAiBlameHandlerFromExtension
package/dist/index.mjs CHANGED
@@ -32,12 +32,11 @@ var init_env = __esm({
32
32
  });
33
33
 
34
34
  // src/mcp/core/configs.ts
35
- var MCP_DEFAULT_API_URL, MCP_API_KEY_HEADER_NAME, MCP_LOGIN_MAX_WAIT, MCP_LOGIN_CHECK_DELAY, MCP_VUL_REPORT_DIGEST_TIMEOUT_MS, MCP_MAX_FILE_SIZE, MCP_PERIODIC_CHECK_INTERVAL, MCP_DEFAULT_MAX_FILES_TO_SCAN, MCP_REPORT_ID_EXPIRATION_MS, MCP_TOOLS_BROWSER_COOLDOWN_MS, MCP_DEFAULT_LIMIT, isAutoScan, MVS_AUTO_FIX_OVERRIDE, MCP_AUTO_FIX_DEBUG_MODE, MCP_PERIODIC_TRACK_INTERVAL, MCP_DEFAULT_REST_API_URL, MCP_SYSTEM_FIND_TIMEOUT_MS;
35
+ var MCP_API_KEY_HEADER_NAME, MCP_LOGIN_MAX_WAIT, MCP_LOGIN_CHECK_DELAY, MCP_VUL_REPORT_DIGEST_TIMEOUT_MS, MCP_MAX_FILE_SIZE, MCP_PERIODIC_CHECK_INTERVAL, MCP_DEFAULT_MAX_FILES_TO_SCAN, MCP_REPORT_ID_EXPIRATION_MS, MCP_TOOLS_BROWSER_COOLDOWN_MS, MCP_DEFAULT_LIMIT, isAutoScan, MVS_AUTO_FIX_OVERRIDE, MCP_AUTO_FIX_DEBUG_MODE, MCP_PERIODIC_TRACK_INTERVAL, MCP_DEFAULT_REST_API_URL, MCP_SYSTEM_FIND_TIMEOUT_MS;
36
36
  var init_configs = __esm({
37
37
  "src/mcp/core/configs.ts"() {
38
38
  "use strict";
39
39
  init_env();
40
- MCP_DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
41
40
  MCP_API_KEY_HEADER_NAME = "x-mobb-key";
42
41
  MCP_LOGIN_MAX_WAIT = 2 * 60 * 1e3;
43
42
  MCP_LOGIN_CHECK_DELAY = 2 * 1e3;
@@ -9812,6 +9811,7 @@ import * as dotenv from "dotenv";
9812
9811
  import { z as z24 } from "zod";
9813
9812
  var debug5 = Debug4("mobbdev:constants");
9814
9813
  dotenv.config({ path: path6.join(getModuleRootDir(), ".env") });
9814
+ var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
9815
9815
  var scmFriendlyText = {
9816
9816
  ["Ado" /* Ado */]: "Azure DevOps",
9817
9817
  ["Bitbucket" /* Bitbucket */]: "Bitbucket",
@@ -10069,7 +10069,6 @@ import chalk8 from "chalk";
10069
10069
 
10070
10070
  // src/commands/index.ts
10071
10071
  import chalkAnimation from "chalk-animation";
10072
- import Configstore3 from "configstore";
10073
10072
 
10074
10073
  // src/features/analysis/index.ts
10075
10074
  import fs9 from "fs";
@@ -10078,7 +10077,6 @@ import path9 from "path";
10078
10077
  import { env as env2 } from "process";
10079
10078
  import { pipeline } from "stream/promises";
10080
10079
  import chalk6 from "chalk";
10081
- import Configstore2 from "configstore";
10082
10080
  import Debug19 from "debug";
10083
10081
  import extract from "extract-zip";
10084
10082
  import { createSpinner as createSpinner4 } from "nanospinner";
@@ -10091,7 +10089,6 @@ import { z as z29 } from "zod";
10091
10089
  import crypto from "crypto";
10092
10090
  import os from "os";
10093
10091
  import chalk3 from "chalk";
10094
- import Configstore from "configstore";
10095
10092
  import Debug7 from "debug";
10096
10093
  import open from "open";
10097
10094
 
@@ -10180,7 +10177,7 @@ import Debug5 from "debug";
10180
10177
  import { createClient } from "graphql-ws";
10181
10178
  import { HttpsProxyAgent } from "https-proxy-agent";
10182
10179
  import WebSocket from "ws";
10183
- var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
10180
+ var DEFAULT_API_URL2 = "https://api.mobb.ai/v1/graphql";
10184
10181
  var debug6 = Debug5("mobbdev:subscribe");
10185
10182
  var SUBSCRIPTION_TIMEOUT_MS = 30 * 60 * 1e3;
10186
10183
  function createWSClient(options) {
@@ -10216,7 +10213,7 @@ function subscribe(query, variables, callback, wsClientOptions) {
10216
10213
  return new Promise((resolve, reject) => {
10217
10214
  let timer = null;
10218
10215
  const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
10219
- const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL;
10216
+ const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL2;
10220
10217
  const client = createWSClient({
10221
10218
  ...wsClientOptions,
10222
10219
  websocket: WebSocket,
@@ -10722,6 +10719,25 @@ var GQLClient = class {
10722
10719
  }
10723
10720
  };
10724
10721
 
10722
+ // src/utils/ConfigStoreService.ts
10723
+ import Configstore from "configstore";
10724
+ function createConfigStore(defaultValues = { apiToken: "" }) {
10725
+ const API_URL2 = process.env["API_URL"] || DEFAULT_API_URL;
10726
+ let domain = "";
10727
+ try {
10728
+ const url = new URL(API_URL2);
10729
+ domain = url.hostname;
10730
+ } catch (e) {
10731
+ domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
10732
+ }
10733
+ const sanitizedDomain = domain.replace(/\./g, "_");
10734
+ return new Configstore(`mobbdev-${sanitizedDomain}`, defaultValues);
10735
+ }
10736
+ function getConfigStore() {
10737
+ return createConfigStore();
10738
+ }
10739
+ var configStore = getConfigStore();
10740
+
10725
10741
  // src/commands/handleMobbLogin.ts
10726
10742
  var debug8 = Debug7("mobbdev:commands");
10727
10743
  var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
@@ -10730,7 +10746,20 @@ var webLoginUrl = `${WEB_APP_URL}/cli-login`;
10730
10746
  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(
10731
10747
  "press any key to continue"
10732
10748
  )};`;
10733
- var config2 = new Configstore(packageJson.name, { apiToken: "" });
10749
+ async function getAuthenticatedGQLClient({
10750
+ inputApiKey = "",
10751
+ isSkipPrompts = true
10752
+ }) {
10753
+ let gqlClient = new GQLClient({
10754
+ apiKey: inputApiKey || configStore.get("apiToken") || "",
10755
+ type: "apiKey"
10756
+ });
10757
+ gqlClient = await handleMobbLogin({
10758
+ inGqlClient: gqlClient,
10759
+ skipPrompts: isSkipPrompts
10760
+ });
10761
+ return gqlClient;
10762
+ }
10734
10763
  async function handleMobbLogin({
10735
10764
  inGqlClient,
10736
10765
  apiKey,
@@ -10806,7 +10835,7 @@ async function handleMobbLogin({
10806
10835
  const loginSuccess = await newGqlClient.validateUserToken();
10807
10836
  if (loginSuccess) {
10808
10837
  debug8(`set api token ${newApiToken}`);
10809
- config2.set("apiToken", newApiToken);
10838
+ configStore.set("apiToken", newApiToken);
10810
10839
  loginSpinner.success({
10811
10840
  text: `\u{1F513} Login to Mobb successful! ${typeof loginSpinner === "string" ? `Logged in as ${loginSuccess}` : ""}`
10812
10841
  });
@@ -11883,8 +11912,8 @@ async function forkSnyk(args, { display }) {
11883
11912
  }
11884
11913
  async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
11885
11914
  debug17("get snyk report start %s %s", reportPath, repoRoot);
11886
- const config7 = await forkSnyk(["config"], { display: false });
11887
- const { message: configMessage } = config7;
11915
+ const config2 = await forkSnyk(["config"], { display: false });
11916
+ const { message: configMessage } = config2;
11888
11917
  if (!configMessage.includes("api: ")) {
11889
11918
  const snykLoginSpinner = createSpinner3().start();
11890
11919
  if (!skipPrompts) {
@@ -11896,7 +11925,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
11896
11925
  snykLoginSpinner.update({
11897
11926
  text: "\u{1F513} Waiting for Snyk login to complete"
11898
11927
  });
11899
- debug17("no token in the config %s", config7);
11928
+ debug17("no token in the config %s", config2);
11900
11929
  await forkSnyk(["auth"], { display: true });
11901
11930
  snykLoginSpinner.success({ text: "\u{1F513} Login to Snyk Successful" });
11902
11931
  }
@@ -12040,8 +12069,6 @@ var getReportUrl = ({
12040
12069
  fixReportId
12041
12070
  }) => `${WEB_APP_URL}/organization/${organizationId}/project/${projectId}/report/${fixReportId}`;
12042
12071
  var debug19 = Debug19("mobbdev:index");
12043
- var config3 = new Configstore2(packageJson.name, { apiToken: "" });
12044
- debug19("config %o", config3);
12045
12072
  async function runAnalysis(params, options) {
12046
12073
  const tmpObj = tmp2.dirSync({
12047
12074
  unsafeCleanup: true
@@ -12189,14 +12216,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
12189
12216
  debug19("start %s %s", dirname, repo);
12190
12217
  const { createSpinner: createSpinner5 } = Spinner2({ ci });
12191
12218
  skipPrompts = skipPrompts || ci;
12192
- let gqlClient = new GQLClient({
12193
- apiKey: apiKey ?? config3.get("apiToken") ?? "",
12194
- type: "apiKey"
12195
- });
12196
- gqlClient = await handleMobbLogin({
12197
- inGqlClient: gqlClient,
12198
- skipPrompts,
12199
- apiKey
12219
+ const gqlClient = await getAuthenticatedGQLClient({
12220
+ inputApiKey: apiKey,
12221
+ isSkipPrompts: skipPrompts
12200
12222
  });
12201
12223
  if (!mobbProjectName) {
12202
12224
  throw new Error("mobbProjectName is required");
@@ -12706,17 +12728,11 @@ async function analyze({
12706
12728
  { skipPrompts }
12707
12729
  );
12708
12730
  }
12709
- var config4 = new Configstore3(packageJson.name, { apiToken: "" });
12710
12731
  async function addScmToken(addScmTokenOptions) {
12711
12732
  const { apiKey, token, organization, scmType, url, refreshToken, ci } = addScmTokenOptions;
12712
- let gqlClient = new GQLClient({
12713
- apiKey: apiKey ?? config4.get("apiToken") ?? "",
12714
- type: "apiKey"
12715
- });
12716
- gqlClient = await handleMobbLogin({
12717
- inGqlClient: gqlClient,
12718
- skipPrompts: ci,
12719
- apiKey
12733
+ const gqlClient = await getAuthenticatedGQLClient({
12734
+ inputApiKey: apiKey,
12735
+ isSkipPrompts: ci
12720
12736
  });
12721
12737
  if (!scmType) {
12722
12738
  throw new CliError(errorMessages.invalidScmType);
@@ -12896,9 +12912,6 @@ async function analyzeHandler(args) {
12896
12912
  await analyze(args, { skipPrompts: args.yes });
12897
12913
  }
12898
12914
 
12899
- // src/args/commands/claude_code.ts
12900
- import Configstore5 from "configstore";
12901
-
12902
12915
  // src/features/claude_code/data_collector.ts
12903
12916
  import { z as z32 } from "zod";
12904
12917
 
@@ -12906,7 +12919,6 @@ import { z as z32 } from "zod";
12906
12919
  import fsPromises3 from "fs/promises";
12907
12920
  import path11 from "path";
12908
12921
  import chalk9 from "chalk";
12909
- import Configstore4 from "configstore";
12910
12922
  import { withFile } from "tmp-promise";
12911
12923
  import z31 from "zod";
12912
12924
  var PromptItemZ = z31.object({
@@ -12995,18 +13007,6 @@ async function uploadAiBlameHandlerFromExtension(args) {
12995
13007
  });
12996
13008
  });
12997
13009
  }
12998
- var config5 = new Configstore4(packageJson.name, { apiToken: "" });
12999
- async function getAuthenticatedGQLClientForIdeExtension() {
13000
- let gqlClient = new GQLClient({
13001
- apiKey: config5.get("apiToken") ?? "",
13002
- type: "apiKey"
13003
- });
13004
- gqlClient = await handleMobbLogin({
13005
- inGqlClient: gqlClient,
13006
- skipPrompts: true
13007
- });
13008
- return gqlClient;
13009
- }
13010
13010
  async function uploadAiBlameHandler(args, exitOnError = true) {
13011
13011
  const prompts = args.prompt || [];
13012
13012
  const inferences = args.inference || [];
@@ -13049,7 +13049,9 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
13049
13049
  blameType: blameTypes[i] || "CHAT" /* Chat */
13050
13050
  });
13051
13051
  }
13052
- const authenticatedClient = await getAuthenticatedGQLClientForIdeExtension();
13052
+ const authenticatedClient = await getAuthenticatedGQLClient({
13053
+ isSkipPrompts: true
13054
+ });
13053
13055
  const initRes = await authenticatedClient.uploadAIBlameInferencesInitRaw({
13054
13056
  sessions
13055
13057
  });
@@ -13478,7 +13480,6 @@ async function installMobbHooks(options = {}) {
13478
13480
  }
13479
13481
 
13480
13482
  // src/args/commands/claude_code.ts
13481
- var config6 = new Configstore5(packageJson.name, { apiToken: "" });
13482
13483
  var claudeCodeInstallHookBuilder = (yargs2) => {
13483
13484
  return yargs2.option("save-env", {
13484
13485
  type: "boolean",
@@ -13500,14 +13501,7 @@ var claudeCodeProcessHookBuilder = (yargs2) => {
13500
13501
  };
13501
13502
  var claudeCodeInstallHookHandler = async (argv) => {
13502
13503
  try {
13503
- const gqlClient = new GQLClient({
13504
- apiKey: config6.get("apiToken") ?? "",
13505
- type: "apiKey"
13506
- });
13507
- await handleMobbLogin({
13508
- inGqlClient: gqlClient,
13509
- skipPrompts: false
13510
- });
13504
+ await getAuthenticatedGQLClient({ isSkipPrompts: false });
13511
13505
  await installMobbHooks({ saveEnv: argv["save-env"] });
13512
13506
  process.exit(0);
13513
13507
  } catch (error) {
@@ -13574,7 +13568,7 @@ import {
13574
13568
  } from "@modelcontextprotocol/sdk/types.js";
13575
13569
 
13576
13570
  // src/mcp/Logger.ts
13577
- import Configstore6 from "configstore";
13571
+ import Configstore2 from "configstore";
13578
13572
 
13579
13573
  // src/mcp/services/WorkspaceService.ts
13580
13574
  var WorkspaceService = class {
@@ -13660,7 +13654,7 @@ var Logger = class {
13660
13654
  __publicField(this, "lastKnownPath", null);
13661
13655
  this.host = WorkspaceService.getHost();
13662
13656
  this.unknownPathSuffix = Math.floor(1e3 + Math.random() * 9e3).toString();
13663
- this.mobbConfigStore = new Configstore6("mobb-logs", {});
13657
+ this.mobbConfigStore = new Configstore2("mobb-logs", {});
13664
13658
  this.mobbConfigStore.set("version", packageJson.version);
13665
13659
  }
13666
13660
  /**
@@ -13857,29 +13851,6 @@ var GetLatestReportByRepoUrlResponseSchema = z33.object({
13857
13851
  expiredReport: z33.array(ExpiredReportSchema)
13858
13852
  });
13859
13853
 
13860
- // src/mcp/services/ConfigStoreService.ts
13861
- import Configstore7 from "configstore";
13862
- init_configs();
13863
- function createConfigStore(defaultValues = { apiToken: "" }) {
13864
- const API_URL2 = process.env["API_URL"] || MCP_DEFAULT_API_URL;
13865
- let domain = "";
13866
- try {
13867
- const url = new URL(API_URL2);
13868
- domain = url.hostname;
13869
- } catch (e) {
13870
- domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
13871
- }
13872
- const sanitizedDomain = domain.replace(/\./g, "_");
13873
- return new Configstore7(
13874
- `${packageJson.name}-${sanitizedDomain}`,
13875
- defaultValues
13876
- );
13877
- }
13878
- function getConfigStore() {
13879
- return createConfigStore();
13880
- }
13881
- var configStore = getConfigStore();
13882
-
13883
13854
  // src/mcp/services/McpAuthService.ts
13884
13855
  import crypto2 from "crypto";
13885
13856
  import os3 from "os";
@@ -13968,7 +13939,7 @@ var McpGQLClient = class {
13968
13939
  __publicField(this, "currentUser", null);
13969
13940
  __publicField(this, "apiUrl");
13970
13941
  this._auth = args;
13971
- this.apiUrl = process.env["API_URL"] || MCP_DEFAULT_API_URL;
13942
+ this.apiUrl = process.env["API_URL"] || DEFAULT_API_URL;
13972
13943
  logDebug(`[GraphQL] Creating graphql client with api url ${this.apiUrl}`, {
13973
13944
  args
13974
13945
  });
@@ -14687,34 +14658,34 @@ var readConfigFile = (filePath) => {
14687
14658
  return null;
14688
14659
  }
14689
14660
  };
14690
- var mergeConfigIntoResult = (config7, mergedConfig) => {
14691
- if (config7?.projects) {
14661
+ var mergeConfigIntoResult = (config2, mergedConfig) => {
14662
+ if (config2?.projects) {
14692
14663
  const allMcpServers = {};
14693
- for (const projectPath in config7.projects) {
14694
- const project = config7.projects[projectPath];
14664
+ for (const projectPath in config2.projects) {
14665
+ const project = config2.projects[projectPath];
14695
14666
  if (project?.mcpServers) {
14696
14667
  Object.assign(allMcpServers, project.mcpServers);
14697
14668
  }
14698
14669
  }
14699
14670
  mergedConfig.mcpServers = { ...mergedConfig.mcpServers, ...allMcpServers };
14700
14671
  }
14701
- if (config7?.mcpServers) {
14672
+ if (config2?.mcpServers) {
14702
14673
  mergedConfig.mcpServers = {
14703
14674
  ...mergedConfig.mcpServers,
14704
- ...config7.mcpServers
14675
+ ...config2.mcpServers
14705
14676
  };
14706
14677
  }
14707
- if (config7?.servers) {
14708
- mergedConfig.servers = { ...mergedConfig.servers, ...config7.servers };
14678
+ if (config2?.servers) {
14679
+ mergedConfig.servers = { ...mergedConfig.servers, ...config2.servers };
14709
14680
  }
14710
14681
  };
14711
14682
  var readMCPConfig = (hostName) => {
14712
14683
  const configPaths = getMCPConfigPaths(hostName);
14713
14684
  const mergedConfig = {};
14714
14685
  for (const configPath of configPaths) {
14715
- const config7 = readConfigFile(configPath);
14716
- if (config7) {
14717
- mergeConfigIntoResult(config7, mergedConfig);
14686
+ const config2 = readConfigFile(configPath);
14687
+ if (config2) {
14688
+ mergeConfigIntoResult(config2, mergedConfig);
14718
14689
  }
14719
14690
  }
14720
14691
  return Object.keys(mergedConfig).length > 0 ? mergedConfig : null;
@@ -14841,10 +14812,10 @@ var getHostInfo = (additionalMcpList) => {
14841
14812
  if (cfg) allConfigs[ide] = cfg;
14842
14813
  }
14843
14814
  for (const additionalPath of uniqueAdditionalPaths) {
14844
- const config7 = readConfigFile(additionalPath);
14845
- if (!config7) continue;
14815
+ const config2 = readConfigFile(additionalPath);
14816
+ if (!config2) continue;
14846
14817
  const mergedConfig = {};
14847
- mergeConfigIntoResult(config7, mergedConfig);
14818
+ mergeConfigIntoResult(config2, mergedConfig);
14848
14819
  if (Object.keys(mergedConfig).length > 0) {
14849
14820
  allConfigs["system"] = mergedConfig;
14850
14821
  }
@@ -14912,7 +14883,7 @@ var getHostInfo = (additionalMcpList) => {
14912
14883
  }
14913
14884
  }
14914
14885
  for (const { ide, name, command, isRunning } of servers) {
14915
- const config7 = allConfigs[ide] || null;
14886
+ const config2 = allConfigs[ide] || null;
14916
14887
  const ideName = ide.charAt(0).toUpperCase() + ide.slice(1) || "Unknown";
14917
14888
  let ideVersion = "Unknown";
14918
14889
  const platform2 = os4.platform();
@@ -14929,8 +14900,8 @@ var getHostInfo = (additionalMcpList) => {
14929
14900
  }
14930
14901
  }
14931
14902
  let mcpConfigObj = {};
14932
- if (config7) {
14933
- const allServers = config7.mcpServers || config7.servers || {};
14903
+ if (config2) {
14904
+ const allServers = config2.mcpServers || config2.servers || {};
14934
14905
  if (name in allServers && allServers[name]) {
14935
14906
  mcpConfigObj = allServers[name];
14936
14907
  }
@@ -15268,7 +15239,7 @@ var ToolRegistry = class {
15268
15239
 
15269
15240
  // src/mcp/core/McpServer.ts
15270
15241
  var McpServer = class {
15271
- constructor(config7, govOrgId = "") {
15242
+ constructor(config2, govOrgId = "") {
15272
15243
  __publicField(this, "server");
15273
15244
  __publicField(this, "toolRegistry");
15274
15245
  __publicField(this, "promptRegistry");
@@ -15282,8 +15253,8 @@ var McpServer = class {
15282
15253
  this.mcpUsageService = govOrgId ? new McpUsageService(govOrgId) : null;
15283
15254
  this.server = new Server(
15284
15255
  {
15285
- name: config7.name,
15286
- version: config7.version
15256
+ name: config2.name,
15257
+ version: config2.version
15287
15258
  },
15288
15259
  {
15289
15260
  capabilities: {
@@ -15299,7 +15270,7 @@ var McpServer = class {
15299
15270
  this.setupParentProcessMonitoring();
15300
15271
  logInfo("MCP server instance created");
15301
15272
  logDebug("MCP server instance config", {
15302
- config: config7,
15273
+ config: config2,
15303
15274
  parentPid: this.parentPid
15304
15275
  });
15305
15276
  }
@@ -19170,10 +19141,15 @@ var PatchApplicationService = class {
19170
19141
  */
19171
19142
  static writeFileWithFixComment({
19172
19143
  filePath,
19144
+ repositoryPath,
19173
19145
  content,
19174
19146
  fix,
19175
19147
  scanContext
19176
19148
  }) {
19149
+ const { normalizedPath: normalizedFilePath } = this.resolvePathWithinRepo({
19150
+ repositoryPath,
19151
+ targetPath: filePath
19152
+ });
19177
19153
  let finalContent = content;
19178
19154
  if (MCP_AUTO_FIX_DEBUG_MODE) {
19179
19155
  const fixType = fix.safeIssueType || "Security Issue";
@@ -19205,10 +19181,28 @@ var PatchApplicationService = class {
19205
19181
  }
19206
19182
  );
19207
19183
  }
19208
- const dirPath = path20.dirname(filePath);
19184
+ const dirPath = path20.dirname(normalizedFilePath);
19209
19185
  mkdirSync(dirPath, { recursive: true });
19210
- writeFileSync(filePath, finalContent, "utf8");
19211
- return filePath;
19186
+ writeFileSync(normalizedFilePath, finalContent, "utf8");
19187
+ return normalizedFilePath;
19188
+ }
19189
+ static resolvePathWithinRepo({
19190
+ repositoryPath,
19191
+ targetPath
19192
+ }) {
19193
+ const repoRoot = path20.resolve(repositoryPath);
19194
+ const normalizedPath = path20.resolve(repoRoot, targetPath);
19195
+ const repoRootWithSep = repoRoot.endsWith(path20.sep) ? repoRoot : `${repoRoot}${path20.sep}`;
19196
+ if (normalizedPath !== repoRoot && !normalizedPath.startsWith(repoRootWithSep)) {
19197
+ throw new Error(
19198
+ `Security violation: target path ${targetPath} resolves outside repository`
19199
+ );
19200
+ }
19201
+ return {
19202
+ repoRoot,
19203
+ normalizedPath,
19204
+ relativePath: path20.relative(repoRoot, normalizedPath)
19205
+ };
19212
19206
  }
19213
19207
  /**
19214
19208
  * Extracts target file path from a fix
@@ -19678,21 +19672,17 @@ var PatchApplicationService = class {
19678
19672
  repositoryPath,
19679
19673
  scanContext
19680
19674
  }) {
19681
- const sanitizedRepoPath = String(repositoryPath || "").replace("\0", "").replace(/^(\.\.(\/|\\))+/, "");
19682
- const sanitizedTargetFile = String(targetFile || "").replace("\0", "").replace(/^(\.\.(\/|\\))+/, "");
19683
- const absoluteFilePath = path20.resolve(
19684
- sanitizedRepoPath,
19685
- sanitizedTargetFile
19686
- );
19687
- const relativePath = path20.relative(sanitizedRepoPath, absoluteFilePath);
19688
- if (relativePath.startsWith("..")) {
19689
- throw new Error(
19690
- `Security violation: target file ${targetFile} resolves outside repository`
19691
- );
19692
- }
19675
+ const {
19676
+ repoRoot,
19677
+ normalizedPath: absoluteFilePath,
19678
+ relativePath
19679
+ } = this.resolvePathWithinRepo({
19680
+ repositoryPath,
19681
+ targetPath: targetFile
19682
+ });
19693
19683
  logDebug(`[${scanContext}] Resolving file path for ${targetFile}`, {
19694
- repositoryPath: sanitizedRepoPath,
19695
- targetFile: sanitizedTargetFile,
19684
+ repositoryPath: repoRoot,
19685
+ targetFile,
19696
19686
  absoluteFilePath,
19697
19687
  relativePath,
19698
19688
  exists: existsSync6(absoluteFilePath)
@@ -19714,6 +19704,7 @@ var PatchApplicationService = class {
19714
19704
  const newContent = this.applyHunksToEmptyFile(fileDiff.chunks);
19715
19705
  const actualPath = this.writeFileWithFixComment({
19716
19706
  filePath: absoluteFilePath,
19707
+ repositoryPath,
19717
19708
  content: newContent,
19718
19709
  fix,
19719
19710
  scanContext
@@ -19762,6 +19753,7 @@ var PatchApplicationService = class {
19762
19753
  if (modifiedContent !== originalContent) {
19763
19754
  const actualPath = this.writeFileWithFixComment({
19764
19755
  filePath: absoluteFilePath,
19756
+ repositoryPath,
19765
19757
  content: modifiedContent,
19766
19758
  fix,
19767
19759
  scanContext
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
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",
@@ -75,7 +75,7 @@
75
75
  "http-proxy-agent": "7.0.2",
76
76
  "https-proxy-agent": "7.0.6",
77
77
  "ignore": "7.0.5",
78
- "inquirer": "9.3.7",
78
+ "inquirer": "9.3.8",
79
79
  "isomorphic-ws": "5.0.0",
80
80
  "istextorbinary": "9.5.0",
81
81
  "libsodium-wrappers": "0.7.15",
@@ -89,7 +89,7 @@
89
89
  "sax": "1.4.3",
90
90
  "semver": "7.7.3",
91
91
  "simple-git": "3.30.0",
92
- "snyk": "1.1300.2",
92
+ "snyk": "1.1301.0",
93
93
  "tar": "6.2.1",
94
94
  "tmp": "0.2.5",
95
95
  "tmp-promise": "3.0.3",