korekt-cli 0.13.5 → 0.13.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "korekt-cli",
3
- "version": "0.13.5",
3
+ "version": "0.13.6",
4
4
  "description": "AI-powered code review CLI - Keep your kode korekt",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/git-logic.js CHANGED
@@ -31,33 +31,54 @@ export function truncateContent(content, maxLines = 2000) {
31
31
  */
32
32
  export function normalizeRepoUrl(url) {
33
33
  // Handle Azure DevOps SSH format: git@ssh.dev.azure.com:v3/org/project/repo
34
- const azureDevOpsSshMatch = url.match(/git@ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\/(.+)/);
34
+ // [^:]* allows SSH config aliases like git@ssh.dev.azure.com-work:v3/...
35
+ const azureDevOpsSshMatch = url.match(
36
+ /git@ssh\.dev\.azure\.com[^:]*:v3\/([^/]+)\/([^/]+)\/(.+?)(?:\.git)?$/
37
+ );
35
38
  if (azureDevOpsSshMatch) {
36
39
  const [, org, project, repo] = azureDevOpsSshMatch;
37
40
  return `https://dev.azure.com/${org}/${project}/_git/${repo}`;
38
41
  }
39
42
 
40
43
  // Handle GitHub SSH format: git@github.com:user/repo.git
41
- const githubSshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
44
+ // [^:]* allows SSH config aliases like git@github.com-personal:user/repo.git
45
+ const githubSshMatch = url.match(/git@github\.com[^:]*:([^/]+)\/(.+?)(?:\.git)?$/);
42
46
  if (githubSshMatch) {
43
47
  const [, user, repo] = githubSshMatch;
44
48
  return `https://github.com/${user}/${repo}`;
45
49
  }
46
50
 
47
51
  // Handle GitLab SSH format: git@gitlab.com:user/repo.git
48
- const gitlabSshMatch = url.match(/git@gitlab\.com:([^/]+)\/(.+?)(?:\.git)?$/);
52
+ // [^:]* allows SSH config aliases like git@gitlab.com-work:user/repo.git
53
+ const gitlabSshMatch = url.match(/git@gitlab\.com[^:]*:([^/]+)\/(.+?)(?:\.git)?$/);
49
54
  if (gitlabSshMatch) {
50
55
  const [, user, repo] = gitlabSshMatch;
51
56
  return `https://gitlab.com/${user}/${repo}`;
52
57
  }
53
58
 
54
59
  // Handle Bitbucket SSH format: git@bitbucket.org:user/repo.git
55
- const bitbucketSshMatch = url.match(/git@bitbucket\.org:([^/]+)\/(.+?)(?:\.git)?$/);
60
+ // [^:]* allows SSH config aliases like git@bitbucket.org-astoisavljevic:user/repo.git
61
+ const bitbucketSshMatch = url.match(/git@bitbucket\.org[^:]*:([^/]+)\/(.+?)(?:\.git)?$/);
56
62
  if (bitbucketSshMatch) {
57
63
  const [, user, repo] = bitbucketSshMatch;
58
64
  return `https://bitbucket.org/${user}/${repo}`;
59
65
  }
60
66
 
67
+ // Generic SSH fallback for self-hosted/unknown providers
68
+ // SCP-style: git@host:path or user@host:path (negative lookahead excludes URLs with ://)
69
+ const scpMatch = url.match(/^(?!.*:\/\/)([^@]+)@([^:]+):(.+?)(?:\.git)?$/);
70
+ if (scpMatch) {
71
+ const [, , host, path] = scpMatch;
72
+ return `https://${host}/${path}`;
73
+ }
74
+
75
+ // SSH protocol: ssh://user@host/path or ssh://user@host:port/path
76
+ const sshProtoMatch = url.match(/^ssh:\/\/(?:[^@]+@)?([^/:]+)(?::\d+)?\/(.+?)(?:\.git)?$/);
77
+ if (sshProtoMatch) {
78
+ const [, host, path] = sshProtoMatch;
79
+ return `https://${host}/${path}`;
80
+ }
81
+
61
82
  // If already HTTPS or other format, return as-is (possibly removing .git suffix)
62
83
  return url.replace(/\.git$/, '');
63
84
  }
@@ -477,6 +477,12 @@ describe('normalizeRepoUrl', () => {
477
477
  expect(normalizeRepoUrl(sshUrl)).toBe(expected);
478
478
  });
479
479
 
480
+ it('should strip .git suffix from Azure DevOps SSH URL', () => {
481
+ const sshUrl = 'git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git';
482
+ const expected = 'https://dev.azure.com/MyOrg/MyProject/_git/MyRepo';
483
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
484
+ });
485
+
480
486
  it('should normalize GitHub SSH URL to HTTPS', () => {
481
487
  const sshUrl = 'git@github.com:user/repo.git';
482
488
  const expected = 'https://github.com/user/repo';
@@ -522,6 +528,68 @@ describe('normalizeRepoUrl', () => {
522
528
  const adoUrl = 'https://dev.azure.com/VanillaSoftCollection/VanillaLand/_git/VanillaLand';
523
529
  expect(normalizeRepoUrl(adoUrl)).toBe(adoUrl);
524
530
  });
531
+
532
+ // SSH config alias tests (e.g., multiple SSH keys per provider)
533
+ it('should normalize Bitbucket SSH URL with config alias', () => {
534
+ const sshUrl = 'git@bitbucket.org-astoisavljevic:jatheon/audit.git';
535
+ const expected = 'https://bitbucket.org/jatheon/audit';
536
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
537
+ });
538
+
539
+ it('should normalize GitHub SSH URL with config alias', () => {
540
+ const sshUrl = 'git@github.com-personal:user/repo.git';
541
+ const expected = 'https://github.com/user/repo';
542
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
543
+ });
544
+
545
+ it('should normalize GitLab SSH URL with config alias', () => {
546
+ const sshUrl = 'git@gitlab.com-work:team/project.git';
547
+ const expected = 'https://gitlab.com/team/project';
548
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
549
+ });
550
+
551
+ it('should normalize Azure DevOps SSH URL with config alias', () => {
552
+ const sshUrl = 'git@ssh.dev.azure.com-work:v3/MyOrg/MyProject/MyRepo';
553
+ const expected = 'https://dev.azure.com/MyOrg/MyProject/_git/MyRepo';
554
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
555
+ });
556
+
557
+ // Generic SSH fallback for self-hosted/unknown providers
558
+ it('should normalize generic SCP-style SSH URL with IP address', () => {
559
+ const sshUrl = 'git@192.168.1.1:org/repo.git';
560
+ const expected = 'https://192.168.1.1/org/repo';
561
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
562
+ });
563
+
564
+ it('should normalize generic SCP-style SSH URL with hostname', () => {
565
+ const sshUrl = 'git@selfhosted.example.com:team/repo.git';
566
+ const expected = 'https://selfhosted.example.com/team/repo';
567
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
568
+ });
569
+
570
+ it('should normalize generic SCP-style SSH URL without .git suffix', () => {
571
+ const sshUrl = 'git@selfhosted.example.com:team/repo';
572
+ const expected = 'https://selfhosted.example.com/team/repo';
573
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
574
+ });
575
+
576
+ it('should normalize ssh:// protocol URL', () => {
577
+ const sshUrl = 'ssh://git@selfhosted.example.com/team/repo.git';
578
+ const expected = 'https://selfhosted.example.com/team/repo';
579
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
580
+ });
581
+
582
+ it('should normalize ssh:// protocol URL with port (port dropped)', () => {
583
+ const sshUrl = 'ssh://git@myhost:2222/org/repo.git';
584
+ const expected = 'https://myhost/org/repo';
585
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
586
+ });
587
+
588
+ it('should normalize ssh:// protocol URL without username', () => {
589
+ const sshUrl = 'ssh://myhost/org/repo.git';
590
+ const expected = 'https://myhost/org/repo';
591
+ expect(normalizeRepoUrl(sshUrl)).toBe(expected);
592
+ });
525
593
  });
526
594
 
527
595
  describe('shouldIgnoreFile', () => {