mobbdev 1.2.51 → 1.2.53

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.
@@ -4557,6 +4557,9 @@ function subscribeStream(query, variables, handlers, wsClientOptions) {
4557
4557
  };
4558
4558
  }
4559
4559
 
4560
+ // src/features/analysis/scm/ado/ado.ts
4561
+ import pLimit from "p-limit";
4562
+
4560
4563
  // src/features/analysis/scm/utils/index.ts
4561
4564
  import { z as z15 } from "zod";
4562
4565
 
@@ -6521,6 +6524,8 @@ var debug3 = Debug3("mobbdev:scm:ado");
6521
6524
 
6522
6525
  // src/features/analysis/scm/ado/AdoSCMLib.ts
6523
6526
  import { setTimeout as setTimeout2 } from "timers/promises";
6527
+ import pLimit2 from "p-limit";
6528
+ init_client_generates();
6524
6529
 
6525
6530
  // src/features/analysis/scm/scmSubmit/index.ts
6526
6531
  init_GitService();
@@ -6593,7 +6598,7 @@ import {
6593
6598
  Gitlab
6594
6599
  } from "@gitbeaker/rest";
6595
6600
  import Debug5 from "debug";
6596
- import pLimit from "p-limit";
6601
+ import pLimit3 from "p-limit";
6597
6602
  import {
6598
6603
  Agent,
6599
6604
  fetch as undiciFetch,
@@ -7879,7 +7884,7 @@ async function getRepositoryUrl() {
7879
7884
  }
7880
7885
  const remoteUrl = await gitService.getRemoteUrl();
7881
7886
  const parsed = parseScmURL(remoteUrl);
7882
- return parsed?.scmType === "GitHub" /* GitHub */ || parsed?.scmType === "GitLab" /* GitLab */ ? remoteUrl : null;
7887
+ return parsed?.scmType && parsed.scmType !== "Unknown" ? remoteUrl : null;
7883
7888
  } catch {
7884
7889
  return null;
7885
7890
  }
package/dist/index.mjs CHANGED
@@ -4170,6 +4170,9 @@ import multimatch from "multimatch";
4170
4170
  import StreamZip from "node-stream-zip";
4171
4171
  import tmp from "tmp";
4172
4172
 
4173
+ // src/features/analysis/scm/ado/ado.ts
4174
+ import pLimit from "p-limit";
4175
+
4173
4176
  // src/features/analysis/scm/errors.ts
