@codecora/cli 0.0.4 → 0.0.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.
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # CORA CLI
2
2
 
3
- > AI-powered code review before you commit.
3
+ > Catch bugs & security issues BEFORE you commit. Save 2+ hours/week on code reviews.
4
+
5
+ ![npm version](https://badge.fury.io/js/%40codecora%2Fcli.svg)
6
+ ![downloads](https://img.shields.io/npm/dm/%40codecora/cli.svg)
7
+ ![license](https://img.shields.io/npm/l/%40codecora/cli.svg)
4
8
 
5
9
  **Website:** [https://codecora.dev](https://codecora.dev) | **Docs:** [https://codecora.dev/docs/cli](https://codecora.dev/docs/cli)
6
10
 
@@ -14,9 +18,17 @@ CORA CLI brings AI code review to your local development workflow. Get instant f
14
18
  - **Git Hooks** - Automatic review on every commit
15
19
  - **Cross-platform** - Works on macOS, Linux, and Windows
16
20
 
21
+ ## Benefits
22
+
23
+ - **Save Time** - Reduce code review time by 2+ hours per week
24
+ - **Catch Bugs Early** - Find issues before they reach production
25
+ - **Security First** - Detect vulnerabilities and security risks
26
+ - **Learn Best Practices** - Get AI-powered suggestions for code improvement
27
+ - **Zero Friction** - Works with your existing Git workflow
28
+
17
29
  ## Installation
18
30
 
19
- ### Option 1: Using npm/bun (Requires Node.js 20+)
31
+ ### Using npm/bun (Requires Node.js 20+)
20
32
 
21
33
  ```bash
22
34
  # Using npm
@@ -29,15 +41,63 @@ bun install -g @codecora/cli
29
41
  ## Quick Start
30
42
 
31
43
  ```bash
32
- # 1. Login to CORA
44
+ # 1. Install CORA CLI
45
+ npm install -g @codecora/cli
46
+
47
+ # 2. Login to CORA
33
48
  cora auth login
34
49
 
35
- # 2. Review staged changes
50
+ # 3. Review staged changes
36
51
  cora review
52
+ ```
53
+
54
+ **Example Output:**
37
55
 
38
- # 3. Enable automatic pre-commit review (optional)
39
- cora enable
40
56
  ```
57
+ ✅ Review complete
58
+
59
+ Found 2 issues:
60
+
61
+ 🔴 Critical: SQL injection risk
62
+ File: src/auth.ts:45
63
+ User input not sanitized before query
64
+
65
+ 🟡 Major: Missing error handling
66
+ File: src/api.ts:12
67
+ API call lacks try-catch block
68
+
69
+ 💡 Suggestions available. Run with --include-walkthrough for details.
70
+ ```
71
+
72
+ ## Use Cases
73
+
74
+ CORA CLI is perfect for:
75
+
76
+ - **Pre-commit Hooks** - Automatically review code before every commit
77
+ - **CI/CD Pipelines** - Integrate into GitHub Actions, GitLab CI, Jenkins
78
+ - **Legacy Code Audit** - Review entire codebases with `--base` flag
79
+ - **Pull Request Reviews** - Check feature branches before merging
80
+ - **Learning Projects** - Get AI feedback on code quality and best practices
81
+
82
+ ## Why CORA vs Others?
83
+
84
+ | Feature | CORA | SonarQube | CodeClimate | DeepSource |
85
+ |---------|------|-----------|-------------|------------|
86
+ | **Setup Time** | 30 seconds | Hours | Hours | Hours |
87
+ | **Pre-commit** | ✅ Native | ❌ Plugin | ❌ Plugin | ❌ Plugin |
88
+ | **AI-Powered** | ✅ GPT-4/Claude | ❌ Rule-based | ❌ Rule-based | ❌ Rule-based |
89
+ | **Your AI Key** | ✅ Use your own | ❌ Locked in | ❌ Locked in | ❌ Locked in |
90
+ | **Privacy** | ✅ Code stays local | ⚠️ Cloud scan | ⚠️ Cloud scan | ⚠️ Cloud scan |
91
+ | **Free Tier** | ✅ 100 reviews/mo | ❌ $120/yr min | ❌ $50/yr min | ❌ Subscription |
92
+ | **Languages** | All languages | Limited | Limited | Limited |
93
+
94
+ **Key Differentiators:**
95
+ - **Fastest Setup** - Install and run in 30 seconds, no configuration needed
96
+ - **AI-Powered** - Uses latest GPT-4/Claude models, not outdated rule engines
97
+ - **Your AI Key** - Use your own OpenAI/Anthropic key, no vendor lock-in
98
+ - **Privacy-First** - Code analyzed by YOUR AI provider, we never see your code
99
+ - **Zero Maintenance** - No servers to manage, no databases to configure
100
+ - **Always Updated** - Automatically benefits from latest AI model improvements
41
101
 
42
102
  ## Usage
43
103
 
@@ -69,6 +129,12 @@ cora review --unstaged
69
129
  # Review specific files
70
130
  cora review --files src/app.ts src/utils.ts
71
131
 
132
+ # Review committed changes
133
+ cora review --base main # Review branch vs main
134
+ cora review --commits 3 # Review last 3 commits
135
+ cora review --revision-range abc..def # Review specific range
136
+ cora review --unpushed # Review unpushed commits
137
+
72
138
  # JSON output for CI/CD
73
139
  cora review --format json
74
140
  ```
@@ -100,6 +166,10 @@ cora disable # Uninstall pre-commit hook
100
166
  | `-s, --staged` | Review staged changes (default) |
101
167
  | `-u, --unstaged` | Review unstaged changes |
102
168
  | `-f, --files <files...>` | Review specific files |
169
+ | `--base <ref>` | Review changes from base ref to HEAD (e.g., "main") |
170
+ | `--revision-range <range>` | Review specific commit range (e.g., "HEAD~3..HEAD") |
171
+ | `--commits <number>` | Review last N commits |
172
+ | `--unpushed` | Review unpushed commits |
103
173
  | `--format <format>` | Output format (pretty, json, compact) |
104
174
 
105
175
  ## Configuration
@@ -120,9 +190,28 @@ Configuration is stored in `~/.codecora/`:
120
190
 
121
191
  ## CI/CD Integration
122
192
 
193
+ ### Supported Languages
194
+
195
+ CORA CLI supports code review for all programming languages including:
196
+ - JavaScript / TypeScript
197
+ - Python
198
+ - Java / Kotlin
199
+ - Go
200
+ - Rust
201
+ - PHP
202
+ - Ruby
203
+ - C# / .NET
204
+ - And more...
205
+
123
206
  ### Using API Keys (Recommended)
124
207
 
125
- For CI/CD workflows, use API Keys instead of session tokens:
208
+ For CI/CD workflows, use API Keys instead of session tokens.
209
+
210
+ **Getting an API Key:**
211
+ 1. Login to [codecora.dev](https://codecora.dev)
212
+ 2. Go to Dashboard → API Keys
213
+ 3. Click "Generate API Key"
214
+ 4. Copy the key and use in your CI/CD pipeline
126
215
 
127
216
  ```yaml
128
217
  # Example: GitHub Actions
@@ -181,11 +270,24 @@ CORA_SKIP=1 git commit -m "message"
181
270
  - A Codecora account (sign up at https://codecora.dev)
182
271
  - An OpenAI-compatible API key configured in your workspace
183
272
 
273
+ ## Pricing
274
+
275
+ - **Free Tier** - 100 reviews/month during beta
276
+ - **Pro Tier** - Coming soon
277
+ - **Enterprise** - Contact us for custom solutions
278
+
184
279
  ## License
185
280
 
186
281
  MIT © [CORA](https://codecora.dev)
187
282
 
188
283
  ## Support
189
284
 
190
- - [Documentation](https://codecora.dev/docs/cli)
191
- - [Website](https://codecora.dev)
285
+ - 📧 **Email**: support@codecora.dev
286
+ - 📚 [Documentation](https://codecora.dev/docs/cli)
287
+ - 🌐 [Website](https://codecora.dev)
288
+ - 💬 [Community Discord](https://discord.gg/codecora)
289
+
290
+ **Getting Help:**
291
+ - Check our [Documentation](https://codecora.dev/docs/cli) for detailed guides
292
+ - Join our [Discord community](https://discord.gg/codecora) for quick questions
293
+ - Email us at support@codecora.dev for technical issues
package/bin/cora.js CHANGED
@@ -84,6 +84,10 @@ program
84
84
  .option('-s, --staged', 'Review staged changes (default: true)')
85
85
  .option('-u, --unstaged', 'Review unstaged changes')
86
86
  .option('-f, --files <files...>', 'Review specific files')
87
+ .option('--base <ref>', 'Review changes from base ref to HEAD (e.g., "main", "develop")')
88
+ .option('--revision-range <range>', 'Review specific commit range (e.g., "HEAD~3..HEAD", "abc123..def456")')
89
+ .option('--commits <number>', 'Review last N commits', parseInt)
90
+ .option('--unpushed', 'Review unpushed commits')
87
91
  .option('-m, --max-tokens <number>', 'Maximum tokens to use', parseInt)
88
92
  .option('-i, --include-walkthrough', 'Include full walkthrough')
89
93
  .option('--mock', 'Mock mode for testing')
@@ -96,6 +100,10 @@ program
96
100
  branch: options.branch,
97
101
  staged: options.unstaged ? false : options.staged !== false,
98
102
  files: options.files,
103
+ base: options.base,
104
+ revisionRange: options.revisionRange,
105
+ commits: options.commits,
106
+ unpushed: options.unpushed,
99
107
  maxTokens: options.maxTokens,
100
108
  includeWalkthrough: options.includeWalkthrough,
101
109
  mock: options.mock,
@@ -48,7 +48,7 @@ export async function login(serverUrl) {
48
48
  }
49
49
  // Store session directly from server response
50
50
  await setAuthToken(authResult.token, targetServerUrl, authResult.userId, authResult.email, authResult.expiresAt);
51
- console.log(`\nSuccessfully logged in as ${authResult.email}`);
51
+ console.log(`\nSuccessfully logged in${authResult.email ? ` as ${authResult.email}` : ''}`);
52
52
  process.exit(0);
53
53
  }
54
54
  catch (error) {
@@ -171,7 +171,7 @@ function createCallbackServer() {
171
171
  const url = new URL(req.url, `http://localhost:${FIXED_PORT}`);
172
172
  const token = url.searchParams.get('token');
173
173
  const userId = url.searchParams.get('userId');
174
- const email = url.searchParams.get('email');
174
+ const email = url.searchParams.get('email'); // Optional, can be fetched via API
175
175
  const expiresAt = url.searchParams.get('expiresAt');
176
176
  const error = url.searchParams.get('error');
177
177
  if (error) {
@@ -181,7 +181,8 @@ function createCallbackServer() {
181
181
  server.close();
182
182
  return;
183
183
  }
184
- if (token && userId && email && expiresAt) {
184
+ // Email is optional - can be fetched via API after login
185
+ if (token && userId && expiresAt) {
185
186
  res.writeHead(200, { 'Content-Type': 'text/html' });
186
187
  res.end(`
187
188
  <!DOCTYPE html>
@@ -193,7 +194,7 @@ function createCallbackServer() {
193
194
  </body>
194
195
  </html>
195
196
  `);
196
- resolvePromise({ token, userId, email, expiresAt });
197
+ resolvePromise({ token, userId, email: email || undefined, expiresAt });
197
198
  server.close();
198
199
  }
199
200
  else {
@@ -36,6 +36,10 @@ export async function review(options = {}) {
36
36
  staged: options.staged !== false,
37
37
  files: options.files,
38
38
  cwd,
39
+ base: options.base,
40
+ revisionRange: options.revisionRange,
41
+ commits: options.commits,
42
+ unpushed: options.unpushed,
39
43
  });
40
44
  }
41
45
  catch (error) {
@@ -112,9 +112,11 @@ export async function setAuthToken(sessionToken, serverUrl, userId, email, expir
112
112
  serverUrl,
113
113
  expiresAt,
114
114
  },
115
- user: {
115
+ user: email ? {
116
116
  id: userId,
117
117
  email,
118
+ } : {
119
+ id: userId,
118
120
  },
119
121
  });
120
122
  }
package/dist/git/diff.js CHANGED
@@ -149,7 +149,21 @@ export function validateDiffSize(diff, maxSize = 10 * 1024 * 1024 // 10MB defaul
149
149
  * Main function to get diff based on options.
150
150
  */
151
151
  export function getReviewDiff(options) {
152
- const { staged = true, files, cwd = process.cwd() } = options;
152
+ const { staged = true, files, cwd = process.cwd(), base, revisionRange, commits, unpushed, } = options;
153
+ // Commit-based review takes precedence
154
+ if (revisionRange) {
155
+ return getCommitDiff(revisionRange, cwd);
156
+ }
157
+ if (unpushed) {
158
+ return getUnpushedDiff(cwd);
159
+ }
160
+ if (commits !== undefined) {
161
+ return getLastCommitsDiff(commits, cwd);
162
+ }
163
+ if (base) {
164
+ return getBaseDiff(base, cwd);
165
+ }
166
+ // Default behavior: staged/unstaged/files
153
167
  if (files && files.length > 0) {
154
168
  return getFilesDiff(files, staged, cwd);
155
169
  }
@@ -160,3 +174,51 @@ export function getReviewDiff(options) {
160
174
  return getUnstagedDiff(cwd);
161
175
  }
162
176
  }
177
+ /**
178
+ * Get diff between two git refs (commits, branches, tags)
179
+ *
180
+ * Examples:
181
+ * - "main...HEAD" - changes from main to current branch
182
+ * - "abc123..def456" - changes between two commits
183
+ * - "v1.0.0..HEAD" - changes since tag v1.0.0
184
+ */
185
+ export function getCommitDiff(revisionRange, cwd = process.cwd()) {
186
+ const result = execFileSafe('git', ['diff', revisionRange], { cwd });
187
+ if (result.status !== 0) {
188
+ throw new Error(`Failed to get commit diff: ${result.stderr || result.error?.message}`);
189
+ }
190
+ return result.stdout;
191
+ }
192
+ /**
193
+ * Get diff of unpushed commits
194
+ *
195
+ * Returns diff between HEAD and the remote tracking branch.
196
+ */
197
+ export function getUnpushedDiff(cwd = process.cwd()) {
198
+ // First, get the remote tracking branch
199
+ const trackingResult = execFileSafe('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], { cwd });
200
+ if (trackingResult.status !== 0) {
201
+ throw new Error('No upstream branch found. Cannot determine unpushed commits. ' +
202
+ 'Hint: Set upstream with `git push -u origin <branch>`');
203
+ }
204
+ const trackingBranch = trackingResult.stdout.trim();
205
+ return getCommitDiff(`${trackingBranch}...HEAD`, cwd);
206
+ }
207
+ /**
208
+ * Get diff of last N commits
209
+ *
210
+ * Returns diff between HEAD~N and HEAD.
211
+ */
212
+ export function getLastCommitsDiff(count, cwd = process.cwd()) {
213
+ const revisionRange = `HEAD~${count}..HEAD`;
214
+ return getCommitDiff(revisionRange, cwd);
215
+ }
216
+ /**
217
+ * Get diff from base branch to HEAD
218
+ *
219
+ * Compares current HEAD with the specified base branch.
220
+ */
221
+ export function getBaseDiff(base, cwd = process.cwd()) {
222
+ const revisionRange = `${base}...HEAD`;
223
+ return getCommitDiff(revisionRange, cwd);
224
+ }
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.0.4';
1
+ export const VERSION = '0.0.5';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codecora/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "description": "CORA CLI - AI code review before commit",
6
6
  "main": "./dist/index.js",