agentic-kdd 3.5.5 → 3.5.7

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.
@@ -212,6 +212,52 @@ function migrateDB(db) {
212
212
  "CREATE UNIQUE INDEX IF NOT EXISTS idx_rel_unique ON relaciones(desde_id, tipo, hacia_id)",
213
213
  ];
214
214
  indices.forEach(sql => { try { db.exec(sql); } catch(e) {} });
215
+
216
+ // v2.2 — nuevas tablas (seguro llamar múltiples veces)
217
+ const tablasV22 = [
218
+ `CREATE TABLE IF NOT EXISTS git_context_log (
219
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
220
+ sesion_id TEXT NOT NULL,
221
+ rama TEXT, commit_hash TEXT,
222
+ archivos_modificados TEXT DEFAULT '[]',
223
+ riesgos_detectados TEXT DEFAULT '[]',
224
+ predicciones TEXT DEFAULT '[]',
225
+ tiene_riesgos_altos INTEGER DEFAULT 0,
226
+ fecha TEXT DEFAULT (datetime('now'))
227
+ )`,
228
+ `CREATE TABLE IF NOT EXISTS cicd_reports (
229
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
230
+ episodio_id TEXT, plataforma TEXT DEFAULT 'github',
231
+ workflow TEXT, rama TEXT, commit_hash TEXT, actor TEXT, repo TEXT,
232
+ run_id TEXT, run_url TEXT,
233
+ tests_pasando INTEGER DEFAULT 0, tests_fallando INTEGER DEFAULT 0,
234
+ archivos_tocados TEXT DEFAULT '[]', errores_tests TEXT DEFAULT '[]',
235
+ es_exito INTEGER DEFAULT 0,
236
+ fecha TEXT DEFAULT (datetime('now'))
237
+ )`,
238
+ `CREATE TABLE IF NOT EXISTS prediction_log (
239
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
240
+ tarea TEXT, modulo TEXT, archivos TEXT DEFAULT '[]',
241
+ nivel_predicho TEXT, alertas TEXT DEFAULT '[]', precondiciones TEXT DEFAULT '[]',
242
+ fue_correcto INTEGER, ciclo_id TEXT,
243
+ fecha TEXT DEFAULT (datetime('now'))
244
+ )`,
245
+ ];
246
+ tablasV22.forEach(sql => { try { db.exec(sql); } catch(e) {} });
247
+
248
+ // v2.2 — embedding en episodios
249
+ const migracionesV22 = [
250
+ "ALTER TABLE episodios ADD COLUMN embedding TEXT",
251
+ ];
252
+ migracionesV22.forEach(sql => { try { db.exec(sql); } catch(e) {} });
253
+
254
+ // v2.2 — índices nuevas tablas
255
+ const indicesV22 = [
256
+ "CREATE INDEX IF NOT EXISTS idx_git_context_fecha ON git_context_log(fecha)",
257
+ "CREATE INDEX IF NOT EXISTS idx_cicd_rama ON cicd_reports(rama)",
258
+ "CREATE INDEX IF NOT EXISTS idx_prediction_fecha ON prediction_log(fecha)",
259
+ ];
260
+ indicesV22.forEach(sql => { try { db.exec(sql); } catch(e) {} });
215
261
  }
216
262
 
217
263
  // ─── SNAPSHOT ─────────────────────────────────────────────────────────────────
@@ -1323,9 +1369,657 @@ if (_args[0] === 'decay') {
1323
1369
  console.log(`Decay aplicado: ${r.procesados} nodos procesados`);
1324
1370
  }
1325
1371
  if (_args[0] === 'buscar') {
1326
- const r = buscarHibrido(_args[1], _args[2], parseInt(_args[3]) || 10);
1327
- console.log(JSON.stringify(r, null, 2));
1372
+ // v2.2: búsqueda híbrida con embeddings si disponibles
1373
+ const embMod = getEmbeddingsModuleGrafo();
1374
+ if (embMod && embMod.isAvailable()) {
1375
+ buscarHibridoConEmbeddings(_args[1], _args[2], parseInt(_args[3]) || 10)
1376
+ .then(r => console.log(JSON.stringify({ resultados: r, trace: { metodo: 'vector_hybrid_rrf' } }, null, 2)));
1377
+ } else {
1378
+ const r = buscarHibrido(_args[1], _args[2], parseInt(_args[3]) || 10);
1379
+ console.log(JSON.stringify(r, null, 2));
1380
+ }
1328
1381
  }
1329
1382
  if (_args[0] === 'coala') {
1330
1383
  statsCoala();
1331
1384
  }
