agentic-kdd 2.1.1 → 2.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/package.json +1 -1
- package/src/init.js +53 -412
package/package.json
CHANGED
package/src/init.js
CHANGED
|
@@ -5,228 +5,10 @@ const path = require('path');
|
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
6
|
const chalk = require('chalk');
|
|
7
7
|
const ora = require('ora');
|
|
8
|
-
const inquirer = require('inquirer');
|
|
9
8
|
|
|
10
9
|
const GITHUB_REPO = 'Adrianlpz211/Agentic-KDD';
|
|
11
10
|
const TEMP_DIR = path.join(require('os').tmpdir(), 'agentic-kdd-download');
|
|
12
11
|
|
|
13
|
-
// ── Plantillas por stack ────────────────────────────────────────
|
|
14
|
-
const TEMPLATES = {
|
|
15
|
-
nextjs: {
|
|
16
|
-
nombre: 'Next.js App',
|
|
17
|
-
tipo: 'NUEVO',
|
|
18
|
-
modulos_impl: [
|
|
19
|
-
'| 1 | Auth y middleware | /login, /registro, middleware.ts |',
|
|
20
|
-
'| 2 | Layout y navegación | app/layout.tsx, componentes nav |',
|
|
21
|
-
],
|
|
22
|
-
modulos_pend: [
|
|
23
|
-
'- [ ] Dashboard principal',
|
|
24
|
-
'- [ ] Módulo de usuarios',
|
|
25
|
-
'- [ ] API routes principales',
|
|
26
|
-
],
|
|
27
|
-
reglas: [
|
|
28
|
-
'- App Router (no Pages Router)',
|
|
29
|
-
'- Server Components por defecto, Client Components solo cuando necesario',
|
|
30
|
-
'- Queries de base de datos solo en lib/queries/',
|
|
31
|
-
'- Tailwind CSS para estilos',
|
|
32
|
-
'- TypeScript estricto',
|
|
33
|
-
],
|
|
34
|
-
descripcion: 'Aplicación web con Next.js 14 App Router, TypeScript y Tailwind CSS.',
|
|
35
|
-
},
|
|
36
|
-
laravel: {
|
|
37
|
-
nombre: 'Laravel App',
|
|
38
|
-
tipo: 'NUEVO',
|
|
39
|
-
modulos_impl: [
|
|
40
|
-
'| 1 | Auth y roles | routes/auth.php, AuthController |',
|
|
41
|
-
'| 2 | Modelos base | app/Models/, migraciones |',
|
|
42
|
-
],
|
|
43
|
-
modulos_pend: [
|
|
44
|
-
'- [ ] Panel de administración',
|
|
45
|
-
'- [ ] API REST principal',
|
|
46
|
-
'- [ ] Jobs y queues',
|
|
47
|
-
],
|
|
48
|
-
reglas: [
|
|
49
|
-
'- Lógica de negocio en Services, no en Controllers',
|
|
50
|
-
'- Queries complejas en Repositories',
|
|
51
|
-
'- Form Requests para validación',
|
|
52
|
-
'- Resources para transformar respuestas API',
|
|
53
|
-
'- Jobs para procesos en background',
|
|
54
|
-
],
|
|
55
|
-
descripcion: 'Aplicación web con Laravel, MySQL y arquitectura MVC.',
|
|
56
|
-
},
|
|
57
|
-
node: {
|
|
58
|
-
nombre: 'Node.js API',
|
|
59
|
-
tipo: 'NUEVO',
|
|
60
|
-
modulos_impl: [
|
|
61
|
-
'| 1 | Servidor y configuración | index.js, config/, middleware |',
|
|
62
|
-
'| 2 | Auth JWT | routes/auth.js, middleware/auth.js |',
|
|
63
|
-
],
|
|
64
|
-
modulos_pend: [
|
|
65
|
-
'- [ ] Endpoints principales',
|
|
66
|
-
'- [ ] Base de datos y modelos',
|
|
67
|
-
'- [ ] Tests de integración',
|
|
68
|
-
],
|
|
69
|
-
reglas: [
|
|
70
|
-
'- Express con middleware centralizado',
|
|
71
|
-
'- Lógica en services/, no en routes',
|
|
72
|
-
'- Variables de entorno en .env, nunca hardcoded',
|
|
73
|
-
'- Manejo de errores centralizado',
|
|
74
|
-
],
|
|
75
|
-
descripcion: 'API REST con Node.js, Express y base de datos.',
|
|
76
|
-
},
|
|
77
|
-
react: {
|
|
78
|
-
nombre: 'React App',
|
|
79
|
-
tipo: 'NUEVO',
|
|
80
|
-
modulos_impl: [
|
|
81
|
-
'| 1 | Estructura base | App.tsx, router, layout |',
|
|
82
|
-
'| 2 | Estado global | context o zustand |',
|
|
83
|
-
],
|
|
84
|
-
modulos_pend: [
|
|
85
|
-
'- [ ] Componentes principales',
|
|
86
|
-
'- [ ] Integración con API',
|
|
87
|
-
'- [ ] Tests de componentes',
|
|
88
|
-
],
|
|
89
|
-
reglas: [
|
|
90
|
-
'- Componentes funcionales con hooks',
|
|
91
|
-
'- Estado local con useState, global con Context/Zustand',
|
|
92
|
-
'- Llamadas API centralizadas en services/',
|
|
93
|
-
'- CSS Modules o Tailwind, no inline styles',
|
|
94
|
-
],
|
|
95
|
-
descripcion: 'Aplicación React con TypeScript y gestión de estado.',
|
|
96
|
-
},
|
|
97
|
-
php: {
|
|
98
|
-
nombre: 'PHP App',
|
|
99
|
-
tipo: 'NUEVO',
|
|
100
|
-
modulos_impl: [
|
|
101
|
-
'| 1 | Configuración base | config.php, conexión DB |',
|
|
102
|
-
'| 2 | Auth | login.php, session |',
|
|
103
|
-
],
|
|
104
|
-
modulos_pend: [
|
|
105
|
-
'- [ ] Módulo principal',
|
|
106
|
-
'- [ ] Panel de administración',
|
|
107
|
-
],
|
|
108
|
-
reglas: [
|
|
109
|
-
'- Queries preparadas siempre (PDO)',
|
|
110
|
-
'- Validación en el servidor',
|
|
111
|
-
'- Sin lógica en las vistas',
|
|
112
|
-
],
|
|
113
|
-
descripcion: 'Aplicación PHP con MySQL.',
|
|
114
|
-
},
|
|
115
|
-
python: {
|
|
116
|
-
nombre: 'Python App',
|
|
117
|
-
tipo: 'NUEVO',
|
|
118
|
-
modulos_impl: [
|
|
119
|
-
'| 1 | Estructura base | main.py, config.py |',
|
|
120
|
-
'| 2 | Auth | auth/, middleware |',
|
|
121
|
-
],
|
|
122
|
-
modulos_pend: [
|
|
123
|
-
'- [ ] Endpoints principales',
|
|
124
|
-
'- [ ] Base de datos',
|
|
125
|
-
'- [ ] Tests',
|
|
126
|
-
],
|
|
127
|
-
reglas: [
|
|
128
|
-
'- FastAPI o Django según el proyecto',
|
|
129
|
-
'- Pydantic para validación',
|
|
130
|
-
'- SQLAlchemy para queries',
|
|
131
|
-
'- pytest para tests',
|
|
132
|
-
],
|
|
133
|
-
descripcion: 'Aplicación Python con FastAPI/Django.',
|
|
134
|
-
},
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// ── Detectar stack ──────────────────────────────────────────────
|
|
138
|
-
function detectStack(projectPath) {
|
|
139
|
-
const stack = {
|
|
140
|
-
framework: '—', language: '—', runtime: '—',
|
|
141
|
-
base_datos: '—', packageManager: 'npm',
|
|
142
|
-
templateKey: null,
|
|
143
|
-
commands: { install: 'npm install', dev: 'npm run dev', build: 'npm run build', test: 'npm test', lint: 'npm run lint' }
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
if (fs.existsSync(path.join(projectPath, 'package.json'))) {
|
|
147
|
-
const pkg = fs.readJsonSync(path.join(projectPath, 'package.json'), { throws: false }) || {};
|
|
148
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
149
|
-
stack.language = deps['typescript'] ? 'TypeScript' : 'JavaScript';
|
|
150
|
-
stack.runtime = 'Node.js';
|
|
151
|
-
|
|
152
|
-
if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
|
|
153
|
-
stack.packageManager = 'pnpm';
|
|
154
|
-
stack.commands = { install: 'pnpm install', dev: 'pnpm dev', build: 'pnpm build', test: 'pnpm test', lint: 'pnpm lint' };
|
|
155
|
-
} else if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
|
|
156
|
-
stack.packageManager = 'yarn';
|
|
157
|
-
stack.commands = { install: 'yarn', dev: 'yarn dev', build: 'yarn build', test: 'yarn test', lint: 'yarn lint' };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (deps['next']) {
|
|
161
|
-
stack.framework = `Next.js ${(deps['next']||'').replace(/[\^~]/,'')}`;
|
|
162
|
-
stack.templateKey = 'nextjs';
|
|
163
|
-
if (deps['@supabase/supabase-js']) stack.base_datos = 'Supabase PostgreSQL';
|
|
164
|
-
else if (deps['prisma'] || deps['@prisma/client']) stack.base_datos = 'Prisma';
|
|
165
|
-
else if (deps['mongoose']) stack.base_datos = 'MongoDB';
|
|
166
|
-
} else if (deps['vue']) {
|
|
167
|
-
stack.framework = `Vue ${(deps['vue']||'').replace(/[\^~]/,'')}`;
|
|
168
|
-
} else if (deps['react'] && !deps['next']) {
|
|
169
|
-
stack.framework = 'React';
|
|
170
|
-
stack.templateKey = 'react';
|
|
171
|
-
} else if (deps['express']) {
|
|
172
|
-
stack.framework = 'Express';
|
|
173
|
-
stack.templateKey = 'node';
|
|
174
|
-
stack.commands.dev = pkg.scripts?.dev || 'node index.js';
|
|
175
|
-
} else if (deps['fastify']) {
|
|
176
|
-
stack.framework = 'Fastify';
|
|
177
|
-
stack.templateKey = 'node';
|
|
178
|
-
} else if (deps['@nestjs/core']) {
|
|
179
|
-
stack.framework = 'NestJS';
|
|
180
|
-
stack.templateKey = 'node';
|
|
181
|
-
stack.commands.dev = 'npm run start:dev';
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (fs.existsSync(path.join(projectPath, 'composer.json'))) {
|
|
186
|
-
const composer = fs.readJsonSync(path.join(projectPath, 'composer.json'), { throws: false }) || {};
|
|
187
|
-
stack.language = 'PHP'; stack.runtime = 'PHP';
|
|
188
|
-
stack.packageManager = 'composer';
|
|
189
|
-
stack.commands = { install: 'composer install', dev: 'php artisan serve', build: 'composer build', test: './vendor/bin/phpunit', lint: 'composer lint' };
|
|
190
|
-
if ((composer.require || {})['laravel/framework']) {
|
|
191
|
-
stack.framework = `Laravel ${((composer.require||{})['laravel/framework']||'').replace(/[\^~]/,'')}`;
|
|
192
|
-
stack.templateKey = 'laravel';
|
|
193
|
-
} else {
|
|
194
|
-
stack.framework = 'PHP';
|
|
195
|
-
stack.templateKey = 'php';
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (fs.existsSync(path.join(projectPath, 'pyproject.toml')) ||
|
|
200
|
-
fs.existsSync(path.join(projectPath, 'requirements.txt'))) {
|
|
201
|
-
stack.language = 'Python'; stack.runtime = 'Python';
|
|
202
|
-
stack.packageManager = 'pip';
|
|
203
|
-
stack.templateKey = 'python';
|
|
204
|
-
stack.commands = { install: 'pip install -r requirements.txt', dev: 'uvicorn main:app --reload', build: 'pip install -e .', test: 'pytest', lint: 'flake8' };
|
|
205
|
-
if (fs.existsSync(path.join(projectPath, 'pyproject.toml'))) {
|
|
206
|
-
const toml = fs.readFileSync(path.join(projectPath, 'pyproject.toml'), 'utf8');
|
|
207
|
-
if (toml.includes('fastapi')) { stack.framework = 'FastAPI'; }
|
|
208
|
-
else if (toml.includes('django')) { stack.framework = 'Django'; }
|
|
209
|
-
else { stack.framework = 'Python'; }
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return stack;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// ── Detectar si el proyecto tiene contenido ─────────────────────
|
|
217
|
-
function detectProjectState(projectPath) {
|
|
218
|
-
const hasCode = fs.existsSync(path.join(projectPath, 'src')) ||
|
|
219
|
-
fs.existsSync(path.join(projectPath, 'app')) ||
|
|
220
|
-
fs.existsSync(path.join(projectPath, 'pages')) ||
|
|
221
|
-
fs.existsSync(path.join(projectPath, 'api'));
|
|
222
|
-
const hasKnowledge = fs.existsSync(path.join(projectPath, '.agentic', 'conocimiento')) &&
|
|
223
|
-
fs.readdirSync(path.join(projectPath, '.agentic', 'conocimiento')).filter(f => f !== 'README.md').length > 0;
|
|
224
|
-
const hasPackageFile = fs.existsSync(path.join(projectPath, 'package.json')) ||
|
|
225
|
-
fs.existsSync(path.join(projectPath, 'composer.json')) ||
|
|
226
|
-
fs.existsSync(path.join(projectPath, 'pyproject.toml'));
|
|
227
|
-
return { hasCode, hasKnowledge, hasPackageFile };
|
|
228
|
-
}
|
|
229
|
-
|
|
230
12
|
// ── Descargar desde GitHub ──────────────────────────────────────
|
|
231
13
|
async function downloadFromGitHub(spinner) {
|
|
232
14
|
const tmpFile = path.join(require('os').tmpdir(), 'agentic-kdd.tar.gz');
|
|
@@ -243,110 +25,45 @@ async function downloadFromGitHub(spinner) {
|
|
|
243
25
|
|
|
244
26
|
// ── Copiar archivos al proyecto ─────────────────────────────────
|
|
245
27
|
function copyAgenticFiles(sourcePath, projectPath) {
|
|
246
|
-
|
|
247
|
-
|
|
28
|
+
// Archivos raíz
|
|
29
|
+
const rootFiles = ['CLAUDE.md', '_LOCKS.md', '.cursorrules', 'dashboard.cjs', 'docs', '.cursor', '.audit'];
|
|
30
|
+
for (const file of rootFiles) {
|
|
248
31
|
const src = path.join(sourcePath, file);
|
|
249
32
|
const dest = path.join(projectPath, file);
|
|
250
33
|
if (fs.existsSync(src)) fs.copySync(src, dest, { overwrite: true });
|
|
251
34
|
}
|
|
252
35
|
|
|
253
|
-
const agSrc
|
|
36
|
+
const agSrc = path.join(sourcePath, '.agentic');
|
|
254
37
|
const agDest = path.join(projectPath, '.agentic');
|
|
255
38
|
|
|
256
39
|
if (fs.existsSync(agSrc)) {
|
|
40
|
+
// Agentes — siempre sobreescribir
|
|
257
41
|
fs.copySync(path.join(agSrc, 'agentes'), path.join(agDest, 'agentes'), { overwrite: true });
|
|
42
|
+
|
|
43
|
+
// Grafo — siempre sobreescribir
|
|
258
44
|
fs.copySync(path.join(agSrc, 'grafo'), path.join(agDest, 'grafo'), { overwrite: true });
|
|
259
|
-
fs.ensureDirSync(path.join(agDest, 'specs'));
|
|
260
|
-
fs.ensureDirSync(path.join(projectPath, '_output'));
|
|
261
45
|
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
46
|
+
// Carpetas que solo se crean si no existen (no sobreescribir memoria del usuario)
|
|
47
|
+
const onlyCreate = ['memoria', 'specs', 'conocimiento'];
|
|
48
|
+
for (const dir of onlyCreate) {
|
|
49
|
+
const src = path.join(agSrc, dir);
|
|
50
|
+
const dest = path.join(agDest, dir);
|
|
51
|
+
if (!fs.existsSync(dest)) {
|
|
52
|
+
if (fs.existsSync(src)) fs.copySync(src, dest);
|
|
53
|
+
else fs.ensureDirSync(dest);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
265
56
|
|
|
57
|
+
// PLAN.md — solo si no existe
|
|
266
58
|
const planDest = path.join(agDest, 'PLAN.md');
|
|
267
|
-
if (!fs.existsSync(planDest))
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
fs.ensureDirSync(path.dirname(knDest));
|
|
272
|
-
if (!fs.existsSync(knDest)) fs.copySync(knSrc, knDest);
|
|
59
|
+
if (!fs.existsSync(planDest)) {
|
|
60
|
+
const planSrc = path.join(agSrc, 'PLAN.md');
|
|
61
|
+
if (fs.existsSync(planSrc)) fs.copySync(planSrc, planDest);
|
|
62
|
+
}
|
|
273
63
|
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// ── Escribir config.md completo y listo ────────────────────────
|
|
277
|
-
function writeConfig(projectPath, data) {
|
|
278
|
-
const { name, description, isNew, stack, template } = data;
|
|
279
|
-
const tpl = template || {};
|
|
280
|
-
|
|
281
|
-
const modulosImpl = tpl.modulos_impl ? tpl.modulos_impl.join('\n') : '_El agente Setup los detecta al correr aa: configurar_';
|
|
282
|
-
const modulosPend = tpl.modulos_pend ? tpl.modulos_pend.join('\n') : '_El agente Setup los detecta al correr aa: configurar_';
|
|
283
|
-
const reglas = tpl.reglas ? tpl.reglas.join('\n') : '_Se definen durante el desarrollo._';
|
|
284
|
-
|
|
285
|
-
const config = `# Agentic KDD — Configuración del proyecto
|
|
286
|
-
CONFIGURADO: SI
|
|
287
|
-
VERSION: 2.0
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## Proyecto
|
|
292
|
-
Nombre: ${name}
|
|
293
|
-
Descripción: ${description}
|
|
294
|
-
Tipo: ${isNew ? 'NUEVO' : 'EXISTENTE'}
|
|
295
|
-
|
|
296
|
-
## Stack
|
|
297
|
-
\`\`\`yaml
|
|
298
|
-
frontend:
|
|
299
|
-
framework: ${stack.framework}
|
|
300
|
-
language: ${stack.language}
|
|
301
|
-
|
|
302
|
-
backend:
|
|
303
|
-
runtime: ${stack.runtime || stack.language}
|
|
304
|
-
framework: ${stack.framework}
|
|
305
|
-
base_datos: ${stack.base_datos || '—'}
|
|
306
64
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
commands:
|
|
311
|
-
install: ${stack.commands.install}
|
|
312
|
-
dev: ${stack.commands.dev}
|
|
313
|
-
build: ${stack.commands.build}
|
|
314
|
-
test: ${stack.commands.test}
|
|
315
|
-
lint: ${stack.commands.lint}
|
|
316
|
-
\`\`\`
|
|
317
|
-
|
|
318
|
-
## Módulos
|
|
319
|
-
|
|
320
|
-
### Implementados
|
|
321
|
-
| Fase | Módulo | Rutas clave |
|
|
322
|
-
|------|--------|-------------|
|
|
323
|
-
${modulosImpl}
|
|
324
|
-
|
|
325
|
-
### Pendientes
|
|
326
|
-
${modulosPend}
|
|
327
|
-
|
|
328
|
-
## Archivos compartidos críticos
|
|
329
|
-
_El Setup los detecta al correr aa: configurar._
|
|
330
|
-
|
|
331
|
-
## Reglas del proyecto
|
|
332
|
-
|
|
333
|
-
### Agentic KDD
|
|
334
|
-
- \`aa:\` → pipeline completo sin pausas ni confirmaciones entre agentes
|
|
335
|
-
- \`audit:\` → solo auditar, no modificar código
|
|
336
|
-
- Context Guard: validar instrucción contra config/conocimiento/código
|
|
337
|
-
|
|
338
|
-
### Desarrollo ${stack.framework !== '—' ? stack.framework : ''}
|
|
339
|
-
${reglas}
|
|
340
|
-
|
|
341
|
-
## Sinónimos del proyecto
|
|
342
|
-
_Sin sinónimos registrados aún._
|
|
343
|
-
|
|
344
|
-
## Mapa BD → módulo
|
|
345
|
-
_El agente Setup lo detecta._
|
|
346
|
-
`;
|
|
347
|
-
|
|
348
|
-
fs.ensureDirSync(path.join(projectPath, '.agentic'));
|
|
349
|
-
fs.writeFileSync(path.join(projectPath, '.agentic', 'config.md'), config, 'utf8');
|
|
65
|
+
// Crear _output si no existe
|
|
66
|
+
fs.ensureDirSync(path.join(projectPath, '_output'));
|
|
350
67
|
}
|
|
351
68
|
|
|
352
69
|
// ── Comando principal: akdd init ────────────────────────────────
|
|
@@ -357,87 +74,14 @@ async function init() {
|
|
|
357
74
|
console.log(chalk.gray(' github.com/Adrianlpz211/Agentic-KDD\n'));
|
|
358
75
|
|
|
359
76
|
// Verificar si ya está instalado
|
|
360
|
-
const alreadyInstalled = fs.existsSync(path.join(projectPath, '.agentic', '
|
|
77
|
+
const alreadyInstalled = fs.existsSync(path.join(projectPath, '.agentic', 'agentes'));
|
|
361
78
|
if (alreadyInstalled) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
type: 'confirm', name: 'confirm',
|
|
366
|
-
message: chalk.yellow('Agentic KDD ya está instalado. ¿Reinstalar?'),
|
|
367
|
-
default: false
|
|
368
|
-
}]);
|
|
369
|
-
if (!confirm) {
|
|
370
|
-
console.log(chalk.gray('\n Usa akdd update para actualizar los agentes sin perder tu memoria.\n'));
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
79
|
+
console.log(chalk.yellow(' Agentic KDD ya está instalado en este proyecto.'));
|
|
80
|
+
console.log(chalk.gray(' Para actualizar los agentes sin perder tu memoria: akdd update\n'));
|
|
81
|
+
return;
|
|
374
82
|
}
|
|
375
83
|
|
|
376
|
-
//
|
|
377
|
-
const state = detectProjectState(projectPath);
|
|
378
|
-
const stack = detectStack(projectPath);
|
|
379
|
-
|
|
380
|
-
// Mostrar lo que detectó
|
|
381
|
-
if (stack.framework !== '—') {
|
|
382
|
-
console.log(chalk.green(` ✓ Stack detectado: ${stack.framework} · ${stack.language} · ${stack.packageManager}`));
|
|
383
|
-
}
|
|
384
|
-
if (state.hasCode) {
|
|
385
|
-
console.log(chalk.green(' ✓ Código existente detectado'));
|
|
386
|
-
}
|
|
387
|
-
if (state.hasKnowledge) {
|
|
388
|
-
console.log(chalk.green(' ✓ Documentación encontrada en conocimiento/'));
|
|
389
|
-
}
|
|
390
|
-
console.log('');
|
|
391
|
-
|
|
392
|
-
// ── PREGUNTA 1 — Nombre ─────────────────────────────────────────
|
|
393
|
-
const { name } = await inquirer.prompt([{
|
|
394
|
-
type: 'input', name: 'name',
|
|
395
|
-
message: 'Nombre del proyecto:',
|
|
396
|
-
default: path.basename(projectPath)
|
|
397
|
-
}]);
|
|
398
|
-
|
|
399
|
-
// ── PREGUNTA 2 — Nuevo o existente ──────────────────────────────
|
|
400
|
-
const { isNew } = await inquirer.prompt([{
|
|
401
|
-
type: 'list', name: 'isNew',
|
|
402
|
-
message: '¿El proyecto es nuevo o ya tiene código?',
|
|
403
|
-
choices: [
|
|
404
|
-
{ name: 'Nuevo — empezando desde cero', value: true },
|
|
405
|
-
{ name: 'Existente — ya tiene código o avance', value: false }
|
|
406
|
-
],
|
|
407
|
-
default: !state.hasCode
|
|
408
|
-
}]);
|
|
409
|
-
|
|
410
|
-
// ── PREGUNTA 3 — Descripción (solo proyectos nuevos sin docs) ──
|
|
411
|
-
let description = '—';
|
|
412
|
-
if (isNew && !state.hasKnowledge) {
|
|
413
|
-
const { desc } = await inquirer.prompt([{
|
|
414
|
-
type: 'input', name: 'desc',
|
|
415
|
-
message: 'Describe brevemente qué hace el proyecto:',
|
|
416
|
-
validate: (v) => v.trim().length > 5 || 'Al menos 5 caracteres'
|
|
417
|
-
}]);
|
|
418
|
-
description = desc;
|
|
419
|
-
} else if (!isNew && state.hasCode) {
|
|
420
|
-
description = 'Proyecto existente — el agente Setup detectará módulos y describirá el proyecto al correr aa: configurar';
|
|
421
|
-
} else if (state.hasKnowledge) {
|
|
422
|
-
description = 'El agente Setup leerá conocimiento/ y generará la descripción';
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// ── DOCUMENTACIÓN ──────────────────────────────────────────────
|
|
426
|
-
if (!state.hasKnowledge) {
|
|
427
|
-
const { hasDocs } = await inquirer.prompt([{
|
|
428
|
-
type: 'confirm', name: 'hasDocs',
|
|
429
|
-
message: '¿Tienes specs, wireframes o documentación del proyecto?',
|
|
430
|
-
default: false
|
|
431
|
-
}]);
|
|
432
|
-
if (hasDocs) {
|
|
433
|
-
console.log('\n' + chalk.cyan(' Sube tus archivos a:'));
|
|
434
|
-
console.log(chalk.bold(' .agentic/conocimiento/'));
|
|
435
|
-
console.log(chalk.gray(' (PDFs, Markdown, specs, wireframes — cualquier formato)\n'));
|
|
436
|
-
await inquirer.prompt([{ type: 'input', name: 'ready', message: 'Presiona Enter cuando hayas subido los archivos...' }]);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// ── Instalar ────────────────────────────────────────────────────
|
|
84
|
+
// Instalar
|
|
441
85
|
const spinner = ora({ text: 'Descargando Agentic KDD...', color: 'magenta' }).start();
|
|
442
86
|
|
|
443
87
|
try {
|
|
@@ -446,37 +90,34 @@ async function init() {
|
|
|
446
90
|
spinner.text = 'Instalando archivos...';
|
|
447
91
|
copyAgenticFiles(sourcePath, projectPath);
|
|
448
92
|
|
|
449
|
-
spinner.text = 'Generando configuración...';
|
|
450
|
-
const template = stack.templateKey ? TEMPLATES[stack.templateKey] : null;
|
|
451
|
-
writeConfig(projectPath, { name, description, isNew, stack, template });
|
|
452
|
-
|
|
453
93
|
fs.removeSync(TEMP_DIR);
|
|
454
94
|
spinner.succeed(chalk.green('¡Agentic KDD instalado!'));
|
|
455
95
|
|
|
456
|
-
//
|
|
96
|
+
// Mostrar qué se instaló
|
|
457
97
|
console.log('\n' + chalk.bold(' Instalado:'));
|
|
458
|
-
console.log(chalk.gray(' .agentic/
|
|
459
|
-
console.log(chalk.gray(' .
|
|
460
|
-
console.log(chalk.gray('
|
|
461
|
-
console.log(chalk.gray('
|
|
462
|
-
console.log(chalk.gray(' .
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
console.log(' ' + chalk.hex('#
|
|
474
|
-
console.log('
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
98
|
+
console.log(chalk.gray(' .agentic/agentes/ — pipeline de 9 agentes'));
|
|
99
|
+
console.log(chalk.gray(' .agentic/grafo/ — motor SQLite de conocimiento'));
|
|
100
|
+
console.log(chalk.gray(' .agentic/memoria/ — errores, patrones, decisiones'));
|
|
101
|
+
console.log(chalk.gray(' .agentic/conocimiento/ — documentación del proyecto'));
|
|
102
|
+
console.log(chalk.gray(' .agentic/specs/ — specs auto-generadas'));
|
|
103
|
+
console.log(chalk.gray(' .audit/ — departamento QA (7 subagentes)'));
|
|
104
|
+
console.log(chalk.gray(' dashboard.cjs — dashboard visual'));
|
|
105
|
+
console.log(chalk.gray(' CLAUDE.md — activa aa: / ag: / audit:'));
|
|
106
|
+
console.log(chalk.gray(' .cursorrules — reglas para Cursor'));
|
|
107
|
+
|
|
108
|
+
// Instrucción final — clara y directa
|
|
109
|
+
console.log('\n' + chalk.bold.hex('#2a3050')(' ─────────────────────────────────────────────'));
|
|
110
|
+
console.log(chalk.bold(' Último paso — abre este proyecto en'));
|
|
111
|
+
console.log(chalk.bold(' Cursor o Claude Code y ejecuta:'));
|
|
112
|
+
console.log('');
|
|
113
|
+
console.log(' ' + chalk.bold.hex('#a78bfa')('aa: configurar'));
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(chalk.gray(' Esto completa la configuración leyendo'));
|
|
116
|
+
console.log(chalk.gray(' tu código real. Solo se hace una vez.'));
|
|
117
|
+
console.log(chalk.bold.hex('#2a3050')(' ─────────────────────────────────────────────'));
|
|
118
|
+
|
|
119
|
+
console.log('\n' + chalk.gray(' Tip: si tienes specs, wireframes o docs del proyecto,'));
|
|
120
|
+
console.log(chalk.gray(' cópialos a .agentic/conocimiento/ antes de configurar.\n'));
|
|
480
121
|
|
|
481
122
|
} catch (err) {
|
|
482
123
|
spinner.fail(chalk.red('Error en la instalación'));
|