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
package/README.md CHANGED
@@ -1,21 +1,31 @@
1
1
  # Nayan AI 🤖
2
2
 
3
- A CLI tool that uses [Codex CLI](https://github.com/openai/codex) to review GitHub Pull Requests for bugs, security vulnerabilities, performance issues, error handling, edge cases, and code quality.
3
+ A CLI tool that uses [Codex](https://github.com/openai/codex) or [Claude Code](https://code.claude.com) to review GitHub Pull Requests and scan repositories for security vulnerabilities with AI-powered agentic analysis and auto-fix capabilities.
4
4
 
5
5
  ## Features
6
6
 
7
- - **🤖 Agentic Review**: Uses Codex CLI's intelligent coding agent for deep code analysis
7
+ ### PR Review
8
+ - **🤖 Agentic Review**: Uses Codex CLI or Claude Code CLI's intelligent coding agents for deep code analysis
8
9
  - **🐛 Bug Detection**: Finds logic errors, null pointer issues, race conditions, and edge cases
9
10
  - **🔐 Security Analysis**: Detects SQL injection, XSS, hardcoded secrets, and auth issues
10
11
  - **⚡ Performance Checks**: Identifies memory leaks, N+1 queries, and unnecessary computations
11
12
  - **🛡️ Error Handling**: Catches missing try/catch, unhandled promises, and silent failures
12
13
  - **✅ Test Coverage**: Checks if tests are added for new functionality
13
- - **🖥️ Local Execution**: Run reviews from your terminal, no GitHub Actions required
14
- - **🏢 Enterprise Support**: Works with GitHub Enterprise Server (auto-detected)
15
- - **🔒 Private Repos**: Full support for private repositories
16
14
  - **💬 Inline Comments**: Posts review comments directly on the relevant lines of code
17
15
  - **📊 Summary Report**: Provides an overview of all issues found
18
16
 
17
+ ### Vulnerability Scanning
18
+ - **🔍 Multi-Language Support**: Scans npm, Python, Go, Rust, Ruby, PHP, Java, and .NET projects
19
+ - **🤖 AI-Powered Analysis**: Uses Codex or Claude to detect vulnerabilities beyond native tools
20
+ - **📋 CVE Tracking**: Lists all CVE identifiers found in dependencies
21
+ - **🔧 Auto-Fix**: Generates fixes and creates PRs automatically with `--fix` flag
22
+ - **🎯 Context-Aware Severity**: Adjusts severity based on project type (bundled vs server-side)
23
+
24
+ ### General
25
+ - **🖥️ Local Execution**: Run from your terminal, no GitHub Actions / Jenkins required
26
+ - **🏢 Enterprise Support**: Works with GitHub Enterprise Server (auto-detected)
27
+ - **🔒 Private Repos**: Full support for private repositories
28
+
19
29
  ## Installation
20
30
 
21
31
  ### Prerequisites
@@ -38,20 +48,97 @@ npm install -g nayan-ai
38
48
 
39
49
  ## Usage
40
50
 
41
- ### Basic Usage
51
+ ### Review Command
52
+
53
+ Review a GitHub Pull Request for code issues:
54
+
55
+ ```bash
56
+ nayan-ai review https://github.com/owner/repo/pull/123 --token ghp_xxx
57
+ ```
58
+
59
+ #### Review Options
60
+
61
+ | Option | Description |
62
+ |--------|-------------|
63
+ | `-t, --token` | GitHub personal access token (required) |
64
+ | `-l, --llm` | LLM provider: `codex` (default) or `claude` |
65
+ | `-d, --dry` | Analyze without posting comments to GitHub |
66
+ | `-i, --inline` | Post inline comments on files instead of summary |
67
+
68
+ ### Scan Command
69
+
70
+ Scan a GitHub repository for package vulnerabilities using native tools + AI analysis:
42
71
 
43
72
  ```bash
44
- # Review a PR using URL
45
- nayan-ai https://github.com/owner/repo/pull/123 --token ghp_xxx
73
+ # Basic scan - detect and analyze all projects in the repo
74
+ nayan-ai scan https://github.com/owner/repo --token ghp_xxx
75
+
76
+ # Scan specific paths in the repo (detects all projects inside)
77
+ nayan-ai scan https://github.com/owner/repo --token ghp_xxx --paths packages/api,packages/web
78
+
79
+ # Auto-fix vulnerabilities and create a PR
80
+ nayan-ai scan https://github.com/owner/repo --token ghp_xxx --fix
81
+
82
+ # Auto-fix with custom branch name
83
+ nayan-ai scan https://github.com/owner/repo --token ghp_xxx --fix --branch nayan-ai/security-updates
46
84
  ```
47
85
 
48
- ### Options
86
+ #### Scan Options
87
+
88
+ | Option | Description |
89
+ |--------|-------------|
90
+ | `-t, --token` | GitHub personal access token (required) |
91
+ | `-l, --llm` | LLM provider: `codex` (default) or `claude` |
92
+ | `-p, --paths` | Comma-separated list of paths to scan for projects |
93
+ | `-f, --fix` | Auto-fix vulnerabilities and create a PR |
94
+ | `-b, --branch` | Branch name for fix PR (default: `nayan-ai/security-fixes-<timestamp>`) |
95
+
96
+ #### Scan Output
97
+
98
+ The scan provides:
99
+ - **Per-project vulnerabilities** grouped by severity (Critical, High, Medium, Low)
100
+ - **CVE identifiers** for each vulnerability
101
+ - **Suggested fixes** with package version updates
102
+ - **Breaking changes warnings** when applicable
103
+
104
+ #### Auto-Fix Workflow
105
+
106
+ When using `--fix`, Nayan AI will:
107
+ 1. Analyze vulnerabilities and generate fixes using AI
108
+ 2. Create a new branch with the fixes
109
+ 3. Update manifest files (package.json, requirements.txt, etc.)
110
+ 4. Commit and push changes
111
+ 5. Create a Pull Request with detailed description of all changes
112
+
113
+ #### Supported Project Types
114
+
115
+ | Type | Manifest | Lock Files | Native Scanner |
116
+ |------|----------|------------|----------------|
117
+ | **npm** | package.json | package-lock.json, yarn.lock, pnpm-lock.yaml | `npm audit` |
118
+ | **Python** | requirements.txt | Pipfile.lock, poetry.lock | `pip-audit` |
119
+ | **Go** | go.mod | go.sum | `govulncheck` |
120
+ | **Rust** | Cargo.toml | Cargo.lock | `cargo audit` |
121
+ | **Ruby** | Gemfile | Gemfile.lock | `bundle audit` |
122
+ | **PHP** | composer.json | composer.lock | `composer audit` |
123
+ | **Java** | pom.xml | - | `mvn dependency-check` |
124
+ | **.NET** | *.csproj | packages.lock.json | `dotnet list --vulnerable` |
125
+
126
+ #### Context-Aware Severity
127
+
128
+ The AI adjusts vulnerability severity based on project context:
129
+
130
+ - **Bundled/Static Projects** (React, Vue, Angular, SPAs):
131
+ - DevDependencies → LOW (not in production bundle)
132
+ - Build tools (webpack, babel, eslint) → LOW
133
+ - Only runtime deps in client bundle → HIGH
134
+
135
+ - **Server-side Projects** (Node.js APIs, Express):
136
+ - Runtime dependencies → HIGH
137
+ - DevDependencies → LOW
49
138
 
50
- | Option | Description |
51
- |--------|--------------------------------------------------------|
52
- | `-t, --token` | GitHub personal access token to access code (required) |
53
- | `-d, --dry` | Analyze without posting comments to Github |
54
- | `-i, --inline` | Post inline comments on files instead of summary |
139
+ - **Libraries** (npm/pypi packages):
140
+ - Runtime deps → HIGH (affects consumers)
141
+ - DevDependencies LOW
55
142
 
56
143
  ## License
57
144
 
package/dist/cli.js CHANGED
@@ -1,172 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
- import chalk from 'chalk';
4
- import ora from 'ora';
5
- import { GitHubClient, parseFiles, parsePRReference } from './github.js';
6
- import { issuesToReviewComments, generateSummary } from './analyzer.js';
7
- import { analyzeWithCodex } from './codex.js';
8
- import { analyzeWithClaude } from './claude.js';
9
- import { cloneRepo } from './repo.js';
10
3
  import { createRequire } from 'module';
11
- import { execSync } from 'child_process';
4
+ import { reviewCommand } from './review/command.js';
5
+ import { scanCommand } from './scan/command.js';
12
6
  const require = createRequire(import.meta.url);
13
7
  const { version } = require('../package.json');
14
- const VALID_LLM_PROVIDERS = ['codex', 'claude'];
15
8
  program
16
9
  .name('nayan-ai')
17
- .description('AI-powered PR code reviewer using Codex CLI')
18
- .version(version)
10
+ .description('AI powered code reviewer using Codex & Claude Code agents')
11
+ .version(version);
12
+ program
13
+ .command('review')
14
+ .description('Review a GitHub Pull Request')
19
15
  .argument('<pr-url>', 'GitHub PR URL (e.g., https://github.com/owner/repo/pull/123)')
20
16
  .requiredOption('-t, --token <token>', 'GitHub personal access token')
21
- .option('-v, --verbose', 'Show real-time output from Codex CLI', false)
17
+ .option('-v, --verbose', 'Show real-time output from CLI', false)
22
18
  .option('-d, --dry', 'Only analyze, don\'t post comments', false)
23
19
  .option('-i, --inline', 'Post inline comments instead of summary', false)
24
20
  .option('-l, --llm <provider>', 'LLM provider: codex (default) or claude', 'codex')
25
21
  .option('--format <format>', 'Output format: text, json', 'text')
26
- .action(run);
22
+ .action((prUrl, options) => reviewCommand(prUrl, options));
23
+ program
24
+ .command('scan')
25
+ .description('Scan a GitHub repository for package vulnerabilities using AI')
26
+ .argument('<repo-url>', 'GitHub repo URL (e.g., https://github.com/owner/repo)')
27
+ .requiredOption('-t, --token <token>', 'GitHub personal access token')
28
+ .option('-p, --paths <paths>', 'Comma-separated list of paths to scan for projects')
29
+ .option('-l, --llm <provider>', 'LLM provider: codex (default) or claude', 'codex')
30
+ .option('-v, --verbose', 'Show real-time output from CLI', false)
31
+ .option('--format <format>', 'Output format: text, json', 'text')
32
+ .option('-f, --fix', 'Auto-fix vulnerabilities and create a PR with changes', false)
33
+ .option('-b, --branch <name>', 'Branch name for fix PR', 'nayan-ai/security-fixes-' + Date.now())
34
+ .action((repoUrl, options) => scanCommand(repoUrl, options));
27
35
  program.parse();
28
- function checkLLMAvailability(provider) {
29
- if (provider === 'codex') {
30
- execSync('npx @openai/codex --version', { stdio: 'ignore' });
31
- }
32
- else if (provider === 'claude') {
33
- execSync('claude --version', { stdio: 'ignore' });
34
- }
35
- }
36
- async function run(prUrl, options) {
37
- try {
38
- // Validate --llm option
39
- if (!VALID_LLM_PROVIDERS.includes(options.llm)) {
40
- console.error(chalk.red(`Error: Invalid LLM provider '${options.llm}'. Valid options: ${VALID_LLM_PROVIDERS.join(', ')}`));
41
- process.exit(1);
42
- }
43
- // Check if the selected LLM CLI is available
44
- checkLLMAvailability(options.llm);
45
- const prInfo = parsePRReference(prUrl);
46
- const githubUrl = prInfo.githubUrl;
47
- console.log(chalk.bold.blue('\n🤖 Nayan AI - PR Reviewer'));
48
- console.log('━'.repeat(40));
49
- console.log(` Repository: ${chalk.cyan(`${prInfo.owner}/${prInfo.repo}`)}`);
50
- console.log(` PR Number: ${chalk.cyan(`#${prInfo.number}`)}`);
51
- if (githubUrl) {
52
- console.log(` GitHub: ${chalk.cyan(githubUrl)}`);
53
- }
54
- if (options.dry) {
55
- console.log(` Mode: ${chalk.yellow('Dry Run (no comments will be posted)')}`);
56
- }
57
- console.log('━'.repeat(40) + '\n');
58
- const github = new GitHubClient(options.token, githubUrl);
59
- // Fetch PR details
60
- let spinner = ora('Fetching PR details...').start();
61
- const pr = await github.getPullRequest(prInfo);
62
- spinner.succeed(`PR: ${pr.title}`);
63
- // Fetch changed files
64
- spinner = ora('Fetching changed files...').start();
65
- const files = await github.getPullRequestFiles(prInfo);
66
- const fileChanges = parseFiles(files);
67
- spinner.succeed(`Found ${fileChanges.length} files with changes`);
68
- // Clone and analyze with Codex CLI
69
- spinner = ora('Cloning repository...').start();
70
- const repo = await cloneRepo(prInfo, options.token, githubUrl);
71
- let issues;
72
- try {
73
- spinner.succeed('Repository cloned');
74
- const llmName = options.llm === 'claude' ? 'Claude Code' : 'Codex';
75
- console.log(chalk.cyan(`Running code review with ${llmName} CLI...\n`));
76
- if (options.llm === 'claude') {
77
- const claudeOpts = { verbose: options.verbose };
78
- issues = await analyzeWithClaude(repo.path, 'origin/main', claudeOpts);
79
- }
80
- else {
81
- const codexOpts = { verbose: options.verbose };
82
- issues = await analyzeWithCodex(repo.path, 'origin/main', codexOpts);
83
- }
84
- console.log(chalk.green(`\n✔ Analysis complete: ${issues.length} issues found`));
85
- }
86
- finally {
87
- await repo.cleanup();
88
- }
89
- // Display results
90
- console.log(chalk.bold('\n📋 Review Summary'));
91
- console.log('─'.repeat(41));
92
- if (options.format === 'json') {
93
- console.log(JSON.stringify(issues, null, 2));
94
- }
95
- else {
96
- printIssuesSummary(issues);
97
- }
98
- // Post to GitHub
99
- if (!options.dry) {
100
- spinner = ora('Posting review to GitHub...').start();
101
- if (options.inline) {
102
- // Post inline comments on specific lines
103
- const reviewComments = issuesToReviewComments(issues);
104
- const summary = generateSummary(issues);
105
- await github.postReview(prInfo, pr.head.sha, summary, reviewComments);
106
- spinner.succeed('Inline review posted to GitHub');
107
- }
108
- else {
109
- // Post summary as a PR-level comment (default)
110
- const summary = generateSummary(issues);
111
- await github.postComment(prInfo, summary);
112
- spinner.succeed('Review summary posted to GitHub');
113
- }
114
- }
115
- else {
116
- console.log(chalk.yellow('\nDry run mode - no comments posted to GitHub'));
117
- }
118
- console.log(chalk.green('\n✅ Review complete!\n'));
119
- }
120
- catch (error) {
121
- console.error(chalk.red('\nError:'), error instanceof Error ? error.message : error);
122
- process.exit(1);
123
- }
124
- }
125
- function printIssuesSummary(issues) {
126
- if (issues.length === 0) {
127
- console.log(chalk.green(' No issues found! The code looks good.'));
128
- return;
129
- }
130
- const bySeverity = {
131
- error: issues.filter((i) => i.severity === 'error'),
132
- warning: issues.filter((i) => i.severity === 'warning'),
133
- info: issues.filter((i) => i.severity === 'info'),
134
- };
135
- // Print errors
136
- if (bySeverity.error.length > 0) {
137
- console.log(chalk.red.bold(`\n 🔴 Errors (${bySeverity.error.length}):`));
138
- for (const issue of bySeverity.error) {
139
- const icon = issue.category === 'functionality' ? '🐛' : issue.category === 'readability' ? '📖' : '⚡';
140
- console.log(chalk.red(` ${icon} ${issue.filename}:${issue.line}`));
141
- console.log(` ${issue.message}`);
142
- if (issue.suggestion) {
143
- console.log(chalk.dim(` 💡 ${issue.suggestion}`));
144
- }
145
- }
146
- }
147
- // Print warnings
148
- if (bySeverity.warning.length > 0) {
149
- console.log(chalk.yellow.bold(`\n 🟡 Warnings (${bySeverity.warning.length}):`));
150
- for (const issue of bySeverity.warning) {
151
- const icon = issue.category === 'functionality' ? '🐛' : issue.category === 'readability' ? '📖' : '⚡';
152
- console.log(chalk.yellow(` ${icon} ${issue.filename}:${issue.line}`));
153
- console.log(` ${issue.message}`);
154
- if (issue.suggestion) {
155
- console.log(chalk.dim(` 💡 ${issue.suggestion}`));
156
- }
157
- }
158
- }
159
- // Print info
160
- if (bySeverity.info.length > 0) {
161
- console.log(chalk.blue.bold(`\n 🔵 Info (${bySeverity.info.length}):`));
162
- for (const issue of bySeverity.info) {
163
- const icon = issue.category === 'functionality' ? '🐛' : issue.category === 'readability' ? '📖' : '⚡';
164
- console.log(chalk.blue(` ${icon} ${issue.filename}:${issue.line}`));
165
- console.log(` ${issue.message}`);
166
- if (issue.suggestion) {
167
- console.log(chalk.dim(` 💡 ${issue.suggestion}`));
168
- }
169
- }
170
- }
171
- }
172
36
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,2DAA2D,CAAC;KACxE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,8BAA8B,CAAC;KAC3C,QAAQ,CAAC,UAAU,EAAE,8DAA8D,CAAC;KACpF,cAAc,CAAC,qBAAqB,EAAE,8BAA8B,CAAC;KACrE,MAAM,CAAC,eAAe,EAAE,gCAAgC,EAAE,KAAK,CAAC;KAChE,MAAM,CAAC,WAAW,EAAE,oCAAoC,EAAE,KAAK,CAAC;KAChE,MAAM,CAAC,cAAc,EAAE,yCAAyC,EAAE,KAAK,CAAC;KACxE,MAAM,CAAC,sBAAsB,EAAE,yCAAyC,EAAE,OAAO,CAAC;KAClF,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,CAAC;KAChE,MAAM,CAAC,CAAC,KAAa,EAAE,OAAsB,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAEpF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+DAA+D,CAAC;KAC5E,QAAQ,CAAC,YAAY,EAAE,uDAAuD,CAAC;KAC/E,cAAc,CAAC,qBAAqB,EAAE,8BAA8B,CAAC;KACrE,MAAM,CAAC,qBAAqB,EAAE,oDAAoD,CAAC;KACnF,MAAM,CAAC,sBAAsB,EAAE,yCAAyC,EAAE,OAAO,CAAC;KAClF,MAAM,CAAC,eAAe,EAAE,gCAAgC,EAAE,KAAK,CAAC;KAChE,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,CAAC;KAChE,MAAM,CAAC,WAAW,EAAE,uDAAuD,EAAE,KAAK,CAAC;KACnF,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,EAAE,0BAA0B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;KAChG,MAAM,CAAC,CAAC,OAAe,EAAE,OAAoB,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAEpF,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { CodeIssue } from './types.js';
2
+ export interface ClaudeOptions {
3
+ verbose?: boolean;
4
+ }
5
+ export declare const analyzeWithClaude: (repoPath: string, prompt: string, options: ClaudeOptions) => Promise<CodeIssue[]>;
6
+ export declare const analyzeWithClaudeRaw: (repoPath: string, prompt: string, options: ClaudeOptions) => Promise<any>;
@@ -0,0 +1,180 @@
1
+ import { spawn } from 'child_process';
2
+ import chalk from 'chalk';
3
+ export const analyzeWithClaude = async (repoPath, prompt, options) => {
4
+ const response = await runClaudeExec(repoPath, prompt, options);
5
+ return parseClaudeResponse(response);
6
+ };
7
+ export const analyzeWithClaudeRaw = async (repoPath, prompt, options) => {
8
+ const response = await runClaudeExec(repoPath, prompt, options);
9
+ return parseClaudeResponseRaw(response);
10
+ };
11
+ const runClaudeExec = (repoPath, prompt, options) => new Promise((resolve, reject) => {
12
+ const args = ['-p', '--output-format', 'json', prompt];
13
+ if (options.verbose) {
14
+ console.log(`\n[Claude] Running: claude ${args.slice(0, 3).join(' ')} "<prompt>"`);
15
+ console.log(`[Claude] Working directory: ${repoPath}`);
16
+ }
17
+ const startTime = Date.now();
18
+ const child = spawn('claude', args, { cwd: repoPath, stdio: ['pipe', 'pipe', 'pipe'] });
19
+ let stdout = '';
20
+ let stderr = '';
21
+ child.stdout.on('data', (data) => {
22
+ const chunk = data.toString();
23
+ stdout += chunk;
24
+ if (options.verbose) {
25
+ process.stdout.write(chunk);
26
+ }
27
+ else {
28
+ process.stdout.write(chalk.gray('.'));
29
+ }
30
+ });
31
+ child.stderr.on('data', (data) => {
32
+ const chunk = data.toString();
33
+ stderr += chunk;
34
+ if (options.verbose)
35
+ process.stderr.write(chunk);
36
+ });
37
+ child.on('close', (code) => {
38
+ if (!options.verbose)
39
+ console.log();
40
+ console.log(`\n[Claude] Completed in ${((Date.now() - startTime) / 1000).toFixed(1)}s`);
41
+ if (code !== 0) {
42
+ reject(new Error(`Claude review failed (exit ${code}): ${(stderr || stdout || 'Unknown error').slice(0, 500)}`));
43
+ return;
44
+ }
45
+ resolve(stdout);
46
+ });
47
+ child.on('error', (err) => {
48
+ if (err.code === 'ENOENT') {
49
+ reject(new Error('claude CLI not found. Install Claude Code CLI first: https://code.claude.com'));
50
+ return;
51
+ }
52
+ reject(err);
53
+ });
54
+ });
55
+ const mapIssue = (item) => ({
56
+ filename: item.filename || item.package || 'unknown',
57
+ line: item.line || 0,
58
+ category: item.category || 'functionality',
59
+ severity: item.severity || 'info',
60
+ message: item.message || item.title || item.description,
61
+ suggestion: item.suggestion || item.fixedIn,
62
+ // Preserve vulnerability-specific fields for scan command
63
+ package: item.package,
64
+ version: item.version,
65
+ title: item.title,
66
+ description: item.description,
67
+ fixedIn: item.fixedIn,
68
+ cve: item.cve,
69
+ });
70
+ const extractItems = (json) => {
71
+ if (Array.isArray(json.issues))
72
+ return json.issues;
73
+ if (Array.isArray(json.vulnerabilities))
74
+ return json.vulnerabilities;
75
+ return [];
76
+ };
77
+ const extractFixData = (text) => {
78
+ const fixMatch = text.match(/\{[\s\S]*"(?:fixes|updatedManifest)"[\s\S]*\}/);
79
+ if (!fixMatch)
80
+ return null;
81
+ try {
82
+ const parsed = JSON.parse(fixMatch[0]);
83
+ if (parsed.fixes || parsed.updatedManifest)
84
+ return parsed;
85
+ }
86
+ catch {
87
+ // ignore
88
+ }
89
+ return null;
90
+ };
91
+ const extractIssuesFromText = (text) => {
92
+ // First check for fix response
93
+ const fixData = extractFixData(text);
94
+ if (fixData) {
95
+ return [{
96
+ ...mapIssue({ message: 'Fix response' }),
97
+ _rawFixData: fixData
98
+ }];
99
+ }
100
+ const jsonMatch = text.match(/\{\s*"(?:issues|vulnerabilities)"\s*:\s*\[[\s\S]*?\]\s*\}/);
101
+ if (!jsonMatch)
102
+ return null;
103
+ try {
104
+ const parsed = JSON.parse(jsonMatch[0]);
105
+ const items = extractItems(parsed);
106
+ if (items.length > 0) {
107
+ return items.filter((item) => item.message || item.package || item.title).map(mapIssue);
108
+ }
109
+ }
110
+ catch {
111
+ // ignore
112
+ }
113
+ return null;
114
+ };
115
+ const parseClaudeResponse = (response) => {
116
+ try {
117
+ const parsed = JSON.parse(response);
118
+ const text = parsed.result || parsed.text || response;
119
+ // Check for fix response first
120
+ const fixData = extractFixData(typeof text === 'string' ? text : JSON.stringify(text));
121
+ if (fixData) {
122
+ return [{
123
+ ...mapIssue({ message: 'Fix response' }),
124
+ _rawFixData: fixData
125
+ }];
126
+ }
127
+ const issues = extractIssuesFromText(text);
128
+ if (issues)
129
+ return issues;
130
+ }
131
+ catch {
132
+ // Not valid JSON wrapper
133
+ }
134
+ const issues = extractIssuesFromText(response);
135
+ if (issues)
136
+ return issues;
137
+ if (response.trim() && !response.includes('"issues"') && !response.includes('"vulnerabilities"')) {
138
+ console.warn(chalk.yellow(`\n⚠ Warning: Claude response does not contain expected format`));
139
+ console.warn(chalk.gray(` Response preview: ${response.slice(0, 200)}...`));
140
+ }
141
+ return [];
142
+ };
143
+ const parseClaudeResponseRaw = (response) => {
144
+ try {
145
+ const parsed = JSON.parse(response);
146
+ const text = parsed.result || parsed.text || response;
147
+ // Try to parse the text as JSON
148
+ if (typeof text === 'string') {
149
+ try {
150
+ return JSON.parse(text);
151
+ }
152
+ catch {
153
+ // Text contains JSON somewhere
154
+ const jsonMatch = text.match(/\{[\s\S]*"(?:fixes|updatedManifest|issues|vulnerabilities)"[\s\S]*\}/);
155
+ if (jsonMatch) {
156
+ return JSON.parse(jsonMatch[0]);
157
+ }
158
+ }
159
+ }
160
+ // If parsed already has the structure we need
161
+ if (parsed.fixes || parsed.updatedManifest) {
162
+ return parsed;
163
+ }
164
+ }
165
+ catch {
166
+ // Not valid JSON wrapper
167
+ }
168
+ // Try to find JSON in raw response
169
+ const jsonMatch = response.match(/\{[\s\S]*"(?:fixes|updatedManifest|issues|vulnerabilities)"[\s\S]*\}/);
170
+ if (jsonMatch) {
171
+ try {
172
+ return JSON.parse(jsonMatch[0]);
173
+ }
174
+ catch {
175
+ // ignore
176
+ }
177
+ }
178
+ return null;
179
+ };
180
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/common/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CodeIssue } from './types.js';
2
+ export interface CodexOptions {
3
+ verbose?: boolean;
4
+ }
5
+ export declare const analyzeWithCodex: (repoPath: string, prompt: string, options: CodexOptions) => Promise<CodeIssue[]>;
6
+ export declare const analyzeWithCodexRaw: (repoPath: string, prompt: string, options: CodexOptions) => Promise<any>;