@kodus/cli 0.0.12 → 0.1.5

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.
Files changed (131) hide show
  1. package/README.md +380 -0
  2. package/dist/cli.d.ts +4 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +23 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/auth/index.d.ts +3 -0
  7. package/dist/commands/auth/index.d.ts.map +1 -0
  8. package/dist/commands/auth/index.js +36 -0
  9. package/dist/commands/auth/index.js.map +1 -0
  10. package/dist/commands/auth/login.d.ts +7 -0
  11. package/dist/commands/auth/login.d.ts.map +1 -0
  12. package/dist/commands/auth/login.js +80 -0
  13. package/dist/commands/auth/login.js.map +1 -0
  14. package/dist/commands/auth/logout.d.ts +2 -0
  15. package/dist/commands/auth/logout.d.ts.map +1 -0
  16. package/dist/commands/auth/logout.js +24 -0
  17. package/dist/commands/auth/logout.js.map +1 -0
  18. package/dist/commands/auth/signup.d.ts +2 -0
  19. package/dist/commands/auth/signup.d.ts.map +1 -0
  20. package/dist/commands/auth/signup.js +59 -0
  21. package/dist/commands/auth/signup.js.map +1 -0
  22. package/dist/commands/auth/status.d.ts +2 -0
  23. package/dist/commands/auth/status.d.ts.map +1 -0
  24. package/dist/commands/auth/status.js +91 -0
  25. package/dist/commands/auth/status.js.map +1 -0
  26. package/dist/commands/auth/team-key.d.ts +5 -0
  27. package/dist/commands/auth/team-key.d.ts.map +1 -0
  28. package/dist/commands/auth/team-key.js +59 -0
  29. package/dist/commands/auth/team-key.js.map +1 -0
  30. package/dist/commands/auth/token.d.ts +2 -0
  31. package/dist/commands/auth/token.d.ts.map +1 -0
  32. package/dist/commands/auth/token.js +31 -0
  33. package/dist/commands/auth/token.js.map +1 -0
  34. package/dist/commands/pr.d.ts +3 -0
  35. package/dist/commands/pr.d.ts.map +1 -0
  36. package/dist/commands/pr.js +75 -0
  37. package/dist/commands/pr.js.map +1 -0
  38. package/dist/commands/review.d.ts +3 -0
  39. package/dist/commands/review.d.ts.map +1 -0
  40. package/dist/commands/review.js +164 -0
  41. package/dist/commands/review.js.map +1 -0
  42. package/dist/commands/upgrade.d.ts +3 -0
  43. package/dist/commands/upgrade.d.ts.map +1 -0
  44. package/dist/commands/upgrade.js +35 -0
  45. package/dist/commands/upgrade.js.map +1 -0
  46. package/dist/constants.d.ts +3 -0
  47. package/dist/constants.d.ts.map +1 -0
  48. package/dist/constants.js +3 -0
  49. package/dist/constants.js.map +1 -0
  50. package/dist/formatters/json.d.ts +7 -0
  51. package/dist/formatters/json.d.ts.map +1 -0
  52. package/dist/formatters/json.js +7 -0
  53. package/dist/formatters/json.js.map +1 -0
  54. package/dist/formatters/markdown.d.ts +7 -0
  55. package/dist/formatters/markdown.d.ts.map +1 -0
  56. package/dist/formatters/markdown.js +93 -0
  57. package/dist/formatters/markdown.js.map +1 -0
  58. package/dist/formatters/prompt.d.ts +12 -0
  59. package/dist/formatters/prompt.d.ts.map +1 -0
  60. package/dist/formatters/prompt.js +90 -0
  61. package/dist/formatters/prompt.js.map +1 -0
  62. package/dist/formatters/terminal.d.ts +7 -0
  63. package/dist/formatters/terminal.d.ts.map +1 -0
  64. package/dist/formatters/terminal.js +127 -0
  65. package/dist/formatters/terminal.js.map +1 -0
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +9 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/services/api/api.interface.d.ts +42 -0
  71. package/dist/services/api/api.interface.d.ts.map +1 -0
  72. package/dist/services/api/api.interface.js +2 -0
  73. package/dist/services/api/api.interface.js.map +1 -0
  74. package/dist/services/api/api.real.d.ts +7 -0
  75. package/dist/services/api/api.real.d.ts.map +1 -0
  76. package/dist/services/api/api.real.js +252 -0
  77. package/dist/services/api/api.real.js.map +1 -0
  78. package/dist/services/api/index.d.ts +4 -0
  79. package/dist/services/api/index.d.ts.map +1 -0
  80. package/dist/services/api/index.js +3 -0
  81. package/dist/services/api/index.js.map +1 -0
  82. package/dist/services/auth.service.d.ts +19 -0
  83. package/dist/services/auth.service.d.ts.map +1 -0
  84. package/dist/services/auth.service.js +90 -0
  85. package/dist/services/auth.service.js.map +1 -0
  86. package/dist/services/context.service.d.ts +22 -0
  87. package/dist/services/context.service.d.ts.map +1 -0
  88. package/dist/services/context.service.js +104 -0
  89. package/dist/services/context.service.js.map +1 -0
  90. package/dist/services/fix.service.d.ts +31 -0
  91. package/dist/services/fix.service.d.ts.map +1 -0
  92. package/dist/services/fix.service.js +120 -0
  93. package/dist/services/fix.service.js.map +1 -0
  94. package/dist/services/git.service.d.ts +32 -0
  95. package/dist/services/git.service.d.ts.map +1 -0
  96. package/dist/services/git.service.js +261 -0
  97. package/dist/services/git.service.js.map +1 -0
  98. package/dist/services/review.service.d.ts +28 -0
  99. package/dist/services/review.service.d.ts.map +1 -0
  100. package/dist/services/review.service.js +111 -0
  101. package/dist/services/review.service.js.map +1 -0
  102. package/dist/types/index.d.ts +161 -0
  103. package/dist/types/index.d.ts.map +1 -0
  104. package/dist/types/index.js +15 -0
  105. package/dist/types/index.js.map +1 -0
  106. package/dist/ui/interactive.d.ts +26 -0
  107. package/dist/ui/interactive.d.ts.map +1 -0
  108. package/dist/ui/interactive.js +371 -0
  109. package/dist/ui/interactive.js.map +1 -0
  110. package/dist/utils/config.d.ts +10 -0
  111. package/dist/utils/config.d.ts.map +1 -0
  112. package/dist/utils/config.js +54 -0
  113. package/dist/utils/config.js.map +1 -0
  114. package/dist/utils/credentials.d.ts +6 -0
  115. package/dist/utils/credentials.d.ts.map +1 -0
  116. package/dist/utils/credentials.js +54 -0
  117. package/dist/utils/credentials.js.map +1 -0
  118. package/dist/utils/rate-limit.d.ts +5 -0
  119. package/dist/utils/rate-limit.d.ts.map +1 -0
  120. package/dist/utils/rate-limit.js +47 -0
  121. package/dist/utils/rate-limit.js.map +1 -0
  122. package/package.json +41 -33
  123. package/index.js +0 -15
  124. package/license.md +0 -21
  125. package/readme.md +0 -128
  126. package/scripts/setup-db.sh +0 -77
  127. package/src/commands/install.js +0 -357
  128. package/src/config/default.js +0 -66
  129. package/src/utils/helpers.js +0 -128
  130. package/templates/.env.example +0 -142
  131. package/templates/docker-compose.yml +0 -139
