agentic-kdd 2.0.8 → 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/src/init.js CHANGED
@@ -5,85 +5,11 @@ 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
- // ── Detectar stack ─────────────────────────────────────────────
14
- function detectStack(projectPath) {
15
- const stack = {
16
- framework: '—',
17
- language: '—',
18
- packageManager: 'npm',
19
- commands: {
20
- install: 'npm install',
21
- dev: 'npm run dev',
22
- build: 'npm run build',
23
- test: 'npm test',
24
- lint: 'npm run lint'
25
- }
26
- };
27
-
28
- if (fs.existsSync(path.join(projectPath, 'package.json'))) {
29
- const pkg = fs.readJsonSync(path.join(projectPath, 'package.json'), { throws: false }) || {};
30
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
31
- stack.language = 'TypeScript/JavaScript';
32
-
33
- if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
34
- stack.packageManager = 'pnpm';
35
- stack.commands = { install: 'pnpm install', dev: 'pnpm dev', build: 'pnpm build', test: 'pnpm test', lint: 'pnpm lint' };
36
- } else if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
37
- stack.packageManager = 'yarn';
38
- stack.commands = { install: 'yarn install', dev: 'yarn dev', build: 'yarn build', test: 'yarn test', lint: 'yarn lint' };
39
- }
40
-
41
- if (deps['next']) stack.framework = `Next.js ${deps['next'].replace('^','')}`;
42
- else if (deps['vue']) stack.framework = `Vue ${deps['vue'].replace('^','')}`;
43
- else if (deps['react']) stack.framework = `React`;
44
- else if (deps['express']) stack.framework = `Express`;
45
- else if (deps['@nestjs/core']) stack.framework = `NestJS`;
46
- }
47
-
48
- if (fs.existsSync(path.join(projectPath, 'composer.json'))) {
49
- stack.language = 'PHP';
50
- stack.packageManager = 'composer';
51
- stack.commands = { install: 'composer install', dev: 'php artisan serve', build: 'composer build', test: './vendor/bin/phpunit', lint: 'composer lint' };
52
- const composer = fs.readJsonSync(path.join(projectPath, 'composer.json'), { throws: false }) || {};
53
- if ((composer.require || {})['laravel/framework']) stack.framework = 'Laravel';
54
- else stack.framework = 'PHP';
55
- }
56
-
57
- if (fs.existsSync(path.join(projectPath, 'pyproject.toml')) ||
58
- fs.existsSync(path.join(projectPath, 'requirements.txt'))) {
59
- stack.language = 'Python';
60
- stack.packageManager = 'pip';
61
- stack.commands = { install: 'pip install -r requirements.txt', dev: 'uvicorn main:app --reload', build: 'pip install -e .', test: 'pytest', lint: 'flake8' };
62
- stack.framework = 'Python';
63
- }
64
-
65
- return stack;
66
- }
67
-
68
- // ── Detectar si el proyecto tiene contenido ────────────────────
69
- function detectProjectState(projectPath) {
70
- const hasCode = fs.existsSync(path.join(projectPath, 'src')) ||
71
- fs.existsSync(path.join(projectPath, 'app')) ||
72
- fs.existsSync(path.join(projectPath, 'pages')) ||
73
- fs.existsSync(path.join(projectPath, 'api'));
74
-
75
- const hasKnowledge = fs.existsSync(path.join(projectPath, '.agentic', 'conocimiento')) &&
76
- fs.readdirSync(path.join(projectPath, '.agentic', 'conocimiento'))
77
- .filter(f => f !== 'README.md').length > 0;
78
-
79
- const hasPackageFile = fs.existsSync(path.join(projectPath, 'package.json')) ||
80
- fs.existsSync(path.join(projectPath, 'composer.json')) ||
81
- fs.existsSync(path.join(projectPath, 'pyproject.toml'));
82
-
83
- return { hasCode, hasKnowledge, hasPackageFile };
84
- }
85
-
86
- // ── Descargar desde GitHub ─────────────────────────────────────
12
+ // ── Descargar desde GitHub ──────────────────────────────────────
87
13
  async function downloadFromGitHub(spinner) {
88
14
  const tmpFile = path.join(require('os').tmpdir(), 'agentic-kdd.tar.gz');
89
15
  try {
@@ -97,200 +23,66 @@ async function downloadFromGitHub(spinner) {
97
23
  }
98
24
  }
99
25
 
100
- // ── Copiar archivos al proyecto ────────────────────────────────
26
+ // ── Copiar archivos al proyecto ─────────────────────────────────
101
27
  function copyAgenticFiles(sourcePath, projectPath) {
102
- const files = ['CLAUDE.md', '_LOCKS.md', '_output', 'docs', '.cursor'];
103
-
104
- for (const file of files) {
28
+ // Archivos raíz
29
+ const rootFiles = ['CLAUDE.md', '_LOCKS.md', '.cursorrules', 'dashboard.cjs', 'docs', '.cursor', '.audit'];
30
+ for (const file of rootFiles) {
105
31
  const src = path.join(sourcePath, file);
106
32
  const dest = path.join(projectPath, file);
107
33
  if (fs.existsSync(src)) fs.copySync(src, dest, { overwrite: true });
108
34
  }
109
35
 
110
- // .agentic — copiar agentes y estructura pero NO sobreescribir memoria si existe
111
- const agSrc = path.join(sourcePath, '.agentic');
36
+ const agSrc = path.join(sourcePath, '.agentic');
112
37
  const agDest = path.join(projectPath, '.agentic');
113
38
 
114
39
  if (fs.existsSync(agSrc)) {
115
- // Agentes siempre se actualizan
40
+ // Agentes siempre sobreescribir
116
41
  fs.copySync(path.join(agSrc, 'agentes'), path.join(agDest, 'agentes'), { overwrite: true });
117
42
 
118
- // Memoria y config solo si no existen
119
- const memorySrc = path.join(agSrc, 'memoria');
120
- const memoryDest = path.join(agDest, 'memoria');
121
- if (!fs.existsSync(memoryDest)) fs.copySync(memorySrc, memoryDest);
122
-
123
- const configDest = path.join(agDest, 'config.md');
124
- if (!fs.existsSync(configDest)) {
125
- fs.copySync(path.join(agSrc, 'config.md'), configDest);
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
+ 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
+ }
126
55
  }
127
56
 
128
- // PLAN.md solo si no existe
57
+ // PLAN.md solo si no existe
129
58
  const planDest = path.join(agDest, 'PLAN.md');
130
59
  if (!fs.existsSync(planDest)) {
131
- fs.copySync(path.join(agSrc, 'PLAN.md'), planDest);
60
+ const planSrc = path.join(agSrc, 'PLAN.md');
61
+ if (fs.existsSync(planSrc)) fs.copySync(planSrc, planDest);
132
62
  }
133
-
134
- // conocimiento/README siempre
135
- const knSrc = path.join(agSrc, 'conocimiento', 'README.md');
136
- const knDest = path.join(agDest, 'conocimiento', 'README.md');
137
- fs.ensureDirSync(path.dirname(knDest));
138
- if (!fs.existsSync(knDest)) fs.copySync(knSrc, knDest);
139
63
  }
140
- }
141
-
142
- // ── Escribir config.md con la info recopilada ──────────────────
143
- function writeConfig(projectPath, data) {
144
- const { name, description, isNew, stack } = data;
145
-
146
- const config = `# Agentic KDD — Configuración del proyecto
147
- CONFIGURADO: SI
148
- VERSION: 2.0
149
-
150
- ## Proyecto
151
- Nombre: ${name}
152
- Descripción: ${description}
153
- Tipo: ${isNew ? 'NUEVO' : 'EXISTENTE'}
154
-
155
- ## Stack
156
- \`\`\`yaml
157
- frontend:
158
- framework: ${stack.framework}
159
- language: ${stack.language}
160
-
161
- backend:
162
- runtime: ${stack.language}
163
- framework: ${stack.framework}
164
- base_datos: —
165
64
 
166
- devops:
167
- package_manager: ${stack.packageManager}
168
-
169
- commands:
170
- install: ${stack.commands.install}
171
- dev: ${stack.commands.dev}
172
- build: ${stack.commands.build}
173
- test: ${stack.commands.test}
174
- lint: ${stack.commands.lint}
175
- \`\`\`
176
-
177
- ## Módulos
178
- ### Implementados
179
- _El agente Setup los detecta al correr aa: configurar_
180
-
181
- ### Pendientes
182
- _El agente Setup los detecta al correr aa: configurar_
183
-
184
- ## Archivos compartidos críticos
185
- _El Setup los detecta._
186
-
187
- ## Reglas del proyecto
188
- _Se definen durante el desarrollo._
189
-
190
- ## Sinónimos del proyecto
191
- _Sin sinónimos registrados aún._
192
- `;
193
-
194
- fs.writeFileSync(path.join(projectPath, '.agentic', 'config.md'), config, 'utf8');
65
+ // Crear _output si no existe
66
+ fs.ensureDirSync(path.join(projectPath, '_output'));
195
67
  }
196
68
 
197
- // ── Comando principal: akdd init ───────────────────────────────
69
+ // ── Comando principal: akdd init ────────────────────────────────
198
70
  async function init() {
199
71
  const projectPath = process.cwd();
200
72
 
201
- console.log('\n' + chalk.bold.blue(' Agentic KDD') + chalk.gray(' — autonomous development pipeline'));
73
+ console.log('\n' + chalk.bold.hex('#8b5cf6')(' 🤖 Agentic KDD') + chalk.gray(' — autonomous development pipeline'));
202
74
  console.log(chalk.gray(' github.com/Adrianlpz211/Agentic-KDD\n'));
203
75
 
204
76
  // Verificar si ya está instalado
205
- const alreadyInstalled = fs.existsSync(path.join(projectPath, '.agentic', 'config.md'));
77
+ const alreadyInstalled = fs.existsSync(path.join(projectPath, '.agentic', 'agentes'));
206
78
  if (alreadyInstalled) {
207
- const content = fs.readFileSync(path.join(projectPath, '.agentic', 'config.md'), 'utf8');
208
- if (content.includes('CONFIGURADO: SI')) {
209
- const { confirm } = await inquirer.prompt([{
210
- type: 'confirm',
211
- name: 'confirm',
212
- message: chalk.yellow('Agentic KDD ya está instalado. ¿Reinstalar?'),
213
- default: false
214
- }]);
215
- if (!confirm) {
216
- console.log(chalk.gray('\n Usa akdd update para actualizar sin perder tu memoria.\n'));
217
- return;
218
- }
219
- }
220
- }
221
-
222
- // Detectar estado del proyecto
223
- const state = detectProjectState(projectPath);
224
- const stack = detectStack(projectPath);
225
-
226
- // ── PREGUNTA 1 — Nuevo o existente ────────────────────────────
227
- const { isNew } = await inquirer.prompt([{
228
- type: 'list',
229
- name: 'isNew',
230
- message: '¿El proyecto es nuevo o ya está encaminado?',
231
- choices: [
232
- { name: 'Nuevo — empezando desde cero', value: true },
233
- { name: 'Existente — ya tiene código o avance', value: false }
234
- ],
235
- default: !state.hasCode
236
- }]);
237
-
238
- // ── PREGUNTA 2 — Documentación ────────────────────────────────
239
- let hasDocsAnswer = false;
240
-
241
- if (!state.hasKnowledge) {
242
- const { hasDocs } = await inquirer.prompt([{
243
- type: 'confirm',
244
- name: 'hasDocs',
245
- message: '¿Tienes documentación del proyecto? (specs, wireframes, reglas de negocio, etc.)',
246
- default: false
247
- }]);
248
- hasDocsAnswer = hasDocs;
249
-
250
- if (hasDocs) {
251
- console.log('\n' + chalk.cyan(' Sube tus archivos a la carpeta:'));
252
- console.log(chalk.bold(' .agentic/conocimiento/'));
253
- console.log(chalk.gray(' (PDFs, Markdown, Word, specs — cualquier formato)\n'));
254
-
255
- await inquirer.prompt([{
256
- type: 'input',
257
- name: 'ready',
258
- message: 'Presiona Enter cuando hayas subido los archivos...'
259
- }]);
260
- }
261
- } else {
262
- console.log(chalk.green(' ✓ Encontré archivos en conocimiento/ — el Setup los leerá al configurar'));
263
- hasDocsAnswer = true;
264
- }
265
-
266
- // ── PREGUNTA 3 — Nombre ────────────────────────────────────────
267
- const { name } = await inquirer.prompt([{
268
- type: 'input',
269
- name: 'name',
270
- message: 'Nombre del proyecto:',
271
- default: path.basename(projectPath)
272
- }]);
273
-
274
- // Descripción según el caso
275
- let description = '—';
276
-
277
- if (isNew && !hasDocsAnswer) {
278
- // Proyecto nuevo sin docs — pedir descripción
279
- const { desc } = await inquirer.prompt([{
280
- type: 'input',
281
- name: 'desc',
282
- message: 'Describe brevemente el proyecto (qué hace, para quién):',
283
- validate: (v) => v.trim().length > 10 || 'Por favor da una descripción de al menos 10 caracteres'
284
- }]);
285
- description = desc;
286
- } else if (!isNew && state.hasCode) {
287
- description = 'Proyecto existente — el agente Setup detectará los módulos y describirá el proyecto al correr aa: configurar';
288
- } else if (hasDocsAnswer) {
289
- description = 'El agente Setup leerá conocimiento/ y generará la descripción al correr aa: configurar';
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;
290
82
  }
291
83
 
292
- // ── Descargar e instalar ───────────────────────────────────────
293
- const spinner = ora({ text: 'Descargando Agentic KDD desde GitHub...', color: 'blue' }).start();
84
+ // Instalar
85
+ const spinner = ora({ text: 'Descargando Agentic KDD...', color: 'magenta' }).start();
294
86
 
295
87
  try {
296
88
  const sourcePath = await downloadFromGitHub(spinner);
@@ -298,30 +90,34 @@ async function init() {
298
90
  spinner.text = 'Instalando archivos...';
299
91
  copyAgenticFiles(sourcePath, projectPath);
300
92
 
301
- spinner.text = 'Configurando proyecto...';
302
- writeConfig(projectPath, { name, description, isNew, stack });
303
-
304
93
  fs.removeSync(TEMP_DIR);
305
-
306
94
  spinner.succeed(chalk.green('¡Agentic KDD instalado!'));
307
95
 
308
- console.log('\n' + chalk.bold(' Siguiente paso — abre el proyecto en Cursor o Claude Code y escribe:\n'));
309
-
310
- if (!isNew && state.hasCode) {
311
- console.log(chalk.cyan(' aa: configurar') + chalk.gray(' ← el Setup leerá el código y configurará todo'));
312
- } else if (hasDocsAnswer) {
313
- console.log(chalk.cyan(' aa: configurar') + chalk.gray(' ← el Setup leerá conocimiento/ y configurará todo'));
314
- } else {
315
- console.log(chalk.cyan(' aa: configurar') + chalk.gray(' ← el Setup terminará la configuración'));
316
- }
317
-
318
- console.log(chalk.cyan(' aa: [tu tarea]') + chalk.gray(' ← cuando esté configurado, a trabajar\n'));
319
-
320
- if (!hasDocsAnswer && isNew) {
321
- console.log(chalk.yellow(' 💡 Tip: si tienes specs o docs del proyecto, súbelos a'));
322
- console.log(chalk.yellow(' .agentic/conocimiento/ antes de correr aa: configurar'));
323
- console.log(chalk.gray(' Esto hará que el Context Guard funcione mejor.\n'));
324
- }
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'));
325
121
 
326
122
  } catch (err) {
327
123
  spinner.fail(chalk.red('Error en la instalación'));