Skip to content

Commit 0b36400

Browse files
committed
add some spice to cli
1 parent 311478e commit 0b36400

File tree

4 files changed

+189
-12
lines changed

4 files changed

+189
-12
lines changed

src/cli/celebration.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// src/cli/celebration.js
2+
import chalk from 'chalk';
3+
4+
const frames = [
5+
`
6+
🎉
7+
\\|/
8+
|
9+
/ \\
10+
`,
11+
`
12+
🎊
13+
/|\\
14+
|
15+
/ \\
16+
`,
17+
`
18+
19+
\\|/
20+
|
21+
/ \\
22+
`
23+
];
24+
25+
export function celebrate(message) {
26+
let frameIndex = 0;
27+
const animation = setInterval(() => {
28+
process.stdout.write('\x1B[2J\x1B[3J\x1B[H');
29+
console.log(chalk.rainbow(`
30+
===============================
31+
${message}
32+
===============================
33+
`));
34+
console.log(chalk.cyan(frames[frameIndex]));
35+
frameIndex = (frameIndex + 1) % frames.length;
36+
}, 200);
37+
38+
// Stop after 2 seconds
39+
setTimeout(() => {
40+
clearInterval(animation);
41+
process.stdout.write('\x1B[2J\x1B[3J\x1B[H');
42+
console.log(chalk.green(`
43+
===============================
44+
${message}
45+
===============================
46+
`));
47+
}, 2000);
48+
}

src/cli/createRagApp.js

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,36 @@ import path from 'path';
44
import { execSync } from 'child_process';
55
import chalk from 'chalk';
66
import { displayLogo } from './asciiLogo.js';
7+
import MongoSpinner from './spinner.js';
8+
import { celebrate } from './celebration.js';
9+
import FunProgressBar from './progressBar.js';
710

8-
export function createRagApp(projectName) {
9-
const projectPath = path.resolve(process.cwd(), projectName);
11+
export async function createRagApp(projectName) {
12+
const spinner = new MongoSpinner();
13+
const progressBar = new FunProgressBar();
14+
15+
// Display the ASCII logo
1016
displayLogo();
11-
17+
18+
const projectPath = path.resolve(process.cwd(), projectName);
1219

1320
if (fs.existsSync(projectPath)) {
1421
console.error(chalk.red(`Error: Directory "${projectName}" already exists.`));
1522
process.exit(1);
1623
}
1724

1825
console.log(chalk.green(`\n🚀 Creating a new RAG app in ${projectPath}\n`));
26+
27+
// Start the creation process with spinner
28+
spinner.start('Initializing your RAG app');
1929
fs.mkdirSync(projectPath, { recursive: true });
30+
await new Promise(resolve => setTimeout(resolve, 1000));
31+
spinner.stop(true);
32+
33+
// Show progress while creating files
34+
console.log(chalk.cyan('\nPreparing your MongoDB RAG environment...'));
35+
let currentProgress = 0;
36+
progressBar.update(currentProgress);
2037

2138
// Step 1: Create package.json
2239
fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify({
@@ -35,8 +52,10 @@ export function createRagApp(projectName) {
3552
"mongodb-rag": "^0.15.0"
3653
}
3754
}, null, 2));
55+
currentProgress += 0.25;
56+
progressBar.update(currentProgress);
3857

39-
// Step 2: Create .env file with corrected variables
58+
// Step 2: Create .env file
4059
fs.writeFileSync(path.join(projectPath, '.env'), `
4160
MONGODB_URI=mongodb+srv://your_user:your_password@your-cluster.mongodb.net/mongorag
4261
PORT=5000
@@ -49,8 +68,10 @@ EMBEDDING_MODEL=text-embedding-3-small # Adjust for different providers
4968
# MongoDB Vector Search Index
5069
VECTOR_INDEX=default
5170
`);
71+
currentProgress += 0.25;
72+
progressBar.update(currentProgress);
5273

53-
// Step 3: Create server.js with environment-aware embedding configuration
74+
// Step 3: Create server.js
5475
fs.writeFileSync(path.join(projectPath, 'server.js'), `
5576
import express from 'express';
5677
import cors from 'cors';
@@ -101,13 +122,26 @@ app.listen(process.env.PORT || 5000, () => {
101122
console.log(\`🚀 Server running on port \${process.env.PORT || 5000}\`);
102123
});
103124
`);
125+
currentProgress += 0.25;
126+
progressBar.update(currentProgress);
104127

105-
// Step 4: Install dependencies
128+
// Step 4: Install dependencies with spinner
106129
console.log(chalk.blue(`\n📦 Installing dependencies...\n`));
130+
spinner.start('Installing packages');
107131
execSync(`cd ${projectPath} && npm install`, { stdio: 'inherit' });
108-
109-
console.log(chalk.green(`\n✅ Project created successfully!`));
110-
console.log(chalk.yellow(`\nNext steps:`));
111-
console.log(chalk.cyan(` cd ${projectName}`));
112-
console.log(chalk.cyan(` npm run dev`));
113-
}
132+
spinner.stop(true);
133+
currentProgress = 1;
134+
progressBar.update(currentProgress);
135+
136+
// Show celebration
137+
await new Promise(resolve => setTimeout(resolve, 500));
138+
celebrate('RAG App Created Successfully! 🎉');
139+
140+
// Show next steps after celebration (keeping original format)
141+
setTimeout(() => {
142+
console.log(chalk.green(`\n✅ Project created successfully!`));
143+
console.log(chalk.yellow(`\nNext steps:`));
144+
console.log(chalk.cyan(` cd ${projectName}`));
145+
console.log(chalk.cyan(` npm run dev`));
146+
}, 2500);
147+
}