@@ -0,0 +1,120 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ /**
4
+ * Fix Service - Applies code fixes to files
5
+ */
6
+ class FixService {
7
+ /**
8
+ * Applies a single fix to a file
9
+ */
10
+ async applyFix(issue) {
11
+ if (!issue.fixable || !issue.fix) {
12
+ throw new Error('Issue is not fixable');
13
+ }
14
+ const filePath = path.resolve(issue.file);
15
+ const content = await fs.readFile(filePath, 'utf-8');
16
+ const lines = content.split('\n');
17
+ const fix = issue.fix;
18
+ switch (fix.type) {
19
+ case 'replace':
20
+ await this.applyReplace(filePath, lines, fix);
21
+ break;
22
+ case 'insert':
23
+ await this.applyInsert(filePath, lines, fix);
24
+ break;
25
+ case 'delete':
26
+ await this.applyDelete(filePath, lines, fix);
27
+ break;
28
+ }
29
+ }
30
+ /**
31
+ * Applies multiple fixes to files
32
+ */
33
+ async applyFixes(issues) {
34
+ let applied = 0;
35
+ let failed = 0;
36
+ // Group fixes by file to avoid conflicts
37
+ const fixesByFile = new Map();
38
+ for (const issue of issues) {
39
+ if (issue.fixable && issue.fix) {
40
+ const file = issue.file;
41
+ if (!fixesByFile.has(file)) {
42
+ fixesByFile.set(file, []);
43
+ }
44
+ fixesByFile.get(file).push(issue);
45
+ }
46
+ }
47
+ // Sort fixes by line number (descending) to avoid line number shifts
48
+ for (const [file, fileIssues] of fixesByFile.entries()) {
49
+ fileIssues.sort((a, b) => (b.line || 0) - (a.line || 0));
50
+ for (const issue of fileIssues) {
51
+ try {
52
+ await this.applyFix(issue);
53
+ applied++;
54
+ }
55
+ catch (error) {
56
+ failed++;
57
+ console.error(`Failed to apply fix for ${issue.file}:${issue.line}`, error);
58
+ }
59
+ }
60
+ }
61
+ return { applied, failed };
62
+ }
63
+ /**
64
+ * Generates a preview diff for a fix
65
+ */
66
+ generatePreview(issue) {
67
+ if (!issue.fixable || !issue.fix) {
68
+ return 'No fix available';
69
+ }
70
+ const lines = [];
71
+ const fix = issue.fix;
72
+ lines.push(`File: ${issue.file}:${issue.line}`);
73
+ lines.push('');
74
+ if (fix.oldCode) {
75
+ lines.push('- ' + fix.oldCode.split('\n').join('\n- '));
76
+ }
77
+ lines.push('+ ' + fix.newCode.split('\n').join('\n+ '));
78
+ return lines.join('\n');
79
+ }
80
+ async applyReplace(filePath, lines, fix) {
81
+ // Replace lines from startLine to endLine with newCode
82
+ const newCodeLines = fix.newCode.split('\n');
83
+ // Lines are 1-indexed, array is 0-indexed
84
+ const startIdx = fix.startLine - 1;
85
+ const endIdx = fix.endLine - 1;
86
+ // Remove old lines and insert new ones
87
+ lines.splice(startIdx, endIdx - startIdx + 1, ...newCodeLines);
88
+ await fs.writeFile(filePath, lines.join('\n'), 'utf-8');
89
+ }
90
+ async applyInsert(filePath, lines, fix) {
91
+ const newCodeLines = fix.newCode.split('\n');
92
+ const insertIdx = fix.startLine - 1;
93
+ lines.splice(insertIdx, 0, ...newCodeLines);
94
+ await fs.writeFile(filePath, lines.join('\n'), 'utf-8');
95
+ }
96
+ async applyDelete(filePath, lines, fix) {
97
+ const startIdx = fix.startLine - 1;
98
+ const endIdx = fix.endLine - 1;
99
+ lines.splice(startIdx, endIdx - startIdx + 1);
100
+ await fs.writeFile(filePath, lines.join('\n'), 'utf-8');
101
+ }
102
+ /**
103
+ * Checks if a fix can be safely applied
104
+ */
105
+ async canApplyFix(issue) {
106
+ if (!issue.fixable || !issue.fix) {
107
+ return false;
108
+ }
109
+ try {
110
+ const filePath = path.resolve(issue.file);
111
+ await fs.access(filePath);
112
+ return true;
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ }
118
+ }
119
+ export const fixService = new FixService();
120
+ //# sourceMappingURL=fix.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.service.js","sourceRoot":"","sources":["../../src/services/fix.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { FileDiff, FileContent, GitInfo, PlatformType } from '../types/index.js';
2
+ declare class GitService {
3
+ private git;
4
+ constructor();
5
+ private ensureRepo;
6
+ isGitRepository(): Promise<boolean>;
7
+ getGitRoot(): Promise<string>;
8
+ getRemoteUrl(remote?: string): Promise<string | null>;
9
+ extractOrgRepo(): Promise<{
10
+ org: string;
11
+ repo: string;
12
+ } | null>;
13
+ getWorkingTreeDiff(): Promise<string>;
14
+ getStagedDiff(): Promise<string>;
15
+ getDiffForCommit(commitSha: string): Promise<string>;
16
+ getDiffForBranch(branchName: string): Promise<string>;
17
+ getDiffForFiles(files: string[]): Promise<string>;
18
+ getModifiedFiles(): Promise<FileDiff[]>;
19
+ getFullFileContents(explicitFiles?: string[], options?: {
20
+ staged?: boolean;
21
+ commit?: string;
22
+ branch?: string;
23
+ }): Promise<FileContent[]>;
24
+ getCurrentBranch(): Promise<string>;
25
+ getHeadCommit(): Promise<string>;
26
+ getUserEmail(): Promise<string | undefined>;
27
+ getGitInfo(): Promise<GitInfo>;
28
+ inferPlatform(remote: string | null | undefined): PlatformType;
29
+ }
30
+ export declare const gitService: GitService;
31
+ export {};
32
+ //# sourceMappingURL=git.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.service.d.ts","sourceRoot":"","sources":["../../src/services/git.service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtF,cAAM,UAAU;IACd,OAAO,CAAC,GAAG,CAAY;;YAMT,UAAU;IAOlB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IASnC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAK7B,YAAY,CAAC,MAAM,SAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUvD,cAAc,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAoB/D,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAOrC,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpD,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOrD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAejD,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IA2CvC,mBAAmB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE;QAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA2EpB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAS3C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAmCpC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY;CAc/D;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC"}
@@ -0,0 +1,261 @@
1
+ import { simpleGit } from 'simple-git';
2
+ import fs from 'fs/promises';
3
+ import path from 'path';
4
+ class GitService {
5
+ git;
6
+ constructor() {
7
+ this.git = simpleGit();
8
+ }
9
+ async ensureRepo() {
10
+ const isRepo = await this.isGitRepository();
11
+ if (!isRepo) {
12
+ throw new Error('Not a git repository. Run inside a Git repo or initialize one with "git init".');
13
+ }
14
+ }
15
+ async isGitRepository() {
16
+ try {
17
+ await this.git.revparse(['--git-dir']);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ async getGitRoot() {
25
+ await this.ensureRepo();
26
+ return this.git.revparse(['--show-toplevel']);
27
+ }
28
+ async getRemoteUrl(remote = 'origin') {
29
+ try {
30
+ const remotes = await this.git.getRemotes(true);
31
+ const found = remotes.find((r) => r.name === remote);
32
+ return found?.refs?.fetch || null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ async extractOrgRepo() {
39
+ const remoteUrl = await this.getRemoteUrl();
40
+ if (!remoteUrl)
41
+ return null;
42
+ const patterns = [
43
+ /github\.com[:/]([^/]+)\/([^/.]+)/,
44
+ /gitlab\.com[:/]([^/]+)\/([^/.]+)/,
45
+ /bitbucket\.org[:/]([^/]+)\/([^/.]+)/,
46
+ ];
47
+ for (const pattern of patterns) {
48
+ const match = remoteUrl.match(pattern);
49
+ if (match) {
50
+ return { org: match[1], repo: match[2] };
51
+ }
52
+ }
53
+ return null;
54
+ }
55
+ async getWorkingTreeDiff() {
56
+ await this.ensureRepo();
57
+ const staged = await this.git.diff(['--cached']);
58
+ const unstaged = await this.git.diff();
59
+ return `${staged}\n${unstaged}`.trim();
60
+ }
61
+ async getStagedDiff() {
62
+ await this.ensureRepo();
63
+ return this.git.diff(['--cached']);
64
+ }
65
+ async getDiffForCommit(commitSha) {
66
+ await this.ensureRepo();
67
+ return this.git.diff([`${commitSha}^`, commitSha]);
68
+ }
69
+ async getDiffForBranch(branchName) {
70
+ await this.ensureRepo();
71
+ // Compara branch atual contra branch especificado (ex: main)
72
+ // Usa three-dot notation pra pegar diff desde o merge base
73
+ return this.git.diff([`${branchName}...HEAD`]);
74
+ }
75
+ async getDiffForFiles(files) {
76
+ await this.ensureRepo();
77
+ const diffs = [];
78
+ for (const file of files) {
79
+ const stagedDiff = await this.git.diff(['--cached', '--', file]);
80
+ const unstagedDiff = await this.git.diff(['--', file]);
81
+ if (stagedDiff)
82
+ diffs.push(stagedDiff);
83
+ if (unstagedDiff)
84
+ diffs.push(unstagedDiff);
85
+ }
86
+ return diffs.join('\n').trim();
87
+ }
88
+ async getModifiedFiles() {
89
+ await this.ensureRepo();
90
+ const status = await this.git.status();
91
+ const files = [];
92
+ const processFile = async (file, gitStatus) => {
93
+ let status = 'modified';
94
+ if (gitStatus === 'A' || gitStatus === '?')
95
+ status = 'added';
96
+ else if (gitStatus === 'D')
97
+ status = 'deleted';
98
+ else if (gitStatus === 'R')
99
+ status = 'renamed';
100
+ const diff = await this.git.diff(['--', file]);
101
+ const lines = diff.split('\n');
102
+ let additions = 0;
103
+ let deletions = 0;
104
+ for (const line of lines) {
105
+ if (line.startsWith('+') && !line.startsWith('+++'))
106
+ additions++;
107
+ if (line.startsWith('-') && !line.startsWith('---'))
108
+ deletions++;
109
+ }
110
+ return { file, status, additions, deletions, diff };
111
+ };
112
+ for (const file of status.staged) {
113
+ files.push(await processFile(file, 'M'));
114
+ }
115
+ for (const file of status.modified) {
116
+ if (!files.find((f) => f.file === file)) {
117
+ files.push(await processFile(file, 'M'));
118
+ }
119
+ }
120
+ for (const file of status.not_added) {
121
+ files.push(await processFile(file, 'A'));
122
+ }
123
+ return files;
124
+ }
125
+ async getFullFileContents(explicitFiles, options) {
126
+ await this.ensureRepo();
127
+ // 1. Identificar arquivos a processar
128
+ let filesToRead;
129
+ // Fetch modified files once upfront to avoid N+1 performance issue
130
+ const allModifiedFiles = await this.getModifiedFiles();
131
+ const modifiedFilesMap = new Map(allModifiedFiles.map(f => [f.file, f]));
132
+ if (explicitFiles && explicitFiles.length > 0) {
133
+ // Arquivos explícitos fornecidos
134
+ filesToRead = explicitFiles;
135
+ }
136
+ else {
137
+ // Detectar automaticamente via getModifiedFiles()
138
+ filesToRead = allModifiedFiles.map(f => f.file);
139
+ }
140
+ // 2. Para cada arquivo, ler conteúdo E diff
141
+ const fileContents = [];
142
+ for (const filePath of filesToRead) {
143
+ try {
144
+ // Determinar status do arquivo
145
+ const fileInfo = modifiedFilesMap.get(filePath);
146
+ const status = fileInfo?.status || 'modified';
147
+ // Pular arquivos deletados (não tem conteúdo)
148
+ if (status === 'deleted')
149
+ continue;
150
+ // Pegar diff específico desse arquivo
151
+ let fileDiff;
152
+ if (options?.branch) {
153
+ // Diff entre branch e HEAD
154
+ fileDiff = await this.git.diff([`${options.branch}...HEAD`, '--', filePath]);
155
+ }
156
+ else if (options?.commit) {
157
+ // Diff do commit específico
158
+ fileDiff = await this.git.diff([`${options.commit}^`, options.commit, '--', filePath]);
159
+ }
160
+ else if (options?.staged) {
161
+ // Diff staged apenas
162
+ fileDiff = await this.git.diff(['--cached', '--', filePath]);
163
+ }
164
+ else {
165
+ // Diff completo (staged + unstaged)
166
+ const stagedDiff = await this.git.diff(['--cached', '--', filePath]);
167
+ const unstagedDiff = await this.git.diff(['--', filePath]);
168
+ fileDiff = `${stagedDiff}\n${unstagedDiff}`.trim();
169
+ }
170
+ // Ler conteúdo do arquivo
171
+ let content;
172
+ if (options?.commit) {
173
+ // Ler do commit específico
174
+ content = await this.git.show([`${options.commit}:${filePath}`]);
175
+ }
176
+ else {
177
+ // Ler do working tree (fs.readFile)
178
+ // Para branch comparison, lê a versão atual (HEAD)
179
+ const fullPath = path.resolve(filePath);
180
+ content = await fs.readFile(fullPath, 'utf-8');
181
+ }
182
+ fileContents.push({
183
+ path: filePath,
184
+ content,
185
+ status,
186
+ diff: fileDiff,
187
+ });
188
+ }
189
+ catch (error) {
190
+ // Arquivo pode ser binário ou inacessível - pular silenciosamente
191
+ continue;
192
+ }
193
+ }
194
+ return fileContents;
195
+ }
196
+ async getCurrentBranch() {
197
+ return this.git.revparse(['--abbrev-ref', 'HEAD']);
198
+ }
199
+ async getHeadCommit() {
200
+ return this.git.revparse(['HEAD']);
201
+ }
202
+ async getUserEmail() {
203
+ try {
204
+ const email = await this.git.raw(['config', 'user.email']);
205
+ return email.trim() || undefined;
206
+ }
207
+ catch {
208
+ return undefined;
209
+ }
210
+ }
211
+ async getGitInfo() {
212
+ const info = {
213
+ userEmail: undefined,
214
+ remote: undefined,
215
+ branch: undefined,
216
+ commitSha: undefined,
217
+ };
218
+ try {
219
+ info.userEmail = await this.getUserEmail();
220
+ }
221
+ catch {
222
+ // Git config not set
223
+ }
224
+ try {
225
+ info.remote = await this.getRemoteUrl();
226
+ }
227
+ catch {
228
+ // No remote configured
229
+ }
230
+ try {
231
+ info.branch = await this.getCurrentBranch();
232
+ }
233
+ catch {
234
+ // Not on a branch (detached HEAD)
235
+ }
236
+ try {
237
+ info.commitSha = await this.getHeadCommit();
238
+ }
239
+ catch {
240
+ // No commits yet
241
+ }
242
+ return info;
243
+ }
244
+ inferPlatform(remote) {
245
+ if (!remote)
246
+ return undefined;
247
+ const lowerRemote = remote.toLowerCase();
248
+ if (lowerRemote.includes('github.com'))
249
+ return 'GITHUB';
250
+ if (lowerRemote.includes('gitlab.com'))
251
+ return 'GITLAB';
252
+ if (lowerRemote.includes('bitbucket.org'))
253
+ return 'BITBUCKET';
254
+ if (lowerRemote.includes('dev.azure.com') || lowerRemote.includes('visualstudio.com')) {
255
+ return 'AZURE_REPOS';
256
+ }
257
+ return undefined;
258
+ }
259
+ }
260
+ export const gitService = new GitService();
261
+ //# sourceMappingURL=git.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.service.js","sourceRoot":"","sources":["../../src/services/git.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ReviewResult, TrialReviewResult } from '../types/index.js';
2
+ declare class ReviewService {
3
+ analyze(diff: string, rulesOnly?: boolean, fast?: boolean, options?: {
4
+ files?: string[];
5
+ staged?: boolean;
6
+ commit?: string;
7
+ branch?: string;
8
+ }): Promise<ReviewResult>;
9
+ getPullRequestSuggestions(params: {
10
+ prUrl?: string;
11
+ prNumber?: number;
12
+ repositoryId?: string;
13
+ format?: 'markdown';
14
+ severity?: string;
15
+ category?: string;
16
+ }): Promise<{
17
+ result: ReviewResult;
18
+ markdown?: string;
19
+ }>;
20
+ trialAnalyze(diff: string): Promise<TrialReviewResult>;
21
+ private normalizeSuggestionsResponse;
22
+ private mapFileSuggestions;
23
+ private mapPrLevelSuggestions;
24
+ private normalizeSeverity;
25
+ }
26
+ export declare const reviewService: ReviewService;
27
+ export {};
28
+ //# sourceMappingURL=review.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.service.d.ts","sourceRoot":"","sources":["../../src/services/review.service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,YAAY,EAAE,iBAAiB,EAAwH,MAAM,mBAAmB,CAAC;AAE7M,cAAM,aAAa;IACX,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,OAAO,EACnB,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACjF,OAAO,CAAC,YAAY,CAAC;IA8ClB,yBAAyB,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAahN,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAK5D,OAAO,CAAC,4BAA4B;IAuBpC,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,iBAAiB;CAQ1B;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { api } from './api/index.js';
2
+ import { authService } from './auth.service.js';
3
+ import { gitService } from './git.service.js';
4
+ import { getTrialIdentifier } from '../utils/rate-limit.js';
5
+ import { loadConfig } from '../utils/config.js';
6
+ import { CLI_VERSION } from '../constants.js';
7
+ class ReviewService {
8
+ async analyze(diff, rulesOnly, fast, options) {
9
+ const token = await authService.getValidToken();
10
+ const reviewConfig = {
11
+ rulesOnly,
12
+ fast,
13
+ };
14
+ if (!fast) {
15
+ reviewConfig.files = await gitService.getFullFileContents(options?.files, {
16
+ staged: options?.staged,
17
+ commit: options?.commit,
18
+ branch: options?.branch,
19
+ });
20
+ }
21
+ const teamConfig = await loadConfig();
22
+ const isTeamKey = token.startsWith('kodus_');
23
+ if (isTeamKey && teamConfig) {
24
+ const gitInfo = await gitService.getGitInfo();
25
+ const inferredPlatform = gitInfo.remote
26
+ ? gitService.inferPlatform(gitInfo.remote)
27
+ : undefined;
28
+ return api.review.analyzeWithMetrics(diff, token, reviewConfig, {
29
+ userEmail: gitInfo.userEmail,
30
+ gitRemote: gitInfo.remote || undefined,
31
+ branch: gitInfo.branch,
32
+ commitSha: gitInfo.commitSha,
33
+ inferredPlatform,
34
+ cliVersion: CLI_VERSION,
35
+ });
36
+ }
37
+ return api.review.analyze(diff, token, reviewConfig);
38
+ }
39
+ async getPullRequestSuggestions(params) {
40
+ if (!params.prUrl && !(params.prNumber && params.repositoryId)) {
41
+ throw new Error('Provide prUrl or prNumber with repositoryId to fetch pull request suggestions.');
42
+ }
43
+ const token = await authService.getValidToken();
44
+ const response = await api.review.getPullRequestSuggestions(token, params);
45
+ return {
46
+ result: this.normalizeSuggestionsResponse(response),
47
+ markdown: response.markdown,
48
+ };
49
+ }
50
+ async trialAnalyze(diff) {
51
+ const fingerprint = await getTrialIdentifier();
52
+ return api.review.trialAnalyze(diff, fingerprint);
53
+ }
54
+ normalizeSuggestionsResponse(response) {
55
+ let issues = [];
56
+ if (Array.isArray(response.issues)) {
57
+ issues = response.issues;
58
+ }
59
+ else if (Array.isArray(response.suggestions)) {
60
+ issues = response.suggestions;
61
+ }
62
+ else if (response.suggestions && typeof response.suggestions === 'object') {
63
+ const suggestionsObj = response.suggestions;
64
+ issues = [
65
+ ...this.mapFileSuggestions(suggestionsObj.files ?? []),
66
+ ...this.mapPrLevelSuggestions(suggestionsObj.prLevel ?? []),
67
+ ];
68
+ }
69
+ return {
70
+ summary: response.summary ?? 'Pull request suggestions',
71
+ issues,
72
+ filesAnalyzed: response.filesAnalyzed ?? new Set(issues.map(i => i.file)).size,
73
+ duration: response.duration ?? 0,
74
+ };
75
+ }
76
+ mapFileSuggestions(files) {
77
+ return files.map((s) => ({
78
+ file: s.filePath ?? s.relevantFile,
79
+ line: s.relevantLinesStart ?? 1,
80
+ endLine: s.relevantLinesEnd,
81
+ severity: this.normalizeSeverity(s.severity),
82
+ message: s.suggestionContent,
83
+ suggestion: s.oneSentenceSummary,
84
+ ruleId: s.label,
85
+ }));
86
+ }
87
+ mapPrLevelSuggestions(prLevel) {
88
+ return prLevel.map((s) => ({
89
+ file: 'PR',
90
+ line: 0,
91
+ severity: this.normalizeSeverity(s.severity),
92
+ message: s.suggestionContent,
93
+ suggestion: s.oneSentenceSummary,
94
+ ruleId: s.label,
95
+ }));
96
+ }
97
+ normalizeSeverity(severity) {
98
+ if (!severity)
99
+ return 'info';
100
+ const s = severity.toLowerCase();
101
+ if (s === 'critical')
102
+ return 'critical';
103
+ if (s === 'high' || s === 'error')
104
+ return 'error';
105
+ if (s === 'medium' || s === 'warning')
106
+ return 'warning';
107
+ return 'info';
108
+ }
109
+ }
110
+ export const reviewService = new ReviewService();
111
+ //# sourceMappingURL=review.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.service.js","sourceRoot":"","sources":["../../src/services/review.service.ts"],"names":[],"mappings":"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"}