create-rag-app 0.1.0 ā 0.1.2
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 +53 -49
- package/bin/cli.js +7 -7
- package/package.json +9 -1
- package/src/index.js +65 -65
- package/src/prompts.js +66 -66
- package/src/utils.js +62 -62
- package/templates/nextjs-rag/.env.example +13 -13
- package/templates/nextjs-rag/documents/readme.txt +1 -1
- package/templates/nextjs-rag/jsconfig.json +15 -15
- package/templates/nextjs-rag/next.config.mjs +7 -7
- package/templates/nextjs-rag/package.json +33 -33
- package/templates/nextjs-rag/postcss.config.js +6 -6
- package/templates/nextjs-rag/scripts/ingest.js +25 -25
- package/templates/nextjs-rag/src/app/api/chat/route.js +52 -52
- package/templates/nextjs-rag/src/app/api/ingest/route.js +51 -51
- package/templates/nextjs-rag/src/app/globals.css +43 -43
- package/templates/nextjs-rag/src/app/layout.js +17 -17
- package/templates/nextjs-rag/src/app/page.js +352 -352
- package/templates/nextjs-rag/src/lib/ingest.js +123 -123
- package/templates/nextjs-rag/src/lib/llm.js +54 -54
- package/templates/nextjs-rag/tailwind.config.js +18 -18
package/README.md
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
|
-
# Create RAG App
|
|
2
|
-
|
|
3
|
-
Scaffold a production-ready RAG (Retrieval Augmented Generation) application in seconds.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
create-rag-app my-ai-project
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
# Create RAG App
|
|
2
|
+
|
|
3
|
+
Scaffold a production-ready RAG (Retrieval Augmented Generation) application in seconds.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/create-rag-app)
|
|
6
|
+
[](https://www.npmjs.com/package/create-rag-app)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- š **Next.js & React**: Modern frontend with Tailwind setup.
|
|
12
|
+
- š¦ **LangChain**: Best-in-class RAG pipeline.
|
|
13
|
+
- šļø **ChromaDB**: Built-in local vector database.
|
|
14
|
+
- š¤ **Multi-LLM Support**: Switch between OpenAI, Groq, and Ollama.
|
|
15
|
+
- š **Document Ingestion**: Simple script to index PDFs and Text files.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Run directly with npx
|
|
21
|
+
npx create-rag-app my-ai-project
|
|
22
|
+
|
|
23
|
+
# Or install globally
|
|
24
|
+
npm install -g create-rag-app
|
|
25
|
+
create-rag-app my-ai-project
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Structure Result
|
|
29
|
+
|
|
30
|
+
The created app will have:
|
|
31
|
+
|
|
32
|
+
- `src/app`: User Interface (Chat)
|
|
33
|
+
- `src/lib`: RAG Utilities
|
|
34
|
+
- `scripts/ingest.js`: Document processor
|
|
35
|
+
- `documents/`: Folder to drop your knowledge base
|
|
36
|
+
|
|
37
|
+
## Development
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Clone the repo
|
|
41
|
+
git clone https://github.com/your-username/create-rag-app.git
|
|
42
|
+
|
|
43
|
+
# Install dependencies
|
|
44
|
+
npm install
|
|
45
|
+
|
|
46
|
+
# Test locally
|
|
47
|
+
npm link
|
|
48
|
+
create-rag-app test-project
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
package/bin/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { main } from "../src/index.js";
|
|
4
|
-
|
|
5
|
-
main().catch((err) => {
|
|
6
|
-
console.error(err);
|
|
7
|
-
process.exit(1);
|
|
8
|
-
});
|
|
2
|
+
|
|
3
|
+
import { main } from "../src/index.js";
|
|
4
|
+
|
|
5
|
+
main().catch((err) => {
|
|
6
|
+
console.error(err);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-rag-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Scaffold a new RAG application",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,14 @@
|
|
|
24
24
|
"chroma",
|
|
25
25
|
"ai"
|
|
26
26
|
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/itwaasyou/create-rag-app.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/itwaasyou/create-rag-app",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/itwaasyou/create-rag-app/issues"
|
|
34
|
+
},
|
|
27
35
|
"license": "MIT",
|
|
28
36
|
"dependencies": {
|
|
29
37
|
"chalk": "^5.6.2",
|
package/src/index.js
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { Command } from "commander";
|
|
5
|
-
import { getOptions } from "./prompts.js";
|
|
6
|
-
import { checkDir, copyTemplate, installDependencies } from "./utils.js";
|
|
7
|
-
|
|
8
|
-
const packageJson = JSON.parse(
|
|
9
|
-
await fs.readFile(new URL("../package.json", import.meta.url))
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export async function main() {
|
|
13
|
-
console.log(chalk.bold.cyan("\nš Welcome to Create RAG App!\n"));
|
|
14
|
-
|
|
15
|
-
let projectName;
|
|
16
|
-
|
|
17
|
-
const program = new Command(packageJson.name)
|
|
18
|
-
.version(packageJson.version)
|
|
19
|
-
.arguments('[project-directory]')
|
|
20
|
-
.usage(`${chalk.green('[project-directory]')} [options]`)
|
|
21
|
-
.action((name) => {
|
|
22
|
-
projectName = name;
|
|
23
|
-
})
|
|
24
|
-
.parse(process.argv);
|
|
25
|
-
|
|
26
|
-
const options = await getOptions(projectName);
|
|
27
|
-
const projectPath = path.resolve(process.cwd(), options.projectName);
|
|
28
|
-
|
|
29
|
-
console.log(`\nCreating a new RAG app in: ${chalk.green(projectPath)}\n`);
|
|
30
|
-
|
|
31
|
-
// Ensure directory doesn't exist
|
|
32
|
-
checkDir(projectPath);
|
|
33
|
-
|
|
34
|
-
// Copy template
|
|
35
|
-
// We need to map the template option to a folder name
|
|
36
|
-
// The 'value' in prompts.js choices is 'nextjs-rag', so ensure that folder exists in templates/
|
|
37
|
-
const templateName = options.template;
|
|
38
|
-
await copyTemplate(templateName, projectPath);
|
|
39
|
-
|
|
40
|
-
// Configure Environment Variables
|
|
41
|
-
const envExamplePath = path.join(projectPath, ".env.example");
|
|
42
|
-
const envPath = path.join(projectPath, ".env");
|
|
43
|
-
|
|
44
|
-
if (await fs.pathExists(envExamplePath)) {
|
|
45
|
-
await fs.copy(envExamplePath, envPath);
|
|
46
|
-
console.log(chalk.green("ā Created .env file from example"));
|
|
47
|
-
|
|
48
|
-
// Inject selected provider config
|
|
49
|
-
let envContent = await fs.readFile(envPath, "utf-8");
|
|
50
|
-
envContent += `\n# Auto-generated config\n`;
|
|
51
|
-
envContent += `LLM_PROVIDER=${options.provider}\n`;
|
|
52
|
-
envContent += `VECTOR_DB=${options.vectorDb}\n`;
|
|
53
|
-
await fs.writeFile(envPath, envContent);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Install Dependencies (user requested automatic installation)
|
|
57
|
-
await installDependencies(projectPath);
|
|
58
|
-
|
|
59
|
-
// Final Success Message
|
|
60
|
-
console.log(chalk.bold.green("\nš Success! Your RAG app is ready."));
|
|
61
|
-
console.log(chalk.yellow("\nNext steps:"));
|
|
62
|
-
console.log(chalk.cyan(` cd ${options.projectName}`));
|
|
63
|
-
console.log(chalk.cyan(` npm run dev`));
|
|
64
|
-
console.log("");
|
|
65
|
-
}
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { getOptions } from "./prompts.js";
|
|
6
|
+
import { checkDir, copyTemplate, installDependencies } from "./utils.js";
|
|
7
|
+
|
|
8
|
+
const packageJson = JSON.parse(
|
|
9
|
+
await fs.readFile(new URL("../package.json", import.meta.url))
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export async function main() {
|
|
13
|
+
console.log(chalk.bold.cyan("\nš Welcome to Create RAG App!\n"));
|
|
14
|
+
|
|
15
|
+
let projectName;
|
|
16
|
+
|
|
17
|
+
const program = new Command(packageJson.name)
|
|
18
|
+
.version(packageJson.version)
|
|
19
|
+
.arguments('[project-directory]')
|
|
20
|
+
.usage(`${chalk.green('[project-directory]')} [options]`)
|
|
21
|
+
.action((name) => {
|
|
22
|
+
projectName = name;
|
|
23
|
+
})
|
|
24
|
+
.parse(process.argv);
|
|
25
|
+
|
|
26
|
+
const options = await getOptions(projectName);
|
|
27
|
+
const projectPath = path.resolve(process.cwd(), options.projectName);
|
|
28
|
+
|
|
29
|
+
console.log(`\nCreating a new RAG app in: ${chalk.green(projectPath)}\n`);
|
|
30
|
+
|
|
31
|
+
// Ensure directory doesn't exist
|
|
32
|
+
checkDir(projectPath);
|
|
33
|
+
|
|
34
|
+
// Copy template
|
|
35
|
+
// We need to map the template option to a folder name
|
|
36
|
+
// The 'value' in prompts.js choices is 'nextjs-rag', so ensure that folder exists in templates/
|
|
37
|
+
const templateName = options.template;
|
|
38
|
+
await copyTemplate(templateName, projectPath);
|
|
39
|
+
|
|
40
|
+
// Configure Environment Variables
|
|
41
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
42
|
+
const envPath = path.join(projectPath, ".env");
|
|
43
|
+
|
|
44
|
+
if (await fs.pathExists(envExamplePath)) {
|
|
45
|
+
await fs.copy(envExamplePath, envPath);
|
|
46
|
+
console.log(chalk.green("ā Created .env file from example"));
|
|
47
|
+
|
|
48
|
+
// Inject selected provider config
|
|
49
|
+
let envContent = await fs.readFile(envPath, "utf-8");
|
|
50
|
+
envContent += `\n# Auto-generated config\n`;
|
|
51
|
+
envContent += `LLM_PROVIDER=${options.provider}\n`;
|
|
52
|
+
envContent += `VECTOR_DB=${options.vectorDb}\n`;
|
|
53
|
+
await fs.writeFile(envPath, envContent);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Install Dependencies (user requested automatic installation)
|
|
57
|
+
await installDependencies(projectPath);
|
|
58
|
+
|
|
59
|
+
// Final Success Message
|
|
60
|
+
console.log(chalk.bold.green("\nš Success! Your RAG app is ready."));
|
|
61
|
+
console.log(chalk.yellow("\nNext steps:"));
|
|
62
|
+
console.log(chalk.cyan(` cd ${options.projectName}`));
|
|
63
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
64
|
+
console.log("");
|
|
65
|
+
}
|
package/src/prompts.js
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
import inquirer from "inquirer";
|
|
3
|
-
|
|
4
|
-
export async function getOptions(initialProjectName) {
|
|
5
|
-
let questions = [
|
|
6
|
-
{
|
|
7
|
-
type: "input",
|
|
8
|
-
name: "projectName",
|
|
9
|
-
message: "What is your project named?",
|
|
10
|
-
default: "my-rag-app",
|
|
11
|
-
validate: (input) => {
|
|
12
|
-
if (/^([a-z0-9\-\_\.]+)$/.test(input)) return true;
|
|
13
|
-
return "Project name may only include letters, numbers, dashes, and underscores.";
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
type: "list",
|
|
18
|
-
name: "template",
|
|
19
|
-
message: "Which template would you like to use?",
|
|
20
|
-
choices: [
|
|
21
|
-
{ name: "Next.js + LangChain + ChromaDB (Recommended)", value: "nextjs-rag" },
|
|
22
|
-
{ name: "Express API + PDF Processor (Backend Only)", value: "express-rag" }, // Future scope
|
|
23
|
-
],
|
|
24
|
-
default: "nextjs-rag",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
type: "list",
|
|
28
|
-
name: "provider",
|
|
29
|
-
message: "Which LLM provider do you want configured?",
|
|
30
|
-
choices: [
|
|
31
|
-
{ name: "OpenAI (GPT-4o, GPT-3.5)", value: "openai" },
|
|
32
|
-
{ name: "Groq (Llama 3, Mixtral - Fast!)", value: "groq" },
|
|
33
|
-
{ name: "Ollama (Local Models)", value: "ollama" },
|
|
34
|
-
{ name: "Gemini (Google DeepMind)", value: "gemini" },
|
|
35
|
-
],
|
|
36
|
-
default: "openai",
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: "list",
|
|
40
|
-
name: "vectorDb",
|
|
41
|
-
message: "Which Vector Database do you want to use?",
|
|
42
|
-
choices: [
|
|
43
|
-
{ name: "ChromaDB (Local)", value: "chroma" },
|
|
44
|
-
{ name: "Supabase pgvector (Cloud)", value: "supabase" },
|
|
45
|
-
],
|
|
46
|
-
default: "chroma",
|
|
47
|
-
},
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
if (initialProjectName) {
|
|
51
|
-
if (/^([a-z0-9\-\_\.]+)$/.test(initialProjectName)) {
|
|
52
|
-
// Valid project name provided via CLI, skip the prompt
|
|
53
|
-
questions = questions.filter(q => q.name !== "projectName");
|
|
54
|
-
} else {
|
|
55
|
-
console.log("ā Invalid project name provided via CLI.");
|
|
56
|
-
initialProjectName = null; // Force prompt
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const answers = await inquirer.prompt(questions);
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
projectName: initialProjectName || answers.projectName,
|
|
64
|
-
...answers
|
|
65
|
-
};
|
|
66
|
-
}
|
|
1
|
+
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
|
|
4
|
+
export async function getOptions(initialProjectName) {
|
|
5
|
+
let questions = [
|
|
6
|
+
{
|
|
7
|
+
type: "input",
|
|
8
|
+
name: "projectName",
|
|
9
|
+
message: "What is your project named?",
|
|
10
|
+
default: "my-rag-app",
|
|
11
|
+
validate: (input) => {
|
|
12
|
+
if (/^([a-z0-9\-\_\.]+)$/.test(input)) return true;
|
|
13
|
+
return "Project name may only include letters, numbers, dashes, and underscores.";
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
type: "list",
|
|
18
|
+
name: "template",
|
|
19
|
+
message: "Which template would you like to use?",
|
|
20
|
+
choices: [
|
|
21
|
+
{ name: "Next.js + LangChain + ChromaDB (Recommended)", value: "nextjs-rag" },
|
|
22
|
+
{ name: "Express API + PDF Processor (Backend Only)", value: "express-rag" }, // Future scope
|
|
23
|
+
],
|
|
24
|
+
default: "nextjs-rag",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: "list",
|
|
28
|
+
name: "provider",
|
|
29
|
+
message: "Which LLM provider do you want configured?",
|
|
30
|
+
choices: [
|
|
31
|
+
{ name: "OpenAI (GPT-4o, GPT-3.5)", value: "openai" },
|
|
32
|
+
{ name: "Groq (Llama 3, Mixtral - Fast!)", value: "groq" },
|
|
33
|
+
{ name: "Ollama (Local Models)", value: "ollama" },
|
|
34
|
+
{ name: "Gemini (Google DeepMind)", value: "gemini" },
|
|
35
|
+
],
|
|
36
|
+
default: "openai",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "list",
|
|
40
|
+
name: "vectorDb",
|
|
41
|
+
message: "Which Vector Database do you want to use?",
|
|
42
|
+
choices: [
|
|
43
|
+
{ name: "ChromaDB (Local)", value: "chroma" },
|
|
44
|
+
{ name: "Supabase pgvector (Cloud)", value: "supabase" },
|
|
45
|
+
],
|
|
46
|
+
default: "chroma",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
if (initialProjectName) {
|
|
51
|
+
if (/^([a-z0-9\-\_\.]+)$/.test(initialProjectName)) {
|
|
52
|
+
// Valid project name provided via CLI, skip the prompt
|
|
53
|
+
questions = questions.filter(q => q.name !== "projectName");
|
|
54
|
+
} else {
|
|
55
|
+
console.log("ā Invalid project name provided via CLI.");
|
|
56
|
+
initialProjectName = null; // Force prompt
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const answers = await inquirer.prompt(questions);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
projectName: initialProjectName || answers.projectName,
|
|
64
|
+
...answers
|
|
65
|
+
};
|
|
66
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import { exec } from "child_process";
|
|
6
|
-
import util from "util";
|
|
7
|
-
import ora from "ora";
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = path.dirname(__filename);
|
|
12
|
-
const execAsync = util.promisify(exec);
|
|
13
|
-
|
|
14
|
-
export function checkDir(targetPath) {
|
|
15
|
-
if (fs.existsSync(targetPath)) {
|
|
16
|
-
console.error(chalk.red(`\nā Error: Directory ${path.basename(targetPath)} already exists.`));
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function copyTemplate(templateName, targetPath) {
|
|
22
|
-
const spinner = ora("Copying project files...").start();
|
|
23
|
-
|
|
24
|
-
// Assuming templates live in ../templates relative to this file
|
|
25
|
-
const templateDir = path.resolve(__dirname, "../templates", templateName);
|
|
26
|
-
|
|
27
|
-
if (!fs.existsSync(templateDir)) {
|
|
28
|
-
spinner.fail(chalk.red(`Template ${templateName} not found at ${templateDir}`));
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
await fs.copy(templateDir, targetPath);
|
|
34
|
-
spinner.succeed(chalk.green("Project files created successfully."));
|
|
35
|
-
} catch (err) {
|
|
36
|
-
spinner.fail(chalk.red("Failed to copy files."));
|
|
37
|
-
console.error(err);
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function installDependencies(targetPath) {
|
|
43
|
-
const spinner = ora("Installing dependencies... This might take a moment.").start();
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
// Run npm install in the new directory
|
|
47
|
-
await execAsync("npm install", { cwd: targetPath });
|
|
48
|
-
spinner.succeed(chalk.green("Dependencies installed via npm."));
|
|
49
|
-
} catch (err) {
|
|
50
|
-
// Fallback for peer dependency conflicts common in AI libraries
|
|
51
|
-
try {
|
|
52
|
-
spinner.text = "Retrying with --legacy-peer-deps...";
|
|
53
|
-
await execAsync("npm install --legacy-peer-deps", { cwd: targetPath });
|
|
54
|
-
spinner.succeed(chalk.green("Dependencies installed with legacy peer deps."));
|
|
55
|
-
} catch (retryErr) {
|
|
56
|
-
spinner.fail(chalk.red("Failed to install dependencies."));
|
|
57
|
-
console.log(chalk.yellow("You can try installing manually:"));
|
|
58
|
-
console.log(chalk.cyan(` cd ${path.basename(targetPath)}`));
|
|
59
|
-
console.log(chalk.cyan(" npm install --legacy-peer-deps"));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
1
|
+
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { exec } from "child_process";
|
|
6
|
+
import util from "util";
|
|
7
|
+
import ora from "ora";
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
const execAsync = util.promisify(exec);
|
|
13
|
+
|
|
14
|
+
export function checkDir(targetPath) {
|
|
15
|
+
if (fs.existsSync(targetPath)) {
|
|
16
|
+
console.error(chalk.red(`\nā Error: Directory ${path.basename(targetPath)} already exists.`));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function copyTemplate(templateName, targetPath) {
|
|
22
|
+
const spinner = ora("Copying project files...").start();
|
|
23
|
+
|
|
24
|
+
// Assuming templates live in ../templates relative to this file
|
|
25
|
+
const templateDir = path.resolve(__dirname, "../templates", templateName);
|
|
26
|
+
|
|
27
|
+
if (!fs.existsSync(templateDir)) {
|
|
28
|
+
spinner.fail(chalk.red(`Template ${templateName} not found at ${templateDir}`));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
await fs.copy(templateDir, targetPath);
|
|
34
|
+
spinner.succeed(chalk.green("Project files created successfully."));
|
|
35
|
+
} catch (err) {
|
|
36
|
+
spinner.fail(chalk.red("Failed to copy files."));
|
|
37
|
+
console.error(err);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function installDependencies(targetPath) {
|
|
43
|
+
const spinner = ora("Installing dependencies... This might take a moment.").start();
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
// Run npm install in the new directory
|
|
47
|
+
await execAsync("npm install", { cwd: targetPath });
|
|
48
|
+
spinner.succeed(chalk.green("Dependencies installed via npm."));
|
|
49
|
+
} catch (err) {
|
|
50
|
+
// Fallback for peer dependency conflicts common in AI libraries
|
|
51
|
+
try {
|
|
52
|
+
spinner.text = "Retrying with --legacy-peer-deps...";
|
|
53
|
+
await execAsync("npm install --legacy-peer-deps", { cwd: targetPath });
|
|
54
|
+
spinner.succeed(chalk.green("Dependencies installed with legacy peer deps."));
|
|
55
|
+
} catch (retryErr) {
|
|
56
|
+
spinner.fail(chalk.red("Failed to install dependencies."));
|
|
57
|
+
console.log(chalk.yellow("You can try installing manually:"));
|
|
58
|
+
console.log(chalk.cyan(` cd ${path.basename(targetPath)}`));
|
|
59
|
+
console.log(chalk.cyan(" npm install --legacy-peer-deps"));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
# AI Provider Keys
|
|
3
|
-
OPENAI_API_KEY=sk-your-key-here
|
|
4
|
-
GROQ_API_KEY=your-groq-key
|
|
5
|
-
GOOGLE_API_KEY=your-gemini-key-here
|
|
6
|
-
|
|
7
|
-
# Vector DB
|
|
8
|
-
# Default to local persistent client
|
|
9
|
-
CHROMA_URL=http://localhost:8000
|
|
10
|
-
COLLECTION_NAME=rag-docs
|
|
11
|
-
|
|
12
|
-
# App Config
|
|
13
|
-
NEXT_PUBLIC_APP_NAME="My RAG App"
|
|
1
|
+
|
|
2
|
+
# AI Provider Keys
|
|
3
|
+
OPENAI_API_KEY=sk-your-key-here
|
|
4
|
+
GROQ_API_KEY=your-groq-key
|
|
5
|
+
GOOGLE_API_KEY=your-gemini-key-here
|
|
6
|
+
|
|
7
|
+
# Vector DB
|
|
8
|
+
# Default to local persistent client
|
|
9
|
+
CHROMA_URL=http://localhost:8000
|
|
10
|
+
COLLECTION_NAME=rag-docs
|
|
11
|
+
|
|
12
|
+
# App Config
|
|
13
|
+
NEXT_PUBLIC_APP_NAME="My RAG App"
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Put your PDF or .txt files here to be ingested by the RAG pipeline.
|
|
1
|
+
Put your PDF or .txt files here to be ingested by the RAG pipeline.
|
|
2
2
|
Then run `npm run ingest` to build the vector index.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"baseUrl": ".",
|
|
4
|
-
"paths": {
|
|
5
|
-
"@/*": ["./src/*"]
|
|
6
|
-
},
|
|
7
|
-
// Useful for Next.js strict mode and modern JS features
|
|
8
|
-
"target": "ESNext",
|
|
9
|
-
"module": "ESNext",
|
|
10
|
-
"jsx": "preserve",
|
|
11
|
-
"strict": false
|
|
12
|
-
},
|
|
13
|
-
"include": ["next-env.d.ts", "**/*.js", "**/*.jsx", ".next/types/**/*.ts"],
|
|
14
|
-
"exclude": ["node_modules"]
|
|
15
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"baseUrl": ".",
|
|
4
|
+
"paths": {
|
|
5
|
+
"@/*": ["./src/*"]
|
|
6
|
+
},
|
|
7
|
+
// Useful for Next.js strict mode and modern JS features
|
|
8
|
+
"target": "ESNext",
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"jsx": "preserve",
|
|
11
|
+
"strict": false
|
|
12
|
+
},
|
|
13
|
+
"include": ["next-env.d.ts", "**/*.js", "**/*.jsx", ".next/types/**/*.ts"],
|
|
14
|
+
"exclude": ["node_modules"]
|
|
15
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/** @type {import('next').NextConfig} */
|
|
2
|
-
const nextConfig = {
|
|
3
|
-
reactStrictMode: true,
|
|
4
|
-
serverExternalPackages: ["chromadb"],
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export default nextConfig;
|
|
1
|
+
/** @type {import('next').NextConfig} */
|
|
2
|
+
const nextConfig = {
|
|
3
|
+
reactStrictMode: true,
|
|
4
|
+
serverExternalPackages: ["chromadb"],
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default nextConfig;
|