jstar-reviewer 2.1.1 → 2.1.4
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 +2 -2
- package/bin/jstar.js +2 -2
- package/dist/scripts/config.js +1 -1
- package/dist/scripts/gemini-embedding.js +2 -2
- package/dist/scripts/indexer.js +38 -5
- package/dist/scripts/reviewer.js +4 -3
- package/package.json +1 -1
- package/scripts/config.ts +1 -1
- package/scripts/gemini-embedding.ts +2 -2
- package/scripts/indexer.ts +42 -7
- package/scripts/reviewer.ts +4 -3
- package/setup.js +5 -5
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ curl -fsSL https://raw.githubusercontent.com/JStaRFilms/jstar-code-review/v2.0.0
|
|
|
38
38
|
### After Install:
|
|
39
39
|
|
|
40
40
|
1. **Check Config**: The tool now **auto-creates** `.env.example` and `.jstar/` when you run it.
|
|
41
|
-
2. **Add Keys**: Copy `.env.example` → `.env.local` and add your `
|
|
41
|
+
2. **Add Keys**: Copy `.env.example` → `.env.local` and add your `GEMINI_API_KEY` and `GROQ_API_KEY`.
|
|
42
42
|
3. **Index**: Run `jstar init` (or `pnpm run index:init`) to build the brain.
|
|
43
43
|
4. **Review**: Stage changes (`git add`) and run `jstar review` (or `pnpm run review`).
|
|
44
44
|
|
|
@@ -91,7 +91,7 @@ pnpm install
|
|
|
91
91
|
Create `.env.local`:
|
|
92
92
|
|
|
93
93
|
```env
|
|
94
|
-
|
|
94
|
+
GEMINI_API_KEY=your_gemini_key
|
|
95
95
|
GROQ_API_KEY=your_groq_key
|
|
96
96
|
```
|
|
97
97
|
|
package/bin/jstar.js
CHANGED
|
@@ -50,7 +50,7 @@ ${COLORS.bold}EXAMPLES:${COLORS.reset}
|
|
|
50
50
|
jstar review
|
|
51
51
|
|
|
52
52
|
${COLORS.bold}ENVIRONMENT:${COLORS.reset}
|
|
53
|
-
|
|
53
|
+
GEMINI_API_KEY Required for Gemini embeddings (or GOOGLE_API_KEY)
|
|
54
54
|
GROQ_API_KEY Required for Groq LLM reviews
|
|
55
55
|
|
|
56
56
|
${COLORS.dim}Report issues: https://github.com/JStaRFilms/jstar-code-review${COLORS.reset}
|
|
@@ -135,7 +135,7 @@ function runScript(scriptName) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
const REQUIRED_ENV_VARS = {
|
|
138
|
-
'
|
|
138
|
+
'GEMINI_API_KEY': '# Required: Gemini API key (or GOOGLE_API_KEY)\nGEMINI_API_KEY=your_gemini_api_key_here',
|
|
139
139
|
'GROQ_API_KEY': '# Required: Groq API key for LLM reviews\nGROQ_API_KEY=your_groq_api_key_here',
|
|
140
140
|
'REVIEW_MODEL_NAME': '# Optional: Override the default model\n# REVIEW_MODEL_NAME=moonshotai/kimi-k2-instruct-0905'
|
|
141
141
|
};
|
package/dist/scripts/config.js
CHANGED
|
@@ -42,7 +42,7 @@ const fs = __importStar(require("fs"));
|
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
// --- Auto-Setup Logic ---
|
|
44
44
|
const REQUIRED_ENV_VARS = {
|
|
45
|
-
'
|
|
45
|
+
'GEMINI_API_KEY': '# Required: Gemini API key (or GOOGLE_API_KEY)\nGEMINI_API_KEY=your_gemini_api_key_here',
|
|
46
46
|
'GROQ_API_KEY': '# Required: Groq API key for LLM reviews\nGROQ_API_KEY=your_groq_api_key_here',
|
|
47
47
|
'REVIEW_MODEL_NAME': '# Optional: Override the default model\n# REVIEW_MODEL_NAME=moonshotai/kimi-k2-instruct-0905'
|
|
48
48
|
};
|
|
@@ -6,9 +6,9 @@ class GeminiEmbedding {
|
|
|
6
6
|
constructor() {
|
|
7
7
|
// Stubs for BaseEmbedding compliance
|
|
8
8
|
this.embedBatchSize = 10;
|
|
9
|
-
const apiKey = process.env.GOOGLE_API_KEY;
|
|
9
|
+
const apiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
10
10
|
if (!apiKey) {
|
|
11
|
-
throw new Error("
|
|
11
|
+
throw new Error("GEMINI_API_KEY is missing from environment variables.");
|
|
12
12
|
}
|
|
13
13
|
this.genAI = new generative_ai_1.GoogleGenerativeAI(apiKey);
|
|
14
14
|
// User requested 'text-embedding-004', which has better rate limits
|
package/dist/scripts/indexer.js
CHANGED
|
@@ -42,19 +42,52 @@ const mock_llm_1 = require("./mock-llm");
|
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
const fs = __importStar(require("fs"));
|
|
44
44
|
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
+
// IMPORTANT: Import config for side effects (loads dotenv from cwd)
|
|
46
|
+
require("./config");
|
|
45
47
|
// Configuration
|
|
46
48
|
const STORAGE_DIR = path.join(process.cwd(), ".jstar", "storage");
|
|
47
|
-
|
|
49
|
+
// Smart source directory detection
|
|
50
|
+
function getSourceDir() {
|
|
51
|
+
const cwd = process.cwd();
|
|
52
|
+
// 1. Check for --path argument
|
|
53
|
+
const args = process.argv.slice(2);
|
|
54
|
+
const pathArgIndex = args.indexOf('--path');
|
|
55
|
+
if (pathArgIndex !== -1 && args[pathArgIndex + 1]) {
|
|
56
|
+
const customPath = path.resolve(cwd, args[pathArgIndex + 1]);
|
|
57
|
+
if (fs.existsSync(customPath)) {
|
|
58
|
+
return customPath;
|
|
59
|
+
}
|
|
60
|
+
console.error(chalk_1.default.red(`❌ Custom path not found: ${customPath}`));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
// 2. Try common source directories
|
|
64
|
+
const candidates = ['src', 'lib', 'app', 'scripts', '.'];
|
|
65
|
+
for (const dir of candidates) {
|
|
66
|
+
const fullPath = path.join(cwd, dir);
|
|
67
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
|
|
68
|
+
// Skip '.' if there's a more specific match
|
|
69
|
+
if (dir === '.' && candidates.slice(0, -1).some(d => fs.existsSync(path.join(cwd, d)))) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
return fullPath;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Default to cwd
|
|
76
|
+
return cwd;
|
|
77
|
+
}
|
|
48
78
|
async function main() {
|
|
49
79
|
// 0. Environment Validation
|
|
50
|
-
|
|
51
|
-
|
|
80
|
+
const geminiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
81
|
+
if (!geminiKey) {
|
|
82
|
+
console.error(chalk_1.default.red("❌ Missing GEMINI_API_KEY (or GOOGLE_API_KEY)!"));
|
|
52
83
|
console.log(chalk_1.default.yellow("\nPlease ensure you have a .env.local file. Check .env.example for a template.\n"));
|
|
53
84
|
process.exit(1);
|
|
54
85
|
}
|
|
55
86
|
const args = process.argv.slice(2);
|
|
56
87
|
const isWatch = args.includes("--watch");
|
|
88
|
+
const SOURCE_DIR = getSourceDir();
|
|
57
89
|
console.log(chalk_1.default.blue("🧠 J-Star Indexer: Scanning codebase..."));
|
|
90
|
+
console.log(chalk_1.default.dim(` Source: ${SOURCE_DIR}`));
|
|
58
91
|
// 1. Load documents (Your Code)
|
|
59
92
|
if (!fs.existsSync(SOURCE_DIR)) {
|
|
60
93
|
console.error(chalk_1.default.red(`❌ Source directory not found: ${SOURCE_DIR}`));
|
|
@@ -114,8 +147,8 @@ async function main() {
|
|
|
114
147
|
}
|
|
115
148
|
catch (e) {
|
|
116
149
|
console.error(chalk_1.default.red("❌ Indexing Failed:"), e.message);
|
|
117
|
-
if (e.message.includes("
|
|
118
|
-
console.log(chalk_1.default.yellow("👉 Tip: Make sure you have
|
|
150
|
+
if (e.message.includes("API") || e.message.includes("key")) {
|
|
151
|
+
console.log(chalk_1.default.yellow("👉 Tip: Make sure you have GEMINI_API_KEY in your .env.local file."));
|
|
119
152
|
}
|
|
120
153
|
process.exit(1);
|
|
121
154
|
}
|
package/dist/scripts/reviewer.js
CHANGED
|
@@ -49,7 +49,8 @@ const gemini_embedding_1 = require("./gemini-embedding");
|
|
|
49
49
|
const mock_llm_1 = require("./mock-llm");
|
|
50
50
|
const dashboard_1 = require("./dashboard");
|
|
51
51
|
const llamaindex_1 = require("llamaindex");
|
|
52
|
-
const
|
|
52
|
+
const geminiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
53
|
+
const google = (0, google_1.createGoogleGenerativeAI)({ apiKey: geminiKey });
|
|
53
54
|
const groq = (0, groq_1.createGroq)({ apiKey: process.env.GROQ_API_KEY });
|
|
54
55
|
const embedModel = new gemini_embedding_1.GeminiEmbedding();
|
|
55
56
|
const llm = new mock_llm_1.MockLLM();
|
|
@@ -126,10 +127,10 @@ function parseReviewResponse(text) {
|
|
|
126
127
|
async function main() {
|
|
127
128
|
console.log(chalk_1.default.blue("🕵️ J-Star Reviewer: Analyzing your changes...\n"));
|
|
128
129
|
// 0. Environment Validation
|
|
129
|
-
if (!
|
|
130
|
+
if (!geminiKey || !process.env.GROQ_API_KEY) {
|
|
130
131
|
console.error(chalk_1.default.red("❌ Missing API Keys!"));
|
|
131
132
|
console.log(chalk_1.default.yellow("\nPlease ensure you have a .env.local file with:"));
|
|
132
|
-
console.log(chalk_1.default.white("- GOOGLE_API_KEY"));
|
|
133
|
+
console.log(chalk_1.default.white("- GEMINI_API_KEY (or GOOGLE_API_KEY)"));
|
|
133
134
|
console.log(chalk_1.default.white("- GROQ_API_KEY"));
|
|
134
135
|
console.log(chalk_1.default.white("\nCheck .env.example for a template.\n"));
|
|
135
136
|
return;
|
package/package.json
CHANGED
package/scripts/config.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Severity } from "./types";
|
|
|
5
5
|
|
|
6
6
|
// --- Auto-Setup Logic ---
|
|
7
7
|
const REQUIRED_ENV_VARS = {
|
|
8
|
-
'
|
|
8
|
+
'GEMINI_API_KEY': '# Required: Gemini API key (or GOOGLE_API_KEY)\nGEMINI_API_KEY=your_gemini_api_key_here',
|
|
9
9
|
'GROQ_API_KEY': '# Required: Groq API key for LLM reviews\nGROQ_API_KEY=your_groq_api_key_here',
|
|
10
10
|
'REVIEW_MODEL_NAME': '# Optional: Override the default model\n# REVIEW_MODEL_NAME=moonshotai/kimi-k2-instruct-0905'
|
|
11
11
|
};
|
|
@@ -5,9 +5,9 @@ export class GeminiEmbedding {
|
|
|
5
5
|
private model: any;
|
|
6
6
|
|
|
7
7
|
constructor() {
|
|
8
|
-
const apiKey = process.env.GOOGLE_API_KEY;
|
|
8
|
+
const apiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
9
9
|
if (!apiKey) {
|
|
10
|
-
throw new Error("
|
|
10
|
+
throw new Error("GEMINI_API_KEY is missing from environment variables.");
|
|
11
11
|
}
|
|
12
12
|
this.genAI = new GoogleGenerativeAI(apiKey);
|
|
13
13
|
// User requested 'text-embedding-004', which has better rate limits
|
package/scripts/indexer.ts
CHANGED
|
@@ -9,25 +9,60 @@ import { MockLLM } from "./mock-llm";
|
|
|
9
9
|
import * as path from "path";
|
|
10
10
|
import * as fs from "fs";
|
|
11
11
|
import chalk from "chalk";
|
|
12
|
-
|
|
12
|
+
// IMPORTANT: Import config for side effects (loads dotenv from cwd)
|
|
13
|
+
import "./config";
|
|
13
14
|
|
|
14
15
|
// Configuration
|
|
15
16
|
const STORAGE_DIR = path.join(process.cwd(), ".jstar", "storage");
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
// Smart source directory detection
|
|
19
|
+
function getSourceDir(): string {
|
|
20
|
+
const cwd = process.cwd();
|
|
21
|
+
|
|
22
|
+
// 1. Check for --path argument
|
|
23
|
+
const args = process.argv.slice(2);
|
|
24
|
+
const pathArgIndex = args.indexOf('--path');
|
|
25
|
+
if (pathArgIndex !== -1 && args[pathArgIndex + 1]) {
|
|
26
|
+
const customPath = path.resolve(cwd, args[pathArgIndex + 1]);
|
|
27
|
+
if (fs.existsSync(customPath)) {
|
|
28
|
+
return customPath;
|
|
29
|
+
}
|
|
30
|
+
console.error(chalk.red(`❌ Custom path not found: ${customPath}`));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2. Try common source directories
|
|
35
|
+
const candidates = ['src', 'lib', 'app', 'scripts', '.'];
|
|
36
|
+
for (const dir of candidates) {
|
|
37
|
+
const fullPath = path.join(cwd, dir);
|
|
38
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
|
|
39
|
+
// Skip '.' if there's a more specific match
|
|
40
|
+
if (dir === '.' && candidates.slice(0, -1).some(d => fs.existsSync(path.join(cwd, d)))) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
return fullPath;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Default to cwd
|
|
48
|
+
return cwd;
|
|
49
|
+
}
|
|
17
50
|
|
|
18
51
|
async function main() {
|
|
19
52
|
// 0. Environment Validation
|
|
20
|
-
|
|
21
|
-
|
|
53
|
+
const geminiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
54
|
+
if (!geminiKey) {
|
|
55
|
+
console.error(chalk.red("❌ Missing GEMINI_API_KEY (or GOOGLE_API_KEY)!"));
|
|
22
56
|
console.log(chalk.yellow("\nPlease ensure you have a .env.local file. Check .env.example for a template.\n"));
|
|
23
57
|
process.exit(1);
|
|
24
58
|
}
|
|
25
59
|
|
|
26
60
|
const args = process.argv.slice(2);
|
|
27
61
|
const isWatch = args.includes("--watch");
|
|
62
|
+
const SOURCE_DIR = getSourceDir();
|
|
28
63
|
|
|
29
64
|
console.log(chalk.blue("🧠 J-Star Indexer: Scanning codebase..."));
|
|
30
|
-
|
|
65
|
+
console.log(chalk.dim(` Source: ${SOURCE_DIR}`));
|
|
31
66
|
|
|
32
67
|
// 1. Load documents (Your Code)
|
|
33
68
|
if (!fs.existsSync(SOURCE_DIR)) {
|
|
@@ -91,8 +126,8 @@ async function main() {
|
|
|
91
126
|
|
|
92
127
|
} catch (e: any) {
|
|
93
128
|
console.error(chalk.red("❌ Indexing Failed:"), e.message);
|
|
94
|
-
if (e.message.includes("
|
|
95
|
-
console.log(chalk.yellow("👉 Tip: Make sure you have
|
|
129
|
+
if (e.message.includes("API") || e.message.includes("key")) {
|
|
130
|
+
console.log(chalk.yellow("👉 Tip: Make sure you have GEMINI_API_KEY in your .env.local file."));
|
|
96
131
|
}
|
|
97
132
|
process.exit(1);
|
|
98
133
|
}
|
package/scripts/reviewer.ts
CHANGED
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
serviceContextFromDefaults
|
|
19
19
|
} from "llamaindex";
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const geminiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
22
|
+
const google = createGoogleGenerativeAI({ apiKey: geminiKey });
|
|
22
23
|
const groq = createGroq({ apiKey: process.env.GROQ_API_KEY });
|
|
23
24
|
|
|
24
25
|
const embedModel = new GeminiEmbedding();
|
|
@@ -110,10 +111,10 @@ async function main() {
|
|
|
110
111
|
console.log(chalk.blue("🕵️ J-Star Reviewer: Analyzing your changes...\n"));
|
|
111
112
|
|
|
112
113
|
// 0. Environment Validation
|
|
113
|
-
if (!
|
|
114
|
+
if (!geminiKey || !process.env.GROQ_API_KEY) {
|
|
114
115
|
console.error(chalk.red("❌ Missing API Keys!"));
|
|
115
116
|
console.log(chalk.yellow("\nPlease ensure you have a .env.local file with:"));
|
|
116
|
-
console.log(chalk.white("- GOOGLE_API_KEY"));
|
|
117
|
+
console.log(chalk.white("- GEMINI_API_KEY (or GOOGLE_API_KEY)"));
|
|
117
118
|
console.log(chalk.white("- GROQ_API_KEY"));
|
|
118
119
|
console.log(chalk.white("\nCheck .env.example for a template.\n"));
|
|
119
120
|
return;
|
package/setup.js
CHANGED
|
@@ -67,8 +67,8 @@ const SCRIPTS = {
|
|
|
67
67
|
const ENV_EXAMPLE = `# J-Star Code Reviewer Configuration
|
|
68
68
|
# Copy this to .env.local and fill in your keys
|
|
69
69
|
|
|
70
|
-
# Required:
|
|
71
|
-
|
|
70
|
+
# Required: Gemini API key (or GOOGLE_API_KEY)
|
|
71
|
+
GEMINI_API_KEY=your_gemini_api_key_here
|
|
72
72
|
|
|
73
73
|
# Required: Groq API key for LLM reviews
|
|
74
74
|
GROQ_API_KEY=your_groq_api_key_here
|
|
@@ -115,7 +115,7 @@ async function main() {
|
|
|
115
115
|
|
|
116
116
|
// HARDCODED: Tagged release URL - NOT configurable for security
|
|
117
117
|
// To update, modify this constant and publish a new version of setup.js
|
|
118
|
-
const BASE_URL = 'https://raw.githubusercontent.com/JStaRFilms/jstar-code-review/v2.1.
|
|
118
|
+
const BASE_URL = 'https://raw.githubusercontent.com/JStaRFilms/jstar-code-review/v2.1.4';
|
|
119
119
|
|
|
120
120
|
// Validate URL matches our exact expected pattern (defense in depth)
|
|
121
121
|
function isValidUrl(url) {
|
|
@@ -272,7 +272,7 @@ async function main() {
|
|
|
272
272
|
// 6. Update .env.example (intelligently merge, don't override)
|
|
273
273
|
const envExamplePath = path.join(cwd, '.env.example');
|
|
274
274
|
const REQUIRED_ENV_VARS = {
|
|
275
|
-
'
|
|
275
|
+
'GEMINI_API_KEY': '# Required: Gemini API key (or GOOGLE_API_KEY)\nGEMINI_API_KEY=your_gemini_api_key_here',
|
|
276
276
|
'GROQ_API_KEY': '# Required: Groq API key for LLM reviews\nGROQ_API_KEY=your_groq_api_key_here',
|
|
277
277
|
'REVIEW_MODEL_NAME': '# Optional: Override the default model\n# REVIEW_MODEL_NAME=moonshotai/kimi-k2-instruct-0905'
|
|
278
278
|
};
|
|
@@ -355,7 +355,7 @@ async function main() {
|
|
|
355
355
|
console.log('\n🎉 J-Star Code Reviewer installed!\n');
|
|
356
356
|
console.log('Next steps:');
|
|
357
357
|
console.log(' 1. Copy .env.example to .env.local');
|
|
358
|
-
console.log(' 2. Add your
|
|
358
|
+
console.log(' 2. Add your GEMINI_API_KEY and GROQ_API_KEY');
|
|
359
359
|
console.log(' 3. Run: pnpm run index:init');
|
|
360
360
|
console.log(' 4. Stage changes and run: pnpm run review');
|
|
361
361
|
console.log('\n' + '─'.repeat(50) + '\n');
|