mobbdev 1.1.32 → 1.1.35

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.
package/dist/index.mjs CHANGED
@@ -717,12 +717,71 @@ var init_FileUtils = __esm({
717
717
  // src/features/analysis/scm/services/GitService.ts
718
718
  var GitService_exports = {};
719
719
  __export(GitService_exports, {
720
- GitService: () => GitService
720
+ GitService: () => GitService,
721
+ isGitHubUrl: () => isGitHubUrl,
722
+ normalizeGitUrl: () => normalizeGitUrl
721
723
  });
722
724
  import fs2 from "fs";
723
725
  import ignore from "ignore";
724
726
  import * as path2 from "path";
725
727
  import { simpleGit } from "simple-git";
728
+ function normalizeGitUrl(url) {
729
+ let normalizedUrl = url;
730
+ if (normalizedUrl.endsWith(".git")) {
731
+ normalizedUrl = normalizedUrl.slice(0, -".git".length);
732
+ }
733
+ const sshToHttpsMappings = [
734
+ // GitHub
735
+ { pattern: "git@github.com:", replacement: "https://github.com/" },
736
+ // GitLab
737
+ { pattern: "git@gitlab.com:", replacement: "https://gitlab.com/" },
738
+ // Bitbucket
739
+ { pattern: "git@bitbucket.org:", replacement: "https://bitbucket.org/" },
740
+ // Azure DevOps (SSH format)
741
+ {
742
+ pattern: "git@ssh.dev.azure.com:",
743
+ replacement: "https://dev.azure.com/"
744
+ },
745
+ // Azure DevOps (alternative SSH format)
746
+ {
747
+ pattern: /git@([^:]+):v3\/([^/]+)\/([^/]+)\/([^/]+)/,
748
+ replacement: "https://$1/$2/_git/$4"
749
+ }
750
+ ];
751
+ for (const mapping of sshToHttpsMappings) {
752
+ if (typeof mapping.pattern === "string") {
753
+ if (normalizedUrl.startsWith(mapping.pattern)) {
754
+ normalizedUrl = normalizedUrl.replace(
755
+ mapping.pattern,
756
+ mapping.replacement
757
+ );
758
+ break;
759
+ }
760
+ } else {
761
+ const match = normalizedUrl.match(mapping.pattern);
762
+ if (match) {
763
+ normalizedUrl = normalizedUrl.replace(
764
+ mapping.pattern,
765
+ mapping.replacement
766
+ );
767
+ break;
768
+ }
769
+ }
770
+ }
771
+ if (normalizedUrl.startsWith("https://") || normalizedUrl.startsWith("http://")) {
772
+ normalizedUrl = normalizedUrl.replace(/^(https?:\/\/)([^@/]+@)/, "$1");
773
+ }
774
+ return normalizedUrl;
775
+ }
776
+ function isGitHubUrl(normalizedUrl) {
777
+ try {
778
+ const url = new URL(normalizedUrl);
779
+ const host = url.host.toLowerCase();
780
+ return host === "github.com" || host.endsWith(".github.com");
781
+ } catch {
782
+ return false;
783
+ }
784
+ }
726
785
  var MAX_COMMIT_DIFF_SIZE_BYTES, GitService;
727
786
  var init_GitService = __esm({
728
787
  "src/features/analysis/scm/services/GitService.ts"() {
@@ -843,7 +902,7 @@ var init_GitService = __esm({
843
902
  this.git.revparse(["HEAD"]),
844
903
  this.git.revparse(["--abbrev-ref", "HEAD"])
845
904
  ]);
846
- const normalizedRepoUrl = repoUrl.value ? this.normalizeGitUrl(repoUrl.value) : "";
905
+ const normalizedRepoUrl = repoUrl.value ? normalizeGitUrl(repoUrl.value) : "";
847
906
  this.log("[GitService] Git repository information retrieved", "debug", {
848
907
  repoUrl: normalizedRepoUrl,
849
908
  hash,
@@ -941,23 +1000,14 @@ var init_GitService = __esm({
941
1000
  }
942
1001
  }
943
1002
  /**
944
- * Gets the remote repository URL
1003
+ * Gets the remote repository URL (origin)
945
1004
  */
946
1005
  async getRemoteUrl() {
947
1006
  this.log("[GitService] Getting remote repository URL", "debug");
948
1007
  try {
949
1008
  const remoteUrl = await this.git.getConfig("remote.origin.url");
950
1009
  const url = remoteUrl.value || "";
951
- let normalizedUrl = url;
952
- if (normalizedUrl.endsWith(".git")) {
953
- normalizedUrl = normalizedUrl.slice(0, -".git".length);
954
- }
955
- if (normalizedUrl.startsWith("git@github.com:")) {
956
- normalizedUrl = normalizedUrl.replace(
957
- "git@github.com:",
958
- "https://github.com/"
959
- );
960
- }
1010
+ const normalizedUrl = normalizeGitUrl(url);
961
1011
  this.log("[GitService] Remote repository URL retrieved", "debug", {
962
1012
  url: normalizedUrl
963
1013
  });
@@ -1091,95 +1141,6 @@ var init_GitService = __esm({
1091
1141
  throw new Error(errorMessage);
1092
1142
  }
1093
1143
  }
1094
- /**
1095
- * Normalizes a Git URL to HTTPS format for various Git hosting platforms
1096
- * @param url The Git URL to normalize
1097
- * @returns The normalized HTTPS URL
1098
- */
1099
- normalizeGitUrl(url) {
1100
- let normalizedUrl = url;
1101
- if (normalizedUrl.endsWith(".git")) {
1102
- normalizedUrl = normalizedUrl.slice(0, -".git".length);
1103
- }
1104
- const sshToHttpsMappings = [
1105
- // GitHub
1106
- { pattern: "git@github.com:", replacement: "https://github.com/" },
1107
- // GitLab
1108
- { pattern: "git@gitlab.com:", replacement: "https://gitlab.com/" },
1109
- // Bitbucket
1110
- { pattern: "git@bitbucket.org:", replacement: "https://bitbucket.org/" },
1111
- // Azure DevOps (SSH format)
1112
- {
1113
- pattern: "git@ssh.dev.azure.com:",
1114
- replacement: "https://dev.azure.com/"
1115
- },
1116
- // Azure DevOps (alternative SSH format)
1117
- {
1118
- pattern: /git@([^:]+):v3\/([^/]+)\/([^/]+)\/([^/]+)/,
1119
- replacement: "https://$1/$2/_git/$4"
1120
- }
1121
- ];
1122
- for (const mapping of sshToHttpsMappings) {
1123
- if (typeof mapping.pattern === "string") {
1124
- if (normalizedUrl.startsWith(mapping.pattern)) {
1125
- normalizedUrl = normalizedUrl.replace(
1126
- mapping.pattern,
1127
- mapping.replacement
1128
- );
1129
- break;
1130
- }
1131
- } else {
1132
- const match = normalizedUrl.match(mapping.pattern);
1133
- if (match) {
1134
- normalizedUrl = normalizedUrl.replace(
1135
- mapping.pattern,
1136
- mapping.replacement
1137
- );
1138
- break;
1139
- }
1140
- }
1141
- }
1142
- if (normalizedUrl.startsWith("https://") || normalizedUrl.startsWith("http://")) {
1143
- normalizedUrl = normalizedUrl.replace(/^(https?:\/\/)([^@/]+@)/, "$1");
1144
- }
1145
- return normalizedUrl;
1146
- }
1147
- /**
1148
- * Gets all remote repository URLs (equivalent to 'git remote -v')
1149
- */
1150
- async getRepoUrls() {
1151
- this.log("[GitService] Getting all remote repository URLs", "debug");
1152
- try {
1153
- const remotes = await this.git.remote(["-v"]);
1154
- if (!remotes) {
1155
- return {};
1156
- }
1157
- const remoteMap = {};
1158
- remotes.split("\n").forEach((line) => {
1159
- if (!line.trim()) return;
1160
- const [remoteName, url, type2] = line.split(/\s+/);
1161
- if (!remoteName || !url || !type2) return;
1162
- if (!remoteMap[remoteName]) {
1163
- remoteMap[remoteName] = { fetch: "", push: "" };
1164
- }
1165
- const normalizedUrl = this.normalizeGitUrl(url);
1166
- const remote = remoteMap[remoteName];
1167
- if (type2 === "(fetch)") {
1168
- remote.fetch = normalizedUrl;
1169
- } else if (type2 === "(push)") {
1170
- remote.push = normalizedUrl;
1171
- }
1172
- });
1173
- this.log("[GitService] Remote repository URLs retrieved", "debug", {
1174
- remotes: remoteMap
1175
- });
1176
- return remoteMap;
1177
- } catch (error) {
1178
- const errorMessage = `Failed to get remote repository URLs: ${error.message}`;
1179
- this.log(`[GitService] ${errorMessage}`, "error", { error });
1180
- throw new Error(errorMessage);
1181
- }
1182
- }
1183
1144
  /**
1184
1145
  * Fetches the contents of the .gitignore file from the repository
1185
1146
  * @returns The contents of the .gitignore file as a string, or null if the file doesn't exist
@@ -2237,9 +2198,10 @@ var GetPromptSummaryDocument = `
2237
2198
  goal
2238
2199
  developersPlan
2239
2200
  aiImplementationDetails
2240
- importantInstructionsAndPushbacks
2241
- frictionScore {
2242
- score
2201
+ developersPushbacks
2202
+ importantInstructionsAndDecisions
2203
+ backAndForthLevel {
2204
+ level
2243
2205
  justification
2244
2206
  }
2245
2207
  }
@@ -7700,6 +7662,7 @@ var REPORT_DEFAULT_FILE_NAME = "report.json";
7700
7662
  init_env();
7701
7663
 
7702
7664
  // src/features/analysis/scm/github/GithubSCMLib.ts
7665
+ import pLimit from "p-limit";
7703
7666
  import { z as z21 } from "zod";
7704
7667
 
7705
7668
  // src/features/analysis/scm/github/github.ts
@@ -8625,6 +8588,7 @@ function getGithubSdk(params = {}) {
8625
8588
  }
8626
8589
 
8627
8590
  // src/features/analysis/scm/github/GithubSCMLib.ts
8591
+ var GITHUB_COMMIT_FETCH_CONCURRENCY = parseInt(process.env["GITHUB_COMMIT_CONCURRENCY"] || "10", 10) || 10;
8628
8592
  function determinePrStatus(state, isDraft) {
8629
8593
  switch (state) {
8630
8594
  case "CLOSED":
@@ -8991,12 +8955,15 @@ var GithubSCMLib = class extends SCMLib {
8991
8955
  }),
8992
8956
  this.getPrDiff({ pull_number: prNumber })
8993
8957
  ]);
8958
+ const limit = pLimit(GITHUB_COMMIT_FETCH_CONCURRENCY);
8994
8959
  const commits = await Promise.all(
8995
8960
  commitsRes.data.map(
8996
- (commit) => this.getCommitDiff(commit.sha, {
8997
- repositoryCreatedAt,
8998
- parentCommitTimestamps
8999
- })
8961
+ (commit) => limit(
8962
+ () => this.getCommitDiff(commit.sha, {
8963
+ repositoryCreatedAt,
8964
+ parentCommitTimestamps
8965
+ })
8966
+ )
9000
8967
  )
9001
8968
  );
9002
8969
  const diffLines = filesRes ? await this._attributeLinesViaBlame(pr.head.ref, filesRes.data, commits) : [];
@@ -13848,6 +13815,7 @@ import path11 from "path";
13848
13815
  import chalk9 from "chalk";
13849
13816
  import { withFile } from "tmp-promise";
13850
13817
  import z31 from "zod";
13818
+ init_GitService();
13851
13819
 
13852
13820
  // src/utils/computerName.ts
13853
13821
  import { execSync } from "child_process";
@@ -14119,6 +14087,19 @@ var PromptItemZ = z31.object({
14119
14087
  }).optional()
14120
14088
  });
14121
14089
  var PromptItemArrayZ = z31.array(PromptItemZ);
14090
+ async function getRepositoryUrl() {
14091
+ try {
14092
+ const gitService = new GitService(process.cwd());
14093
+ const isRepo = await gitService.isGitRepository();
14094
+ if (!isRepo) {
14095
+ return null;
14096
+ }
14097
+ const remoteUrl = await gitService.getRemoteUrl();
14098
+ return isGitHubUrl(remoteUrl) ? remoteUrl : null;
14099
+ } catch {
14100
+ return null;
14101
+ }
14102
+ }
14122
14103
  function getSystemInfo() {
14123
14104
  let userName;
14124
14105
  try {
@@ -14215,7 +14196,8 @@ async function uploadAiBlameHandlerFromExtension(args) {
14215
14196
  args: uploadArgs,
14216
14197
  exitOnError: false,
14217
14198
  apiUrl: args.apiUrl,
14218
- webAppUrl: args.webAppUrl
14199
+ webAppUrl: args.webAppUrl,
14200
+ repositoryUrl: args.repositoryUrl
14219
14201
  });
14220
14202
  });
14221
14203
  });
@@ -14251,6 +14233,7 @@ async function uploadAiBlameHandler(options) {
14251
14233
  }
14252
14234
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
14253
14235
  const { computerName, userName } = getSystemInfo();
14236
+ const repositoryUrl = options.repositoryUrl !== void 0 ? options.repositoryUrl : await getRepositoryUrl();
14254
14237
  const sessions = [];
14255
14238
  for (let i = 0; i < prompts.length; i++) {
14256
14239
  const promptPath = String(prompts[i]);
@@ -14277,7 +14260,8 @@ async function uploadAiBlameHandler(options) {
14277
14260
  blameType: blameTypes[i] || "CHAT" /* Chat */,
14278
14261
  computerName,
14279
14262
  userName,
14280
- sessionId: sessionIds[i]
14263
+ sessionId: sessionIds[i],
14264
+ repositoryUrl
14281
14265
  });
14282
14266
  }
14283
14267
  const authenticatedClient = await getAuthenticatedGQLClient({
@@ -14333,7 +14317,8 @@ async function uploadAiBlameHandler(options) {
14333
14317
  blameType: s.blameType,
14334
14318
  computerName: s.computerName,
14335
14319
  userName: s.userName,
14336
- sessionId: s.sessionId
14320
+ sessionId: s.sessionId,
14321
+ repositoryUrl: s.repositoryUrl
14337
14322
  };
14338
14323
  });
14339
14324
  try {
@@ -22440,11 +22425,7 @@ Call this tool instead of ${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES} when you only
22440
22425
  if (!gitValidation.isValid) {
22441
22426
  throw new Error(`Invalid git repository: ${gitValidation.error}`);
22442
22427
  }
22443
- const repoUrls = await gitService.getRepoUrls();
22444
- if (Object.keys(repoUrls).length > 0 && !repoUrls["origin"]) {
22445
- throw new Error("Repository must have an origin remote");
22446
- }
22447
- const originUrl = repoUrls["origin"]?.fetch;
22428
+ const originUrl = await gitService.getRemoteUrl();
22448
22429
  if (!originUrl) {
22449
22430
  throw new Error("No origin URL found for the repository");
22450
22431
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.1.32",
3
+ "version": "1.1.35",
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",
@@ -86,6 +86,7 @@
86
86
  "node-stream-zip": "1.15.0",
87
87
  "octokit": "3.2.1",
88
88
  "open": "8.4.2",
89
+ "p-limit": "3.1.0",
89
90
  "parse-diff": "0.11.1",
90
91
  "sax": "1.4.3",
91
92
  "semver": "7.7.3",