4174
4177
  var InvalidAccessTokenError = class extends Error {
4175
4178
  constructor(m, scmType) {
@@ -7094,6 +7097,136 @@ async function getAdoSdk(params) {
7094
7097
  );
7095
7098
  return res.pullRequestId;
7096
7099
  },
7100
+ async getAdoPullRequestMetadata({
7101
+ repoUrl,
7102
+ prNumber
7103
+ }) {
7104
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7105
+ const git = await api2.getGitApi();
7106
+ const pr = await git.getPullRequest(repo, prNumber, projectName);
7107
+ if (!pr) {
7108
+ throw new Error(`Pull request #${prNumber} not found`);
7109
+ }
7110
+ return {
7111
+ title: pr.title,
7112
+ targetBranch: (pr.targetRefName || "").replace("refs/heads/", ""),
7113
+ sourceBranch: (pr.sourceRefName || "").replace("refs/heads/", ""),
7114
+ headCommitSha: pr.lastMergeSourceCommit?.commitId || pr.lastMergeCommit?.commitId || ""
7115
+ };
7116
+ },
7117
+ async getAdoPrFiles({
7118
+ repoUrl,
7119
+ prNumber
7120
+ }) {
7121
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7122
+ const git = await api2.getGitApi();
7123
+ const iterations = await git.getPullRequestIterations(
7124
+ repo,
7125
+ prNumber,
7126
+ projectName
7127
+ );
7128
+ if (!iterations || iterations.length === 0) {
7129
+ return [];
7130
+ }
7131
+ const lastIteration = iterations[iterations.length - 1];
7132
+ if (!lastIteration?.id) {
7133
+ return [];
7134
+ }
7135
+ const iterationId = lastIteration.id;
7136
+ const changes = await git.getPullRequestIterationChanges(
7137
+ repo,
7138
+ prNumber,
7139
+ iterationId,
7140
+ projectName
7141
+ );
7142
+ if (!changes?.changeEntries) {
7143
+ return [];
7144
+ }
7145
+ return changes.changeEntries.filter((entry) => {
7146
+ const changeType = entry.changeType;
7147
+ return changeType !== 16 && entry.item?.path;
7148
+ }).map((entry) => {
7149
+ const path27 = entry.item.path;
7150
+ return path27.startsWith("/") ? path27.slice(1) : path27;
7151
+ });
7152
+ },
7153
+ async searchAdoPullRequests({
7154
+ repoUrl,
7155
+ status,
7156
+ skip,
7157
+ top
7158
+ }) {
7159
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7160
+ const git = await api2.getGitApi();
7161
+ const searchCriteria = {
7162
+ // Cast to number to avoid TypeScript enum compatibility issues between
7163
+ // our AdoPullRequestStatus and azure-devops-node-api's PullRequestStatus
7164
+ status: status ?? 4 /* All */
7165
+ };
7166
+ const prs = await git.getPullRequests(
7167
+ repo,
7168
+ searchCriteria,
7169
+ projectName,
7170
+ void 0,
7171
+ // maxCommentLength
7172
+ skip,
7173
+ top
7174
+ );
7175
+ return prs;
7176
+ },
7177
+ async getAdoPullRequestMetrics({
7178
+ repoUrl,
7179
+ prNumber
7180
+ }) {
7181
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7182
+ const git = await api2.getGitApi();
7183
+ const pr = await git.getPullRequest(repo, prNumber, projectName);
7184
+ if (!pr) {
7185
+ throw new Error(`Pull request #${prNumber} not found`);
7186
+ }
7187
+ const threads = await git.getThreads(repo, prNumber, projectName);
7188
+ const commentIds = (threads || []).filter((t) => t.id && t.comments && t.comments.length > 0).map((t) => String(t.id));
7189
+ return {
7190
+ pr,
7191
+ commentIds,
7192
+ linesAdded: 0
7193
+ };
7194
+ },
7195
+ async getAdoRecentCommits({
7196
+ repoUrl,
7197
+ since
7198
+ }) {
7199
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7200
+ const git = await api2.getGitApi();
7201
+ const repository = await git.getRepository(
7202
+ decodeURI(repo),
7203
+ projectName ? decodeURI(projectName) : void 0
7204
+ );
7205
+ const defaultBranch = repository.defaultBranch?.replace("refs/heads/", "");
7206
+ const commits = await git.getCommits(
7207
+ repo,
7208
+ {
7209
+ fromDate: since,
7210
+ itemVersion: defaultBranch ? { version: defaultBranch } : void 0,
7211
+ $top: 100
7212
+ },
7213
+ projectName
7214
+ );
7215
+ return commits;
7216
+ },
7217
+ async getAdoPrCommits({
7218
+ repoUrl,
7219
+ prNumber
7220
+ }) {
7221
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
7222
+ const git = await api2.getGitApi();
7223
+ const commits = await git.getPullRequestCommits(
7224
+ repo,
7225
+ prNumber,
7226
+ projectName
7227
+ );
7228
+ return (commits || []).filter((c) => c.commitId).map((c) => c.commitId);
7229
+ },
7097
7230
  async getAdoRepoDefaultBranch({
7098
7231
  repoUrl
7099
7232
  }) {
@@ -7232,28 +7365,38 @@ async function getAdoRepoList({
7232
7365
  });
7233
7366
  const gitOrg = await orgApi.getGitApi();
7234
7367
  const orgRepos = await gitOrg.getRepositories();
7368
+ const repoLimit = pLimit(5);
7235
7369
  const repoInfoList = (await Promise.allSettled(
7236
- orgRepos.map(async (repo) => {
7237
- if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
7238
- throw new InvalidRepoUrlError("bad repo");
7239
- }
7240
- const branch = await gitOrg.getBranch(
7241
- repo.name,
7242
- repo.defaultBranch.replace(/^refs\/heads\//, ""),
7243
- repo.project?.name
7244
- );
7245
- return {
7246
- repoName: repo.name,
7247
- repoUrl: repo.remoteUrl.replace(
7248
- /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
7249
- "https://"
7250
- ),
7251
- repoOwner: org,
7252
- repoIsPublic: repo.project?.visibility === 2 /* Public */,
7253
- repoLanguages: [],
7254
- repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
7255
- };
7256
- })
7370
+ orgRepos.map(
7371
+ (repo) => repoLimit(async () => {
7372
+ if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
7373
+ throw new InvalidRepoUrlError("bad repo");
7374
+ }
7375
+ const branch = await gitOrg.getBranch(
7376
+ repo.name,
7377
+ repo.defaultBranch.replace(/^refs\/heads\//, ""),
7378
+ repo.project?.name
7379
+ );
7380
+ return {
7381
+ repoName: repo.name,
7382
+ repoUrl: repo.remoteUrl.replace(
7383
+ /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
7384
+ "https://"
7385
+ ),
7386
+ repoOwner: org,
7387
+ repoIsPublic: repo.project?.visibility === 2 /* Public */,
7388
+ repoLanguages: [],
7389
+ repoUpdatedAt: (
7390
+ // Use the latest available timestamp.
7391
+ // branch.commit.committer.date = last commit on default branch.
7392
+ // project.lastUpdateTime = last project-level change (may be stale).
7393
+ // ADO doesn't expose a per-repo "last pushed" date like GitHub does,
7394
+ // so feature branch pushes won't be reflected until merged.
7395
+ branch.commit?.committer?.date?.toISOString() || repo.project?.lastUpdateTime?.toISOString() || (/* @__PURE__ */ new Date()).toISOString()
7396
+ )
7397
+ };
7398
+ })
7399
+ )
7257
7400
  )).reduce((acc, res) => {
7258
7401
  if (res.status === "fulfilled") {
7259
7402
  acc.push(res.value);
@@ -7273,6 +7416,8 @@ async function getAdoRepoList({
7273
7416
 
7274
7417
  // src/features/analysis/scm/ado/AdoSCMLib.ts
7275
7418
  import { setTimeout as setTimeout2 } from "timers/promises";
7419
+ import pLimit2 from "p-limit";
7420
+ init_client_generates();
7276
7421
 
7277
7422
  // src/features/analysis/scm/scmSubmit/index.ts
7278
7423
  init_GitService();
@@ -7407,6 +7552,19 @@ var SCMLib = class {
7407
7552
  }
7408
7553
  };
7409
7554
 
7555
+ // src/features/analysis/scm/utils/cursorValidation.ts
7556
+ var MAX_CURSOR_VALUE = 1e5;
7557
+ function parseCursorSafe(cursor, defaultValue = 0, maxValue = MAX_CURSOR_VALUE) {
7558
+ if (cursor === null || cursor === void 0 || cursor === "") {
7559
+ return defaultValue;
7560
+ }
7561
+ const parsed = parseInt(cursor, 10);
7562
+ if (isNaN(parsed) || parsed < 0 || parsed > maxValue) {
7563
+ return defaultValue;
7564
+ }
7565
+ return parsed;
7566
+ }
7567
+
7410
7568
  // src/features/analysis/scm/ado/AdoSCMLib.ts
7411
7569
  async function initAdoSdk(params) {
7412
7570
  const { url, accessToken, scmOrg } = params;
@@ -7599,28 +7757,190 @@ var AdoSCMLib = class extends SCMLib {
7599
7757
  markdownComment: comment
7600
7758
  });
7601
7759
  }
7602
- async getSubmitRequestMetadata(_submitRequestId) {
7603
- throw new Error("getSubmitRequestMetadata not implemented for ADO");
7760
+ async getSubmitRequestMetadata(submitRequestId) {
7761
+ this._validateAccessTokenAndUrl();
7762
+ const adoSdk = await this.getAdoSdk();
7763
+ return adoSdk.getAdoPullRequestMetadata({
7764
+ repoUrl: this.url,
7765
+ prNumber: Number(submitRequestId)
7766
+ });
7604
7767
  }
7605
- async getPrFiles(_prNumber) {
7606
- throw new Error("getPrFiles not implemented for ADO");
7768
+ async getPrFiles(prNumber) {
7769
+ this._validateAccessTokenAndUrl();
7770
+ const adoSdk = await this.getAdoSdk();
7771
+ return adoSdk.getAdoPrFiles({
7772
+ repoUrl: this.url,
7773
+ prNumber
7774
+ });
7607
7775
  }
7608
- async searchSubmitRequests(_params) {
7609
- throw new Error("searchSubmitRequests not implemented for ADO");
7776
+ async searchSubmitRequests(params) {
7777
+ this._validateAccessToken();
7778
+ const adoSdk = await this.getAdoSdk();
7779
+ const skip = parseCursorSafe(params.cursor, 0);
7780
+ const top = params.limit || 10;
7781
+ let status = 4 /* All */;
7782
+ if (params.filters?.state === "open") {
7783
+ status = 1 /* Active */;
7784
+ } else if (params.filters?.state === "closed") {
7785
+ status = 4 /* All */;
7786
+ }
7787
+ const prs = await adoSdk.searchAdoPullRequests({
7788
+ repoUrl: params.repoUrl,
7789
+ status,
7790
+ skip,
7791
+ top: top + 1
7792
+ // Fetch one extra to determine hasMore
7793
+ });
7794
+ const apiHasMore = prs.length > top;
7795
+ const prsPage = prs.slice(0, top);
7796
+ const getAdoPrUpdatedDate = (pr) => pr.closedDate || pr.lastMergeSourceCommit?.committer?.date || pr.creationDate || /* @__PURE__ */ new Date();
7797
+ let filtered = prsPage;
7798
+ if (params.filters?.updatedAfter) {
7799
+ const afterDate = params.filters.updatedAfter;
7800
+ filtered = prsPage.filter((pr) => getAdoPrUpdatedDate(pr) > afterDate);
7801
+ }
7802
+ if (params.filters?.state === "closed") {
7803
+ filtered = filtered.filter(
7804
+ (pr) => pr.status === 3 /* Completed */ || pr.status === 2 /* Abandoned */
7805
+ );
7806
+ }
7807
+ const results = filtered.map((pr) => {
7808
+ let prStatus = "open";
7809
+ if (pr.status === 3 /* Completed */) {
7810
+ prStatus = "merged";
7811
+ } else if (pr.status === 2 /* Abandoned */) {
7812
+ prStatus = "closed";
7813
+ }
7814
+ return {
7815
+ submitRequestId: String(pr.pullRequestId),
7816
+ submitRequestNumber: pr.pullRequestId || 0,
7817
+ title: pr.title || "",
7818
+ status: prStatus,
7819
+ sourceBranch: (pr.sourceRefName || "").replace("refs/heads/", ""),
7820
+ targetBranch: (pr.targetRefName || "").replace("refs/heads/", ""),
7821
+ authorName: pr.createdBy?.displayName,
7822
+ authorEmail: pr.createdBy?.uniqueName,
7823
+ createdAt: pr.creationDate || /* @__PURE__ */ new Date(),
7824
+ updatedAt: getAdoPrUpdatedDate(pr),
7825
+ description: pr.description,
7826
+ tickets: [],
7827
+ changedLines: { added: 0, removed: 0 }
7828
+ };
7829
+ });
7830
+ return {
7831
+ results,
7832
+ nextCursor: apiHasMore ? String(skip + top) : void 0,
7833
+ hasMore: apiHasMore
7834
+ };
7610
7835
  }
7611
- async searchRepos(_params) {
7612
- throw new Error("searchRepos not implemented for ADO");
7836
+ // TODO: Performance — this fetches ALL repositories on every call, then paginates
7837
+ // in-memory. For orgs with thousands of repos this can be slow and wasteful,
7838
+ // especially when the UI pages through results (each page triggers a full re-fetch).
7839
+ // Consider caching the fetched list with a short TTL, or using ADO's
7840
+ // getRepositoriesPaged() API per-project for true server-side pagination.
7841
+ async searchRepos(params) {
7842
+ this._validateAccessToken();
7843
+ if (this.url && new URL(this.url).origin !== scmCloudUrl.Ado) {
7844
+ throw new Error(
7845
+ `Oauth token is not supported for ADO on prem - ${this.url}`
7846
+ );
7847
+ }
7848
+ const allRepos = await getAdoRepoList({
7849
+ orgName: params.scmOrg,
7850
+ accessToken: this.accessToken,
7851
+ tokenOrg: this.scmOrg
7852
+ });
7853
+ allRepos.sort((a, b) => {
7854
+ const dateA = a.repoUpdatedAt ? new Date(a.repoUpdatedAt).getTime() : 0;
7855
+ const dateB = b.repoUpdatedAt ? new Date(b.repoUpdatedAt).getTime() : 0;
7856
+ return dateB - dateA;
7857
+ });
7858
+ const page = parseCursorSafe(params.cursor, 0);
7859
+ const limit = params.limit || 100;
7860
+ const start = page;
7861
+ const pageResults = allRepos.slice(start, start + limit);
7862
+ const hasMore = start + limit < allRepos.length;
7863
+ return {
7864
+ results: pageResults,
7865
+ nextCursor: hasMore ? String(start + limit) : void 0,
7866
+ hasMore
7867
+ };
7613
7868
  }
7614
- // TODO: Add comprehensive tests for getPullRequestMetrics (ADO)
7615
- // See clients/cli/src/features/analysis/scm/__tests__/github.test.ts:589-648 for reference
7616
- async getPullRequestMetrics(_prNumber) {
7617
- throw new Error("getPullRequestMetrics not implemented for ADO");
7869
+ async getPrCommitsBatch(repoUrl, prNumbers) {
7870
+ this._validateAccessToken();
7871
+ const adoSdk = await this.getAdoSdk();
7872
+ const result = /* @__PURE__ */ new Map();
7873
+ const limit = pLimit2(5);
7874
+ await Promise.all(
7875
+ prNumbers.map(
7876
+ (prNumber) => limit(async () => {
7877
+ try {
7878
+ const commits = await adoSdk.getAdoPrCommits({
7879
+ repoUrl,
7880
+ prNumber
7881
+ });
7882
+ result.set(prNumber, commits);
7883
+ } catch (error) {
7884
+ console.warn(
7885
+ `[AdoSCMLib.getPrCommitsBatch] Failed to fetch commits for PR #${prNumber}:`,
7886
+ error instanceof Error ? error.message : String(error)
7887
+ );
7888
+ result.set(prNumber, []);
7889
+ }
7890
+ })
7891
+ )
7892
+ );
7893
+ return result;
7618
7894
  }
7619
- async getRecentCommits(_since) {
7620
- throw new Error("getRecentCommits not implemented for ADO");
7895
+ async getPullRequestMetrics(prNumber) {
7896
+ this._validateAccessTokenAndUrl();
7897
+ const adoSdk = await this.getAdoSdk();
7898
+ const { pr, commentIds, linesAdded } = await adoSdk.getAdoPullRequestMetrics({
7899
+ repoUrl: this.url,
7900
+ prNumber
7901
+ });
7902
+ let prStatus = "ACTIVE" /* Active */;
7903
+ if (pr.status === 3) {
7904
+ prStatus = "MERGED" /* Merged */;
7905
+ } else if (pr.status === 2) {
7906
+ prStatus = "CLOSED" /* Closed */;
7907
+ } else if (pr.isDraft) {
7908
+ prStatus = "DRAFT" /* Draft */;
7909
+ }
7910
+ return {
7911
+ prId: String(prNumber),
7912
+ repositoryUrl: this.url,
7913
+ prCreatedAt: pr.creationDate || /* @__PURE__ */ new Date(),
7914
+ prMergedAt: pr.closedDate && pr.status === 3 ? pr.closedDate : null,
7915
+ linesAdded,
7916
+ prStatus,
7917
+ commentIds
7918
+ };
7919
+ }
7920
+ async getRecentCommits(since) {
7921
+ this._validateAccessTokenAndUrl();
7922
+ const adoSdk = await this.getAdoSdk();
7923
+ const commits = await adoSdk.getAdoRecentCommits({
7924
+ repoUrl: this.url,
7925
+ since
7926
+ });
7927
+ return {
7928
+ data: commits.map((c) => ({
7929
+ sha: c.commitId || "",
7930
+ commit: {
7931
+ committer: c.committer?.date ? { date: c.committer.date.toISOString() } : void 0,
7932
+ author: c.author ? { email: c.author.email, name: c.author.name } : void 0,
7933
+ message: c.comment
7934
+ },
7935
+ parents: c.parents?.map((sha) => ({ sha }))
7936
+ }))
7937
+ };
7621
7938
  }
7622
7939
  async getRateLimitStatus() {
7623
- return null;
7940
+ return {
7941
+ remaining: 1e4,
7942
+ reset: new Date(Date.now() + 36e5)
7943
+ };
7624
7944
  }
7625
7945
  };
7626
7946
 
@@ -8218,19 +8538,6 @@ init_env();
8218
8538
  import { z as z22 } from "zod";
8219
8539
  init_client_generates();
8220
8540
 
8221
- // src/features/analysis/scm/utils/cursorValidation.ts
8222
- var MAX_CURSOR_VALUE = 1e5;
8223
- function parseCursorSafe(cursor, defaultValue = 0, maxValue = MAX_CURSOR_VALUE) {
8224
- if (cursor === null || cursor === void 0 || cursor === "") {
8225
- return defaultValue;
8226
- }
8227
- const parsed = parseInt(cursor, 10);
8228
- if (isNaN(parsed) || parsed < 0 || parsed > maxValue) {
8229
- return defaultValue;
8230
- }
8231
- return parsed;
8232
- }
8233
-
8234
8541
  // src/features/analysis/scm/github/github.ts
8235
8542
  import { RequestError } from "@octokit/request-error";
8236
8543
 
@@ -9597,7 +9904,7 @@ import {
9597
9904
  Gitlab
9598
9905
  } from "@gitbeaker/rest";
9599
9906
  import Debug3 from "debug";
9600
- import pLimit from "p-limit";
9907
+ import pLimit3 from "p-limit";
9601
9908
  import {
9602
9909
  Agent,
9603
9910
  fetch as undiciFetch,
@@ -10026,7 +10333,7 @@ async function getGitlabMrCommitsBatch({
10026
10333
  url: repoUrl,
10027
10334
  gitlabAuthToken: accessToken
10028
10335
  });
10029
- const limit = pLimit(GITLAB_API_CONCURRENCY);
10336
+ const limit = pLimit3(GITLAB_API_CONCURRENCY);
10030
10337
  const results = await Promise.all(
10031
10338
  mrNumbers.map(
10032
10339
  (mrNumber) => limit(async () => {
@@ -10065,7 +10372,7 @@ async function getGitlabMrDataBatch({
10065
10372
  url: repoUrl,
10066
10373
  gitlabAuthToken: accessToken
10067
10374
  });
10068
- const limit = pLimit(GITLAB_API_CONCURRENCY);
10375
+ const limit = pLimit3(GITLAB_API_CONCURRENCY);
10069
10376
  const results = await Promise.all(
10070
10377
  mrNumbers.map(
10071
10378
  (mrNumber) => limit(async () => {
@@ -13060,7 +13367,7 @@ async function getRepositoryUrl() {
13060
13367
  }
13061
13368
  const remoteUrl = await gitService.getRemoteUrl();
13062
13369
  const parsed = parseScmURL(remoteUrl);
13063
- return parsed?.scmType === "GitHub" /* GitHub */ || parsed?.scmType === "GitLab" /* GitLab */ ? remoteUrl : null;
13370
+ return parsed?.scmType && parsed.scmType !== "Unknown" ? remoteUrl : null;
13064
13371
  } catch {
13065
13372
  return null;
13066
13373
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.2.51",
3
+ "version": "1.2.53",
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",