agentic-kdd 2.1.2 → 2.1.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/package.json +1 -1
- package/src/init.js +185 -47
package/package.json
CHANGED
package/src/init.js
CHANGED
|
@@ -5,6 +5,7 @@ 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');
|
|
8
9
|
|
|
9
10
|
const GITHUB_REPO = 'Adrianlpz211/Agentic-KDD';
|
|
10
11
|
const TEMP_DIR = path.join(require('os').tmpdir(), 'agentic-kdd-download');
|
|
@@ -25,10 +26,9 @@ async function downloadFromGitHub(spinner) {
|
|
|
25
26
|
|
|
26
27
|
// ── Copiar archivos al proyecto ─────────────────────────────────
|
|
27
28
|
function copyAgenticFiles(sourcePath, projectPath) {
|
|
28
|
-
// Archivos raíz
|
|
29
29
|
const rootFiles = ['CLAUDE.md', '_LOCKS.md', '.cursorrules', 'dashboard.cjs', 'docs', '.cursor', '.audit'];
|
|
30
30
|
for (const file of rootFiles) {
|
|
31
|
-
const src
|
|
31
|
+
const src = path.join(sourcePath, file);
|
|
32
32
|
const dest = path.join(projectPath, file);
|
|
33
33
|
if (fs.existsSync(src)) fs.copySync(src, dest, { overwrite: true });
|
|
34
34
|
}
|
|
@@ -37,24 +37,19 @@ function copyAgenticFiles(sourcePath, projectPath) {
|
|
|
37
37
|
const agDest = path.join(projectPath, '.agentic');
|
|
38
38
|
|
|
39
39
|
if (fs.existsSync(agSrc)) {
|
|
40
|
-
// Agentes — siempre sobreescribir
|
|
41
40
|
fs.copySync(path.join(agSrc, 'agentes'), path.join(agDest, 'agentes'), { overwrite: true });
|
|
41
|
+
fs.copySync(path.join(agSrc, 'grafo'), path.join(agDest, 'grafo'), { overwrite: true });
|
|
42
42
|
|
|
43
|
-
// Grafo — siempre sobreescribir
|
|
44
|
-
fs.copySync(path.join(agSrc, 'grafo'), path.join(agDest, 'grafo'), { overwrite: true });
|
|
45
|
-
|
|
46
|
-
// Carpetas que solo se crean si no existen (no sobreescribir memoria del usuario)
|
|
47
43
|
const onlyCreate = ['memoria', 'specs', 'conocimiento'];
|
|
48
44
|
for (const dir of onlyCreate) {
|
|
49
|
-
const src = path.join(agSrc, dir);
|
|
50
45
|
const dest = path.join(agDest, dir);
|
|
51
46
|
if (!fs.existsSync(dest)) {
|
|
47
|
+
const src = path.join(agSrc, dir);
|
|
52
48
|
if (fs.existsSync(src)) fs.copySync(src, dest);
|
|
53
49
|
else fs.ensureDirSync(dest);
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
// PLAN.md — solo si no existe
|
|
58
53
|
const planDest = path.join(agDest, 'PLAN.md');
|
|
59
54
|
if (!fs.existsSync(planDest)) {
|
|
60
55
|
const planSrc = path.join(agSrc, 'PLAN.md');
|
|
@@ -62,10 +57,98 @@ function copyAgenticFiles(sourcePath, projectPath) {
|
|
|
62
57
|
}
|
|
63
58
|
}
|
|
64
59
|
|
|
65
|
-
// Crear _output si no existe
|
|
66
60
|
fs.ensureDirSync(path.join(projectPath, '_output'));
|
|
67
61
|
}
|
|
68
62
|
|
|
63
|
+
// ── Detectar stack ──────────────────────────────────────────────
|
|
64
|
+
function detectStack(projectPath) {
|
|
65
|
+
const stack = { framework: '—', language: '—', packageManager: 'npm' };
|
|
66
|
+
if (fs.existsSync(path.join(projectPath, 'package.json'))) {
|
|
67
|
+
const pkg = fs.readJsonSync(path.join(projectPath, 'package.json'), { throws: false }) || {};
|
|
68
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
69
|
+
stack.language = deps['typescript'] ? 'TypeScript' : 'JavaScript';
|
|
70
|
+
if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) stack.packageManager = 'pnpm';
|
|
71
|
+
else if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) stack.packageManager = 'yarn';
|
|
72
|
+
if (deps['next']) stack.framework = `Next.js ${(deps['next']||'').replace(/[\^~]/,'')}`;
|
|
73
|
+
else if (deps['react'] && !deps['next']) stack.framework = 'React';
|
|
74
|
+
else if (deps['express']) stack.framework = 'Express';
|
|
75
|
+
else if (deps['fastify']) stack.framework = 'Fastify';
|
|
76
|
+
else if (deps['@nestjs/core']) stack.framework = 'NestJS';
|
|
77
|
+
}
|
|
78
|
+
if (fs.existsSync(path.join(projectPath, 'composer.json'))) {
|
|
79
|
+
const composer = fs.readJsonSync(path.join(projectPath, 'composer.json'), { throws: false }) || {};
|
|
80
|
+
stack.language = 'PHP'; stack.packageManager = 'composer';
|
|
81
|
+
if ((composer.require||{})['laravel/framework']) stack.framework = 'Laravel';
|
|
82
|
+
else stack.framework = 'PHP';
|
|
83
|
+
}
|
|
84
|
+
if (fs.existsSync(path.join(projectPath, 'pyproject.toml')) ||
|
|
85
|
+
fs.existsSync(path.join(projectPath, 'requirements.txt'))) {
|
|
86
|
+
stack.language = 'Python'; stack.packageManager = 'pip';
|
|
87
|
+
stack.framework = 'Python';
|
|
88
|
+
}
|
|
89
|
+
return stack;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ── Consolidar docs en conocimiento/ ───────────────────────────
|
|
93
|
+
function consolidarDocs(projectPath) {
|
|
94
|
+
const conocimientoPath = path.join(projectPath, '.agentic', 'conocimiento');
|
|
95
|
+
const consolidados = [];
|
|
96
|
+
const ignorar = ['node_modules', '.git', '.agentic', '_output', 'dist', 'build', '.next', 'vendor'];
|
|
97
|
+
|
|
98
|
+
// Extensiones útiles como conocimiento
|
|
99
|
+
const extensionesUtiles = ['.md', '.pdf', '.txt'];
|
|
100
|
+
// Nombres específicos que siempre son útiles
|
|
101
|
+
const nombresUtiles = ['README', 'SPEC', 'SPECS', 'CONTEXT', 'CONTEXTO', 'REQUIREMENTS',
|
|
102
|
+
'ARCHITECTURE', 'DISEÑO', 'DESIGN', 'BRIEF', 'PRD', 'CLAUDE', 'AGENTS'];
|
|
103
|
+
|
|
104
|
+
function esArchivoUtil(nombre) {
|
|
105
|
+
const upper = nombre.toUpperCase().replace(/\.[^.]+$/, '');
|
|
106
|
+
const ext = path.extname(nombre).toLowerCase();
|
|
107
|
+
if (extensionesUtiles.includes(ext)) return true;
|
|
108
|
+
if (nombresUtiles.some(n => upper.includes(n))) return true;
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function recorrer(dir, nivel) {
|
|
113
|
+
if (nivel > 3) return; // máximo 3 niveles de profundidad
|
|
114
|
+
let items;
|
|
115
|
+
try { items = fs.readdirSync(dir); } catch(e) { return; }
|
|
116
|
+
|
|
117
|
+
for (const item of items) {
|
|
118
|
+
if (ignorar.includes(item) || item.startsWith('.')) continue;
|
|
119
|
+
const fullPath = path.join(dir, item);
|
|
120
|
+
const stat = fs.statSync(fullPath);
|
|
121
|
+
|
|
122
|
+
if (stat.isDirectory()) {
|
|
123
|
+
recorrer(fullPath, nivel + 1);
|
|
124
|
+
} else if (stat.isFile() && esArchivoUtil(item)) {
|
|
125
|
+
// No mover repomix — solo usarlo como referencia
|
|
126
|
+
if (item.includes('repomix')) {
|
|
127
|
+
consolidados.push({ src: fullPath, nombre: item, tipo: 'referencia' });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
// No copiar si ya está en conocimiento/
|
|
131
|
+
if (fullPath.startsWith(conocimientoPath)) continue;
|
|
132
|
+
|
|
133
|
+
const destNombre = item;
|
|
134
|
+
const destPath = path.join(conocimientoPath, destNombre);
|
|
135
|
+
// Si ya existe uno con el mismo nombre, agregar prefijo del directorio padre
|
|
136
|
+
const finalDest = fs.existsSync(destPath)
|
|
137
|
+
? path.join(conocimientoPath, path.basename(dir) + '_' + destNombre)
|
|
138
|
+
: destPath;
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
fs.copySync(fullPath, finalDest, { overwrite: false });
|
|
142
|
+
consolidados.push({ src: fullPath, nombre: destNombre, tipo: 'copiado' });
|
|
143
|
+
} catch(e) {}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
recorrer(projectPath, 0);
|
|
149
|
+
return consolidados;
|
|
150
|
+
}
|
|
151
|
+
|
|
69
152
|
// ── Comando principal: akdd init ────────────────────────────────
|
|
70
153
|
async function init() {
|
|
71
154
|
const projectPath = process.cwd();
|
|
@@ -74,57 +157,112 @@ async function init() {
|
|
|
74
157
|
console.log(chalk.gray(' github.com/Adrianlpz211/Agentic-KDD\n'));
|
|
75
158
|
|
|
76
159
|
// Verificar si ya está instalado
|
|
77
|
-
|
|
78
|
-
if (alreadyInstalled) {
|
|
160
|
+
if (fs.existsSync(path.join(projectPath, '.agentic', 'agentes'))) {
|
|
79
161
|
console.log(chalk.yellow(' Agentic KDD ya está instalado en este proyecto.'));
|
|
80
162
|
console.log(chalk.gray(' Para actualizar los agentes sin perder tu memoria: akdd update\n'));
|
|
81
163
|
return;
|
|
82
164
|
}
|
|
83
165
|
|
|
84
|
-
//
|
|
85
|
-
const
|
|
166
|
+
// Detectar stack
|
|
167
|
+
const stack = detectStack(projectPath);
|
|
168
|
+
const hasCode = fs.existsSync(path.join(projectPath, 'src')) ||
|
|
169
|
+
fs.existsSync(path.join(projectPath, 'app')) ||
|
|
170
|
+
fs.existsSync(path.join(projectPath, 'pages'));
|
|
86
171
|
|
|
87
|
-
|
|
88
|
-
|
|
172
|
+
if (stack.framework !== '—')
|
|
173
|
+
console.log(chalk.green(` ✓ Stack detectado: ${stack.framework} · ${stack.language} · ${stack.packageManager}`));
|
|
174
|
+
if (hasCode)
|
|
175
|
+
console.log(chalk.green(' ✓ Código existente detectado'));
|
|
176
|
+
console.log('');
|
|
177
|
+
|
|
178
|
+
// ── PREGUNTA 1: Nombre ──────────────────────────────────────
|
|
179
|
+
const { name } = await inquirer.prompt([{
|
|
180
|
+
type: 'input', name: 'name',
|
|
181
|
+
message: 'Nombre del proyecto:',
|
|
182
|
+
default: path.basename(projectPath)
|
|
183
|
+
}]);
|
|
184
|
+
|
|
185
|
+
// ── PREGUNTA 2: Nuevo o existente ──────────────────────────
|
|
186
|
+
const { isNew } = await inquirer.prompt([{
|
|
187
|
+
type: 'list', name: 'isNew',
|
|
188
|
+
message: '¿El proyecto es nuevo o ya tiene código?',
|
|
189
|
+
choices: [
|
|
190
|
+
{ name: 'Nuevo — empezando desde cero', value: true },
|
|
191
|
+
{ name: 'Existente — ya tiene código o avance', value: false }
|
|
192
|
+
],
|
|
193
|
+
default: !hasCode
|
|
194
|
+
}]);
|
|
89
195
|
|
|
196
|
+
// ── INSTALAR — crear carpetas PRIMERO antes de preguntar docs ──
|
|
197
|
+
const spinner = ora({ text: 'Descargando Agentic KDD...', color: 'magenta' }).start();
|
|
198
|
+
let sourcePath;
|
|
199
|
+
try {
|
|
200
|
+
sourcePath = await downloadFromGitHub(spinner);
|
|
90
201
|
spinner.text = 'Instalando archivos...';
|
|
91
202
|
copyAgenticFiles(sourcePath, projectPath);
|
|
92
|
-
|
|
93
203
|
fs.removeSync(TEMP_DIR);
|
|
94
|
-
spinner.succeed(chalk.green('
|
|
95
|
-
|
|
96
|
-
// Mostrar qué se instaló
|
|
97
|
-
console.log('\n' + chalk.bold(' Instalado:'));
|
|
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'));
|
|
121
|
-
|
|
204
|
+
spinner.succeed(chalk.green('Archivos instalados'));
|
|
122
205
|
} catch (err) {
|
|
123
206
|
spinner.fail(chalk.red('Error en la instalación'));
|
|
124
|
-
console.error(chalk.red('\n ' + err.message));
|
|
125
|
-
console.log(chalk.gray(' Descarga manual: https://github.com/Adrianlpz211/Agentic-KDD\n'));
|
|
207
|
+
console.error(chalk.red('\n ' + err.message + '\n'));
|
|
126
208
|
process.exit(1);
|
|
127
209
|
}
|
|
210
|
+
|
|
211
|
+
// ── PREGUNTA 3: Docs (DESPUÉS de crear carpetas) ───────────
|
|
212
|
+
const { hasDocs } = await inquirer.prompt([{
|
|
213
|
+
type: 'confirm', name: 'hasDocs',
|
|
214
|
+
message: '¿Tienes specs, wireframes o documentación del proyecto?',
|
|
215
|
+
default: false
|
|
216
|
+
}]);
|
|
217
|
+
|
|
218
|
+
if (hasDocs) {
|
|
219
|
+
// Recorrer el proyecto y consolidar docs automáticamente
|
|
220
|
+
console.log('');
|
|
221
|
+
const docsSpinner = ora({ text: 'Buscando archivos de conocimiento...', color: 'cyan' }).start();
|
|
222
|
+
const consolidados = consolidarDocs(projectPath);
|
|
223
|
+
const copiados = consolidados.filter(d => d.tipo === 'copiado');
|
|
224
|
+
const referencias = consolidados.filter(d => d.tipo === 'referencia');
|
|
225
|
+
|
|
226
|
+
if (copiados.length > 0) {
|
|
227
|
+
docsSpinner.succeed(chalk.green(`Archivos de conocimiento centralizados en .agentic/conocimiento/`));
|
|
228
|
+
copiados.forEach(d => console.log(chalk.gray(` ✓ ${d.nombre}`)));
|
|
229
|
+
if (referencias.length > 0) {
|
|
230
|
+
console.log(chalk.gray(`\n Como referencia (no movido):`));
|
|
231
|
+
referencias.forEach(d => console.log(chalk.gray(` ~ ${d.nombre}`)));
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
docsSpinner.warn(chalk.yellow('No se encontraron archivos de conocimiento en el proyecto.'));
|
|
235
|
+
console.log(chalk.gray(' Puedes agregarlos manualmente en .agentic/conocimiento/'));
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
console.log('');
|
|
239
|
+
console.log(chalk.gray(' Tip: puedes agregar specs, docs o wireframes en'));
|
|
240
|
+
console.log(chalk.gray(' .agentic/conocimiento/ en cualquier momento.'));
|
|
241
|
+
console.log(chalk.gray(' Agentic los usará automáticamente en el siguiente aa:'));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ── RESUMEN FINAL ───────────────────────────────────────────
|
|
245
|
+
console.log('\n' + chalk.bold(' Instalado:'));
|
|
246
|
+
console.log(chalk.gray(' .agentic/agentes/ — pipeline de 9 agentes'));
|
|
247
|
+
console.log(chalk.gray(' .agentic/grafo/ — motor SQLite de conocimiento'));
|
|
248
|
+
console.log(chalk.gray(' .agentic/memoria/ — errores, patrones, decisiones'));
|
|
249
|
+
console.log(chalk.gray(' .agentic/conocimiento/ — documentación del proyecto'));
|
|
250
|
+
console.log(chalk.gray(' .agentic/specs/ — specs auto-generadas'));
|
|
251
|
+
console.log(chalk.gray(' .audit/ — departamento QA (7 subagentes)'));
|
|
252
|
+
console.log(chalk.gray(' dashboard.cjs — dashboard visual'));
|
|
253
|
+
console.log(chalk.gray(' CLAUDE.md — activa aa: / ag: / audit:'));
|
|
254
|
+
console.log(chalk.gray(' .cursorrules — reglas para Cursor'));
|
|
255
|
+
|
|
256
|
+
// Instrucción final
|
|
257
|
+
console.log('\n' + chalk.dim(' ─────────────────────────────────────────────'));
|
|
258
|
+
console.log(chalk.bold(' Último paso — abre este proyecto en'));
|
|
259
|
+
console.log(chalk.bold(' Cursor o Claude Code y ejecuta:'));
|
|
260
|
+
console.log('');
|
|
261
|
+
console.log(' ' + chalk.bold.hex('#a78bfa')('aa: configurar'));
|
|
262
|
+
console.log('');
|
|
263
|
+
console.log(chalk.gray(' Esto completa la configuración leyendo tu'));
|
|
264
|
+
console.log(chalk.gray(' código real. Solo se hace una vez.'));
|
|
265
|
+
console.log(chalk.dim(' ─────────────────────────────────────────────\n'));
|
|
128
266
|
}
|
|
129
267
|
|
|
130
268
|
module.exports = { init };
|