nayan-ai 1.0.0-beta.3 → 1.0.0-beta.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 (61) hide show
  1. package/README.md +101 -14
  2. package/dist/cli.js +21 -157
  3. package/dist/cli.js.map +1 -1
  4. package/dist/common/claude.d.ts +6 -0
  5. package/dist/common/claude.js +180 -0
  6. package/dist/common/claude.js.map +1 -0
  7. package/dist/common/codex.d.ts +6 -0
  8. package/dist/common/codex.js +169 -0
  9. package/dist/common/codex.js.map +1 -0
  10. package/dist/common/github.d.ts +22 -0
  11. package/dist/common/github.js +153 -0
  12. package/dist/common/github.js.map +1 -0
  13. package/dist/common/logs.d.ts +15 -0
  14. package/dist/common/logs.js +154 -0
  15. package/dist/common/logs.js.map +1 -0
  16. package/dist/{types.d.ts → common/types.d.ts} +36 -1
  17. package/dist/common/types.js.map +1 -0
  18. package/dist/common/utils.d.ts +3 -0
  19. package/dist/common/utils.js +11 -0
  20. package/dist/common/utils.js.map +1 -0
  21. package/dist/index.d.ts +7 -6
  22. package/dist/index.js +6 -5
  23. package/dist/index.js.map +1 -1
  24. package/dist/{analyzer.d.ts → review/analyzer.d.ts} +1 -1
  25. package/dist/review/analyzer.js.map +1 -0
  26. package/dist/review/command.d.ts +2 -0
  27. package/dist/review/command.js +111 -0
  28. package/dist/review/command.js.map +1 -0
  29. package/dist/review/prompt.js.map +1 -0
  30. package/dist/scan/command.d.ts +2 -0
  31. package/dist/scan/command.js +700 -0
  32. package/dist/scan/command.js.map +1 -0
  33. package/dist/scan/fixer.d.ts +30 -0
  34. package/dist/scan/fixer.js +264 -0
  35. package/dist/scan/fixer.js.map +1 -0
  36. package/dist/scan/prompt.d.ts +4 -0
  37. package/dist/scan/prompt.js +175 -0
  38. package/dist/scan/prompt.js.map +1 -0
  39. package/package.json +2 -2
  40. package/dist/analyzer.js.map +0 -1
  41. package/dist/claude.d.ts +0 -5
  42. package/dist/claude.js +0 -128
  43. package/dist/claude.js.map +0 -1
  44. package/dist/codex.d.ts +0 -5
  45. package/dist/codex.js +0 -129
  46. package/dist/codex.js.map +0 -1
  47. package/dist/github.d.ts +0 -15
  48. package/dist/github.js +0 -88
  49. package/dist/github.js.map +0 -1
  50. package/dist/logs.d.ts +0 -34
  51. package/dist/logs.js +0 -219
  52. package/dist/logs.js.map +0 -1
  53. package/dist/prompt.js.map +0 -1
  54. package/dist/repo.d.ts +0 -8
  55. package/dist/repo.js +0 -61
  56. package/dist/repo.js.map +0 -1
  57. package/dist/types.js.map +0 -1
  58. /package/dist/{types.js → common/types.js} +0 -0
  59. /package/dist/{analyzer.js → review/analyzer.js} +0 -0
  60. /package/dist/{prompt.d.ts → review/prompt.d.ts} +0 -0
  61. /package/dist/{prompt.js → review/prompt.js} +0 -0
