@vortex-ai/cli 0.1.4 → 0.1.45
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/.turbo/turbo-build.log +6 -6
- package/README.md +9 -2
- package/dist/index.js +1073 -947
- package/dist/index.mjs +1065 -939
- package/package.json +5 -3
- package/schema.prisma +70 -0
- package/src/commands/config.ts +73 -0
- package/src/index.ts +26 -1
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vortex-ai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "Vortex CLI - The main entry point",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"vortex": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "tsup src/index.ts --format cjs,esm --external @xenova/transformers",
|
|
10
|
+
"build": "tsup src/index.ts --format cjs,esm --external @xenova/transformers && cp ../db/prisma/schema.prisma ./schema.prisma",
|
|
11
11
|
"dev": "tsx src/index.ts",
|
|
12
12
|
"watch": "tsup src/index.ts --format cjs,esm --watch",
|
|
13
13
|
"lint": "eslint .",
|
|
14
|
-
"check-types": "tsc --noEmit"
|
|
14
|
+
"check-types": "tsc --noEmit",
|
|
15
|
+
"postinstall": "node -e \"const fs=require('fs'); if(fs.existsSync('./schema.prisma')){require('child_process').execSync('npx prisma generate --schema=./schema.prisma', {stdio:'inherit'})}\""
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"@octokit/rest": "^22.0.1",
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
"@google/genai": "^2.5.0",
|
|
20
21
|
"groq-sdk": "^1.2.1",
|
|
21
22
|
"@prisma/client": "^5.14.0",
|
|
23
|
+
"prisma": "^5.14.0",
|
|
22
24
|
"ignore": "^7.0.5",
|
|
23
25
|
"minisearch": "^7.2.0",
|
|
24
26
|
"@xenova/transformers": "^2.17.2",
|
package/schema.prisma
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
datasource db {
|
|
2
|
+
provider = "sqlite"
|
|
3
|
+
url = "file:./vortex.db"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
generator client {
|
|
7
|
+
provider = "prisma-client-js"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
model Chunk {
|
|
11
|
+
id String @id
|
|
12
|
+
file String
|
|
13
|
+
language String
|
|
14
|
+
name String
|
|
15
|
+
symbolPath String
|
|
16
|
+
kind String
|
|
17
|
+
parent String?
|
|
18
|
+
isExported Boolean
|
|
19
|
+
isAsync Boolean
|
|
20
|
+
signature String?
|
|
21
|
+
dependencies String // Stringified JSON array
|
|
22
|
+
startLine Int
|
|
23
|
+
endLine Int
|
|
24
|
+
hash String
|
|
25
|
+
content String
|
|
26
|
+
embedding String? // Stringified JSON array of floats
|
|
27
|
+
createdAt DateTime @default(now())
|
|
28
|
+
updatedAt DateTime @updatedAt
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Persistent memory entries for architectural decisions, known bugs,
|
|
32
|
+
/// and review summaries. Enables Vortex to recall past context.
|
|
33
|
+
model Memory {
|
|
34
|
+
id String @id @default(cuid())
|
|
35
|
+
type String // "review_summary" | "architectural_decision" | "known_bug"
|
|
36
|
+
content String // The actual memory text
|
|
37
|
+
source String // e.g., "PR #42", "issue #15", "manual"
|
|
38
|
+
tags String // JSON array of tags for search
|
|
39
|
+
embedding String? // Stringified JSON array for vector search over memories
|
|
40
|
+
createdAt DateTime @default(now())
|
|
41
|
+
updatedAt DateTime @updatedAt
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Historical review records for tracking past PR reviews.
|
|
45
|
+
/// Enables "Have we seen this pattern before?" queries.
|
|
46
|
+
model ReviewHistory {
|
|
47
|
+
id String @id @default(cuid())
|
|
48
|
+
prNumber Int
|
|
49
|
+
owner String
|
|
50
|
+
repo String
|
|
51
|
+
verdict String // SAFE_TO_MERGE | REQUIRES_CHANGES | NEEDS_DISCUSSION
|
|
52
|
+
summary String // Short summary of the review
|
|
53
|
+
findings String // JSON - full structured findings
|
|
54
|
+
createdAt DateTime @default(now())
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// Cache for LLM responses to reduce latency and API cost
|
|
58
|
+
model LLMCache {
|
|
59
|
+
key String @id
|
|
60
|
+
model String
|
|
61
|
+
response String
|
|
62
|
+
|
|
63
|
+
promptHash String
|
|
64
|
+
contextHash String
|
|
65
|
+
commitHash String?
|
|
66
|
+
|
|
67
|
+
createdAt DateTime @default(now())
|
|
68
|
+
lastAccessedAt DateTime @default(now())
|
|
69
|
+
hitCount Int @default(0)
|
|
70
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as dotenv from "dotenv";
|
|
5
|
+
|
|
6
|
+
const envPath = path.resolve(os.homedir(), ".vortexenv");
|
|
7
|
+
|
|
8
|
+
function readEnv(): Record<string, string> {
|
|
9
|
+
if (!fs.existsSync(envPath)) return {};
|
|
10
|
+
const content = fs.readFileSync(envPath, "utf-8");
|
|
11
|
+
return dotenv.parse(content);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function writeEnv(env: Record<string, string>) {
|
|
15
|
+
const content = Object.entries(env)
|
|
16
|
+
.map(([k, v]) => `${k}="${v.replace(/"/g, '\\"')}"`)
|
|
17
|
+
.join("\n");
|
|
18
|
+
fs.writeFileSync(envPath, content + "\n", { mode: 0o600 });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function configSet(provider: string, value: string) {
|
|
22
|
+
const { default: chalk } = await import("chalk");
|
|
23
|
+
|
|
24
|
+
const providerUpper = provider.toUpperCase();
|
|
25
|
+
let envKey = "";
|
|
26
|
+
|
|
27
|
+
if (providerUpper === "GEMINI") {
|
|
28
|
+
envKey = "GEMINI_API_KEY";
|
|
29
|
+
} else if (providerUpper === "GROQ") {
|
|
30
|
+
envKey = "GROQ_API_KEY";
|
|
31
|
+
} else {
|
|
32
|
+
console.log(chalk.red(`Invalid option: ${chalk.bold(provider)}. Supported options are 'gemini' and 'groq'.`));
|
|
33
|
+
console.log(chalk.gray(`Usage: vortex config set gemini <your-key>`));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const env = readEnv();
|
|
38
|
+
env[envKey] = value;
|
|
39
|
+
writeEnv(env);
|
|
40
|
+
console.log(chalk.green(`✓ Successfully set ${chalk.bold(envKey)}`));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function configGet(key: string) {
|
|
44
|
+
const { default: chalk } = await import("chalk");
|
|
45
|
+
const env = readEnv();
|
|
46
|
+
if (env[key]) {
|
|
47
|
+
console.log(env[key]);
|
|
48
|
+
} else {
|
|
49
|
+
console.log(chalk.gray(`Key ${chalk.bold(key)} is not set.`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function configList() {
|
|
54
|
+
const { default: chalk } = await import("chalk");
|
|
55
|
+
const env = readEnv();
|
|
56
|
+
const keys = Object.keys(env);
|
|
57
|
+
if (keys.length === 0) {
|
|
58
|
+
console.log(chalk.gray("No configuration values set in ~/.vortexenv"));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(chalk.blue.bold("\nVortex Global Configuration:\n"));
|
|
63
|
+
for (const [k, v] of Object.entries(env)) {
|
|
64
|
+
let masked = "***";
|
|
65
|
+
if (v.length > 10) {
|
|
66
|
+
masked = `${v.substring(0, 4)}...${v.substring(v.length - 4)}`;
|
|
67
|
+
} else if (v.length > 0) {
|
|
68
|
+
masked = v;
|
|
69
|
+
}
|
|
70
|
+
console.log(` ${chalk.cyan.bold(k)}: ${chalk.gray(masked)}`);
|
|
71
|
+
}
|
|
72
|
+
console.log(`\nLocation: ${chalk.gray(envPath)}\n`);
|
|
73
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,9 @@ import * as path from "path";
|
|
|
5
5
|
import * as dotenv from "dotenv";
|
|
6
6
|
import * as os from "os";
|
|
7
7
|
|
|
8
|
+
// Suppress dotenv logging
|
|
9
|
+
process.env.DOTENV_CONFIG_QUIET = "true";
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
const monorepoEnv = path.resolve(__dirname, "../../../.env");
|
|
10
13
|
if (require("fs").existsSync(monorepoEnv)) {
|
|
@@ -39,13 +42,16 @@ import { analyzeCommand } from "./commands/analyze";
|
|
|
39
42
|
import { solveCommand } from "./commands/solve";
|
|
40
43
|
import { solveIssueCommand } from "./commands/solve-issue";
|
|
41
44
|
import { cacheCommand } from "./commands/cache";
|
|
45
|
+
import { configSet, configGet, configList } from "./commands/config";
|
|
42
46
|
|
|
43
47
|
const program = new Command();
|
|
44
48
|
|
|
49
|
+
const { version } = require("../package.json");
|
|
50
|
+
|
|
45
51
|
program
|
|
46
52
|
.name("vortex")
|
|
47
53
|
.description("Developer Intelligence & PR Review Engine")
|
|
48
|
-
.version(
|
|
54
|
+
.version(version);
|
|
49
55
|
|
|
50
56
|
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
51
57
|
if (actionCommand.opts().cache === false) {
|
|
@@ -135,6 +141,25 @@ program
|
|
|
135
141
|
.option("--no-cache", "Disable LLM response caching")
|
|
136
142
|
.action(analyzeCommand);
|
|
137
143
|
|
|
144
|
+
const configCmd = program
|
|
145
|
+
.command("config")
|
|
146
|
+
.description("Manage global configuration and API keys");
|
|
147
|
+
|
|
148
|
+
configCmd
|
|
149
|
+
.command("set <provider> <key>")
|
|
150
|
+
.description("Set an API key for a specific provider (gemini or groq)")
|
|
151
|
+
.action(configSet);
|
|
152
|
+
|
|
153
|
+
configCmd
|
|
154
|
+
.command("get <key>")
|
|
155
|
+
.description("Get a global configuration value")
|
|
156
|
+
.action(configGet);
|
|
157
|
+
|
|
158
|
+
configCmd
|
|
159
|
+
.command("list")
|
|
160
|
+
.description("List all global configuration values")
|
|
161
|
+
.action(configList);
|
|
162
|
+
|
|
138
163
|
program.addCommand(cacheCommand);
|
|
139
164
|
|
|
140
165
|
program.parse();
|