src/cli/progressBar.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// src/cli/progressBar.js
2+
import chalk from 'chalk';
3+
4+
const funFacts = [
5+
"Did you know? Vector search helps find similar items even if they use different words!",
6+
"MongoDB Atlas Vector Search uses cosine similarity by default 📐",
7+
"RAG helps combine the power of vector search with your own data 🔋",
8+
"Vector embeddings can capture semantic meaning beyond keywords 🎯",
9+
"MongoDB can handle billions of vectors efficiently! 🚀",
10+
"Vector search is like giving your database a human-like understanding 🧠"
11+
];
12+
13+
class FunProgressBar {
14+
constructor() {
15+
this.width = 40;
16+
this.currentFact = 0;
17+
}
18+
19+
update(progress) {
20+
const filled = Math.round(this.width * progress);
21+
const empty = this.width - filled;
22+
23+
const filledBar = '█'.repeat(filled);
24+
const emptyBar = '░'.repeat(empty);
25+
26+
process.stdout.clearLine();
27+
process.stdout.cursorTo(0);
28+
29+
const percentage = Math.round(progress * 100);
30+
process.stdout.write(
31+
chalk.blue(`[${filledBar}${emptyBar}] ${percentage}%\n`) +
32+
chalk.yellow(`Fun Fact: ${funFacts[this.currentFact]}\n`)
33+
);
34+
35+
this.currentFact = (this.currentFact + 1) % funFacts.length;
36+
}
37+
}
38+
39+
export default FunProgressBar;

src/cli/spinner.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// src/cli/spinner.js
2+
import chalk from 'chalk';
3+
4+
class MongoSpinner {
5+
constructor() {
6+
this.frames = [
7+
'🔍 ○ ○ ○ ', // Search frame
8+
'🔍 ● ○ ○ ', // Loading embeddings
9+
'🔍 ● ● ○ ', // Processing vectors
10+
'🔍 ● ● ● ', // Complete
11+
];
12+
this.interval = null;
13+
this.frameIndex = 0;
14+
this.messages = [
15+
'Preparing vector magic...',
16+
'Calculating embeddings...',
17+
'Optimizing search space...',
18+
'Almost there...'
19+
];
20+
}
21+
22+
start(text = '') {
23+
process.stdout.write('\n');
24+
this.interval = setInterval(() => {
25+
const frame = this.frames[this.frameIndex];
26+
const message = this.messages[this.frameIndex];
27+
process.stdout.clearLine();
28+
process.stdout.cursorTo(0);
29+
process.stdout.write(
30+
chalk.blue(frame) + ' ' +
31+
chalk.cyan(message) + ' ' +
32+
chalk.yellow(text)
33+
);
34+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
35+
}, 800);
36+
}
37+
38+
stop(success = true) {
39+
clearInterval(this.interval);
40+
process.stdout.clearLine();
41+
process.stdout.cursorTo(0);
42+
if (success) {
43+
process.stdout.write(
44+
chalk.green('✨ Vector magic complete! ') +
45+
chalk.blue('🎉\n')
46+
);
47+
} else {
48+
process.stdout.write(
49+
chalk.red('✖ Operation failed ') +
50+
chalk.yellow('😢\n')
51+
);
52+
}
53+
}
54+
}
55+
56+
export default MongoSpinner;

0 commit comments

Comments
 (0)