dolphin-server-modules 2.11.1 → 2.11.3
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/TUTORIAL_NEPALI.md +181 -0
- package/dist/adapters/mongoose/index.test.d.ts +1 -0
- package/dist/adapters/mongoose/index.test.js +145 -0
- package/dist/adapters/mongoose/index.test.js.map +1 -0
- package/dist/adapters/mongoose/integration.test.d.ts +5 -0
- package/dist/adapters/mongoose/integration.test.js +217 -0
- package/dist/adapters/mongoose/integration.test.js.map +1 -0
- package/dist/ai/dolphin-agent/agent.d.ts +5 -0
- package/dist/ai/dolphin-agent/agent.js +93 -46
- package/dist/ai/dolphin-agent/agent.js.map +1 -1
- package/dist/ai/dolphin-agent/config.js +19 -23
- package/dist/ai/dolphin-agent/config.js.map +1 -1
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +286 -0
- package/dist/auth/auth.test.js.map +1 -0
- package/dist/authController/authController.test.d.ts +1 -0
- package/dist/authController/authController.test.js +359 -0
- package/dist/authController/authController.test.js.map +1 -0
- package/dist/bin/cli.js +494 -131
- package/dist/bin/cli.js.map +1 -1
- package/dist/client.test.d.ts +22 -0
- package/dist/client.test.js +573 -0
- package/dist/client.test.js.map +1 -0
- package/dist/controller/controller.test.d.ts +1 -0
- package/dist/controller/controller.test.js +37 -0
- package/dist/controller/controller.test.js.map +1 -0
- package/dist/curd/crud.test.d.ts +1 -0
- package/dist/curd/crud.test.js +104 -0
- package/dist/curd/crud.test.js.map +1 -0
- package/dist/demo-server.d.ts +1 -0
- package/dist/demo-server.js +191 -0
- package/dist/demo-server.js.map +1 -0
- package/dist/djson/djson.test.d.ts +1 -0
- package/dist/djson/djson.test.js +200 -0
- package/dist/djson/djson.test.js.map +1 -0
- package/dist/dolphin-bench.d.ts +1 -0
- package/dist/dolphin-bench.js +63 -0
- package/dist/dolphin-bench.js.map +1 -0
- package/dist/hard-performance-test.d.ts +1 -0
- package/dist/hard-performance-test.js +97 -0
- package/dist/hard-performance-test.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/middleware/zod.test.d.ts +1 -0
- package/dist/middleware/zod.test.js +74 -0
- package/dist/middleware/zod.test.js.map +1 -0
- package/dist/performance-test.d.ts +1 -0
- package/dist/performance-test.js +92 -0
- package/dist/performance-test.js.map +1 -0
- package/dist/real-test-mongoose.d.ts +1 -0
- package/dist/real-test-mongoose.js +104 -0
- package/dist/real-test-mongoose.js.map +1 -0
- package/dist/realtime/camera.d.ts +119 -0
- package/dist/realtime/camera.js +299 -0
- package/dist/realtime/camera.js.map +1 -0
- package/dist/realtime/camera.test.d.ts +1 -0
- package/dist/realtime/camera.test.js +345 -0
- package/dist/realtime/camera.test.js.map +1 -0
- package/dist/realtime/core.d.ts +4 -4
- package/dist/realtime/core.js +5 -5
- package/dist/realtime/core.js.map +1 -1
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +2 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/realtime.test.d.ts +1 -0
- package/dist/realtime/realtime.test.js +623 -0
- package/dist/realtime/realtime.test.js.map +1 -0
- package/dist/realtime/rtsp.d.ts +65 -0
- package/dist/realtime/rtsp.js +410 -0
- package/dist/realtime/rtsp.js.map +1 -0
- package/dist/realtime/rtsp.test.d.ts +1 -0
- package/dist/realtime/rtsp.test.js +361 -0
- package/dist/realtime/rtsp.test.js.map +1 -0
- package/dist/router/router.test.d.ts +1 -0
- package/dist/router/router.test.js +45 -0
- package/dist/router/router.test.js.map +1 -0
- package/dist/server/server.d.ts +8 -8
- package/dist/server/server.js +1 -10
- package/dist/server/server.js.map +1 -1
- package/dist/server/server.test.d.ts +1 -0
- package/dist/server/server.test.js +299 -0
- package/dist/server/server.test.js.map +1 -0
- package/dist/services/ai-service.js +22 -11
- package/dist/services/ai-service.js.map +1 -1
- package/dist/signaling/signaling.test.d.ts +1 -0
- package/dist/signaling/signaling.test.js +112 -0
- package/dist/signaling/signaling.test.js.map +1 -0
- package/dist/swagger/swagger.test.d.ts +1 -0
- package/dist/swagger/swagger.test.js +38 -0
- package/dist/swagger/swagger.test.js.map +1 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.js +247 -70
- package/dist/templates/index.js.map +1 -1
- package/dist/test-2fa-real.d.ts +1 -0
- package/dist/test-2fa-real.js +105 -0
- package/dist/test-2fa-real.js.map +1 -0
- package/dist/test-dolphin.d.ts +1 -0
- package/dist/test-dolphin.js +98 -0
- package/dist/test-dolphin.js.map +1 -0
- package/dist/utils/ctx.d.ts +50 -0
- package/dist/utils/ctx.js +82 -0
- package/dist/utils/ctx.js.map +1 -0
- package/package.json +171 -65
- package/scripts/client.js +838 -703
- package/scripts/benchmark.js +0 -12
- package/scripts/benchmark.ts +0 -12
- package/scripts/list-models.js +0 -34
- package/scripts/run-real-ai-test.js +0 -79
- package/scripts/test-ai-logic.js +0 -44
- package/scripts/test-client.js +0 -105
- package/scripts/test-dolphin.js +0 -36
package/dist/bin/cli.js
CHANGED
|
@@ -2,54 +2,266 @@
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { createServer } from 'http';
|
|
5
|
+
import net from 'net';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
5
7
|
import { AIService } from '../services/ai-service.js';
|
|
6
8
|
import { CLIUI } from '../utils/ui.js';
|
|
7
9
|
import { TEMPLATES } from '../templates/index.js';
|
|
8
10
|
const args = process.argv.slice(2);
|
|
9
11
|
const command = args[0] || 'help';
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
// Version — package.json बाट dynamic पढ्ने
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf8'));
|
|
16
|
+
const VERSION = pkg.version;
|
|
17
|
+
// .env loader
|
|
18
|
+
const envFilePath = path.join(process.cwd(), '.env');
|
|
19
|
+
if (fs.existsSync(envFilePath)) {
|
|
20
|
+
fs.readFileSync(envFilePath, 'utf8').split('\n').forEach(line => {
|
|
21
|
+
const trimmed = line.trim();
|
|
22
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
23
|
+
return;
|
|
24
|
+
const eqIdx = trimmed.indexOf('=');
|
|
25
|
+
if (eqIdx === -1)
|
|
26
|
+
return;
|
|
27
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
28
|
+
const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, '');
|
|
29
|
+
if (key && !process.env[key])
|
|
30
|
+
process.env[key] = value;
|
|
19
31
|
});
|
|
20
32
|
}
|
|
21
33
|
const aiConfig = {
|
|
22
34
|
apiKey: (process.env.DOLPHIN_AI_KEY || process.env.GEMINI_API_KEY || '').trim(),
|
|
23
35
|
baseUrl: process.env.DOLPHIN_AI_BASE_URL,
|
|
24
|
-
model: process.env.DOLPHIN_AI_MODEL
|
|
36
|
+
model: process.env.DOLPHIN_AI_MODEL,
|
|
25
37
|
};
|
|
26
38
|
const useOllama = process.env.USE_OLLAMA === 'true';
|
|
27
39
|
const hasAnyKey = aiConfig.apiKey || process.env.GROQ_API_KEY || process.env.OPENAI_API_KEY;
|
|
28
40
|
if (!hasAnyKey && !useOllama && ['generate', 'generate-full', 'chat'].includes(command)) {
|
|
29
|
-
CLIUI.error('API Key
|
|
41
|
+
CLIUI.error('API Key फेला परेन! .env मा DOLPHIN_AI_KEY, GEMINI_API_KEY, वा GROQ_API_KEY राख्नुहोस्।');
|
|
30
42
|
process.exit(1);
|
|
31
43
|
}
|
|
32
44
|
const ai = new AIService(aiConfig);
|
|
45
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
46
|
+
function ensureDir(dir) {
|
|
47
|
+
if (!fs.existsSync(dir))
|
|
48
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
function writeFile(filePath, content, label) {
|
|
51
|
+
ensureDir(path.dirname(filePath));
|
|
52
|
+
fs.writeFileSync(filePath, content);
|
|
53
|
+
console.log(` 📄 Created: ${label || path.relative(process.cwd(), filePath)}`);
|
|
54
|
+
}
|
|
55
|
+
function capitalize(s) {
|
|
56
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
57
|
+
}
|
|
58
|
+
/** TCP port check — live connection test गर्ने */
|
|
59
|
+
function checkTcpPort(host, port, timeoutMs = 4000) {
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
const socket = new net.Socket();
|
|
62
|
+
socket.setTimeout(timeoutMs);
|
|
63
|
+
socket.once('connect', () => { socket.destroy(); resolve(true); });
|
|
64
|
+
socket.once('error', () => { socket.destroy(); resolve(false); });
|
|
65
|
+
socket.once('timeout', () => { socket.destroy(); resolve(false); });
|
|
66
|
+
socket.connect(port, host);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** URI बाट host र port निकाल्ने */
|
|
70
|
+
function parseUri(uri) {
|
|
71
|
+
try {
|
|
72
|
+
const u = new URL(uri);
|
|
73
|
+
const defaults = {
|
|
74
|
+
'mongodb:': 27017, 'mongodb+srv:': 27017,
|
|
75
|
+
'redis:': 6379, 'rediss:': 6380,
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
host: u.hostname || 'localhost',
|
|
79
|
+
port: parseInt(u.port || '') || defaults[u.protocol] || 3000,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { host: 'localhost', port: 27017 };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Automatically registers the newly created Mongoose model in the entry file (e.g. app.js)
|
|
88
|
+
* where createMongooseAdapter is called, by adding the model import and inserting it into
|
|
89
|
+
* the adapter initialization parameters.
|
|
90
|
+
*/
|
|
91
|
+
function registerModelInAdapter(modelName) {
|
|
92
|
+
const entryFiles = ['app.js', 'app.ts', 'server.js', 'server.ts', 'index.js', 'index.ts'];
|
|
93
|
+
let foundFile = '';
|
|
94
|
+
let content = '';
|
|
95
|
+
for (const file of entryFiles) {
|
|
96
|
+
const fullPath = path.join(process.cwd(), file);
|
|
97
|
+
if (fs.existsSync(fullPath)) {
|
|
98
|
+
const txt = fs.readFileSync(fullPath, 'utf8');
|
|
99
|
+
if (txt.includes('createMongooseAdapter')) {
|
|
100
|
+
foundFile = fullPath;
|
|
101
|
+
content = txt;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!foundFile) {
|
|
107
|
+
console.log(` ⚠️ Could not find any file calling createMongooseAdapter to register ${modelName}.`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// 1. Add Import
|
|
111
|
+
if (content.includes(`models/${modelName}.js`) || content.includes(`models/${modelName}`)) {
|
|
112
|
+
console.log(` ⚠️ ${modelName} is already imported in ${path.basename(foundFile)}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const importLine = `import { ${modelName} } from './models/${modelName}.js';\n`;
|
|
116
|
+
const modelImportRegex = /import\s+{[^}]+}\s+from\s+['"].\/models\/[^'"]+['"];/g;
|
|
117
|
+
const matches = [...content.matchAll(modelImportRegex)];
|
|
118
|
+
if (matches.length > 0) {
|
|
119
|
+
const lastMatch = matches[matches.length - 1];
|
|
120
|
+
const insertPos = lastMatch.index + lastMatch[0].length;
|
|
121
|
+
content = content.slice(0, insertPos) + '\n' + importLine + content.slice(insertPos);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const firstImportIdx = content.indexOf('import ');
|
|
125
|
+
if (firstImportIdx !== -1) {
|
|
126
|
+
content = content.slice(0, firstImportIdx) + importLine + content.slice(firstImportIdx);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
content = importLine + content;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// 2. Add to createMongooseAdapter arguments
|
|
134
|
+
const adapterCallRegex = /createMongooseAdapter\s*\(\s*\{([\s\S]*?)\}\s*\)/;
|
|
135
|
+
const match = content.match(adapterCallRegex);
|
|
136
|
+
if (match) {
|
|
137
|
+
const innerContent = match[1];
|
|
138
|
+
if (innerContent.includes(modelName)) {
|
|
139
|
+
console.log(` ⚠️ ${modelName} already registered in createMongooseAdapter`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
let updatedInner = '';
|
|
143
|
+
if (innerContent.includes('models:')) {
|
|
144
|
+
const modelsRegex = /models\s*:\s*\{\s*([\s\S]*?)\s*\}/;
|
|
145
|
+
const modelsMatch = innerContent.match(modelsRegex);
|
|
146
|
+
if (modelsMatch) {
|
|
147
|
+
const existingModels = modelsMatch[1].trim();
|
|
148
|
+
const updatedModels = existingModels ? `${modelName}, ${existingModels}` : modelName;
|
|
149
|
+
updatedInner = innerContent.replace(modelsRegex, `models: { ${updatedModels} }`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
updatedInner = innerContent.trim() + `, models: { ${modelName} }`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const trimmedInner = innerContent.trim();
|
|
157
|
+
updatedInner = trimmedInner ? `${trimmedInner}, models: { ${modelName} }` : `models: { ${modelName} }`;
|
|
158
|
+
}
|
|
159
|
+
content = content.replace(adapterCallRegex, `createMongooseAdapter({ ${updatedInner} })`);
|
|
160
|
+
fs.writeFileSync(foundFile, content);
|
|
161
|
+
console.log(` ✅ Registered: ${modelName} registered in ${path.relative(process.cwd(), foundFile)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(` ⚠️ Could not parse createMongooseAdapter call in ${path.basename(foundFile)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
33
169
|
async function run() {
|
|
34
170
|
switch (command) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
171
|
+
// ── serve ────────────────────────────────────────────────────────────
|
|
172
|
+
case 'serve': {
|
|
173
|
+
const port = parseInt(args.find(a => a.startsWith('--port='))?.split('=')[1] || '3000');
|
|
174
|
+
CLIUI.heading(`Dolphin Dev Server — port ${port}`);
|
|
38
175
|
const server = createServer((req, res) => {
|
|
39
176
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
40
|
-
res.end('Dolphin Server is swimming!\n');
|
|
177
|
+
res.end('🐬 Dolphin Server is swimming!\n');
|
|
41
178
|
});
|
|
42
179
|
server.listen(port, () => {
|
|
43
180
|
CLIUI.success(`Server is live at http://localhost:${port}`);
|
|
181
|
+
console.log(' Ctrl+C थिचेर रोक्नुहोस्।');
|
|
44
182
|
});
|
|
45
183
|
break;
|
|
46
|
-
|
|
184
|
+
}
|
|
185
|
+
// ── connect mongoose|redis ───────────────────────────────────────────
|
|
186
|
+
case 'connect': {
|
|
187
|
+
const dbType = args[1];
|
|
188
|
+
const uriArg = args[2];
|
|
189
|
+
if (dbType === 'mongoose' || dbType === 'mongo' || dbType === 'mongodb') {
|
|
190
|
+
const uri = uriArg || process.env.MONGO_URI || 'mongodb://localhost:27017';
|
|
191
|
+
CLIUI.heading('MongoDB Connection Test');
|
|
192
|
+
console.log(` URI: ${uri.replace(/:\/\/[^@]+@/, '://***@')}`);
|
|
193
|
+
// Step 1: TCP check
|
|
194
|
+
CLIUI.startSpinner('TCP ping...');
|
|
195
|
+
const { host, port } = parseUri(uri);
|
|
196
|
+
const tcpOk = await checkTcpPort(host, port);
|
|
197
|
+
CLIUI.stopSpinner(tcpOk, tcpOk ? `Host reachable: ${host}:${port}` : `Cannot reach ${host}:${port}`);
|
|
198
|
+
if (!tcpOk) {
|
|
199
|
+
console.log('\n \x1b[33mFix — MongoDB start गर्नुहोस्:\x1b[0m');
|
|
200
|
+
console.log(' brew services start mongodb-community (macOS)');
|
|
201
|
+
console.log(' sudo systemctl start mongod (Linux)');
|
|
202
|
+
console.log(' mongod (manual)');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
// Step 2: Mongoose check
|
|
206
|
+
CLIUI.startSpinner('Mongoose handshake...');
|
|
207
|
+
try {
|
|
208
|
+
const mongoose = await import('mongoose');
|
|
209
|
+
await mongoose.default.connect(uri, { serverSelectionTimeoutMS: 5000 });
|
|
210
|
+
const dbHost = mongoose.default.connection.host;
|
|
211
|
+
await mongoose.default.disconnect();
|
|
212
|
+
CLIUI.stopSpinner(true, `Connected! Host: ${dbHost}`);
|
|
213
|
+
CLIUI.success('MongoDB तयार छ। MONGO_URI .env मा राख्नुहोस्।');
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
CLIUI.stopSpinner(false, e.message);
|
|
217
|
+
CLIUI.error('Mongoose connection failed. URI सही छ?');
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else if (dbType === 'redis') {
|
|
222
|
+
const uri = uriArg || process.env.REDIS_URL || 'redis://localhost:6379';
|
|
223
|
+
CLIUI.heading('Redis Connection Test');
|
|
224
|
+
console.log(` URI: ${uri}`);
|
|
225
|
+
CLIUI.startSpinner('TCP ping...');
|
|
226
|
+
const { host, port } = parseUri(uri);
|
|
227
|
+
const tcpOk = await checkTcpPort(host, port);
|
|
228
|
+
CLIUI.stopSpinner(tcpOk, tcpOk ? `Host reachable: ${host}:${port}` : `Cannot reach ${host}:${port}`);
|
|
229
|
+
if (!tcpOk) {
|
|
230
|
+
console.log('\n \x1b[33mFix — Redis start गर्नुहोस्:\x1b[0m');
|
|
231
|
+
console.log(' brew services start redis (macOS)');
|
|
232
|
+
console.log(' sudo systemctl start redis (Linux)');
|
|
233
|
+
console.log(' redis-server (manual)');
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
CLIUI.startSpinner('Redis PING...');
|
|
237
|
+
try {
|
|
238
|
+
const { createClient } = await import('redis');
|
|
239
|
+
const client = createClient({ url: uri });
|
|
240
|
+
await client.connect();
|
|
241
|
+
const pong = await client.ping();
|
|
242
|
+
await client.quit();
|
|
243
|
+
CLIUI.stopSpinner(pong === 'PONG', `Redis replied: ${pong}`);
|
|
244
|
+
CLIUI.success('Redis तयार छ!');
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
CLIUI.stopSpinner(true, 'TCP OK (redis package: npm install redis)');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
CLIUI.error('Usage:');
|
|
252
|
+
console.log(' dolphin connect mongoose [uri]');
|
|
253
|
+
console.log(' dolphin connect redis [uri]');
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
// ── generate ─────────────────────────────────────────────────────────
|
|
258
|
+
case 'generate': {
|
|
47
259
|
const prompt = args.slice(1).join(' ');
|
|
48
260
|
if (!prompt)
|
|
49
261
|
return CLIUI.error('Usage: dolphin generate "your prompt"');
|
|
50
262
|
CLIUI.startSpinner('AI is generating code');
|
|
51
263
|
try {
|
|
52
|
-
const response = await ai.request(prompt,
|
|
264
|
+
const response = await ai.request(prompt, 'Return ONLY raw JavaScript code. No markdown.');
|
|
53
265
|
const cleanCode = response.replace(/```javascript|```js|```/g, '').trim();
|
|
54
266
|
fs.writeFileSync(path.join(process.cwd(), 'ai-generated.js'), cleanCode);
|
|
55
267
|
CLIUI.stopSpinner(true, 'File generated: ai-generated.js');
|
|
@@ -58,168 +270,319 @@ async function run() {
|
|
|
58
270
|
CLIUI.stopSpinner(false, e.message);
|
|
59
271
|
}
|
|
60
272
|
break;
|
|
61
|
-
|
|
273
|
+
}
|
|
274
|
+
// ── generate-full ────────────────────────────────────────────────────
|
|
275
|
+
case 'generate-full': {
|
|
62
276
|
const fullPrompt = args.slice(1).join(' ');
|
|
63
277
|
if (!fullPrompt)
|
|
64
278
|
return CLIUI.error('Usage: dolphin generate-full "project description"');
|
|
65
279
|
CLIUI.startSpinner('Architecting full project structure');
|
|
66
280
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
- Use 'dolphin-server-modules/auth-controller' for createDolphinAuthController()
|
|
72
|
-
- Use 'dolphin-server-modules/crud' for createCrudController()
|
|
73
|
-
- Models: Mongoose schemas only
|
|
74
|
-
- Controllers: Use Dolphin CRUD controllers
|
|
75
|
-
- Main app: Use createDolphinServer(), not Express
|
|
76
|
-
- DB: Use createMongooseAdapter() for MongoDB
|
|
77
|
-
- Auth: Use createDolphinAuthController()
|
|
78
|
-
- Routes: Direct on app, no separate route files
|
|
79
|
-
- index.js: Main entry point using Dolphin server
|
|
80
|
-
Project Structure:
|
|
81
|
-
- index.js (main server)
|
|
82
|
-
- models/ (Mongoose models)
|
|
83
|
-
- controllers/ (Dolphin controllers)
|
|
84
|
-
- config/db.js (DB connection)
|
|
85
|
-
- .env (env vars)
|
|
86
|
-
Return ONLY a JSON object where keys are file paths and values are code content. No markdown.`;
|
|
87
|
-
const response = await ai.request(fullPrompt, systemPrompt);
|
|
88
|
-
// Extract only the part between { and } to avoid AI's conversational chatter
|
|
281
|
+
const sysPrompt = `You are a Dolphin Framework expert. Generate a production-ready backend project.
|
|
282
|
+
Use: createDolphinServer(), createMongooseAdapter({User,RefreshToken}), createDolphinAuthController(), createCrudController().
|
|
283
|
+
Return ONLY a JSON object: {filePath: fileContent}. No markdown.`;
|
|
284
|
+
const response = await ai.request(fullPrompt, sysPrompt);
|
|
89
285
|
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
90
286
|
const cleaned = jsonMatch ? jsonMatch[0] : response.replace(/```json|```/g, '').trim();
|
|
91
287
|
let files;
|
|
92
288
|
try {
|
|
93
289
|
files = JSON.parse(cleaned);
|
|
94
290
|
}
|
|
95
|
-
catch
|
|
96
|
-
|
|
97
|
-
const sanitized = cleaned.replace(/[\x00-\x1F\x7F-\x9F]/g, (c) => c === '\n' ? '\\n' : (c === '\r' ? '\\r' : (c === '\t' ? '\\t' : '')));
|
|
291
|
+
catch {
|
|
292
|
+
const sanitized = cleaned.replace(/[\x00-\x1F\x7F-\x9F]/g, (c) => c === '\n' ? '\\n' : c === '\r' ? '\\r' : c === '\t' ? '\\t' : '');
|
|
98
293
|
files = JSON.parse(sanitized);
|
|
99
294
|
}
|
|
100
295
|
Object.entries(files).forEach(([fPath, content]) => {
|
|
101
296
|
const fullPath = path.join(process.cwd(), fPath);
|
|
102
|
-
// Don't overwrite existing .env files to protect API keys
|
|
103
297
|
if (fPath === '.env' && fs.existsSync(fullPath)) {
|
|
104
|
-
console.log(
|
|
298
|
+
console.log(' ⚠️ Skipped: .env');
|
|
105
299
|
return;
|
|
106
300
|
}
|
|
107
|
-
|
|
301
|
+
ensureDir(path.dirname(fullPath));
|
|
108
302
|
fs.writeFileSync(fullPath, content);
|
|
109
303
|
console.log(` 📄 Created: ${fPath}`);
|
|
110
304
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
GROQ_API_KEY=your_groq_api_key_here
|
|
118
|
-
OPENAI_API_KEY=your_openai_api_key_here
|
|
119
|
-
`;
|
|
120
|
-
fs.writeFileSync(envPath, defaultEnv);
|
|
121
|
-
console.log(` 📄 Created: .env (with defaults)`);
|
|
122
|
-
}
|
|
123
|
-
CLIUI.stopSpinner(true, 'Project architected successfully!');
|
|
305
|
+
const dotEnv = path.join(process.cwd(), '.env');
|
|
306
|
+
if (!fs.existsSync(dotEnv)) {
|
|
307
|
+
fs.writeFileSync(dotEnv, TEMPLATES.env);
|
|
308
|
+
console.log(' 📄 Created: .env');
|
|
309
|
+
}
|
|
310
|
+
CLIUI.stopSpinner(true, 'Project architected!');
|
|
124
311
|
}
|
|
125
312
|
catch (e) {
|
|
126
313
|
CLIUI.stopSpinner(false, e.message);
|
|
127
314
|
}
|
|
128
315
|
break;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
CLIUI.error(`[Dolphin-Agent]
|
|
135
|
-
});
|
|
316
|
+
}
|
|
317
|
+
// ── chat ─────────────────────────────────────────────────────────────
|
|
318
|
+
case 'chat': {
|
|
319
|
+
import('../ai/dolphin-agent/index.js')
|
|
320
|
+
.then(m => { const a = m.initAgentHook({ framework: 'dolphin', autoGenerateEnv: false }); a.interactiveChat(); })
|
|
321
|
+
.catch(err => CLIUI.error(`[Dolphin-Agent] ${err.message}`));
|
|
136
322
|
break;
|
|
323
|
+
}
|
|
324
|
+
// ── init / init-prod ─────────────────────────────────────────────────
|
|
137
325
|
case 'init':
|
|
138
|
-
case 'init-prod':
|
|
139
|
-
CLIUI.heading('
|
|
326
|
+
case 'init-prod': {
|
|
327
|
+
CLIUI.heading('Production Project Scaffold');
|
|
140
328
|
const dirs = ['models', 'controllers', 'routes', 'middleware', 'services', 'config'];
|
|
141
|
-
dirs.forEach(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
329
|
+
dirs.forEach(d => { ensureDir(path.join(process.cwd(), d)); console.log(` 📁 ${d}/`); });
|
|
330
|
+
const files = [
|
|
331
|
+
['app.js', TEMPLATES.app],
|
|
332
|
+
['config/db.js', TEMPLATES.mongoose],
|
|
333
|
+
['.env', TEMPLATES.env],
|
|
334
|
+
['.gitignore', 'node_modules/\ndist/\n.env\n*.log\n'],
|
|
335
|
+
];
|
|
336
|
+
files.forEach(([rel, content]) => {
|
|
337
|
+
const full = path.join(process.cwd(), rel);
|
|
338
|
+
if (!fs.existsSync(full)) {
|
|
339
|
+
fs.writeFileSync(full, content);
|
|
340
|
+
console.log(` 📄 Created: ${rel}`);
|
|
341
|
+
}
|
|
152
342
|
});
|
|
343
|
+
CLIUI.success('Structure ready!');
|
|
344
|
+
console.log('\n Next steps:');
|
|
345
|
+
console.log(' 1. npm install dolphin-server-modules mongoose');
|
|
346
|
+
console.log(' 2. dolphin connect mongoose — DB test');
|
|
347
|
+
console.log(' 3. node app.js — Server start');
|
|
348
|
+
import('../ai/dolphin-agent/index.js')
|
|
349
|
+
.then(m => m.initAgentHook({ framework: 'dolphin', autoGenerateEnv: true }))
|
|
350
|
+
.catch(() => { });
|
|
153
351
|
break;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
352
|
+
}
|
|
353
|
+
// ── add ──────────────────────────────────────────────────────────────
|
|
354
|
+
case 'add': {
|
|
355
|
+
const sub = args[1];
|
|
356
|
+
const name = args[2];
|
|
357
|
+
// add adapter
|
|
358
|
+
if (sub === 'adapter') {
|
|
359
|
+
const type = name || '';
|
|
360
|
+
const configDir = path.join(process.cwd(), 'config');
|
|
361
|
+
if (['mongoose', 'mongo', 'mongodb'].includes(type)) {
|
|
362
|
+
writeFile(path.join(configDir, 'db.js'), TEMPLATES.mongoose, 'config/db.js');
|
|
363
|
+
CLIUI.success('Mongoose adapter added!');
|
|
364
|
+
console.log('\n Usage: import { connectDB } from \'./config/db.js\';');
|
|
365
|
+
console.log(' connectDB(process.env.MONGO_URI);');
|
|
366
|
+
}
|
|
367
|
+
else if (['sequelize', 'mysql', 'postgres', 'sql'].includes(type)) {
|
|
368
|
+
writeFile(path.join(configDir, 'db.js'), TEMPLATES.sequelize, 'config/db.js');
|
|
369
|
+
CLIUI.success('Sequelize adapter added!');
|
|
370
|
+
console.log('\n MySQL: npm install sequelize mysql2');
|
|
371
|
+
console.log(' PostgreSQL: npm install sequelize pg pg-hstore');
|
|
372
|
+
}
|
|
373
|
+
else if (type === 'redis') {
|
|
374
|
+
writeFile(path.join(configDir, 'redis.js'), TEMPLATES.redis, 'config/redis.js');
|
|
375
|
+
CLIUI.success('Redis adapter added!');
|
|
376
|
+
console.log('\n Install: npm install redis');
|
|
377
|
+
console.log(' Usage: import { connectRedis, cache } from \'./config/redis.js\';');
|
|
164
378
|
}
|
|
165
379
|
else {
|
|
166
|
-
CLIUI.error('
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
380
|
+
CLIUI.error('Unknown adapter. Available: mongoose | sequelize | redis');
|
|
381
|
+
console.log(' Examples:');
|
|
382
|
+
console.log(' dolphin add adapter mongoose');
|
|
383
|
+
console.log(' dolphin add adapter sequelize');
|
|
384
|
+
console.log(' dolphin add adapter redis');
|
|
385
|
+
}
|
|
386
|
+
// add auth
|
|
387
|
+
}
|
|
388
|
+
else if (sub === 'auth') {
|
|
389
|
+
writeFile(path.join(process.cwd(), 'controllers', 'auth.js'), TEMPLATES.auth, 'controllers/auth.js');
|
|
390
|
+
writeFile(path.join(process.cwd(), 'models', 'User.js'), TEMPLATES.authModel, 'models/User.js');
|
|
391
|
+
CLIUI.success('Auth controller + User model added!');
|
|
392
|
+
console.log('\n app.js मा थप्नुहोस्:');
|
|
393
|
+
console.log(' import { auth } from \'./controllers/auth.js\';');
|
|
394
|
+
console.log(' app.post(\'/api/auth/register\', auth.register);');
|
|
395
|
+
console.log(' app.post(\'/api/auth/login\', auth.login);');
|
|
396
|
+
// add crud
|
|
397
|
+
}
|
|
398
|
+
else if (sub === 'crud') {
|
|
182
399
|
if (!name)
|
|
183
400
|
return CLIUI.error('Usage: dolphin add crud <ModelName>');
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
401
|
+
const N = capitalize(name);
|
|
402
|
+
writeFile(path.join(process.cwd(), 'controllers', `${N.toLowerCase()}.js`), TEMPLATES.crud(N), `controllers/${N.toLowerCase()}.js`);
|
|
403
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.crudModel(N), `models/${N}.js`);
|
|
404
|
+
CLIUI.success(`CRUD for ${N} generated!`);
|
|
405
|
+
// add model
|
|
406
|
+
}
|
|
407
|
+
else if (sub === 'model') {
|
|
408
|
+
if (!name)
|
|
409
|
+
return CLIUI.error('Usage: dolphin add model <ModelName> [--adapter]');
|
|
410
|
+
const N = capitalize(name);
|
|
411
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.model(N), `models/${N}.js`);
|
|
412
|
+
CLIUI.success(`${N} model added!`);
|
|
413
|
+
if (args.includes('--adapter') || args.includes('-a')) {
|
|
414
|
+
registerModelInAdapter(N);
|
|
415
|
+
}
|
|
416
|
+
// add model-adapter
|
|
417
|
+
}
|
|
418
|
+
else if (sub === 'model-adapter') {
|
|
419
|
+
if (!name)
|
|
420
|
+
return CLIUI.error('Usage: dolphin add model-adapter <ModelName>');
|
|
421
|
+
const N = capitalize(name);
|
|
422
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.model(N), `models/${N}.js`);
|
|
423
|
+
CLIUI.success(`${N} model added!`);
|
|
424
|
+
registerModelInAdapter(N);
|
|
425
|
+
// add middleware
|
|
426
|
+
}
|
|
427
|
+
else if (sub === 'middleware' || sub === 'mw') {
|
|
428
|
+
if (!name)
|
|
429
|
+
return CLIUI.error('Usage: dolphin add middleware <Name>');
|
|
430
|
+
const N = capitalize(name);
|
|
431
|
+
writeFile(path.join(process.cwd(), 'middleware', `${name.toLowerCase()}.js`), TEMPLATES.middleware(N), `middleware/${name.toLowerCase()}.js`);
|
|
432
|
+
CLIUI.success(`${N} middleware added!`);
|
|
433
|
+
console.log(`\n app.use() मा थप्नुहोस्: import { ${name.toLowerCase()}Middleware } from './middleware/${name.toLowerCase()}.js';`);
|
|
434
|
+
// add route
|
|
435
|
+
}
|
|
436
|
+
else if (sub === 'route' || sub === 'router') {
|
|
437
|
+
if (!name)
|
|
438
|
+
return CLIUI.error('Usage: dolphin add route <Name>');
|
|
439
|
+
const N = capitalize(name);
|
|
440
|
+
writeFile(path.join(process.cwd(), 'routes', `${name.toLowerCase()}.js`), TEMPLATES.route(N), `routes/${name.toLowerCase()}.js`);
|
|
441
|
+
CLIUI.success(`${N} route added!`);
|
|
442
|
+
console.log(`\n import { ${name.toLowerCase()}Router } from './routes/${name.toLowerCase()}.js';`);
|
|
443
|
+
console.log(` app.use('', ${name.toLowerCase()}Router);`);
|
|
444
|
+
// add service
|
|
445
|
+
}
|
|
446
|
+
else if (sub === 'service' || sub === 'svc') {
|
|
447
|
+
if (!name)
|
|
448
|
+
return CLIUI.error('Usage: dolphin add service <Name>');
|
|
449
|
+
const N = capitalize(name);
|
|
450
|
+
writeFile(path.join(process.cwd(), 'services', `${N}.service.js`), TEMPLATES.service(N), `services/${N}.service.js`);
|
|
451
|
+
CLIUI.success(`${N}Service added!`);
|
|
195
452
|
}
|
|
196
453
|
else {
|
|
197
|
-
CLIUI.error('Usage: dolphin add <
|
|
454
|
+
CLIUI.error('Usage: dolphin add <subcommand>');
|
|
455
|
+
console.log('\n adapter <mongoose|sequelize|redis> DB adapter');
|
|
456
|
+
console.log(' auth Auth system');
|
|
457
|
+
console.log(' crud <ModelName> CRUD controller + model');
|
|
458
|
+
console.log(' model <ModelName> [--adapter] Mongoose model (optionally registers it)');
|
|
459
|
+
console.log(' model-adapter <ModelName> Mongoose model & registers in adapter');
|
|
460
|
+
console.log(' middleware <Name> Middleware');
|
|
461
|
+
console.log(' route <Name> Route file');
|
|
462
|
+
console.log(' service <Name> Service class');
|
|
463
|
+
}
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
// ── status ───────────────────────────────────────────────────────────
|
|
467
|
+
case 'status': {
|
|
468
|
+
CLIUI.heading('Dolphin Project Status');
|
|
469
|
+
const cwd = process.cwd();
|
|
470
|
+
const checks = [
|
|
471
|
+
{ label: 'package.json', file: 'package.json' },
|
|
472
|
+
{ label: '.env', file: '.env' },
|
|
473
|
+
{ label: 'app.js / app.ts', file: 'app.js', alt: 'app.ts' },
|
|
474
|
+
{ label: 'config/db.js', file: 'config/db.js', alt: 'config/db.ts' },
|
|
475
|
+
{ label: 'models/', dir: 'models' },
|
|
476
|
+
{ label: 'controllers/', dir: 'controllers' },
|
|
477
|
+
{ label: 'routes/', dir: 'routes' },
|
|
478
|
+
{ label: 'middleware/', dir: 'middleware' },
|
|
479
|
+
{ label: 'services/', dir: 'services' },
|
|
480
|
+
];
|
|
481
|
+
checks.forEach(({ label, file, alt, dir }) => {
|
|
482
|
+
let exists = false;
|
|
483
|
+
if (dir)
|
|
484
|
+
exists = fs.existsSync(path.join(cwd, dir));
|
|
485
|
+
else
|
|
486
|
+
exists = fs.existsSync(path.join(cwd, file)) || (alt ? fs.existsSync(path.join(cwd, alt)) : false);
|
|
487
|
+
const icon = exists ? '\x1b[32m✔\x1b[0m' : '\x1b[33m–\x1b[0m';
|
|
488
|
+
console.log(` ${icon} ${label}`);
|
|
489
|
+
});
|
|
490
|
+
const projPkg = path.join(cwd, 'package.json');
|
|
491
|
+
if (fs.existsSync(projPkg)) {
|
|
492
|
+
const p = JSON.parse(fs.readFileSync(projPkg, 'utf8'));
|
|
493
|
+
const dsm = p.dependencies?.['dolphin-server-modules'] || p.devDependencies?.['dolphin-server-modules'];
|
|
494
|
+
console.log(`\n dolphin-server-modules: ${dsm || '(package.json मा छैन)'}`);
|
|
198
495
|
}
|
|
496
|
+
const dotEnv = path.join(cwd, '.env');
|
|
497
|
+
if (fs.existsSync(dotEnv)) {
|
|
498
|
+
const envText = fs.readFileSync(dotEnv, 'utf8');
|
|
499
|
+
console.log('\n .env keys:');
|
|
500
|
+
['MONGO_URI', 'JWT_SECRET', 'REDIS_URL', 'PORT'].forEach(k => {
|
|
501
|
+
const set = envText.includes(k + '=') && !envText.match(new RegExp(k + '=your_'));
|
|
502
|
+
console.log(` ${set ? '\x1b[32m✔\x1b[0m' : '\x1b[33m–\x1b[0m'} ${k}`);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
console.log(`\n 🐬 Dolphin CLI v${VERSION}`);
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
// ── deploy ───────────────────────────────────────────────────────────
|
|
509
|
+
case 'deploy': {
|
|
510
|
+
CLIUI.heading('Production Deployment (PM2)');
|
|
511
|
+
const entry = fs.existsSync(path.join(process.cwd(), 'dist/index.js')) ? 'dist/index.js'
|
|
512
|
+
: fs.existsSync(path.join(process.cwd(), 'app.js')) ? 'app.js' : 'index.js';
|
|
513
|
+
console.log(`
|
|
514
|
+
\x1b[1mStep 1\x1b[0m — PM2 install:
|
|
515
|
+
\x1b[36mnpm install -g pm2\x1b[0m
|
|
516
|
+
|
|
517
|
+
\x1b[1mStep 2\x1b[0m — Build (TypeScript भए):
|
|
518
|
+
\x1b[36mnpm run build\x1b[0m
|
|
519
|
+
|
|
520
|
+
\x1b[1mStep 3\x1b[0m — Start:
|
|
521
|
+
\x1b[36mpm2 start ${entry} --name "dolphin-app" --env production\x1b[0m
|
|
522
|
+
|
|
523
|
+
\x1b[1mStep 4\x1b[0m — Auto-start on reboot:
|
|
524
|
+
\x1b[36mpm2 startup && pm2 save\x1b[0m
|
|
525
|
+
|
|
526
|
+
\x1b[1mStep 5\x1b[0m — Logs:
|
|
527
|
+
\x1b[36mpm2 logs dolphin-app\x1b[0m
|
|
528
|
+
|
|
529
|
+
─── ecosystem.config.js (cluster mode) ────────────────
|
|
530
|
+
module.exports = {
|
|
531
|
+
apps: [{ name: 'dolphin-app', script: '${entry}',
|
|
532
|
+
instances: 'max', exec_mode: 'cluster',
|
|
533
|
+
env_production: { NODE_ENV: 'production', PORT: 3000 }
|
|
534
|
+
}]
|
|
535
|
+
};
|
|
536
|
+
\x1b[36mpm2 start ecosystem.config.js --env production\x1b[0m
|
|
537
|
+
`);
|
|
199
538
|
break;
|
|
539
|
+
}
|
|
540
|
+
// ── version ──────────────────────────────────────────────────────────
|
|
200
541
|
case '-v':
|
|
201
542
|
case '--version':
|
|
202
|
-
|
|
543
|
+
case 'version':
|
|
544
|
+
console.log(`🐬 Dolphin CLI v${VERSION}`);
|
|
203
545
|
break;
|
|
546
|
+
// ── help ─────────────────────────────────────────────────────────────
|
|
204
547
|
case 'help':
|
|
205
548
|
default:
|
|
206
|
-
CLIUI.heading(
|
|
549
|
+
CLIUI.heading(`Dolphin Framework CLI v${VERSION}`);
|
|
207
550
|
console.log(`
|
|
208
|
-
|
|
209
|
-
serve
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
add
|
|
215
|
-
add
|
|
216
|
-
add
|
|
217
|
-
-
|
|
218
|
-
|
|
219
|
-
|
|
551
|
+
\x1b[1mServer\x1b[0m
|
|
552
|
+
serve [--port=N] Dev server start गर्ने
|
|
553
|
+
|
|
554
|
+
\x1b[1mScaffolding\x1b[0m
|
|
555
|
+
init / init-prod Production project scaffold
|
|
556
|
+
add adapter <type> DB adapter (mongoose|sequelize|redis)
|
|
557
|
+
add auth Auth controller + User model
|
|
558
|
+
add crud <ModelName> CRUD controller + Model
|
|
559
|
+
add model <ModelName> Mongoose model मात्र (use --adapter or model-adapter to register)
|
|
560
|
+
add model-adapter <ModelName> Mongoose model + registers in adapter
|
|
561
|
+
add middleware <Name> Middleware file
|
|
562
|
+
add route <Name> Route file
|
|
563
|
+
add service <Name> Service class
|
|
564
|
+
|
|
565
|
+
\x1b[1mDatabase\x1b[0m
|
|
566
|
+
connect mongoose [uri] MongoDB connection test
|
|
567
|
+
connect redis [uri] Redis connection test
|
|
568
|
+
|
|
569
|
+
\x1b[1mAI (API key चाहिन्छ)\x1b[0m
|
|
570
|
+
generate <prompt> Quick AI code generation
|
|
571
|
+
generate-full <prompt> Full project AI architecture
|
|
572
|
+
chat Autonomous AI Agent (Cursor mode)
|
|
573
|
+
|
|
574
|
+
\x1b[1mProject\x1b[0m
|
|
575
|
+
status Project health check
|
|
576
|
+
deploy PM2 deployment guide
|
|
577
|
+
|
|
578
|
+
\x1b[1mInfo\x1b[0m
|
|
579
|
+
-v / --version Version
|
|
580
|
+
help यो help
|
|
581
|
+
`);
|
|
220
582
|
}
|
|
221
583
|
}
|
|
222
584
|
run().catch(err => {
|
|
223
585
|
CLIUI.error(err.message);
|
|
586
|
+
process.exit(1);
|
|
224
587
|
});
|
|
225
588
|
//# sourceMappingURL=cli.js.map
|