@flowdevcli/flowdev 1.0.4 → 1.0.5

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/.env.example CHANGED
@@ -3,3 +3,4 @@
3
3
 
4
4
  OLLAMA_MODEL=
5
5
 
6
+
package/Dockerfile CHANGED
@@ -1,14 +1,14 @@
1
1
  # Stage 1: Build
2
- FROM node:18-alpine AS builder
2
+ FROM node:28-alpine AS builder
3
3
  WORKDIR /app
4
4
  COPY package*.json ./
5
5
  RUN npm ci
6
6
  COPY . .
7
7
 
8
8
  # Stage 2: Production
9
- FROM node:18-alpine
9
+ FROM node:28-alpine
10
10
  WORKDIR /app
11
11
  COPY --from=builder /app ./
12
12
  EXPOSE 3000
13
13
  # Formats the command string into a JSON array for CMD
14
- CMD ["npm", "run", "dev"]
14
+ CMD ["npm", "start"]
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ FLOWDEV
2
+ =======
3
+ The intelligent CLI for modern workflow automation.
4
+
5
+ FlowDev is a privacy-first, offline-capable CLI tool designed to accelerate developer workflows. From scaffolding Docker environments to generating project structures using local or cloud AI, FlowDev keeps you in the flow without leaving your terminal.
6
+
7
+ > "The developer tool for the next generation."
8
+
9
+ [![npm version](https://img.shields.io/npm/v/flowdev.svg?style=flat-square)](https://www.npmjs.com/package/flowdev)
10
+ [![install size](https://img.shields.io/badge/install%20size-unknown-blue?style=flat-square)](https://packagephobia.com/result?p=flowdev)
11
+ [![downloads](https://img.shields.io/npm/dm/flowdev.svg?style=flat-square)](https://www.npmjs.com/package/flowdev)
12
+
13
+ Install
14
+ =======
15
+
16
+ Global Installation (Recommended)
17
+ ---------------------------------
18
+ To use FlowDev commands anywhere on your system:
19
+
20
+ ```bash
21
+ npm install -g flowdev
22
+
23
+ Local Installation
24
+
25
+ If you prefer to use it per project:
26
+ Bash
27
+
28
+ npm install flowdev --save-dev
29
+
30
+ Usage
31
+
32
+ Once installed, FlowDev exposes the flowdev binary.
33
+
34
+ Check your installation:
35
+
36
+ Bash
37
+ flowdev --version
38
+
39
+ *Configure your environment (API keys & Models):
40
+ Bash
41
+ flowdev config
42
+
43
+
44
+ *Analyze your current project:
45
+ Bash
46
+ flowdev stats
47
+
48
+ *Generate a Docker environment:
49
+ Bash
50
+ flowdev dockerize
51
+
52
+ Features
53
+ AI & Automation (Hybrid Engine)
54
+
55
+ FlowDev integrates with Ollama for offline capabilities and supports DeepSeek for high-performance cloud reasoning.
56
+
57
+ 1. Smart Assistant
58
+ Ask questions about code or architecture using local or cloud models.
59
+ Bash
60
+
61
+ flowdev ask "How do I optimize a React useEffect hook?"
62
+
63
+ 2. Intelligent Audit
64
+ Audit your code for bugs, security, and performance using AI.
65
+ Bash
66
+
67
+ flowdev audit
68
+
69
+ 3. Automatic Documentation
70
+ Generate a professional README.md for your project instantly.
71
+ Bash
72
+
73
+ flowdev readme
74
+
75
+ DevOps & Infrastructure
76
+
77
+ 1. Dockerize
78
+ Instantly generate production-ready Dockerfile and docker-compose.yml files.
79
+ Bash
80
+
81
+ flowdev dockerize
82
+
83
+ 2. Kubernetes (Kube)
84
+ Generate Kubernetes deployment and service manifests for your application.
85
+ Bash
86
+
87
+ flowdev kube
88
+
89
+ Utilities
90
+
91
+ 1. Generate
92
+ Generate a complete project (React, Django, Vue, Angular, Express) with Git and dependencies automatically configured.
93
+ Bash
94
+
95
+ flowdev generate
96
+
97
+ 2. Find (Pattern Search)
98
+ A recursive search tool optimized for developers. Ignores node_modules and binaries.
99
+ Bash
100
+
101
+ flowdev find "TODO" --ext js,ts
102
+
103
+ 3. Stats
104
+ Get an instant breakdown of your project's size, file count, and language distribution.
105
+ Bash
106
+
107
+ flowdev stats
108
+
109
+ Requirements
110
+ Node.js
111
+
112
+ FlowDev requires Node.js v18+.
113
+ Local AI (Optional)
114
+
115
+ To use local AI features, you must have Ollama running locally.
116
+
117
+ Install Ollama: ollama.com
118
+
119
+ Start the service: ollama serve
120
+
121
+ FlowDev handles the rest.
122
+
123
+ Cloud AI (Optional)
124
+
125
+ To use Cloud features (DeepSeek), configure your API key via flowdev config.
126
+ Documentation
127
+ flowdev generate
128
+
129
+ Provisions full-stack templates. Includes a fail-safe execution wrapper that generates a flowdev-debug.log if an installation fails.
130
+ flowdev audit
131
+
132
+ Uses AI to scan for security vulnerabilities and logic flaws. Perfect for pre-commit checks.
133
+ flowdev dockerize
134
+
135
+ Generates optimized configurations using multi-stage builds and non-root security practices.
136
+ flowdev env
137
+
138
+ Scans your project code and generates a .env.example file based on your environment variable usage.
139
+ FAQ
140
+ Does FlowDev send my code to the cloud?
141
+
142
+ By default, No. Local AI processing happens on your machine via Ollama. Cloud processing is only used if you explicitly configure it and choose a cloud model.
143
+ Do I need an API Key?
144
+
145
+ No for local use. Yes if you wish to use cloud models like DeepSeek.
146
+ Why "flowdev"?
147
+
148
+ Because switching contexts breaks your flow. FlowDev keeps you in the terminal, automating the boring stuff so you can focus on the code.
149
+ Changelog
150
+
151
+ See CHANGELOG.md for details on recent updates.
152
+ License
153
+
154
+ [MIT](https://www.google.com/search?q=LICENSE)
155
+
156
+
157
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowdevcli/flowdev",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "AI-powered CLI tool",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,12 +26,13 @@
26
26
  "boxen": "^7.1.1",
27
27
  "chalk": "^5.3.0",
28
28
  "commander": "^11.1.0",
29
+ "conf": "^15.1.0",
29
30
  "dotenv": "^16.3.1",
30
31
  "execa": "^8.0.1",
31
32
  "figlet": "^1.7.0",
32
33
  "fs-extra": "^11.1.1",
33
34
  "gradient-string": "^2.0.2",
34
- "inquirer": "^9.2.11",
35
+ "inquirer": "^9.3.8",
35
36
  "is-binary-path": "^3.0.0",
36
37
  "mammoth": "^1.11.0",
37
38
  "ollama": "^0.6.3",
@@ -46,4 +47,4 @@
46
47
  "publishConfig": {
47
48
  "access": "public"
48
49
  }
49
- }
50
+ }
@@ -1,94 +1,27 @@
1
- import ollama from 'ollama';
1
+ /**
2
+ * @fileoverview FlowDev - Intelligent CLI tool
3
+ * @module flowdev
4
+ * @version 1.0.5
5
+ * * @license MIT
6
+ * Copyright (c) 2026 FlowDev Technologies.
7
+ * * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ * * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ */
19
+
2
20
  import chalk from 'chalk';
3
21
  import ora from 'ora';
4
22
  import fs from 'fs-extra';
5
- import { exec, spawn } from 'node:child_process';
6
- import { promisify } from 'util';
7
23
  import { logger } from '../../utils/logger.js';
8
-
9
- const execAsync = promisify(exec);
10
-
11
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
12
-
13
-
14
- async function waitForOllamaServer({ retries = 15, delayMs = 1000 } = {}) {
15
- for (let i = 0; i < retries; i++) {
16
- try {
17
- await ollama.list();
18
- return true;
19
- } catch (e) {
20
-
21
- logger.debug(`Ollama not ready (attempt ${i + 1}/${retries}): ${e.message}`);
22
- await sleep(delayMs);
23
- }
24
- }
25
- return false;
26
- }
27
-
28
- async function installOllamaEngine(spinner) {
29
- const isWindows = process.platform === 'win32';
30
- const installCmd = isWindows
31
- ? 'winget install Ollama.Ollama --silent --accept-source-agreements'
32
- : 'curl -fsSL https://ollama.com/install.sh | sh';
33
-
34
- spinner.text = chalk.yellow('Downloading FlowDev engine package... (This may take a while)');
35
-
36
- try {
37
-
38
- const { stdout, stderr } = await execAsync(installCmd, { maxBuffer: 10 * 1024 * 1024 });
39
- logger.debug('install stdout: ' + (stdout || '').toString().slice(0, 2000));
40
- logger.debug('install stderr: ' + (stderr || '').toString().slice(0, 2000));
41
-
42
- spinner.succeed(chalk.green('FlowDev Engine installed successfully!'));
43
-
44
- await sleep(1500);
45
- } catch (error) {
46
-
47
- spinner.fail(chalk.red('Automatic installation failed (admin rights or network?)'));
48
- logger.error('Automatic installation error: ' + (error.message || error));
49
- if (error.stdout || error.stderr) {
50
- logger.error('Installer output (truncated):');
51
- logger.error((error.stdout || '').toString().slice(0, 500));
52
- logger.error((error.stderr || '').toString().slice(0, 500));
53
- }
54
-
55
- logger.error(`Try installing it manually: ${isWindows ? 'winget install Ollama.Ollama' : 'curl -fsSL https://ollama.com/install.sh | sh'}`);
56
- throw error;
57
- }
58
- }
59
-
60
- async function ensureOllamaRunning(spinner) {
61
- try {
62
-
63
- await execAsync('ollama --version');
64
- } catch (e) {
65
- logger.info('Ollama binary not found. Attempting automatic install...');
66
-
67
- await installOllamaEngine(spinner);
68
- }
69
-
70
-
71
- if (await waitForOllamaServer({ retries: 3, delayMs: 1000 })) {
72
- return;
73
- }
74
-
75
-
76
- logger.info('Starting ollama serve in background...');
77
- try {
78
-
79
- const child = spawn('ollama', ['serve'], { detached: true, stdio: 'ignore' });
80
- child.unref();
81
- } catch (spawnErr) {
82
- logger.error('Failed to spawn ollama serve: ' + spawnErr.message);
83
- throw spawnErr;
84
- }
85
-
86
-
87
- const ready = await waitForOllamaServer({ retries: 30, delayMs: 1000 });
88
- if (!ready) {
89
- throw new Error('Ollama server did not start in time. Check logs or run `ollama serve` manually.');
90
- }
91
- }
24
+ import { getAIResponse } from '../../utils/engine-check.js';
92
25
 
93
26
  export async function askCommand(question) {
94
27
  if (!question) {
@@ -99,80 +32,33 @@ export async function askCommand(question) {
99
32
  let spinner = ora(chalk.cyan('Initialization...')).start();
100
33
 
101
34
  try {
102
- await ensureOllamaRunning(spinner);
103
-
104
-
105
- const modelName = process.env.OLLAMA_MODEL || 'llama3';
106
-
107
- let hasModel = false;
108
- try {
109
- const models = await ollama.list();
110
- hasModel = Array.isArray(models?.models) && models.models.some((m) => m.name?.startsWith(modelName));
111
- } catch (err) {
112
- logger.debug('Error listing models: ' + (err?.message || err));
113
-
114
- }
115
-
116
- if (!hasModel) {
117
- spinner.text = chalk.magenta('First launch: Configuring neurons...');
118
- spinner.start();
119
-
120
- try {
121
- await ollama.pull({ model: modelName });
122
- spinner.succeed(chalk.green('AI brain in charge !'));
123
- } catch (pullErr) {
124
- spinner.fail(chalk.red('Failed to download model.'));
125
- logger.error('ollama.pull error: ' + (pullErr?.message || pullErr));
126
- throw pullErr;
127
- }
128
-
129
-
130
- spinner = ora(chalk.cyan('Thinking...')).start();
131
- } else {
132
- spinner.text = chalk.cyan('Thinking...');
133
- }
134
-
135
-
136
- let context = 'flowdev intelligent CLI tool';
35
+ let context = 'You are FlowDev, an intelligent CLI assistant.';
137
36
  try {
138
37
  if (await fs.pathExists('package.json')) {
139
38
  const pkg = await fs.readJson('package.json');
140
- if (pkg?.name) context += ` CURRENT CONTEXT: The user is in the project folder "${pkg.name}".`;
39
+ if (pkg?.name) context += ` CURRENT CONTEXT: User is in project "${pkg.name}".`;
141
40
  }
142
- } catch (e) {
143
- logger.debug('Failed to read package.json: ' + (e?.message || e));
144
- }
145
-
146
- const response = await ollama.chat({
147
- model: modelName,
148
- messages: [
149
- { role: 'system', content: context },
150
- { role: 'user', content: question },
151
- ],
152
- stream: true,
153
- });
41
+ } catch (e) {}
42
+ const responseStream = await getAIResponse(
43
+ [
44
+ { role: 'system', content: context },
45
+ { role: 'user', content: question }
46
+ ],
47
+ spinner
48
+ );
154
49
 
155
-
156
50
  spinner.stop();
51
+ console.log(chalk.bold.magenta('FlowDev:'));
157
52
 
158
- for await (const part of response) {
53
+ for await (const part of responseStream) {
159
54
  const content = part?.message?.content;
160
55
  if (typeof content === 'string') {
161
56
  process.stdout.write(chalk.white(content));
162
57
  }
163
58
  }
164
-
165
59
  process.stdout.write('\n');
166
60
  } catch (error) {
167
-
168
- try { spinner.stop(); } catch (_) {}
169
-
170
- logger.error('askCommand error: ' + (error?.message || error));
171
-
172
- if (error?.code === 'ENOENT') {
173
- console.log(chalk.red('\nUnable to find or install Ollama automatically.'));
174
- } else {
175
- console.log(chalk.red(`\nError: ${error?.message || error}`));
176
- }
61
+ spinner.stop();
62
+ logger.error('Error: ' + error.message);
177
63
  }
178
- }
64
+ }
@@ -1,9 +1,27 @@
1
- import ollama from 'ollama';
1
+ /**
2
+ * @fileoverview FlowDev - Intelligent CLI tool
3
+ * @module flowdev
4
+ * @version 1.0.5
5
+ * * @license MIT
6
+ * Copyright (c) 2026 FlowDev Technologies.
7
+ * * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ * * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ */
19
+
2
20
  import chalk from 'chalk';
3
21
  import ora from 'ora';
4
22
  import fs from 'fs-extra';
5
23
  import path from 'path';
6
- import { ensureEngineReady } from '../../utils/engine-check.js';
24
+ import { getAIResponse } from '../../utils/engine-check.js';
7
25
  import { logger } from '../../utils/logger.js';
8
26
 
9
27
  const AUDIT_EXTENSIONS = ['.js', '.ts', '.py', '.php', '.go', '.jsx', '.tsx', '.vue'];
@@ -31,18 +49,15 @@ export async function auditCommand() {
31
49
  return;
32
50
  }
33
51
 
34
- await ensureEngineReady(spinner, 'llama3');
35
-
36
- spinner.text = chalk.magenta(`Auditing ${files.length} files...`);
52
+ spinner.text = chalk.magenta(`Preparing audit for ${files.length} files...`);
37
53
 
38
54
  let codeContext = "";
39
- for (const file of files.slice(0, 10)) {
55
+ for (const file of files.slice(0, 15)) {
40
56
  const content = await fs.readFile(file, 'utf-8');
41
57
  codeContext += `\n--- File: ${path.basename(file)} ---\n${content}\n`;
42
58
  }
43
59
 
44
60
  const prompt = `
45
- As an Expert Security Auditor,
46
61
  Analyze the following code for:
47
62
  1. Potential Bugs or logic errors.
48
63
  2. Security vulnerabilities (exposed keys, unsafe inputs).
@@ -50,26 +65,21 @@ export async function auditCommand() {
50
65
  4. Code quality and Best Practices.
51
66
 
52
67
  Provide a concise report with clear headings and bullet points.
53
- If the code is perfect, congratulate the developer.
54
68
 
55
69
  Code to analyze:
56
- ${codeContext}
70
+ ${codeContext.substring(0, 30000)}
57
71
  `;
58
-
59
- const response = await ollama.chat({
60
- model: 'llama3',
61
- messages: [{ role: 'user', content: prompt }],
62
- stream: true,
63
- });
72
+ const responseStream = await getAIResponse(
73
+ [{ role: 'user', content: prompt }],
74
+ spinner
75
+ );
64
76
 
65
77
  spinner.stop();
66
- console.log(chalk.bold.yellow('\n FLOWDEV AUDIT REPORT\n'));
67
-
68
- for await (const part of response) {
78
+ for await (const part of responseStream) {
69
79
  process.stdout.write(chalk.white(part.message.content));
70
80
  }
71
81
 
72
- console.log(chalk.cyan('\n\nAudit complete. Always double-check AI suggestions before applying.'));
82
+ console.log(chalk.cyan('\n\nAudit complete. Always verify AI suggestions.'));
73
83
 
74
84
  } catch (error) {
75
85
  spinner.stop();
@@ -1,11 +1,29 @@
1
- import ollama from 'ollama';
1
+ /**
2
+ * @fileoverview FlowDev - Intelligent CLI tool
3
+ * @module flowdev
4
+ * @version 1.0.5
5
+ * * @license MIT
6
+ * Copyright (c) 2026 FlowDev Technologies.
7
+ * * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ * * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ */
19
+
2
20
  import chalk from 'chalk';
3
21
  import ora from 'ora';
4
22
  import fs from 'fs-extra';
5
23
  import path from 'path';
6
24
  import isBinaryPath from 'is-binary-path';
7
25
  import { createRequire } from 'module';
8
- import { ensureEngineReady } from '../../utils/engine-check.js';
26
+ import { getAIResponse } from '../../utils/engine-check.js';
9
27
  import { logger } from '../../utils/logger.js';
10
28
 
11
29
  const require = createRequire(import.meta.url);
@@ -38,27 +56,26 @@ export async function explainCommand(filePath) {
38
56
  const spinner = ora(chalk.cyan('Initializing...')).start();
39
57
 
40
58
  try {
41
- await ensureEngineReady(spinner, 'llama3');
42
-
43
59
  spinner.text = chalk.cyan(`Reading ${path.basename(filePath)}...`);
44
60
  const content = await extractText(filePath);
45
61
 
46
- spinner.text = chalk.magenta('Analyzing content...');
47
- const response = await ollama.chat({
48
- model: 'llama3',
49
- messages: [{
50
- role: 'user',
51
- content: `Explain the following content clearly and concisely:\n\n${content.substring(0, 15000)}`
52
- }],
53
- stream: true,
54
- });
62
+
63
+ const responseStream = await getAIResponse(
64
+ [{
65
+ role: 'user',
66
+ content: `Explain the following content clearly and concisely:\n\n${content.substring(0, 15000)}`
67
+ }],
68
+ spinner
69
+ );
55
70
 
56
71
  spinner.stop();
57
72
  console.log(chalk.red.bold(`ANALYSIS: ${path.basename(filePath).toUpperCase()} `));
58
73
 
59
- for await (const part of response) {
74
+ for await (const part of responseStream) {
60
75
  process.stdout.write(chalk.white(part.message.content));
61
76
  }
77
+ process.stdout.write('\n');
78
+
62
79
  } catch (error) {
63
80
  spinner.stop();
64
81
  logger.error(`Explain error: ${error.message}`);
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @fileoverview FlowDev - Intelligent CLI tool
3
+ * @module flowdev
4
+ * @version 1.0.5
5
+ * * @license MIT
6
+ * Copyright (c) 2026 FlowDev Technologies.
7
+ * * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ * * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ */
19
+
20
+ import chalk from 'chalk';
21
+ import ora from 'ora';
22
+ import fs from 'fs-extra';
23
+ import path from 'path';
24
+ import { getAIResponse } from '../../utils/engine-check.js';
25
+ import { logger } from '../../utils/logger.js';
26
+
27
+ export async function readmeCommand() {
28
+ const spinner = ora(chalk.cyan('Reading project structure...')).start();
29
+
30
+ try {
31
+ const rootDir = process.cwd();
32
+ let projectInfo = "";
33
+
34
+ if (await fs.pathExists(path.join(rootDir, 'package.json'))) {
35
+ const pkg = await fs.readJson(path.join(rootDir, 'package.json'));
36
+ projectInfo += `Type: Node.js, Name: ${pkg.name}, Deps: ${Object.keys(pkg.dependencies || {}).join(', ')}`;
37
+ } else if (await fs.pathExists(path.join(rootDir, 'manage.py'))) {
38
+ projectInfo += `Type: Django/Python project`;
39
+ }
40
+
41
+ const prompt = `
42
+ Generate a professional README.md for a project with these details: ${projectInfo}.
43
+ The README should include:
44
+ - A catchy title with an emoji.
45
+ - Description, Installation, Usage.
46
+ - Return ONLY the markdown content.
47
+ `;
48
+
49
+ const responseStream = await getAIResponse(
50
+ [{ role: 'user', content: prompt }],
51
+ spinner
52
+ );
53
+
54
+ let readmeContent = "";
55
+ spinner.text = chalk.magenta('Drafting your documentation...');
56
+
57
+ for await (const part of responseStream) {
58
+ readmeContent += part.message.content;
59
+ }
60
+
61
+ const readmePath = path.join(rootDir, 'README.md');
62
+ await fs.writeFile(readmePath, readmeContent);
63
+
64
+ spinner.succeed(chalk.green('README.md generated successfully!'));
65
+
66
+ } catch (error) {
67
+ spinner.stop();
68
+ logger.error('Failed to generate README: ' + error.message);
69
+ }
70
+ }