mobbdev 1.1.0 → 1.1.2

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
  });
@@ -13409,7 +13411,7 @@ async function writeClaudeSettings(settings) {
13409
13411
  "utf-8"
13410
13412
  );
13411
13413
  }
13412
- async function installMobbHooks() {
13414
+ async function installMobbHooks(options = {}) {
13413
13415
  console.log(chalk10.blue("Installing Mobb hooks in Claude Code settings..."));
13414
13416
  if (!await claudeSettingsExists()) {
13415
13417
  console.log(chalk10.red("\u274C Claude Code settings file not found"));
@@ -13427,12 +13429,33 @@ async function installMobbHooks() {
13427
13429
  if (!settings.hooks.PostToolUse) {
13428
13430
  settings.hooks.PostToolUse = [];
13429
13431
  }
13432
+ let command = "npx --yes mobbdev@latest claude-code-process-hook";
13433
+ if (options.saveEnv) {
13434
+ const envVars = [];
13435
+ if (process.env["WEB_LOGIN_URL"]) {
13436
+ envVars.push(`WEB_LOGIN_URL="${process.env["WEB_LOGIN_URL"]}"`);
13437
+ }
13438
+ if (process.env["WEB_APP_URL"]) {
13439
+ envVars.push(`WEB_APP_URL="${process.env["WEB_APP_URL"]}"`);
13440
+ }
13441
+ if (process.env["API_URL"]) {
13442
+ envVars.push(`API_URL="${process.env["API_URL"]}"`);
13443
+ }
13444
+ if (envVars.length > 0) {
13445
+ command = `${envVars.join(" ")} ${command}`;
13446
+ console.log(
13447
+ chalk10.blue(
13448
+ `Adding environment variables to hook command: ${envVars.join(", ")}`
13449
+ )
13450
+ );
13451
+ }
13452
+ }
13430
13453
  const mobbHookConfig = {
13431
13454
  matcher: "Edit|Write",
13432
13455
  hooks: [
13433
13456
  {
13434
13457
  type: "command",
13435
- command: "npx --yes mobbdev@latest claude-code-process-hook"
13458
+ command
13436
13459
  }
13437
13460
  ]
13438
13461
  };
@@ -13451,17 +13474,23 @@ async function installMobbHooks() {
13451
13474
  await writeClaudeSettings(settings);
13452
13475
  console.log(
13453
13476
  chalk10.green(
13454
- `\u2705 Mobb hooks installed successfully in ${CLAUDE_SETTINGS_PATH}`
13477
+ `\u2705 Mobb hooks ${options.saveEnv ? "and environment variables " : ""}installed successfully in ${CLAUDE_SETTINGS_PATH}`
13455
13478
  )
13456
13479
  );
13457
13480
  }
13458
13481
 
13459
13482
  // src/args/commands/claude_code.ts
13460
- var config6 = new Configstore5(packageJson.name, { apiToken: "" });
13461
13483
  var claudeCodeInstallHookBuilder = (yargs2) => {
13462
- return yargs2.example(
13484
+ return yargs2.option("save-env", {
13485
+ type: "boolean",
13486
+ description: "Save WEB_LOGIN_URL, WEB_APP_URL, and API_URL environment variables to hooks config",
13487
+ default: false
13488
+ }).example(
13463
13489
  "$0 claude-code-install-hook",
13464
13490
  "Install Claude Code hooks for data collection"
13491
+ ).example(
13492
+ "$0 claude-code-install-hook --save-env",
13493
+ "Install hooks and save environment variables to config"
13465
13494
  ).strict();
13466
13495
  };
13467
13496
  var claudeCodeProcessHookBuilder = (yargs2) => {
@@ -13470,17 +13499,10 @@ var claudeCodeProcessHookBuilder = (yargs2) => {
13470
13499
  "Process Claude Code hook data and upload to backend"
13471
13500
  ).strict();
13472
13501
  };
13473
- var claudeCodeInstallHookHandler = async () => {
13502
+ var claudeCodeInstallHookHandler = async (argv) => {
13474
13503
  try {
13475
- const gqlClient = new GQLClient({
13476
- apiKey: config6.get("apiToken") ?? "",
13477
- type: "apiKey"
13478
- });
13479
- await handleMobbLogin({
13480
- inGqlClient: gqlClient,
13481
- skipPrompts: false
13482
- });
13483
- await installMobbHooks();
13504
+ await getAuthenticatedGQLClient({ isSkipPrompts: false });
13505
+ await installMobbHooks({ saveEnv: argv["save-env"] });
13484
13506
  process.exit(0);
13485
13507
  } catch (error) {
13486
13508
  console.error("Failed to install Claude Code hooks:", error);
@@ -13546,7 +13568,7 @@ import {
13546
13568
  } from "@modelcontextprotocol/sdk/types.js";
13547
13569
 
13548
13570
  // src/mcp/Logger.ts
13549
- import Configstore6 from "configstore";
13571
+ import Configstore2 from "configstore";
13550
13572
 
13551
13573
  // src/mcp/services/WorkspaceService.ts
13552
13574
  var WorkspaceService = class {
@@ -13632,7 +13654,7 @@ var Logger = class {
13632
13654
  __publicField(this, "lastKnownPath", null);
13633
13655
  this.host = WorkspaceService.getHost();
13634
13656
  this.unknownPathSuffix = Math.floor(1e3 + Math.random() * 9e3).toString();
13635
- this.mobbConfigStore = new Configstore6("mobb-logs", {});
13657
+ this.mobbConfigStore = new Configstore2("mobb-logs", {});
13636
13658
  this.mobbConfigStore.set("version", packageJson.version);
13637
13659
  }
13638
13660
  /**
@@ -13829,29 +13851,6 @@ var GetLatestReportByRepoUrlResponseSchema = z33.object({
13829
13851
  expiredReport: z33.array(ExpiredReportSchema)
13830
13852
  });
13831
13853
 
13832
- // src/mcp/services/ConfigStoreService.ts
13833
- import Configstore7 from "configstore";
13834
- init_configs();
13835
- function createConfigStore(defaultValues = { apiToken: "" }) {
13836
- const API_URL2 = process.env["API_URL"] || MCP_DEFAULT_API_URL;
13837
- let domain = "";
13838
- try {
13839
- const url = new URL(API_URL2);
13840
- domain = url.hostname;
13841
- } catch (e) {
13842
- domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
13843
- }
13844
- const sanitizedDomain = domain.replace(/\./g, "_");
13845
- return new Configstore7(
13846
- `${packageJson.name}-${sanitizedDomain}`,
13847
- defaultValues
13848
- );
13849
- }
13850
- function getConfigStore() {
13851
- return createConfigStore();
13852
- }
13853
- var configStore = getConfigStore();
13854
-
13855
13854
  // src/mcp/services/McpAuthService.ts
13856
13855
  import crypto2 from "crypto";
13857
13856
  import os3 from "os";
@@ -13940,7 +13939,7 @@ var McpGQLClient = class {
13940
13939
  __publicField(this, "currentUser", null);
13941
13940
  __publicField(this, "apiUrl");
13942
13941
  this._auth = args;
13943
- this.apiUrl = process.env["API_URL"] || MCP_DEFAULT_API_URL;
13942
+ this.apiUrl = process.env["API_URL"] || DEFAULT_API_URL;
13944
13943
  logDebug(`[GraphQL] Creating graphql client with api url ${this.apiUrl}`, {
13945
13944
  args
13946
13945
  });
@@ -14659,34 +14658,34 @@ var readConfigFile = (filePath) => {
14659
14658
  return null;
14660
14659
  }
14661
14660
  };
14662
- var mergeConfigIntoResult = (config7, mergedConfig) => {
14663
- if (config7?.projects) {
14661
+ var mergeConfigIntoResult = (config2, mergedConfig) => {
14662
+ if (config2?.projects) {
14664
14663
  const allMcpServers = {};
14665
- for (const projectPath in config7.projects) {
14666
- const project = config7.projects[projectPath];
14664
+ for (const projectPath in config2.projects) {
14665
+ const project = config2.projects[projectPath];
14667
14666
  if (project?.mcpServers) {
14668
14667
  Object.assign(allMcpServers, project.mcpServers);
14669
14668
  }
14670
14669
  }
14671
14670
  mergedConfig.mcpServers = { ...mergedConfig.mcpServers, ...allMcpServers };
14672
14671
  }
14673
- if (config7?.mcpServers) {
14672
+ if (config2?.mcpServers) {
14674
14673
  mergedConfig.mcpServers = {
14675
14674
  ...mergedConfig.mcpServers,
14676
- ...config7.mcpServers
14675
+ ...config2.mcpServers
14677
14676
  };
14678
14677
  }
14679
- if (config7?.servers) {
14680
- mergedConfig.servers = { ...mergedConfig.servers, ...config7.servers };
14678
+ if (config2?.servers) {
14679
+ mergedConfig.servers = { ...mergedConfig.servers, ...config2.servers };
14681
14680
  }
14682
14681
  };
14683
14682
  var readMCPConfig = (hostName) => {
14684
14683
  const configPaths = getMCPConfigPaths(hostName);
14685
14684
  const mergedConfig = {};
14686
14685
  for (const configPath of configPaths) {
14687
- const config7 = readConfigFile(configPath);
14688
- if (config7) {
14689
- mergeConfigIntoResult(config7, mergedConfig);
14686
+ const config2 = readConfigFile(configPath);
14687
+ if (config2) {
14688
+ mergeConfigIntoResult(config2, mergedConfig);
14690
14689
  }
14691
14690
  }
14692
14691
  return Object.keys(mergedConfig).length > 0 ? mergedConfig : null;
@@ -14813,10 +14812,10 @@ var getHostInfo = (additionalMcpList) => {
14813
14812
  if (cfg) allConfigs[ide] = cfg;
14814
14813
  }
14815
14814
  for (const additionalPath of uniqueAdditionalPaths) {
14816
- const config7 = readConfigFile(additionalPath);
14817
- if (!config7) continue;
14815
+ const config2 = readConfigFile(additionalPath);
14816
+ if (!config2) continue;
14818
14817
  const mergedConfig = {};
14819
- mergeConfigIntoResult(config7, mergedConfig);
14818
+ mergeConfigIntoResult(config2, mergedConfig);
14820
14819
  if (Object.keys(mergedConfig).length > 0) {
14821
14820
  allConfigs["system"] = mergedConfig;
14822
14821
  }
@@ -14884,7 +14883,7 @@ var getHostInfo = (additionalMcpList) => {
14884
14883
  }
14885
14884
  }
14886
14885
  for (const { ide, name, command, isRunning } of servers) {
14887
- const config7 = allConfigs[ide] || null;
14886
+ const config2 = allConfigs[ide] || null;
14888
14887
  const ideName = ide.charAt(0).toUpperCase() + ide.slice(1) || "Unknown";
14889
14888
  let ideVersion = "Unknown";
14890
14889
  const platform2 = os4.platform();
@@ -14901,8 +14900,8 @@ var getHostInfo = (additionalMcpList) => {
14901
14900
  }
14902
14901
  }
14903
14902
  let mcpConfigObj = {};
14904
- if (config7) {
14905
- const allServers = config7.mcpServers || config7.servers || {};
14903
+ if (config2) {
14904
+ const allServers = config2.mcpServers || config2.servers || {};
14906
14905
  if (name in allServers && allServers[name]) {
14907
14906
  mcpConfigObj = allServers[name];
14908
14907
  }
@@ -15240,7 +15239,7 @@ var ToolRegistry = class {
15240
15239
 
15241
15240
  // src/mcp/core/McpServer.ts
15242
15241
  var McpServer = class {
15243
- constructor(config7, govOrgId = "") {
15242
+ constructor(config2, govOrgId = "") {
15244
15243
  __publicField(this, "server");
15245
15244
  __publicField(this, "toolRegistry");
15246
15245
  __publicField(this, "promptRegistry");
@@ -15254,8 +15253,8 @@ var McpServer = class {
15254
15253
  this.mcpUsageService = govOrgId ? new McpUsageService(govOrgId) : null;
15255
15254
  this.server = new Server(
15256
15255
  {
15257
- name: config7.name,
15258
- version: config7.version
15256
+ name: config2.name,
15257
+ version: config2.version
15259
15258
  },
15260
15259
  {
15261
15260
  capabilities: {
@@ -15271,7 +15270,7 @@ var McpServer = class {
15271
15270
  this.setupParentProcessMonitoring();
15272
15271
  logInfo("MCP server instance created");
15273
15272
  logDebug("MCP server instance config", {
15274
- config: config7,
15273
+ config: config2,
15275
15274
  parentPid: this.parentPid
15276
15275
  });
15277
15276
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
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",
@@ -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",