1385
+
1386
+ // ─── v2.2: Nuevos comandos CLI ────────────────────────────────────────────────
1387
+
1388
+ if (_args[0] === 'git-context') {
1389
+ const gitMod = getGitContextModuleGrafo();
1390
+ if (!gitMod) { console.log(' git-context module not available (akdd update)'); process.exit(0); }
1391
+ const db = initDB();
1392
+ const resultado = gitMod.analizarGitContext(ROOT, db);
1393
+ if (resultado.disponible) {
1394
+ const { contexto } = resultado;
1395
+ // Guardar en working_memory
1396
+ const sesionId = `git-${Date.now()}`;
1397
+ try {
1398
+ db.run('UPDATE working_memory SET expirado=1 WHERE expirado=0');
1399
+ db.run(
1400
+ `INSERT INTO working_memory (sesion_id, tipo, contenido, relevancia) VALUES (?,?,?,?)`,
1401
+ sesionId, 'observacion', JSON.stringify(contexto), 1.0
1402
+ );
1403
+ // Log en git_context_log si la tabla existe
1404
+ try {
1405
+ db.run(
1406
+ `INSERT INTO git_context_log (sesion_id, rama, commit_hash, archivos_modificados, riesgos_detectados, predicciones, tiene_riesgos_altos)
1407
+ VALUES (?,?,?,?,?,?,?)`,
1408
+ sesionId,
1409
+ contexto.rama || '',
1410
+ (contexto.commits_recientes?.[0]?.hash || ''),
1411
+ JSON.stringify(contexto.archivos_modificados || []),
1412
+ JSON.stringify(contexto.riesgos || []),
1413
+ JSON.stringify(contexto.predicciones || []),
1414
+ contexto.tiene_riesgos_altos ? 1 : 0
1415
+ );
1416
+ } catch(e) {}
1417
+ } catch(e) {}
1418
+ if (db.type === 'sqljs' && db.save) db.save();
1419
+ db.close();
1420
+ console.log(gitMod.formatearReporte(resultado));
1421
+ } else {
1422
+ db.close();
1423
+ console.log(` ${resultado.mensaje}`);
1424
+ }
1425
+ }
1426
+
1427
+ if (_args[0] === 'predict') {
1428
+ const predMod = getPrediccionModuleGrafo();
1429
+ if (!predMod) { console.log(' prediccion module not available (akdd update)'); process.exit(0); }
1430
+ const db = initDB();
1431
+ predMod.mostrarEstadisticasPrediccion(db);
1432
+ db.close();
1433
+ }
1434
+
1435
+ if (_args[0] === 'ci-install') {
1436
+ const ciMod = getCICDModuleGrafo();
1437
+ if (!ciMod) { console.log(' cicd module not available (akdd update)'); process.exit(0); }
1438
+ ciMod.instalarWorkflow(ROOT);
1439
+ }
1440
+
1441
+ if (_args[0] === 'ci-status') {
1442
+ const ciMod = getCICDModuleGrafo();
1443
+ if (!ciMod) { console.log(' cicd module not available (akdd update)'); process.exit(0); }
1444
+ const db = initDB();
1445
+ ciMod.mostrarEstadoCI(db);
1446
+ db.close();
1447
+ }
1448
+
1449
+ if (_args[0] === 'ci-report') {
1450
+ const ciMod = getCICDModuleGrafo();
1451
+ if (!ciMod) { process.exit(0); } // No fallar CI
1452
+ const db = initDB();
1453
+ const esExito = _args.includes('--success');
1454
+ const outputIdx = _args.indexOf('--output');
1455
+ const outputFile = outputIdx >= 0 ? _args[outputIdx + 1] : null;
1456
+ ciMod.reportarCI(ROOT, db, { esExito, outputFile });
1457
+ if (db.type === 'sqljs' && db.save) db.save();
1458
+ db.close();
1459
+ }
1460
+
1461
+ if (_args[0] === 'embed-status') {
1462
+ const embMod = getEmbeddingsModuleGrafo();
1463
+ console.log('\n Embeddings locales — Agentic KDD v2.2\n');
1464
+ if (!embMod) {
1465
+ console.log(' Estado: módulo embeddings.cjs no encontrado');
1466
+ console.log(' Solución: akdd update\n');
1467
+ } else if (!embMod.isAvailable()) {
1468
+ console.log(' Estado: @xenova/transformers no instalado');
1469
+ console.log(' Modelo: all-MiniLM-L6-v2 (23MB, 100% offline)');
1470
+ console.log(' Instalar: akdd embed-install\n');
1471
+ } else {
1472
+ console.log(' Estado: ✓ disponible');
1473
+ console.log(` Modelo: ${embMod.MODELO}`);
1474
+ console.log(` Dimensiones: ${embMod.DIM}`);
1475
+ console.log(' Búsqueda: vectorial híbrida (RRF)\n');
1476
+ }
1477
+ }
1478
+
1479
+ if (_args[0] === 'embed-install') {
1480
+ const embMod = getEmbeddingsModuleGrafo();
1481
+ if (!embMod) { console.log('\n akdd update primero\n'); process.exit(1); }
1482
+ embMod.instalar();
1483
+ }
1484
+
1485
+ // ─── v2.2: Lazy loaders de módulos (sin romper arranque si no existen) ────────
1486
+ function getEmbeddingsModuleGrafo() {
1487
+ try {
1488
+ const p = path.join(__dirname, 'embeddings.cjs');
1489
+ return fs.existsSync(p) ? require(p) : null;
1490
+ } catch(e) { return null; }
1491
+ }
1492
+ function getGitContextModuleGrafo() {
1493
+ try {
1494
+ const p = path.join(__dirname, 'git-context.cjs');
1495
+ return fs.existsSync(p) ? require(p) : null;
1496
+ } catch(e) { return null; }
1497
+ }
1498
+ function getPrediccionModuleGrafo() {
1499
+ try {
1500
+ const p = path.join(__dirname, 'prediccion.cjs');
1501
+ return fs.existsSync(p) ? require(p) : null;
1502
+ } catch(e) { return null; }
1503
+ }
1504
+ function getCICDModuleGrafo() {
1505
+ try {
1506
+ const p = path.join(__dirname, 'cicd.cjs');
1507
+ return fs.existsSync(p) ? require(p) : null;
1508
+ } catch(e) { return null; }
1509
+ }
1510
+
1511
+ // ─── v2.2: buscar con embeddings (async) ────────────────────────────────────
1512
+ async function buscarHibridoConEmbeddings(query, area, topK) {
1513
+ const embMod = getEmbeddingsModuleGrafo();
1514
+ const db = initDB();
1515
+
1516
+ let sqlNodos = `SELECT *, 'procedural' as memoria_tipo FROM nodos WHERE estado='ACTIVO'`;
1517
+ if (area && area !== 'global') sqlNodos += ` AND (area=? OR area='global')`;
1518
+ const nodosAll = area ? db.all(sqlNodos, area) : db.all(sqlNodos);
1519
+
1520
+ let sqlEp = `SELECT *, 'episodica' as memoria_tipo FROM episodios WHERE relevancia > 0.3`;
1521
+ if (area && area !== 'global') sqlEp += ` AND (area=? OR area='global')`;
1522
+ sqlEp += ' ORDER BY fecha DESC LIMIT 50';
1523
+ const episodiosAll = area ? db.all(sqlEp, area) : db.all(sqlEp);
1524
+
1525
+ const entidadesAll = db.all("SELECT *, 'semantica' as memoria_tipo FROM entidades LIMIT 100");
1526
+ db.close();
1527
+
1528
+ const todos = [...nodosAll, ...episodiosAll, ...entidadesAll];
1529
+ if (embMod && embMod.isAvailable()) {
1530
+ return await embMod.buscarHibridoVectorial(todos, query, topK || 10);
1531
+ }
1532
+ return buscarHibrido(query, area, topK).resultados;
1533
+ }
1534
+
1535
+ // ─── v2.2: sync extendido (git-context + embeddings) ─────────────────────────
1536
+ // Se activa con: node grafo.cjs sync-v2
1537
+ if (_args[0] === 'sync-v2') {
1538
+ (async () => {
1539
+ // 1. Sync normal
1540
+ sincronizar();
1541
+
1542
+ const db = initDB();
1543
+
1544
+ // 2. Git context
1545
+ const gitMod = getGitContextModuleGrafo();
1546
+ if (gitMod && gitMod.gitDisponible(ROOT)) {
1547
+ const resultado = gitMod.analizarGitContext(ROOT, db);
1548
+ if (resultado.disponible && resultado.contexto) {
1549
+ const { riesgos, predicciones } = resultado.contexto;
1550
+ if (riesgos?.some(r => r.nivel === 'ALTO')) {
1551
+ console.log('\n ⚠️ ALERTAS:');
1552
+ riesgos.filter(r => r.nivel === 'ALTO').slice(0, 3).forEach(r =>
1553
+ console.log(` 🔴 [ALTO] ${r.archivo}: ${r.advertencia || ''}`));
1554
+ }
1555
+ if (predicciones?.length > 0) {
1556
+ console.log(' ⚡ Predicciones:');
1557
+ predicciones.slice(0, 3).forEach(p => console.log(` · ${p.mensaje}`));
1558
+ }
1559
+ // Guardar en working_memory
1560
+ const sesionId = `sync-v2-${Date.now()}`;
1561
+ try {
1562
+ db.run('UPDATE working_memory SET expirado=1 WHERE expirado=0');
1563
+ db.run(
1564
+ `INSERT INTO working_memory (sesion_id, tipo, contenido, relevancia) VALUES (?,?,?,?)`,
1565
+ sesionId, 'observacion', JSON.stringify(resultado.contexto), 1.0
1566
+ );
1567
+ } catch(e) {}
1568
+ }
1569
+ }
1570
+
1571
+ // 3. Embeddings — indexar pendientes
1572
+ const embMod = getEmbeddingsModuleGrafo();
1573
+ if (embMod && embMod.isAvailable()) {
1574
+ process.stdout.write(' Embeddings: indexando... ');
1575
+ try {
1576
+ const r = await embMod.indexarPendientes(db, 30);
1577
+ console.log(r.indexados > 0 ? `✓ (${r.indexados} nuevos)` : '✓ (al día)');
1578
+ } catch(e) { console.log(''); }
1579
+ }
1580
+
1581
+ if (db.type === 'sqljs' && db.save) db.save();
1582
+ db.close();
1583
+ })();
1584
+ }
1585
+
1586
+ // ─── v2.2: predicción para Context Guard ─────────────────────────────────────
1587
+ if (_args[0] === 'predecir') {
1588
+ const predMod = getPrediccionModuleGrafo();
1589
+ if (!predMod) { console.log(JSON.stringify({ nivel_riesgo: 'BAJO', alertas: [] })); process.exit(0); }
1590
+ try {
1591
+ const tarea = _args[1] || '';
1592
+ const archivos = _args[2] ? JSON.parse(_args[2]) : [];
1593
+ const modulo = _args[3] || 'global';
1594
+ const db = initDB();
1595
+ const resultado = predMod.evaluarRiesgoTarea(tarea, archivos, modulo, db);
1596
+ db.close();
1597
+ console.log(JSON.stringify(resultado, null, 2));
1598
+ } catch(e) { console.log(JSON.stringify({ nivel_riesgo: 'BAJO', alertas: [], error: e.message })); }
1599
+ }
1600
+
1601
+ // ─── v2.2: schema migration ───────────────────────────────────────────────────
1602
+ // Las nuevas tablas se crean automáticamente en el próximo initDB()
1603
+ // grafo.cjs ya llama migrateDB() que tiene las ALTER TABLE
1604
+ // Solo hay que asegurar que las nuevas tablas de git_context_log, etc. se crean
1605
+
1606
+ // ─── v3.1: Migración para AST, Knowledge Base y Bi-temporal ─────────────────
1607
+ // Agentic KDD v3.1 — Nuevas tablas y columnas para Fases 1-3
1608
+ // Esta función se llama automáticamente en la siguiente ejecución.
1609
+
1610
+ function migrateV3_1(db) {
1611
+ // Columnas bi-temporales en relaciones_semanticas
1612
+ const biTemporalMigrations = [
1613
+ "ALTER TABLE relaciones_semanticas ADD COLUMN valid_at TEXT DEFAULT (datetime('now'))",
1614
+ "ALTER TABLE relaciones_semanticas ADD COLUMN invalid_at TEXT",
1615
+ "ALTER TABLE relaciones_semanticas ADD COLUMN expired_at TEXT",
1616
+ "ALTER TABLE relaciones_semanticas ADD COLUMN episode_id TEXT",
1617
+ "ALTER TABLE relaciones_semanticas ADD COLUMN confidence TEXT DEFAULT 'MEDIA'",
1618
+ "ALTER TABLE relaciones_semanticas ADD COLUMN context TEXT",
1619
+ "ALTER TABLE relaciones_semanticas ADD COLUMN source TEXT DEFAULT 'agent'",
1620
+ ];
1621
+ biTemporalMigrations.forEach(sql => { try { db.exec(sql); } catch(e) {} });
1622
+
1623
+ // Índices bi-temporales
1624
+ const biTemporalIndices = [
1625
+ "CREATE INDEX IF NOT EXISTS idx_rel_sem_valid ON relaciones_semanticas(valid_at)",
1626
+ "CREATE INDEX IF NOT EXISTS idx_rel_sem_invalid ON relaciones_semanticas(invalid_at)",
1627
+ "CREATE INDEX IF NOT EXISTS idx_rel_sem_type ON relaciones_semanticas(tipo)",
1628
+ ];
1629
+ biTemporalIndices.forEach(sql => { try { db.exec(sql); } catch(e) {} });
1630
+
1631
+ // Tabla AST Symbols
1632
+ const astSymbolsSQL = `
1633
+ CREATE TABLE IF NOT EXISTS ast_symbols (
1634
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1635
+ file TEXT NOT NULL,
1636
+ language TEXT NOT NULL,
1637
+ symbol_name TEXT NOT NULL,
1638
+ kind TEXT NOT NULL,
1639
+ line_start INTEGER DEFAULT 0,
1640
+ line_end INTEGER DEFAULT 0,
1641
+ exported INTEGER DEFAULT 0,
1642
+ signature TEXT,
1643
+ pagerank REAL DEFAULT 0.0,
1644
+ last_indexed TEXT DEFAULT (datetime('now')),
1645
+ content_hash TEXT
1646
+ )`;
1647
+ try { db.exec(astSymbolsSQL); } catch(e) {}
1648
+ try { db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_ast_sym_uniq ON ast_symbols(file, symbol_name, kind)"); } catch(e) {}
1649
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_ast_sym_file ON ast_symbols(file)"); } catch(e) {}
1650
+
1651
+ // Tabla AST Edges
1652
+ const astEdgesSQL = `
1653
+ CREATE TABLE IF NOT EXISTS ast_edges (
1654
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1655
+ from_file TEXT NOT NULL,
1656
+ to_file TEXT,
1657
+ from_symbol TEXT,
1658
+ to_symbol TEXT,
1659
+ kind TEXT NOT NULL,
1660
+ weight REAL DEFAULT 1.0,
1661
+ pagerank_src REAL DEFAULT 0.0,
1662
+ last_indexed TEXT DEFAULT (datetime('now'))
1663
+ )`;
1664
+ try { db.exec(astEdgesSQL); } catch(e) {}
1665
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_ast_edge_from ON ast_edges(from_file)"); } catch(e) {}
1666
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_ast_edge_to ON ast_edges(to_file)"); } catch(e) {}
1667
+
1668
+ // Tabla Knowledge Docs (ADRs, gotchas, convenciones)
1669
+ const knowledgeDocsSQL = `
1670
+ CREATE TABLE IF NOT EXISTS knowledge_docs (
1671
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1672
+ doc_id TEXT NOT NULL UNIQUE,
1673
+ tipo TEXT NOT NULL,
1674
+ titulo TEXT NOT NULL,
1675
+ status TEXT DEFAULT 'accepted',
1676
+ fecha TEXT,
1677
+ decision_makers TEXT DEFAULT '[]',
1678
+ afecta TEXT DEFAULT '[]',
1679
+ frontmatter TEXT DEFAULT '{}',
1680
+ contenido TEXT,
1681
+ context TEXT,
1682
+ decision TEXT,
1683
+ consequences TEXT,
1684
+ options TEXT DEFAULT '[]',
1685
+ file_path TEXT,
1686
+ last_indexed TEXT DEFAULT (datetime('now')),
1687
+ content_hash TEXT
1688
+ )`;
1689
+ try { db.exec(knowledgeDocsSQL); } catch(e) {}
1690
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_kdocs_tipo ON knowledge_docs(tipo)"); } catch(e) {}
1691
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_kdocs_status ON knowledge_docs(status)"); } catch(e) {}
1692
+
1693
+ // campo gate_result en fases (para harness tracking)
1694
+ try { db.exec("ALTER TABLE fases ADD COLUMN gate_result TEXT"); } catch(e) {}
1695
+ try { db.exec("ALTER TABLE fases ADD COLUMN harness_passed INTEGER DEFAULT 0"); } catch(e) {}
1696
+
1697
+ // campo ast_indexed en ciclos
1698
+ try { db.exec("ALTER TABLE ciclos ADD COLUMN ast_indexed INTEGER DEFAULT 0"); } catch(e) {}
1699
+ try { db.exec("ALTER TABLE ciclos ADD COLUMN knowledge_loaded INTEGER DEFAULT 0"); } catch(e) {}
1700
+ }
1701
+
1702
+ // Auto-run migrateV3_1 when grafo.cjs is first loaded
1703
+ (function autoMigrateV3_1() {
1704
+ try {
1705
+ const _dbForMigration = initDB();
1706
+ migrateV3_1(_dbForMigration);
1707
+ if (_dbForMigration.save) _dbForMigration.save();
1708
+ _dbForMigration.close();
1709
+ } catch(e) {
1710
+ // Silent — migration runs opportunistically
1711
+ }
1712
+ })();
1713
+
1714
+ // Export migrateV3_1
1715
+ const _exportsV31 = module.exports || {};
1716
+ module.exports = { ..._exportsV31, migrateV3_1 };
1717
+
1718
+
1719
+ // ─── v3.2: Vigencia de Memoria + Verdad Vigente ────────────────────────────
1720
+ // Cierra el Gap #1: límite claro entre memoria vigente, histórica y evidencia
1721
+
1722
+ function migrateV3_2(db) {
1723
+ // Columna vigencia_tipo en nodos
1724
+ try { db.exec("ALTER TABLE nodos ADD COLUMN vigencia_tipo TEXT DEFAULT 'VIGENTE'"); } catch {}
1725
+ try { db.exec("CREATE INDEX IF NOT EXISTS idx_nodos_vigencia ON nodos(vigencia_tipo)"); } catch {}
1726
+ // Inferir vigencia_tipo para registros existentes
1727
+ try {
1728
+ db.exec("UPDATE nodos SET vigencia_tipo='OBSOLETO' WHERE estado='OBSOLETO' AND vigencia_tipo='VIGENTE'");
1729
+ db.exec("UPDATE nodos SET vigencia_tipo='HISTORICO' WHERE estado='CONSOLIDADO' AND vigencia_tipo='VIGENTE'");
1730
+ } catch {}
1731
+ }
1732
+
1733
+ // Auto-run
1734
+ (function autoMigrateV3_2() {
1735
+ try {
1736
+ const _db = initDB();
1737
+ migrateV3_2(_db);
1738
+ if (_db.save) _db.save();
1739
+ _db.close();
1740
+ } catch {}
1741
+ })();
1742
+
1743
+ const _exportsV32 = module.exports || {};
1744
+ module.exports = { ..._exportsV32, migrateV3_2 };
1745
+
1746
+
1747
+ // ─── v3.2: AUTO-INTEGRATION — MemCurator + llms-generator ─────────────────────
1748
+ // Se hookan automáticamente en el flujo de sync existente.
1749
+
1750
+ const _grafoPath = __dirname;
1751
+
1752
+ function _autoRunCurator() {
1753
+ try {
1754
+ const db = initDB();
1755
+ // Contar ciclos desde última curation
1756
+ let lastCuration = 0;
1757
+ try {
1758
+ const meta = db.prepare("SELECT valor FROM metadata WHERE clave='last_curator_cycle'").get();
1759
+ lastCuration = parseInt(meta?.valor || '0');
1760
+ } catch {}
1761
+ const totalCycles = db.prepare("SELECT COUNT(*) as n FROM ciclos").get()?.n || 0;
1762
+ if (totalCycles - lastCuration >= 10) {
1763
+ const { runCuration } = require(require('path').join(_grafoPath, 'mem-curator.cjs'));
1764
+ runCuration(process.cwd());
1765
+ try {
1766
+ db.prepare("INSERT OR REPLACE INTO metadata (clave, valor) VALUES ('last_curator_cycle', ?)").run(String(totalCycles));
1767
+ } catch {
1768
+ try { db.prepare("CREATE TABLE IF NOT EXISTS metadata (clave TEXT PRIMARY KEY, valor TEXT)").run(); } catch {}
1769
+ try { db.prepare("INSERT OR REPLACE INTO metadata (clave, valor) VALUES ('last_curator_cycle', ?)").run(String(totalCycles)); } catch {}
1770
+ }
1771
+ }
1772
+ if (db.save) db.save(); db.close();
1773
+ } catch {}
1774
+ }
1775
+
1776
+ function _autoGenerateLlms() {
1777
+ try {
1778
+ const { generateAll } = require(require('path').join(_grafoPath, 'llms-generator.cjs'));
1779
+ generateAll(process.cwd());
1780
+ } catch {}
1781
+ }
1782
+
1783
+ // Hookar en la función sincronizar existente
1784
+ const _origExports = module.exports || {};
1785
+ const _origSync = _origExports.sincronizar;
1786
+ if (_origSync && typeof _origSync === 'function') {
1787
+ _origExports.sincronizar = function(...args) {
1788
+ const result = _origSync.apply(this, args);
1789
+ try { _autoRunCurator(); } catch {}
1790
+ try { _autoGenerateLlms(); } catch {}
1791
+ return result;
1792
+ };
1793
+ }
1794
+
1795
+ module.exports = { ..._origExports };
1796
+
1797
+ // ─── v3.3: CONTRACT GUARD + CREATIVE ENGINE AUTO-INTEGRATION ─────────────────
1798
+
1799
+ function _autoRunContractGuard(cicloId, testOutput) {
1800
+ try {
1801
+ const db = initDB();
1802
+ const cg = require(require('path').join(__dirname, 'contract-guard.cjs'));
1803
+ cg.migrateSchema(db);
1804
+ if (testOutput) {
1805
+ cg.ingestFromCycle(db, process.cwd(), cicloId, testOutput);
1806
+ }
1807
+ if (db.save) db.save(); db.close();
1808
+ } catch {}
1809
+ }
1810
+
1811
+ function _autoRunCreativeEngine(cicloId) {
1812
+ try {
1813
+ const db = initDB();
1814
+ const ce = require(require('path').join(__dirname, 'creative-engine.cjs'));
1815
+ ce.migrateSchema(db);
1816
+ const result = ce.runCreativePass(db, process.cwd(), cicloId);
1817
+ if (result.new_suggestions > 0 || result.auto_applied > 0) {
1818
+ console.error(`[CREATIVE] Level ${result.level}: ${result.new_suggestions} suggestions, ${result.auto_applied} auto-applied`);
1819
+ }
1820
+ if (db.save) db.save(); db.close();
1821
+ } catch {}
1822
+ }
1823
+
1824
+ // Hook into existing exports
1825
+ const _contractCreativeExports = module.exports || {};
1826
+ const _origSyncCC = _contractCreativeExports.sincronizar;
1827
+ if (_origSyncCC && typeof _origSyncCC === 'function') {
1828
+ _contractCreativeExports.sincronizar = function(...args) {
1829
+ const result = _origSyncCC.apply(this, args);
1830
+ const cicloId = `sync-${Date.now()}`;
1831
+ try { _autoRunContractGuard(cicloId, null); } catch {}
1832
+ try { _autoRunCreativeEngine(cicloId); } catch {}
1833
+ return result;
1834
+ };
1835
+ }
1836
+
1837
+ module.exports = { ..._contractCreativeExports };
1838
+
1839
+ // ─── v3.3: SESSION GUARD AUTO-CHECKPOINT ──────────────────────────────────────
1840
+ function _autoSessionGuard() {
1841
+ try {
1842
+ const db = initDB();
1843
+ const cycles = db.prepare("SELECT COUNT(*) as n FROM ciclos").get()?.n || 0;
1844
+ if (cycles > 0 && cycles % 5 === 0) {
1845
+ const { generateCheckpoint } = require(require('path').join(__dirname, 'session-guard.cjs'));
1846
+ generateCheckpoint(process.cwd());
1847
+ console.error('[SESSION] Checkpoint guardado (.agentic/checkpoint.md)');
1848
+ }
1849
+ if (db.save) db.save(); db.close();
1850
+ } catch {}
1851
+ }
1852
+
1853
+ const _sgExports = module.exports || {};
1854
+ const _origSyncSG = _sgExports.sincronizar;
1855
+ if (_origSyncSG && typeof _origSyncSG === 'function') {
1856
+ _sgExports.sincronizar = function(...args) {
1857
+ const result = _origSyncSG.apply(this, args);
1858
+ try { _autoSessionGuard(); } catch {}
1859
+ return result;
1860
+ };
1861
+ }
1862
+ module.exports = { ..._sgExports };
1863
+
1864
+ // ─── v3.3: AUTONOMOUS DECISION ENGINE AUTO-INTEGRATION ────────────────────────
1865
+ // Se hookea en el sync para correr la cola diferida al final de cada ciclo
1866
+
1867
+ function _autoFlushDeferred() {
1868
+ try {
1869
+ const { flushDeferredQueue } = require(require('path').join(__dirname, 'autonomous-decision.cjs'));
1870
+ const flushed = flushDeferredQueue(process.cwd());
1871
+ if (flushed.length > 0) {
1872
+ console.error(`[AUTONOMOUS] ${flushed.length} deferred item(s) from queue — review as suggestions`);
1873
+ // Add to creative engine suggestions
1874
+ try {
1875
+ const { addSuggestion } = require(require('path').join(__dirname, 'creative-engine.cjs'));
1876
+ const db = initDB();
1877
+ flushed.forEach(item => {
1878
+ addSuggestion(db, {
1879
+ type: 'OPPORTUNITY',
1880
+ title: item.task || 'Deferred task',
1881
+ description: item.reason || 'Deferred by Autonomous Decision Engine',
1882
+ module: (item.files || [])[0] || 'global',
1883
+ }, `deferred-${Date.now()}`);
1884
+ });
1885
+ if (db.save) db.save(); db.close();
1886
+ } catch {}
1887
+ }
1888
+ } catch {}
1889
+ }
1890
+
1891
+ const _adExports = module.exports || {};
1892
+ const _origSyncAD = _adExports.sincronizar;
1893
+ if (_origSyncAD && typeof _origSyncAD === 'function') {
1894
+ _adExports.sincronizar = function(...args) {
1895
+ const result = _origSyncAD.apply(this, args);
1896
+ try { _autoFlushDeferred(); } catch {}
1897
+ return result;
1898
+ };
1899
+ }
1900
+ module.exports = { ..._adExports };
1901
+
1902
+ // ─── v3.4: kdd-memory + knowledge-validator + telemetry INTEGRATION ─────────
1903
+
1904
+ function _autoKDDMemorySync() {
1905
+ try {
1906
+ const { syncFTS } = require(require('path').join(__dirname, 'kdd-memory.cjs'));
1907
+ const db = initDB();
1908
+ const nodeCount = db.prepare("SELECT COUNT(*) as n FROM nodos WHERE estado='ACTIVO'").get()?.n || 0;
1909
+ let ftsCount = 0;
1910
+ try { ftsCount = db.prepare("SELECT COUNT(*) as n FROM nodos_fts").get()?.n || 0; } catch {}
1911
+ if (ftsCount < nodeCount * 0.9) {
1912
+ syncFTS(db);
1913
+ console.error('[KDD-MEMORY] FTS index synced');
1914
+ }
1915
+ if (db.save) db.save(); db.close();
1916
+ } catch {}
1917
+ }
1918
+
1919
+ function _autoKnowledgeValidation() {
1920
+ try {
1921
+ const { scanAll } = require(require('path').join(__dirname, 'knowledge-validator.cjs'));
1922
+ const result = scanAll(process.cwd());
1923
+ if (result.sospechoso > 0 || result.poison_candidates > 0) {
1924
+ console.error(`[VALIDATOR] ${result.sospechoso} suspicious + ${result.poison_candidates} poison candidates`);
1925
+ }
1926
+ } catch {}
1927
+ }
1928
+
1929
+ const _kdmExports = module.exports || {};
1930
+ const _origSyncKDM = _kdmExports.sincronizar;
1931
+ if (_origSyncKDM && typeof _origSyncKDM === 'function') {
1932
+ _kdmExports.sincronizar = function(...args) {
1933
+ const result = _origSyncKDM.apply(this, args);
1934
+ try { _autoKDDMemorySync(); } catch {}
1935
+ return result;
1936
+ };
1937
+ }
1938
+ module.exports = { ..._kdmExports };
1939
+
1940
+ // ─── v3.6: project_settings — config persistente en BD ──────────────────────
1941
+ // Guarda CONFIGURADO, nombre, stack y test command en memoria.db
1942
+ // Fuente de verdad secundaria cuando config.md falla o se pisa durante update
1943
+
1944
+ (function migrateProjectSettings() {
1945
+ try {
1946
+ const _db = initDB();
1947
+
1948
+ // Crear tabla project_settings si no existe
1949
+ _db.exec(`
1950
+ CREATE TABLE IF NOT EXISTS project_settings (
1951
+ key TEXT PRIMARY KEY,
1952
+ value TEXT NOT NULL,
1953
+ updated_at TEXT DEFAULT (datetime('now'))
1954
+ )
1955
+ `);
1956
+
1957
+ // Leer config.md y sincronizar a BD si CONFIGURADO: SI
1958
+ const fs = require('fs');
1959
+ const path = require('path');
1960
+ const configPath = path.join(process.cwd(), '.agentic', 'config.md');
1961
+
1962
+ if (fs.existsSync(configPath)) {
1963
+ const config = fs.readFileSync(configPath, 'utf8');
1964
+ const configured = /^CONFIGURADO:\s*SI/m.test(config);
1965
+
1966
+ if (configured) {
1967
+ // Guardar estado en BD
1968
+ const upsert = _db.prepare(`
1969
+ INSERT INTO project_settings (key, value, updated_at)
1970
+ VALUES (?, ?, datetime('now'))
1971
+ ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at
1972
+ `);
1973
+
1974
+ upsert.run('configured', 'true');
1975
+
1976
+ const nameMatch = config.match(/^Nombre:\s*(.+)$/m);
1977
+ if (nameMatch) upsert.run('project_name', nameMatch[1].trim());
1978
+
1979
+ const testMatch = config.match(/^\s*test:\s*(.+)$/m);
1980
+ if (testMatch && testMatch[1].trim() !== '—') {
1981
+ upsert.run('test_command', testMatch[1].trim());
1982
+ }
1983
+
1984
+ const stackBlock = config.match(/^## Stack\n([\s\S]+?)(?=\n##|$)/m);
1985
+ if (stackBlock) upsert.run('stack', stackBlock[1].trim());
1986
+ }
1987
+ } else {
1988
+ // config.md no existe — intentar restaurar desde BD
1989
+ const settings = {};
1990
+ try {
1991
+ const rows = _db.prepare('SELECT key, value FROM project_settings').all();
1992
+ for (const row of rows) settings[row.key] = row.value;
1993
+ } catch {}
1994
+
1995
+ if (settings.configured === 'true' && fs.existsSync(path.join(process.cwd(), '.agentic'))) {
1996
+ // Reconstruir config.md mínimo desde BD
1997
+ const lines = [
1998
+ '# Agentic KDD — Configuración del proyecto',
1999
+ 'CONFIGURADO: SI',
2000
+ 'VERSION: 2.0',
2001
+ '',
2002
+ '## Proyecto',
2003
+ `Nombre: ${settings.project_name || '(restaurado desde BD)'}`,
2004
+ 'Descripción: —',
2005
+ 'Tipo: EXISTENTE',
2006
+ '',
2007
+ settings.stack ? `## Stack\n${settings.stack}` : '## Stack\n—',
2008
+ '',
2009
+ '## Comando de tests',
2010
+ settings.test_command ? `test: ${settings.test_command}` : 'test: —',
2011
+ ];
2012
+ fs.writeFileSync(configPath, lines.join('\n'), 'utf8');
2013
+ console.error('[AGENTIC] config.md restaurado desde memoria.db');
2014
+ }
2015
+ }
2016
+
2017
+ if (_db.save) _db.save();
2018
+ _db.close();
2019
+ } catch(e) {
2020
+ // Silent — best effort
2021
+ }
2022
+ })();
2023
+
2024
+ const _ps36Exports = module.exports || {};
2025
+ module.exports = { ..._ps36Exports };