nayan-ai 1.0.0-beta.1
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/.github/workflows/publish.yml +26 -0
- package/README.md +54 -0
- package/dist/analyzer.d.ts +3 -0
- package/dist/analyzer.js +66 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/claude.d.ts +5 -0
- package/dist/claude.js +118 -0
- package/dist/claude.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +155 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex.d.ts +5 -0
- package/dist/codex.js +129 -0
- package/dist/codex.js.map +1 -0
- package/dist/github.d.ts +15 -0
- package/dist/github.js +88 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/logs.d.ts +34 -0
- package/dist/logs.js +219 -0
- package/dist/logs.js.map +1 -0
- package/dist/prompt.d.ts +1 -0
- package/dist/prompt.js +76 -0
- package/dist/prompt.js.map +1 -0
- package/dist/repo.d.ts +8 -0
- package/dist/repo.js +61 -0
- package/dist/repo.js.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
- package/src/analyzer.ts +77 -0
- package/src/claude.ts +147 -0
- package/src/cli.ts +172 -0
- package/src/codex.ts +158 -0
- package/src/github.ts +108 -0
- package/src/index.ts +6 -0
- package/src/logs.ts +253 -0
- package/src/prompt.ts +75 -0
- package/src/repo.ts +81 -0
- package/src/types.ts +51 -0
- package/tsconfig.json +19 -0
package/dist/github.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export class GitHubClient {
|
|
2
|
+
token;
|
|
3
|
+
apiBase;
|
|
4
|
+
constructor(token, githubUrl) {
|
|
5
|
+
this.token = token;
|
|
6
|
+
this.apiBase = githubUrl
|
|
7
|
+
? `${githubUrl.replace(/\/$/, '')}/api/v3`
|
|
8
|
+
: 'https://api.github.com';
|
|
9
|
+
}
|
|
10
|
+
async fetch(endpoint, options = {}) {
|
|
11
|
+
const url = `${this.apiBase}${endpoint}`;
|
|
12
|
+
const response = await fetch(url, {
|
|
13
|
+
...options,
|
|
14
|
+
headers: {
|
|
15
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
16
|
+
'Authorization': `Bearer ${this.token}`,
|
|
17
|
+
'User-Agent': 'nayan-ai',
|
|
18
|
+
...options.headers,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const body = await response.text();
|
|
23
|
+
throw new Error(`GitHub API error (${response.status}): ${body}`);
|
|
24
|
+
}
|
|
25
|
+
return response.json();
|
|
26
|
+
}
|
|
27
|
+
async getPullRequest(pr) {
|
|
28
|
+
return this.fetch(`/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}`);
|
|
29
|
+
}
|
|
30
|
+
async getPullRequestFiles(pr) {
|
|
31
|
+
return this.fetch(`/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}/files?per_page=100`);
|
|
32
|
+
}
|
|
33
|
+
async postReview(pr, commitId, body, comments) {
|
|
34
|
+
await this.fetch(`/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}/reviews`, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'Content-Type': 'application/json' },
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
commit_id: commitId,
|
|
39
|
+
body,
|
|
40
|
+
event: 'COMMENT',
|
|
41
|
+
comments,
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async postComment(pr, body) {
|
|
46
|
+
await this.fetch(`/repos/${pr.owner}/${pr.repo}/issues/${pr.number}/comments`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: { 'Content-Type': 'application/json' },
|
|
49
|
+
body: JSON.stringify({ body }),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function parseFiles(files) {
|
|
54
|
+
return files
|
|
55
|
+
.filter((f) => !!f.patch)
|
|
56
|
+
.map((f) => ({
|
|
57
|
+
filename: f.filename,
|
|
58
|
+
patch: f.patch,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
export function parsePRReference(input) {
|
|
62
|
+
// Full URL: https://github.com/owner/repo/pull/123 or https://enterprise.example.com/owner/repo/pull/123
|
|
63
|
+
const urlMatch = input.match(/^(https?:\/\/[^/]+)\/([^/]+)\/([^/]+)\/pull\/(\d+)/);
|
|
64
|
+
if (urlMatch) {
|
|
65
|
+
const baseUrl = urlMatch[1];
|
|
66
|
+
// Only github.com (exactly) is public GitHub, everything else is enterprise
|
|
67
|
+
const isEnterprise = !baseUrl.match(/^https?:\/\/(www\.)?github\.com$/i);
|
|
68
|
+
return {
|
|
69
|
+
owner: urlMatch[2],
|
|
70
|
+
repo: urlMatch[3],
|
|
71
|
+
number: parseInt(urlMatch[4], 10),
|
|
72
|
+
githubUrl: isEnterprise ? baseUrl : undefined,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Short reference: owner/repo#123
|
|
76
|
+
const shortMatch = input.match(/^([^/]+)\/([^#]+)#(\d+)$/);
|
|
77
|
+
if (shortMatch) {
|
|
78
|
+
return {
|
|
79
|
+
owner: shortMatch[1],
|
|
80
|
+
repo: shortMatch[2],
|
|
81
|
+
number: parseInt(shortMatch[3], 10),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
throw new Error('Invalid PR reference. Use:\n' +
|
|
85
|
+
' - https://github.com/owner/repo/pull/123\n' +
|
|
86
|
+
' - owner/repo#123');
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { GitHubClient, parseFiles, parsePRReference } from './github.js';
|
|
2
|
+
export { analyzeWithCodex } from './codex.js';
|
|
3
|
+
export { analyzeWithClaude } from './claude.js';
|
|
4
|
+
export { issuesToReviewComments, generateSummary } from './analyzer.js';
|
|
5
|
+
export { cloneRepo, getGitDiff, getChangedFiles } from './repo.js';
|
|
6
|
+
export type * from './types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { GitHubClient, parseFiles, parsePRReference } from './github.js';
|
|
2
|
+
export { analyzeWithCodex } from './codex.js';
|
|
3
|
+
export { analyzeWithClaude } from './claude.js';
|
|
4
|
+
export { issuesToReviewComments, generateSummary } from './analyzer.js';
|
|
5
|
+
export { cloneRepo, getGitDiff, getChangedFiles } from './repo.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/logs.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface CodexEvent {
|
|
2
|
+
type: string;
|
|
3
|
+
item?: {
|
|
4
|
+
id?: string;
|
|
5
|
+
type?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
command?: string;
|
|
8
|
+
aggregated_output?: string;
|
|
9
|
+
exit_code?: number | null;
|
|
10
|
+
status?: string;
|
|
11
|
+
};
|
|
12
|
+
thread_id?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class LogProcessor {
|
|
15
|
+
private seenFiles;
|
|
16
|
+
private currentPhase;
|
|
17
|
+
private currentSpinner;
|
|
18
|
+
private fileCount;
|
|
19
|
+
private analyzedCount;
|
|
20
|
+
processEvent(event: CodexEvent): void;
|
|
21
|
+
private startSpinner;
|
|
22
|
+
private succeedSpinner;
|
|
23
|
+
private stopSpinner;
|
|
24
|
+
private logAndSpin;
|
|
25
|
+
private handleItemStarted;
|
|
26
|
+
private handleItemCompleted;
|
|
27
|
+
private handleReasoning;
|
|
28
|
+
private wrapText;
|
|
29
|
+
private handleCommandCompleted;
|
|
30
|
+
private extractFilePath;
|
|
31
|
+
private setPhase;
|
|
32
|
+
reset(): void;
|
|
33
|
+
}
|
|
34
|
+
export declare const logProcessor: LogProcessor;
|
package/dist/logs.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
export class LogProcessor {
|
|
4
|
+
seenFiles = new Set();
|
|
5
|
+
currentPhase = '';
|
|
6
|
+
currentSpinner = null;
|
|
7
|
+
fileCount = 0;
|
|
8
|
+
analyzedCount = 0;
|
|
9
|
+
processEvent(event) {
|
|
10
|
+
switch (event.type) {
|
|
11
|
+
case 'thread.started':
|
|
12
|
+
this.startSpinner('Starting analysis...');
|
|
13
|
+
break;
|
|
14
|
+
case 'turn.started':
|
|
15
|
+
// Silent - just marks the start of a turn
|
|
16
|
+
break;
|
|
17
|
+
case 'item.completed':
|
|
18
|
+
this.handleItemCompleted(event);
|
|
19
|
+
break;
|
|
20
|
+
case 'item.started':
|
|
21
|
+
this.handleItemStarted(event);
|
|
22
|
+
break;
|
|
23
|
+
case 'turn.completed':
|
|
24
|
+
// Analysis complete - handled elsewhere
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
startSpinner(text) {
|
|
29
|
+
this.stopSpinner();
|
|
30
|
+
this.currentSpinner = ora({
|
|
31
|
+
text: chalk.cyan(text),
|
|
32
|
+
prefixText: ' ',
|
|
33
|
+
spinner: 'dots'
|
|
34
|
+
}).start();
|
|
35
|
+
}
|
|
36
|
+
succeedSpinner(text) {
|
|
37
|
+
if (this.currentSpinner) {
|
|
38
|
+
this.currentSpinner.succeed(text ? chalk.green(text) : undefined);
|
|
39
|
+
this.currentSpinner = null;
|
|
40
|
+
}
|
|
41
|
+
else if (text) {
|
|
42
|
+
console.log(chalk.green(` ✔ ${text}`));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
stopSpinner() {
|
|
46
|
+
if (this.currentSpinner) {
|
|
47
|
+
this.currentSpinner.stop();
|
|
48
|
+
this.currentSpinner = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
logAndSpin(text) {
|
|
52
|
+
// First, succeed the current spinner to print it
|
|
53
|
+
if (this.currentSpinner) {
|
|
54
|
+
this.currentSpinner.succeed();
|
|
55
|
+
}
|
|
56
|
+
// Then start a new spinner with the new text
|
|
57
|
+
this.currentSpinner = ora({
|
|
58
|
+
text: chalk.cyan(text),
|
|
59
|
+
prefixText: ' ',
|
|
60
|
+
spinner: 'dots'
|
|
61
|
+
}).start();
|
|
62
|
+
}
|
|
63
|
+
handleItemStarted(event) {
|
|
64
|
+
const item = event.item;
|
|
65
|
+
if (!item)
|
|
66
|
+
return;
|
|
67
|
+
if (item.type === 'command_execution' && item.command) {
|
|
68
|
+
const cmd = item.command;
|
|
69
|
+
// Git diff command
|
|
70
|
+
if (cmd.includes('git diff')) {
|
|
71
|
+
this.setPhase('diff');
|
|
72
|
+
this.logAndSpin('Checking differences...');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
handleItemCompleted(event) {
|
|
77
|
+
const item = event.item;
|
|
78
|
+
if (!item)
|
|
79
|
+
return;
|
|
80
|
+
if (item.type === 'reasoning' && item.text) {
|
|
81
|
+
this.handleReasoning(item.text);
|
|
82
|
+
}
|
|
83
|
+
else if (item.type === 'command_execution') {
|
|
84
|
+
this.handleCommandCompleted(item);
|
|
85
|
+
}
|
|
86
|
+
else if (item.type === 'agent_message') {
|
|
87
|
+
this.succeedSpinner('Analysis complete');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
handleReasoning(text) {
|
|
91
|
+
// Clean up the reasoning text - remove ** markers
|
|
92
|
+
const cleanText = text.replace(/\*\*/g, '').trim();
|
|
93
|
+
if (!cleanText)
|
|
94
|
+
return;
|
|
95
|
+
// Split into title (first line/sentence) and details
|
|
96
|
+
const lines = cleanText.split('\n').filter(Boolean);
|
|
97
|
+
// Check if it's a short title or has additional content
|
|
98
|
+
if (lines.length === 1 && cleanText.length < 80) {
|
|
99
|
+
// Short reasoning - just show as spinner
|
|
100
|
+
this.logAndSpin(`💭 ${cleanText}`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Long reasoning - extract title and show details as bullet points
|
|
104
|
+
let title = lines[0];
|
|
105
|
+
let details = '';
|
|
106
|
+
// If single line but long, split at first semicolon or period after 40 chars
|
|
107
|
+
if (lines.length === 1) {
|
|
108
|
+
const splitMatch = cleanText.match(/^(.{30,80}?[;.])\s*(.+)$/);
|
|
109
|
+
if (splitMatch) {
|
|
110
|
+
title = splitMatch[1];
|
|
111
|
+
details = splitMatch[2];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
details = lines.slice(1).join(' ');
|
|
116
|
+
}
|
|
117
|
+
// Show title with spinner
|
|
118
|
+
this.logAndSpin(`💭 ${title}`);
|
|
119
|
+
// If there are details, print them as indented bullet points
|
|
120
|
+
if (details) {
|
|
121
|
+
// Succeed current spinner first
|
|
122
|
+
if (this.currentSpinner) {
|
|
123
|
+
this.currentSpinner.succeed();
|
|
124
|
+
this.currentSpinner = null;
|
|
125
|
+
}
|
|
126
|
+
// Print details indented
|
|
127
|
+
const detailLines = this.wrapText(details, 70);
|
|
128
|
+
detailLines.forEach(line => {
|
|
129
|
+
console.log(chalk.dim(` ${line}`));
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
wrapText(text, maxWidth) {
|
|
135
|
+
const words = text.split(' ');
|
|
136
|
+
const lines = [];
|
|
137
|
+
let currentLine = '';
|
|
138
|
+
for (const word of words) {
|
|
139
|
+
if (currentLine.length + word.length + 1 <= maxWidth) {
|
|
140
|
+
currentLine += (currentLine ? ' ' : '') + word;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
if (currentLine)
|
|
144
|
+
lines.push(currentLine);
|
|
145
|
+
currentLine = word;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (currentLine)
|
|
149
|
+
lines.push(currentLine);
|
|
150
|
+
return lines;
|
|
151
|
+
}
|
|
152
|
+
handleCommandCompleted(item) {
|
|
153
|
+
if (!item)
|
|
154
|
+
return;
|
|
155
|
+
const cmd = item.command || '';
|
|
156
|
+
const output = item.aggregated_output || '';
|
|
157
|
+
// Git diff completed - show changed files count
|
|
158
|
+
if (cmd.includes('git diff') && output) {
|
|
159
|
+
const diffFiles = output.match(/diff --git a\/([^\s]+)/g);
|
|
160
|
+
if (diffFiles && diffFiles.length > 0) {
|
|
161
|
+
this.fileCount = diffFiles.length;
|
|
162
|
+
this.succeedSpinner(`Found ${diffFiles.length} changed files`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// File listing with rg --files
|
|
166
|
+
if (cmd.includes('rg --files') && output) {
|
|
167
|
+
const files = output.trim().split('\n').filter(Boolean);
|
|
168
|
+
if (files.length > 0) {
|
|
169
|
+
this.succeedSpinner(`Identified ${files.length} files to analyze`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// File reading commands - extract and show file path
|
|
173
|
+
const fileMatch = this.extractFilePath(cmd);
|
|
174
|
+
if (fileMatch && !this.seenFiles.has(fileMatch)) {
|
|
175
|
+
this.seenFiles.add(fileMatch);
|
|
176
|
+
this.analyzedCount++;
|
|
177
|
+
this.logAndSpin(`📄 Analyzing ${fileMatch}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
extractFilePath(cmd) {
|
|
181
|
+
// Skip git commands - they're not file reads
|
|
182
|
+
if (cmd.includes('git '))
|
|
183
|
+
return null;
|
|
184
|
+
// Match patterns like:
|
|
185
|
+
// sed -n '1,260p' path/to/file.tsx
|
|
186
|
+
// nl -ba path/to/file.ts
|
|
187
|
+
// cat path/to/file.ts
|
|
188
|
+
const patterns = [
|
|
189
|
+
/sed\s+-n\s+'[^']+'\s+([^\s|]+\.[a-z]{1,4})/i,
|
|
190
|
+
/nl\s+-ba\s+([^\s|]+\.[a-z]{1,4})/i,
|
|
191
|
+
/cat\s+([^\s|]+\.[a-z]{1,4})/i,
|
|
192
|
+
];
|
|
193
|
+
for (const pattern of patterns) {
|
|
194
|
+
const match = cmd.match(pattern);
|
|
195
|
+
if (match && match[1]) {
|
|
196
|
+
// Skip if it's a glob pattern or doesn't look like a real file
|
|
197
|
+
if (match[1].includes('*'))
|
|
198
|
+
continue;
|
|
199
|
+
// Must have a proper file extension (1-4 chars)
|
|
200
|
+
if (!/\.[a-z]{1,4}$/i.test(match[1]))
|
|
201
|
+
continue;
|
|
202
|
+
return match[1];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
setPhase(phase) {
|
|
208
|
+
this.currentPhase = phase;
|
|
209
|
+
}
|
|
210
|
+
reset() {
|
|
211
|
+
this.stopSpinner();
|
|
212
|
+
this.seenFiles.clear();
|
|
213
|
+
this.currentPhase = '';
|
|
214
|
+
this.fileCount = 0;
|
|
215
|
+
this.analyzedCount = 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export const logProcessor = new LogProcessor();
|
|
219
|
+
//# sourceMappingURL=logs.js.map
|
package/dist/logs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"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"}
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getReviewPrompt(baseBranch: string): string;
|
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function getReviewPrompt(baseBranch) {
|
|
2
|
+
return `You are an expert code reviewer. Perform a comprehensive review of ALL code changes in this PR.
|
|
3
|
+
|
|
4
|
+
STEP 1: Run "git diff -U10 ${baseBranch}...HEAD" to get all changed files with 10 lines of context.
|
|
5
|
+
|
|
6
|
+
STEP 2: Analyze the diff directly (skip lock files like yarn.lock, package-lock.json, bun.lock):
|
|
7
|
+
- The diff provides sufficient context for most issues
|
|
8
|
+
- Only read the full file if you need more context to understand the change
|
|
9
|
+
- Focus on the actual changes (+ and - lines) and their immediate context
|
|
10
|
+
|
|
11
|
+
STEP 3: Check each change for these categories:
|
|
12
|
+
|
|
13
|
+
**BUGS & LOGIC ERRORS:**
|
|
14
|
+
- Off-by-one errors in loops/arrays
|
|
15
|
+
- Null/undefined access without checks
|
|
16
|
+
- Race conditions in async code
|
|
17
|
+
- Incorrect boolean logic or conditions
|
|
18
|
+
- Wrong variable usage or typos
|
|
19
|
+
- Infinite loops or recursion without exit
|
|
20
|
+
- Array mutation while iterating
|
|
21
|
+
|
|
22
|
+
**ERROR HANDLING:**
|
|
23
|
+
- Missing try/catch for async operations
|
|
24
|
+
- Unhandled promise rejections
|
|
25
|
+
- Missing error states in UI
|
|
26
|
+
- Silent failures that should be logged
|
|
27
|
+
|
|
28
|
+
**SECURITY:**
|
|
29
|
+
- SQL injection, XSS vulnerabilities
|
|
30
|
+
- Hardcoded secrets or credentials
|
|
31
|
+
- Unsafe user input handling
|
|
32
|
+
- Missing authentication/authorization checks
|
|
33
|
+
|
|
34
|
+
**PERFORMANCE:**
|
|
35
|
+
- Unnecessary re-renders or computations
|
|
36
|
+
- Missing memoization where needed
|
|
37
|
+
- N+1 query patterns
|
|
38
|
+
- Memory leaks (event listeners, subscriptions not cleaned up)
|
|
39
|
+
- Large objects in state that should be normalized
|
|
40
|
+
|
|
41
|
+
**TYPE SAFETY:**
|
|
42
|
+
- Any type usage that should be specific
|
|
43
|
+
- Missing null checks for optional values
|
|
44
|
+
- Type assertions that could fail at runtime
|
|
45
|
+
|
|
46
|
+
**EDGE CASES:**
|
|
47
|
+
- Empty arrays/objects not handled
|
|
48
|
+
- Boundary conditions (0, negative, max values)
|
|
49
|
+
- Network failures not handled
|
|
50
|
+
- Loading/error states missing
|
|
51
|
+
|
|
52
|
+
**CODE QUALITY:**
|
|
53
|
+
- Dead code or unused variables
|
|
54
|
+
- Duplicated logic that should be extracted
|
|
55
|
+
- Overly complex functions that should be split
|
|
56
|
+
- Missing cleanup in useEffect/subscriptions
|
|
57
|
+
|
|
58
|
+
**TEST COVERAGE:**
|
|
59
|
+
- Check if tests are added for new functionality
|
|
60
|
+
- Check if existing tests need to be updated for changed code
|
|
61
|
+
- Identify critical logic that should have unit tests
|
|
62
|
+
- Flag functions with complex branching that need test coverage
|
|
63
|
+
- Check if edge cases in the code have corresponding test cases
|
|
64
|
+
|
|
65
|
+
STEP 4: Output ALL issues as JSON (be thorough - report every issue you find):
|
|
66
|
+
{"issues":[{"filename":"<path>","line":<num>,"category":"functionality"|"performance"|"readability","severity":"error"|"warning"|"info","message":"<description>","suggestion":"<fix>"}]}
|
|
67
|
+
|
|
68
|
+
**SEVERITY GUIDELINES (be consistent):**
|
|
69
|
+
- **error**: Will cause bugs, crashes, security vulnerabilities, or data loss. Examples: null pointer access, unhandled exceptions, SQL injection, race conditions, infinite loops.
|
|
70
|
+
- **warning**: Potential problems that may cause issues in edge cases or under certain conditions. Examples: missing error handling, possible memory leaks, missing null checks for optional values, performance issues.
|
|
71
|
+
- **info**: Code quality improvements, best practices, style suggestions. Examples: dead code, code duplication, missing tests, readability improvements.
|
|
72
|
+
|
|
73
|
+
CRITICAL: Review EVERY changed file in the diff. Do not skip any. Be efficient - analyze the diff context first, only read full files when truly needed.
|
|
74
|
+
If truly no issues after thorough analysis, return {"issues":[]}`;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO;;6BAEoB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEAsE0B,CAAC;AAClE,CAAC"}
|
package/dist/repo.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PRInfo } from './types.js';
|
|
2
|
+
export interface ClonedRepo {
|
|
3
|
+
path: string;
|
|
4
|
+
cleanup: () => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare function cloneRepo(prInfo: PRInfo, token: string, githubUrl?: string): Promise<ClonedRepo>;
|
|
7
|
+
export declare function getGitDiff(repoPath: string): Promise<string>;
|
|
8
|
+
export declare function getChangedFiles(repoPath: string): Promise<string[]>;
|
package/dist/repo.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { mkdtemp, rm } from 'fs/promises';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
export async function cloneRepo(prInfo, token, githubUrl) {
|
|
6
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'nayan-ai-'));
|
|
7
|
+
const baseUrl = githubUrl?.replace(/\/$/, '') || 'https://github.com';
|
|
8
|
+
const cloneUrl = `https://${token}@${baseUrl.replace(/^https?:\/\//, '')}/${prInfo.owner}/${prInfo.repo}.git`;
|
|
9
|
+
// Clone with enough depth to have main branch history
|
|
10
|
+
await runGit(['clone', '--depth', '100', cloneUrl, tempDir]);
|
|
11
|
+
// Fetch the main branch explicitly for comparison
|
|
12
|
+
await runGit(['fetch', 'origin', 'main:refs/remotes/origin/main', '--depth', '100'], tempDir);
|
|
13
|
+
// Fetch the PR branch
|
|
14
|
+
await runGit(['fetch', 'origin', `pull/${prInfo.number}/head:pr-branch`], tempDir);
|
|
15
|
+
await runGit(['checkout', 'pr-branch'], tempDir);
|
|
16
|
+
return {
|
|
17
|
+
path: tempDir,
|
|
18
|
+
cleanup: async () => {
|
|
19
|
+
try {
|
|
20
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// ignore cleanup errors
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function getGitDiff(repoPath) {
|
|
29
|
+
return runGit(['diff', 'origin/main...HEAD', '--unified=3'], repoPath);
|
|
30
|
+
}
|
|
31
|
+
export async function getChangedFiles(repoPath) {
|
|
32
|
+
const output = await runGit(['diff', 'origin/main...HEAD', '--name-only'], repoPath);
|
|
33
|
+
return output.split('\n').filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
function runGit(args, cwd) {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
const child = spawn('git', args, {
|
|
38
|
+
cwd,
|
|
39
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
40
|
+
});
|
|
41
|
+
let stdout = '';
|
|
42
|
+
let stderr = '';
|
|
43
|
+
child.stdout.on('data', (data) => {
|
|
44
|
+
stdout += data.toString();
|
|
45
|
+
});
|
|
46
|
+
child.stderr.on('data', (data) => {
|
|
47
|
+
stderr += data.toString();
|
|
48
|
+
});
|
|
49
|
+
child.on('close', (code) => {
|
|
50
|
+
if (code !== 0) {
|
|
51
|
+
reject(new Error(`git ${args[0]} failed: ${stderr || stdout || 'Unknown error'}`));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
resolve(stdout);
|
|
55
|
+
});
|
|
56
|
+
child.on('error', (err) => {
|
|
57
|
+
reject(err);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=repo.js.map
|
package/dist/repo.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../src/repo.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface PRInfo {
|
|
2
|
+
owner: string;
|
|
3
|
+
repo: string;
|
|
4
|
+
number: number;
|
|
5
|
+
}
|
|
6
|
+
export interface PullRequest {
|
|
7
|
+
number: number;
|
|
8
|
+
title: string;
|
|
9
|
+
head: {
|
|
10
|
+
sha: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface PullRequestFile {
|
|
14
|
+
filename: string;
|
|
15
|
+
status: string;
|
|
16
|
+
patch?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface FileChange {
|
|
19
|
+
filename: string;
|
|
20
|
+
patch: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CodeIssue {
|
|
23
|
+
filename: string;
|
|
24
|
+
line: number;
|
|
25
|
+
category: 'functionality' | 'readability' | 'performance';
|
|
26
|
+
severity: 'error' | 'warning' | 'info';
|
|
27
|
+
message: string;
|
|
28
|
+
suggestion?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ReviewComment {
|
|
31
|
+
path: string;
|
|
32
|
+
line: number;
|
|
33
|
+
side: 'RIGHT';
|
|
34
|
+
body: string;
|
|
35
|
+
}
|
|
36
|
+
export type LLMProvider = 'codex' | 'claude';
|
|
37
|
+
export interface CLIOptions {
|
|
38
|
+
token: string;
|
|
39
|
+
verbose: boolean;
|
|
40
|
+
dry: boolean;
|
|
41
|
+
inline: boolean;
|
|
42
|
+
format: string;
|
|
43
|
+
llm: LLMProvider;
|
|
44
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nayan-ai",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "AI-powered PR code reviewer CLI using Codex CLI agent",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"nayan-ai": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/ursnj/nayan-ai.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ai-code-review",
|
|
20
|
+
"github-code-review",
|
|
21
|
+
"pull-request-review",
|
|
22
|
+
"codex-code-review",
|
|
23
|
+
"claude-code-review",
|
|
24
|
+
"code-review-cli",
|
|
25
|
+
"code-analysis",
|
|
26
|
+
"static-analysis",
|
|
27
|
+
"security-review",
|
|
28
|
+
"automated-review"
|
|
29
|
+
],
|
|
30
|
+
"author": "Niranjan Devasani",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/ursnj/nayan-ai/issues"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/ursnj/nayan-ai#readme",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"chalk": "^5.6.2",
|
|
41
|
+
"commander": "^14.0.2",
|
|
42
|
+
"ora": "^9.1.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^25.1.0",
|
|
46
|
+
"typescript": "^5.9.3"
|
|
47
|
+
}
|
|
48
|
+
}
|