@@ -0,0 +1,169 @@
1
+ import { spawn } from 'child_process';
2
+ import { processCodexEvent, resetLogState } from './logs.js';
3
+ export const analyzeWithCodex = async (repoPath, prompt, options) => {
4
+ const response = await runCodexExec(repoPath, prompt, options);
5
+ return parseCodexResponse(response);
6
+ };
7
+ export const analyzeWithCodexRaw = async (repoPath, prompt, options) => {
8
+ const response = await runCodexExec(repoPath, prompt, options);
9
+ return parseCodexResponseRaw(response);
10
+ };
11
+ const runCodexExec = (repoPath, prompt, options) => new Promise((resolve, reject) => {
12
+ const args = ['@openai/codex', 'exec', '--json', '--full-auto', prompt];
13
+ if (options.verbose) {
14
+ console.log(`\n[Codex] Running: npx ${args.join(' ')}`);
15
+ console.log(`[Codex] Working directory: ${repoPath}`);
16
+ }
17
+ const startTime = Date.now();
18
+ const child = spawn('npx', args, { cwd: repoPath, stdio: ['pipe', 'pipe', 'pipe'] });
19
+ let stdout = '';
20
+ let stderr = '';
21
+ resetLogState();
22
+ child.stdout.on('data', (data) => {
23
+ const chunk = data.toString();
24
+ stdout += chunk;
25
+ chunk.split('\n').filter(Boolean).forEach((line) => {
26
+ try {
27
+ const event = JSON.parse(line);
28
+ if (options.verbose) {
29
+ console.log(JSON.stringify(event, null, 2));
30
+ }
31
+ else {
32
+ processCodexEvent(event);
33
+ }
34
+ }
35
+ catch {
36
+ // Not JSON
37
+ }
38
+ });
39
+ });
40
+ child.stderr.on('data', (data) => {
41
+ const chunk = data.toString();
42
+ stderr += chunk;
43
+ if (options.verbose)
44
+ process.stderr.write(chunk);
45
+ });
46
+ child.on('close', (code) => {
47
+ console.log(`\n[Codex] Completed in ${((Date.now() - startTime) / 1000).toFixed(1)}s`);
48
+ if (code !== 0) {
49
+ reject(new Error(`Codex review failed (exit ${code}): ${(stderr || stdout || 'Unknown error').slice(0, 500)}`));
50
+ return;
51
+ }
52
+ resolve(stdout);
53
+ });
54
+ child.on('error', (err) => {
55
+ if (err.code === 'ENOENT') {
56
+ reject(new Error('npx not found. Install Node.js/npm (Node 18+) to run nayan-ai.'));
57
+ return;
58
+ }
59
+ reject(err);
60
+ });
61
+ });
62
+ const mapIssue = (item) => ({
63
+ filename: item.filename || item.package || 'unknown',
64
+ line: item.line || 0,
65
+ category: item.category || 'functionality',
66
+ severity: item.severity || 'info',
67
+ message: item.message || item.title || item.description,
68
+ suggestion: item.suggestion || item.fixedIn,
69
+ // Preserve vulnerability-specific fields for scan command
70
+ package: item.package,
71
+ version: item.version,
72
+ title: item.title,
73
+ description: item.description,
74
+ fixedIn: item.fixedIn,
75
+ cve: item.cve,
76
+ });
77
+ const extractItems = (json) => {
78
+ if (Array.isArray(json.issues))
79
+ return json.issues;
80
+ if (Array.isArray(json.vulnerabilities))
81
+ return json.vulnerabilities;
82
+ return [];
83
+ };
84
+ const parseCodexResponse = (response) => {
85
+ const lines = response.split('\n').filter(Boolean);
86
+ for (const line of lines) {
87
+ try {
88
+ const event = JSON.parse(line);
89
+ if (event.type === 'item.completed' && event.item?.type === 'agent_message' && event.item.text) {
90
+ const parsed = JSON.parse(event.item.text);
91
+ // Check if this is a fix response (has fixes or updatedManifest)
92
+ if (parsed.fixes || parsed.updatedManifest) {
93
+ // Return as a single item with the raw data preserved
94
+ return [{
95
+ ...mapIssue({ message: 'Fix response' }),
96
+ _rawFixData: parsed
97
+ }];
98
+ }
99
+ const items = extractItems(parsed);
100
+ if (items.length > 0) {
101
+ return items.filter((item) => item.message || item.package || item.title).map(mapIssue);
102
+ }
103
+ }
104
+ }
105
+ catch {
106
+ // Not valid JSON
107
+ }
108
+ }
109
+ // Try to find fix response JSON in raw response
110
+ const fixMatch = response.match(/\{[\s\S]*"(?:fixes|updatedManifest)"[\s\S]*\}/);
111
+ if (fixMatch) {
112
+ try {
113
+ const parsed = JSON.parse(fixMatch[0]);
114
+ if (parsed.fixes || parsed.updatedManifest) {
115
+ return [{
116
+ ...mapIssue({ message: 'Fix response' }),
117
+ _rawFixData: parsed
118
+ }];
119
+ }
120
+ }
121
+ catch {
122
+ // ignore
123
+ }
124
+ }
125
+ const jsonMatch = response.match(/\{\s*"(?:issues|vulnerabilities)"\s*:\s*\[[\s\S]*?\]\s*\}/);
126
+ if (jsonMatch) {
127
+ try {
128
+ const parsed = JSON.parse(jsonMatch[0]);
129
+ const items = extractItems(parsed);
130
+ return items.filter((item) => item.message || item.package || item.title).map(mapIssue);
131
+ }
132
+ catch {
133
+ // ignore
134
+ }
135
+ }
136
+ return [];
137
+ };
138
+ const parseCodexResponseRaw = (response) => {
139
+ const lines = response.split('\n').filter(Boolean);
140
+ for (const line of lines) {
141
+ try {
142
+ const event = JSON.parse(line);
143
+ if (event.type === 'item.completed' && event.item?.type === 'agent_message' && event.item.text) {
144
+ try {
145
+ return JSON.parse(event.item.text);
146
+ }
147
+ catch {
148
+ // Text is not JSON, return as-is
149
+ return { text: event.item.text };
150
+ }
151
+ }
152
+ }
153
+ catch {
154
+ // Not valid JSON line
155
+ }
156
+ }
157
+ // Try to find any JSON object in the response
158
+ const jsonMatch = response.match(/\{[\s\S]*"(?:fixes|updatedManifest|issues|vulnerabilities)"[\s\S]*\}/);
159
+ if (jsonMatch) {
160
+ try {
161
+ return JSON.parse(jsonMatch[0]);
162
+ }
163
+ catch {
164
+ // ignore
165
+ }
166
+ }
167
+ return null;
168
+ };
169
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/common/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { PRInfo, PullRequest, PullRequestFile, FileChange, ReviewComment, RepoInfo } from './types.js';
2
+ export interface ClonedRepo {
3
+ path: string;
4
+ cleanup: () => Promise<void>;
5
+ }
6
+ export interface GitHubConfig {
7
+ token: string;
8
+ githubUrl?: string;
9
+ }
10
+ export declare const getPullRequest: (config: GitHubConfig, pr: PRInfo) => Promise<PullRequest>;
11
+ export declare const getPullRequestFiles: (config: GitHubConfig, pr: PRInfo) => Promise<PullRequestFile[]>;
12
+ export declare const postReview: (config: GitHubConfig, pr: PRInfo, commitId: string, body: string, comments: ReviewComment[]) => Promise<void>;
13
+ export declare const postComment: (config: GitHubConfig, pr: PRInfo, body: string) => Promise<void>;
14
+ export declare const parseFiles: (files: PullRequestFile[]) => FileChange[];
15
+ export declare const parsePRReference: (input: string) => PRInfo & {
16
+ githubUrl?: string;
17
+ };
18
+ export declare const parseRepoReference: (input: string) => RepoInfo;
19
+ export declare const cloneRepo: (prInfo: PRInfo, token: string, githubUrl?: string) => Promise<ClonedRepo>;
20
+ export declare const cloneRepoForScan: (repoInfo: RepoInfo, token: string) => Promise<ClonedRepo>;
21
+ export declare const getGitDiff: (repoPath: string) => Promise<string>;
22
+ export declare const getChangedFiles: (repoPath: string) => Promise<string[]>;
@@ -0,0 +1,153 @@
1
+ import { spawn } from 'child_process';
2
+ import { mkdtemp, rm } from 'fs/promises';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ const getApiBase = (githubUrl) => githubUrl ? `${githubUrl.replace(/\/$/, '')}/api/v3` : 'https://api.github.com';
6
+ const githubFetch = async (config, endpoint, options = {}) => {
7
+ const url = `${getApiBase(config.githubUrl)}${endpoint}`;
8
+ const response = await fetch(url, {
9
+ ...options,
10
+ headers: {
11
+ 'Accept': 'application/vnd.github.v3+json',
12
+ 'Authorization': `Bearer ${config.token}`,
13
+ 'User-Agent': 'nayan-ai',
14
+ ...options.headers,
15
+ },
16
+ });
17
+ if (!response.ok) {
18
+ const body = await response.text();
19
+ throw new Error(`GitHub API error (${response.status}): ${body}`);
20
+ }
21
+ return response.json();
22
+ };
23
+ export const getPullRequest = (config, pr) => githubFetch(config, `/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}`);
24
+ export const getPullRequestFiles = (config, pr) => githubFetch(config, `/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}/files?per_page=100`);
25
+ export const postReview = async (config, pr, commitId, body, comments) => {
26
+ await githubFetch(config, `/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}/reviews`, {
27
+ method: 'POST',
28
+ headers: { 'Content-Type': 'application/json' },
29
+ body: JSON.stringify({
30
+ commit_id: commitId,
31
+ body,
32
+ event: 'COMMENT',
33
+ comments,
34
+ }),
35
+ });
36
+ };
37
+ export const postComment = async (config, pr, body) => {
38
+ await githubFetch(config, `/repos/${pr.owner}/${pr.repo}/issues/${pr.number}/comments`, {
39
+ method: 'POST',
40
+ headers: { 'Content-Type': 'application/json' },
41
+ body: JSON.stringify({ body }),
42
+ });
43
+ };
44
+ export const parseFiles = (files) => files
45
+ .filter((f) => !!f.patch)
46
+ .map((f) => ({
47
+ filename: f.filename,
48
+ patch: f.patch,
49
+ }));
50
+ export const parsePRReference = (input) => {
51
+ const urlMatch = input.match(/^(https?:\/\/[^/]+)\/([^/]+)\/([^/]+)\/pull\/(\d+)/);
52
+ if (urlMatch) {
53
+ const baseUrl = urlMatch[1];
54
+ const isEnterprise = !baseUrl.match(/^https?:\/\/(www\.)?github\.com$/i);
55
+ return {
56
+ owner: urlMatch[2],
57
+ repo: urlMatch[3],
58
+ number: parseInt(urlMatch[4], 10),
59
+ githubUrl: isEnterprise ? baseUrl : undefined,
60
+ };
61
+ }
62
+ const shortMatch = input.match(/^([^/]+)\/([^#]+)#(\d+)$/);
63
+ if (shortMatch) {
64
+ return {
65
+ owner: shortMatch[1],
66
+ repo: shortMatch[2],
67
+ number: parseInt(shortMatch[3], 10),
68
+ };
69
+ }
70
+ throw new Error('Invalid PR reference. Use:\n' +
71
+ ' - https://github.com/owner/repo/pull/123\n' +
72
+ ' - owner/repo#123');
73
+ };
74
+ export const parseRepoReference = (input) => {
75
+ const urlMatch = input.match(/^(https?:\/\/[^/]+)\/([^/]+)\/([^/]+?)(?:\.git)?$/);
76
+ if (urlMatch) {
77
+ const baseUrl = urlMatch[1];
78
+ const isEnterprise = !baseUrl.match(/^https?:\/\/(www\.)?github\.com$/i);
79
+ return {
80
+ owner: urlMatch[2],
81
+ repo: urlMatch[3],
82
+ githubUrl: isEnterprise ? baseUrl : undefined,
83
+ };
84
+ }
85
+ const shortMatch = input.match(/^([^/]+)\/([^/]+)$/);
86
+ if (shortMatch) {
87
+ return {
88
+ owner: shortMatch[1],
89
+ repo: shortMatch[2],
90
+ };
91
+ }
92
+ throw new Error('Invalid repo reference. Use:\n' +
93
+ ' - https://github.com/owner/repo\n' +
94
+ ' - owner/repo');
95
+ };
96
+ export const cloneRepo = async (prInfo, token, githubUrl) => {
97
+ const tempDir = await mkdtemp(join(tmpdir(), 'nayan-ai-'));
98
+ const baseUrl = githubUrl?.replace(/\/$/, '') || 'https://github.com';
99
+ const cloneUrl = `https://${token}@${baseUrl.replace(/^https?:\/\//, '')}/${prInfo.owner}/${prInfo.repo}.git`;
100
+ await runGit(['clone', '--depth', '100', cloneUrl, tempDir]);
101
+ await runGit(['fetch', 'origin', 'main:refs/remotes/origin/main', '--depth', '100'], tempDir);
102
+ await runGit(['fetch', 'origin', `pull/${prInfo.number}/head:pr-branch`], tempDir);
103
+ await runGit(['checkout', 'pr-branch'], tempDir);
104
+ return {
105
+ path: tempDir,
106
+ cleanup: async () => {
107
+ try {
108
+ await rm(tempDir, { recursive: true, force: true });
109
+ }
110
+ catch {
111
+ // ignore
112
+ }
113
+ },
114
+ };
115
+ };
116
+ export const cloneRepoForScan = async (repoInfo, token) => {
117
+ const tempDir = await mkdtemp(join(tmpdir(), 'nayan-ai-scan-'));
118
+ const baseUrl = repoInfo.githubUrl?.replace(/\/$/, '') || 'https://github.com';
119
+ const cloneUrl = `https://${token}@${baseUrl.replace(/^https?:\/\//, '')}/${repoInfo.owner}/${repoInfo.repo}.git`;
120
+ await runGit(['clone', '--depth', '1', cloneUrl, tempDir]);
121
+ return {
122
+ path: tempDir,
123
+ cleanup: async () => {
124
+ try {
125
+ await rm(tempDir, { recursive: true, force: true });
126
+ }
127
+ catch {
128
+ // ignore
129
+ }
130
+ },
131
+ };
132
+ };
133
+ export const getGitDiff = (repoPath) => runGit(['diff', 'origin/main...HEAD', '--unified=3'], repoPath);
134
+ export const getChangedFiles = async (repoPath) => {
135
+ const output = await runGit(['diff', 'origin/main...HEAD', '--name-only'], repoPath);
136
+ return output.split('\n').filter(Boolean);
137
+ };
138
+ const runGit = (args, cwd) => new Promise((resolve, reject) => {
139
+ const child = spawn('git', args, { cwd, stdio: ['pipe', 'pipe', 'pipe'] });
140
+ let stdout = '';
141
+ let stderr = '';
142
+ child.stdout.on('data', (data) => { stdout += data.toString(); });
143
+ child.stderr.on('data', (data) => { stderr += data.toString(); });
144
+ child.on('close', (code) => {
145
+ if (code !== 0) {
146
+ reject(new Error(`git ${args[0]} failed: ${stderr || stdout || 'Unknown error'}`));
147
+ return;
148
+ }
149
+ resolve(stdout);
150
+ });
151
+ child.on('error', reject);
152
+ });
153
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/common/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
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 const resetLogState: () => void;
15
+ export declare const processCodexEvent: (event: CodexEvent) => void;
@@ -0,0 +1,154 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ let state = {
4
+ seenFiles: new Set(),
5
+ spinner: null,
6
+ };
7
+ export const resetLogState = () => {
8
+ if (state.spinner)
9
+ state.spinner.stop();
10
+ state = { seenFiles: new Set(), spinner: null };
11
+ };
12
+ const stopSpinner = () => {
13
+ if (state.spinner) {
14
+ state.spinner.stop();
15
+ state.spinner = null;
16
+ }
17
+ };
18
+ const succeedSpinner = (text) => {
19
+ if (state.spinner) {
20
+ state.spinner.succeed(text ? chalk.green(text) : undefined);
21
+ state.spinner = null;
22
+ }
23
+ else if (text) {
24
+ console.log(chalk.green(` ✔ ${text}`));
25
+ }
26
+ };
27
+ const logAndSpin = (text) => {
28
+ if (state.spinner)
29
+ state.spinner.succeed();
30
+ state.spinner = ora({ text: chalk.cyan(text), prefixText: ' ', spinner: 'dots' }).start();
31
+ };
32
+ const wrapText = (text, maxWidth) => {
33
+ const words = text.split(' ');
34
+ const lines = [];
35
+ let currentLine = '';
36
+ for (const word of words) {
37
+ if (currentLine.length + word.length + 1 <= maxWidth) {
38
+ currentLine += (currentLine ? ' ' : '') + word;
39
+ }
40
+ else {
41
+ if (currentLine)
42
+ lines.push(currentLine);
43
+ currentLine = word;
44
+ }
45
+ }
46
+ if (currentLine)
47
+ lines.push(currentLine);
48
+ return lines;
49
+ };
50
+ const extractFilePath = (cmd) => {
51
+ if (cmd.includes('git '))
52
+ return null;
53
+ const patterns = [
54
+ /sed\s+-n\s+'[^']+'\s+([^\s|]+\.[a-z]{1,4})/i,
55
+ /nl\s+-ba\s+([^\s|]+\.[a-z]{1,4})/i,
56
+ /cat\s+([^\s|]+\.[a-z]{1,4})/i,
57
+ ];
58
+ for (const pattern of patterns) {
59
+ const match = cmd.match(pattern);
60
+ if (match?.[1] && !match[1].includes('*') && /\.[a-z]{1,4}$/i.test(match[1])) {
61
+ return match[1];
62
+ }
63
+ }
64
+ return null;
65
+ };
66
+ const handleReasoning = (text) => {
67
+ const cleanText = text.replace(/\*\*/g, '').trim();
68
+ if (!cleanText)
69
+ return;
70
+ const lines = cleanText.split('\n').filter(Boolean);
71
+ if (lines.length === 1 && cleanText.length < 80) {
72
+ logAndSpin(`💭 ${cleanText}`);
73
+ }
74
+ else {
75
+ let title = lines[0];
76
+ let details = '';
77
+ if (lines.length === 1) {
78
+ const splitMatch = cleanText.match(/^(.{30,80}?[;.])\s*(.+)$/);
79
+ if (splitMatch) {
80
+ title = splitMatch[1];
81
+ details = splitMatch[2];
82
+ }
83
+ }
84
+ else {
85
+ details = lines.slice(1).join(' ');
86
+ }
87
+ logAndSpin(`💭 ${title}`);
88
+ if (details) {
89
+ if (state.spinner) {
90
+ state.spinner.succeed();
91
+ state.spinner = null;
92
+ }
93
+ wrapText(details, 70).forEach(line => console.log(chalk.dim(` ${line}`)));
94
+ }
95
+ }
96
+ };
97
+ const handleCommandCompleted = (item) => {
98
+ if (!item)
99
+ return;
100
+ const cmd = item.command || '';
101
+ const output = item.aggregated_output || '';
102
+ if (cmd.includes('git diff') && output) {
103
+ const diffFiles = output.match(/diff --git a\/([^\s]+)/g);
104
+ if (diffFiles?.length) {
105
+ succeedSpinner(`Found ${diffFiles.length} changed files`);
106
+ }
107
+ }
108
+ if (cmd.includes('rg --files') && output) {
109
+ const files = output.trim().split('\n').filter(Boolean);
110
+ if (files.length) {
111
+ succeedSpinner(`Identified ${files.length} files to analyze`);
112
+ }
113
+ }
114
+ const fileMatch = extractFilePath(cmd);
115
+ if (fileMatch && !state.seenFiles.has(fileMatch)) {
116
+ state.seenFiles.add(fileMatch);
117
+ logAndSpin(`📄 Analyzing ${fileMatch}`);
118
+ }
119
+ };
120
+ const handleItemStarted = (event) => {
121
+ const item = event.item;
122
+ if (item?.type === 'command_execution' && item.command?.includes('git diff')) {
123
+ logAndSpin('Checking differences...');
124
+ }
125
+ };
126
+ const handleItemCompleted = (event) => {
127
+ const item = event.item;
128
+ if (!item)
129
+ return;
130
+ if (item.type === 'reasoning' && item.text) {
131
+ handleReasoning(item.text);
132
+ }
133
+ else if (item.type === 'command_execution') {
134
+ handleCommandCompleted(item);
135
+ }
136
+ else if (item.type === 'agent_message') {
137
+ succeedSpinner('Analysis complete');
138
+ }
139
+ };
140
+ export const processCodexEvent = (event) => {
141
+ switch (event.type) {
142
+ case 'thread.started':
143
+ stopSpinner();
144
+ state.spinner = ora({ text: chalk.cyan('Starting analysis...'), prefixText: ' ', spinner: 'dots' }).start();
145
+ break;
146
+ case 'item.completed':
147
+ handleItemCompleted(event);
148
+ break;
149
+ case 'item.started':
150
+ handleItemStarted(event);
151
+ break;
152
+ }
153
+ };
154
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/common/logs.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export interface PRInfo {
2
2
  owner: string;
3
3
  repo: string;
4
4
  number: number;
5
+ githubUrl?: string;
5
6
  }
6
7
  export interface PullRequest {
7
8
  number: number;
@@ -34,7 +35,7 @@ export interface ReviewComment {
34
35
  body: string;
35
36
  }
36
37
  export type LLMProvider = 'codex' | 'claude';
37
- export interface CLIOptions {
38
+ export interface ReviewOptions {
38
39
  token: string;
39
40
  verbose: boolean;
40
41
  dry: boolean;
@@ -42,3 +43,37 @@ export interface CLIOptions {
42
43
  format: string;
43
44
  llm: LLMProvider;
44
45
  }
46
+ export interface RepoInfo {
47
+ owner: string;
48
+ repo: string;
49
+ githubUrl?: string;
50
+ }
51
+ export interface ScanOptions {
52
+ token: string;
53
+ paths?: string;
54
+ format: string;
55
+ llm: LLMProvider;
56
+ verbose?: boolean;
57
+ fix?: boolean;
58
+ branch?: string;
59
+ }
60
+ export interface Vulnerability {
61
+ package: string;
62
+ version: string;
63
+ severity: 'critical' | 'high' | 'medium' | 'low';
64
+ title: string;
65
+ description?: string;
66
+ fixedIn?: string;
67
+ cve?: string;
68
+ }
69
+ export interface ProjectScanResult {
70
+ projectPath: string;
71
+ projectType: ProjectType;
72
+ vulnerabilities: Vulnerability[];
73
+ }
74
+ export type ProjectType = 'npm' | 'python' | 'go' | 'rust' | 'ruby' | 'php' | 'java' | 'dotnet';
75
+ export interface DetectedProject {
76
+ path: string;
77
+ type: ProjectType;
78
+ lockFile?: string;
79
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { LLMProvider } from './types.js';
2
+ export declare const VALID_LLM_PROVIDERS: readonly ["codex", "claude"];
3
+ export declare function checkLLMAvailability(provider: LLMProvider): void;
@@ -0,0 +1,11 @@
1
+ import { execSync } from 'child_process';
2
+ export const VALID_LLM_PROVIDERS = ['codex', 'claude'];
3
+ export function checkLLMAvailability(provider) {
4
+ if (provider === 'codex') {
5
+ execSync('npx @openai/codex --version', { stdio: 'ignore' });
6
+ }
7
+ else if (provider === 'claude') {
8
+ execSync('claude --version', { stdio: 'ignore' });
9
+ }
10
+ }
11
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAU,CAAC;AAEhE,MAAM,UAAU,oBAAoB,CAAC,QAAqB;IACxD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,QAAQ,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/D,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,QAAQ,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
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';
1
+ export { parseFiles, parsePRReference, parseRepoReference, cloneRepo, cloneRepoForScan, getGitDiff, getChangedFiles, getPullRequest, getPullRequestFiles, postReview, postComment, type GitHubConfig, type ClonedRepo, } from './common/github.js';
2
+ export { analyzeWithCodex } from './common/codex.js';
3
+ export { analyzeWithClaude } from './common/claude.js';
4
+ export { issuesToReviewComments, generateSummary } from './review/analyzer.js';
5
+ export { reviewCommand } from './review/command.js';
6
+ export { scanCommand } from './scan/command.js';
7
+ export type * from './common/types.js';