@hoilab/ada-cli 0.84.22 → 0.85.0
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/CHANGELOG.md +29 -2
- package/README.es.md +17 -6
- package/README.md +109 -11
- package/dist/ada-publico.d.ts +35 -0
- package/dist/ada-publico.d.ts.map +1 -0
- package/dist/ada-publico.js +40 -0
- package/dist/ada-publico.js.map +1 -0
- package/dist/cli/audit-command.d.ts +15 -0
- package/dist/cli/audit-command.d.ts.map +1 -0
- package/dist/cli/audit-command.js +280 -0
- package/dist/cli/audit-command.js.map +1 -0
- package/dist/cli/banco-command.d.ts +15 -0
- package/dist/cli/banco-command.d.ts.map +1 -0
- package/dist/cli/banco-command.js +213 -0
- package/dist/cli/banco-command.js.map +1 -0
- package/dist/cli/cleanse-command.d.ts +11 -0
- package/dist/cli/cleanse-command.d.ts.map +1 -0
- package/dist/cli/cleanse-command.js +101 -0
- package/dist/cli/cleanse-command.js.map +1 -0
- package/dist/cli/commit-command.d.ts +31 -0
- package/dist/cli/commit-command.d.ts.map +1 -0
- package/dist/cli/commit-command.js +158 -0
- package/dist/cli/commit-command.js.map +1 -0
- package/dist/cli/computer-command.d.ts +12 -0
- package/dist/cli/computer-command.d.ts.map +1 -0
- package/dist/cli/computer-command.js +141 -0
- package/dist/cli/computer-command.js.map +1 -0
- package/dist/cli/discover-command.d.ts +18 -0
- package/dist/cli/discover-command.d.ts.map +1 -0
- package/dist/cli/discover-command.js +108 -0
- package/dist/cli/discover-command.js.map +1 -0
- package/dist/cli/hashline-command.d.ts +11 -0
- package/dist/cli/hashline-command.d.ts.map +1 -0
- package/dist/cli/hashline-command.js +106 -0
- package/dist/cli/hashline-command.js.map +1 -0
- package/dist/cli/import-command.d.ts +35 -0
- package/dist/cli/import-command.d.ts.map +1 -0
- package/dist/cli/import-command.js +164 -0
- package/dist/cli/import-command.js.map +1 -0
- package/dist/cli/politica-command.d.ts +20 -0
- package/dist/cli/politica-command.d.ts.map +1 -0
- package/dist/cli/politica-command.js +93 -0
- package/dist/cli/politica-command.js.map +1 -0
- package/dist/cli/refine-command.d.ts +18 -0
- package/dist/cli/refine-command.d.ts.map +1 -0
- package/dist/cli/refine-command.js +101 -0
- package/dist/cli/refine-command.js.map +1 -0
- package/dist/cli/review-command.d.ts +24 -0
- package/dist/cli/review-command.d.ts.map +1 -0
- package/dist/cli/review-command.js +168 -0
- package/dist/cli/review-command.js.map +1 -0
- package/dist/cli/schedule-command.d.ts +17 -0
- package/dist/cli/schedule-command.d.ts.map +1 -0
- package/dist/cli/schedule-command.js +117 -0
- package/dist/cli/schedule-command.js.map +1 -0
- package/dist/cli/serve-command.d.ts +72 -0
- package/dist/cli/serve-command.d.ts.map +1 -0
- package/dist/cli/serve-command.js +568 -0
- package/dist/cli/serve-command.js.map +1 -0
- package/dist/cli/telegram-command.d.ts +18 -0
- package/dist/cli/telegram-command.d.ts.map +1 -0
- package/dist/cli/telegram-command.js +137 -0
- package/dist/cli/telegram-command.js.map +1 -0
- package/dist/cli/telemetria-command.d.ts +22 -0
- package/dist/cli/telemetria-command.d.ts.map +1 -0
- package/dist/cli/telemetria-command.js +127 -0
- package/dist/cli/telemetria-command.js.map +1 -0
- package/dist/cli/undo-command.d.ts +9 -0
- package/dist/cli/undo-command.d.ts.map +1 -0
- package/dist/cli/undo-command.js +56 -0
- package/dist/cli/undo-command.js.map +1 -0
- package/dist/cli/usage-command.d.ts +10 -0
- package/dist/cli/usage-command.d.ts.map +1 -0
- package/dist/cli/usage-command.js +209 -0
- package/dist/cli/usage-command.js.map +1 -0
- package/dist/cli/wiki-command.d.ts +9 -0
- package/dist/cli/wiki-command.d.ts.map +1 -0
- package/dist/cli/wiki-command.js +76 -0
- package/dist/cli/wiki-command.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -11
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/ada.d.ts +58 -0
- package/dist/core/ada.d.ts.map +1 -0
- package/dist/core/ada.js +61 -0
- package/dist/core/ada.js.map +1 -0
- package/dist/core/advisor/guarda.d.ts +66 -0
- package/dist/core/advisor/guarda.d.ts.map +1 -0
- package/dist/core/advisor/guarda.js +191 -0
- package/dist/core/advisor/guarda.js.map +1 -0
- package/dist/core/advisor/runtime.d.ts +66 -0
- package/dist/core/advisor/runtime.d.ts.map +1 -0
- package/dist/core/advisor/runtime.js +121 -0
- package/dist/core/advisor/runtime.js.map +1 -0
- package/dist/core/advisor/sesion.d.ts +109 -0
- package/dist/core/advisor/sesion.d.ts.map +1 -0
- package/dist/core/advisor/sesion.js +139 -0
- package/dist/core/advisor/sesion.js.map +1 -0
- package/dist/core/agent-session.d.ts +30 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +430 -22
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents/loader.d.ts +77 -0
- package/dist/core/agents/loader.d.ts.map +1 -0
- package/dist/core/agents/loader.js +154 -0
- package/dist/core/agents/loader.js.map +1 -0
- package/dist/core/aprobacion/generados.d.ts +37 -0
- package/dist/core/aprobacion/generados.d.ts.map +1 -0
- package/dist/core/aprobacion/generados.js +85 -0
- package/dist/core/aprobacion/generados.js.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts +90 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.js +212 -0
- package/dist/core/aprobacion/politica-de-maquina.js.map +1 -0
- package/dist/core/aprobacion/politica.d.ts +90 -0
- package/dist/core/aprobacion/politica.d.ts.map +1 -0
- package/dist/core/aprobacion/politica.js +375 -0
- package/dist/core/aprobacion/politica.js.map +1 -0
- package/dist/core/arranque/atajos.d.ts +46 -0
- package/dist/core/arranque/atajos.d.ts.map +1 -0
- package/dist/core/arranque/atajos.js +113 -0
- package/dist/core/arranque/atajos.js.map +1 -0
- package/dist/core/audit/exportacion.d.ts +54 -0
- package/dist/core/audit/exportacion.d.ts.map +1 -0
- package/dist/core/audit/exportacion.js +265 -0
- package/dist/core/audit/exportacion.js.map +1 -0
- package/dist/core/audit/libro.d.ts +318 -0
- package/dist/core/audit/libro.d.ts.map +1 -0
- package/dist/core/audit/libro.js +508 -0
- package/dist/core/audit/libro.js.map +1 -0
- package/dist/core/audit/registro-sesion.d.ts +78 -0
- package/dist/core/audit/registro-sesion.d.ts.map +1 -0
- package/dist/core/audit/registro-sesion.js +202 -0
- package/dist/core/audit/registro-sesion.js.map +1 -0
- package/dist/core/audit/retencion.d.ts +82 -0
- package/dist/core/audit/retencion.d.ts.map +1 -0
- package/dist/core/audit/retencion.js +152 -0
- package/dist/core/audit/retencion.js.map +1 -0
- package/dist/core/audit/rutas.d.ts +23 -0
- package/dist/core/audit/rutas.d.ts.map +1 -0
- package/dist/core/audit/rutas.js +23 -0
- package/dist/core/audit/rutas.js.map +1 -0
- package/dist/core/auth-storage.d.ts +0 -3
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -5
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/banco/almacenamiento.d.ts +18 -0
- package/dist/core/banco/almacenamiento.d.ts.map +1 -0
- package/dist/core/banco/almacenamiento.js +50 -0
- package/dist/core/banco/almacenamiento.js.map +1 -0
- package/dist/core/banco/analisis.d.ts +37 -0
- package/dist/core/banco/analisis.d.ts.map +1 -0
- package/dist/core/banco/analisis.js +164 -0
- package/dist/core/banco/analisis.js.map +1 -0
- package/dist/core/banco/bloques.d.ts +39 -0
- package/dist/core/banco/bloques.d.ts.map +1 -0
- package/dist/core/banco/bloques.js +84 -0
- package/dist/core/banco/bloques.js.map +1 -0
- package/dist/core/banco/cargas.d.ts +84 -0
- package/dist/core/banco/cargas.d.ts.map +1 -0
- package/dist/core/banco/cargas.js +520 -0
- package/dist/core/banco/cargas.js.map +1 -0
- package/dist/core/banco/comparar.d.ts +29 -0
- package/dist/core/banco/comparar.d.ts.map +1 -0
- package/dist/core/banco/comparar.js +28 -0
- package/dist/core/banco/comparar.js.map +1 -0
- package/dist/core/banco/ejecutar.d.ts +44 -0
- package/dist/core/banco/ejecutar.d.ts.map +1 -0
- package/dist/core/banco/ejecutar.js +183 -0
- package/dist/core/banco/ejecutar.js.map +1 -0
- package/dist/core/banco/generar.d.ts +24 -0
- package/dist/core/banco/generar.d.ts.map +1 -0
- package/dist/core/banco/generar.js +159 -0
- package/dist/core/banco/generar.js.map +1 -0
- package/dist/core/banco/mutaciones.d.ts +25 -0
- package/dist/core/banco/mutaciones.d.ts.map +1 -0
- package/dist/core/banco/mutaciones.js +215 -0
- package/dist/core/banco/mutaciones.js.map +1 -0
- package/dist/core/banco/tipos.d.ts +121 -0
- package/dist/core/banco/tipos.d.ts.map +1 -0
- package/dist/core/banco/tipos.js +16 -0
- package/dist/core/banco/tipos.js.map +1 -0
- package/dist/core/blobs/almacen.d.ts +81 -0
- package/dist/core/blobs/almacen.d.ts.map +1 -0
- package/dist/core/blobs/almacen.js +198 -0
- package/dist/core/blobs/almacen.js.map +1 -0
- package/dist/core/blobs/broker.d.ts +103 -0
- package/dist/core/blobs/broker.d.ts.map +1 -0
- package/dist/core/blobs/broker.js +204 -0
- package/dist/core/blobs/broker.js.map +1 -0
- package/dist/core/blobs/index.d.ts +70 -0
- package/dist/core/blobs/index.d.ts.map +1 -0
- package/dist/core/blobs/index.js +232 -0
- package/dist/core/blobs/index.js.map +1 -0
- package/dist/core/blobs/payload.d.ts +55 -0
- package/dist/core/blobs/payload.d.ts.map +1 -0
- package/dist/core/blobs/payload.js +255 -0
- package/dist/core/blobs/payload.js.map +1 -0
- package/dist/core/blobs/proveedor.d.ts +85 -0
- package/dist/core/blobs/proveedor.d.ts.map +1 -0
- package/dist/core/blobs/proveedor.js +196 -0
- package/dist/core/blobs/proveedor.js.map +1 -0
- package/dist/core/browser/cdp.d.ts +41 -0
- package/dist/core/browser/cdp.d.ts.map +1 -0
- package/dist/core/browser/cdp.js +119 -0
- package/dist/core/browser/cdp.js.map +1 -0
- package/dist/core/browser/politica.d.ts +51 -0
- package/dist/core/browser/politica.d.ts.map +1 -0
- package/dist/core/browser/politica.js +123 -0
- package/dist/core/browser/politica.js.map +1 -0
- package/dist/core/browser/sesion.d.ts +52 -0
- package/dist/core/browser/sesion.d.ts.map +1 -0
- package/dist/core/browser/sesion.js +176 -0
- package/dist/core/browser/sesion.js.map +1 -0
- package/dist/core/browser/tools.d.ts +16 -0
- package/dist/core/browser/tools.d.ts.map +1 -0
- package/dist/core/browser/tools.js +279 -0
- package/dist/core/browser/tools.js.map +1 -0
- package/dist/core/commit/diff.d.ts +56 -0
- package/dist/core/commit/diff.d.ts.map +1 -0
- package/dist/core/commit/diff.js +145 -0
- package/dist/core/commit/diff.js.map +1 -0
- package/dist/core/commit/mensaje.d.ts +80 -0
- package/dist/core/commit/mensaje.d.ts.map +1 -0
- package/dist/core/commit/mensaje.js +207 -0
- package/dist/core/commit/mensaje.js.map +1 -0
- package/dist/core/compactar/index.d.ts +52 -0
- package/dist/core/compactar/index.d.ts.map +1 -0
- package/dist/core/compactar/index.js +91 -0
- package/dist/core/compactar/index.js.map +1 -0
- package/dist/core/compactar/registro-denso.d.ts +160 -0
- package/dist/core/compactar/registro-denso.d.ts.map +1 -0
- package/dist/core/compactar/registro-denso.js +620 -0
- package/dist/core/compactar/registro-denso.js.map +1 -0
- package/dist/core/computer/captura.d.ts +35 -0
- package/dist/core/computer/captura.d.ts.map +1 -0
- package/dist/core/computer/captura.js +140 -0
- package/dist/core/computer/captura.js.map +1 -0
- package/dist/core/computer/driver.d.ts +130 -0
- package/dist/core/computer/driver.d.ts.map +1 -0
- package/dist/core/computer/driver.js +206 -0
- package/dist/core/computer/driver.js.map +1 -0
- package/dist/core/computer/motor/actions.d.ts +109 -0
- package/dist/core/computer/motor/actions.d.ts.map +1 -0
- package/dist/core/computer/motor/actions.js +157 -0
- package/dist/core/computer/motor/actions.js.map +1 -0
- package/dist/core/computer/motor/bridge.d.ts +232 -0
- package/dist/core/computer/motor/bridge.d.ts.map +1 -0
- package/dist/core/computer/motor/bridge.js +2335 -0
- package/dist/core/computer/motor/bridge.js.map +1 -0
- package/dist/core/computer/motor/cdp.d.ts +107 -0
- package/dist/core/computer/motor/cdp.d.ts.map +1 -0
- package/dist/core/computer/motor/cdp.js +659 -0
- package/dist/core/computer/motor/cdp.js.map +1 -0
- package/dist/core/computer/motor/config.d.ts +23 -0
- package/dist/core/computer/motor/config.d.ts.map +1 -0
- package/dist/core/computer/motor/config.js +100 -0
- package/dist/core/computer/motor/config.js.map +1 -0
- package/dist/core/computer/motor/contract.d.ts +81 -0
- package/dist/core/computer/motor/contract.d.ts.map +1 -0
- package/dist/core/computer/motor/contract.js +14 -0
- package/dist/core/computer/motor/contract.js.map +1 -0
- package/dist/core/computer/motor/note.d.ts +37 -0
- package/dist/core/computer/motor/note.d.ts.map +1 -0
- package/dist/core/computer/motor/note.js +162 -0
- package/dist/core/computer/motor/note.js.map +1 -0
- package/dist/core/computer/motor/outline.d.ts +155 -0
- package/dist/core/computer/motor/outline.d.ts.map +1 -0
- package/dist/core/computer/motor/outline.js +590 -0
- package/dist/core/computer/motor/outline.js.map +1 -0
- package/dist/core/computer/motor/output.d.ts +18 -0
- package/dist/core/computer/motor/output.d.ts.map +1 -0
- package/dist/core/computer/motor/output.js +148 -0
- package/dist/core/computer/motor/output.js.map +1 -0
- package/dist/core/computer/motor/permissions.d.ts +41 -0
- package/dist/core/computer/motor/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/permissions.js +51 -0
- package/dist/core/computer/motor/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/architecture.d.ts +5 -0
- package/dist/core/computer/motor/platform/architecture.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/architecture.js +21 -0
- package/dist/core/computer/motor/platform/architecture.js.map +1 -0
- package/dist/core/computer/motor/platform/coerce.d.ts +4 -0
- package/dist/core/computer/motor/platform/coerce.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/coerce.js +17 -0
- package/dist/core/computer/motor/platform/coerce.js.map +1 -0
- package/dist/core/computer/motor/platform/index.d.ts +4 -0
- package/dist/core/computer/motor/platform/index.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/index.js +79 -0
- package/dist/core/computer/motor/platform/index.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.js +173 -0
- package/dist/core/computer/motor/platform/linux/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts +29 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.js +261 -0
- package/dist/core/computer/motor/platform/linux/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.js +124 -0
- package/dist/core/computer/motor/platform/macos/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts +7 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.js +101 -0
- package/dist/core/computer/motor/platform/macos/browser.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper-path.mjs +34 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts +32 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper.js +277 -0
- package/dist/core/computer/motor/platform/macos/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts +4 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.js +118 -0
- package/dist/core/computer/motor/platform/macos/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/types.d.ts +263 -0
- package/dist/core/computer/motor/platform/types.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/types.js +2 -0
- package/dist/core/computer/motor/platform/types.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.js +163 -0
- package/dist/core/computer/motor/platform/windows/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts +18 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.js +174 -0
- package/dist/core/computer/motor/platform/windows/helper.js.map +1 -0
- package/dist/core/computer/motor/root-selection.d.ts +6 -0
- package/dist/core/computer/motor/root-selection.d.ts.map +1 -0
- package/dist/core/computer/motor/root-selection.js +28 -0
- package/dist/core/computer/motor/root-selection.js.map +1 -0
- package/dist/core/computer/motor/runtime.d.ts +50 -0
- package/dist/core/computer/motor/runtime.d.ts.map +1 -0
- package/dist/core/computer/motor/runtime.js +119 -0
- package/dist/core/computer/motor/runtime.js.map +1 -0
- package/dist/core/computer/motor/state.d.ts +68 -0
- package/dist/core/computer/motor/state.d.ts.map +1 -0
- package/dist/core/computer/motor/state.js +100 -0
- package/dist/core/computer/motor/state.js.map +1 -0
- package/dist/core/computer/motor/view.d.ts +6 -0
- package/dist/core/computer/motor/view.d.ts.map +1 -0
- package/dist/core/computer/motor/view.js +185 -0
- package/dist/core/computer/motor/view.js.map +1 -0
- package/dist/core/computer/motor-ada.d.ts +159 -0
- package/dist/core/computer/motor-ada.d.ts.map +1 -0
- package/dist/core/computer/motor-ada.js +412 -0
- package/dist/core/computer/motor-ada.js.map +1 -0
- package/dist/core/computer/politica.d.ts +56 -0
- package/dist/core/computer/politica.d.ts.map +1 -0
- package/dist/core/computer/politica.js +163 -0
- package/dist/core/computer/politica.js.map +1 -0
- package/dist/core/computer/tools.d.ts +26 -0
- package/dist/core/computer/tools.d.ts.map +1 -0
- package/dist/core/computer/tools.js +399 -0
- package/dist/core/computer/tools.js.map +1 -0
- package/dist/core/context-breakdown.d.ts +80 -0
- package/dist/core/context-breakdown.d.ts.map +1 -0
- package/dist/core/context-breakdown.js +87 -0
- package/dist/core/context-breakdown.js.map +1 -0
- package/dist/core/credenciales/cliente.d.ts +60 -0
- package/dist/core/credenciales/cliente.d.ts.map +1 -0
- package/dist/core/credenciales/cliente.js +81 -0
- package/dist/core/credenciales/cliente.js.map +1 -0
- package/dist/core/credenciales/pool.d.ts +96 -0
- package/dist/core/credenciales/pool.d.ts.map +1 -0
- package/dist/core/credenciales/pool.js +128 -0
- package/dist/core/credenciales/pool.js.map +1 -0
- package/dist/core/credenciales/reposo.d.ts +93 -0
- package/dist/core/credenciales/reposo.d.ts.map +1 -0
- package/dist/core/credenciales/reposo.js +489 -0
- package/dist/core/credenciales/reposo.js.map +1 -0
- package/dist/core/credenciales/servidor.d.ts +55 -0
- package/dist/core/credenciales/servidor.d.ts.map +1 -0
- package/dist/core/credenciales/servidor.js +205 -0
- package/dist/core/credenciales/servidor.js.map +1 -0
- package/dist/core/descubrimiento/comandos.d.ts +30 -0
- package/dist/core/descubrimiento/comandos.d.ts.map +1 -0
- package/dist/core/descubrimiento/comandos.js +76 -0
- package/dist/core/descubrimiento/comandos.js.map +1 -0
- package/dist/core/descubrimiento/mcp.d.ts +42 -0
- package/dist/core/descubrimiento/mcp.d.ts.map +1 -0
- package/dist/core/descubrimiento/mcp.js +130 -0
- package/dist/core/descubrimiento/mcp.js.map +1 -0
- package/dist/core/descubrimiento/reglas.d.ts +61 -0
- package/dist/core/descubrimiento/reglas.d.ts.map +1 -0
- package/dist/core/descubrimiento/reglas.js +134 -0
- package/dist/core/descubrimiento/reglas.js.map +1 -0
- package/dist/core/descubrimiento/skills.d.ts +57 -0
- package/dist/core/descubrimiento/skills.d.ts.map +1 -0
- package/dist/core/descubrimiento/skills.js +113 -0
- package/dist/core/descubrimiento/skills.js.map +1 -0
- package/dist/core/dificultad/clasificador.d.ts +133 -0
- package/dist/core/dificultad/clasificador.d.ts.map +1 -0
- package/dist/core/dificultad/clasificador.js +288 -0
- package/dist/core/dificultad/clasificador.js.map +1 -0
- package/dist/core/edicion/diario.d.ts +37 -0
- package/dist/core/edicion/diario.d.ts.map +1 -0
- package/dist/core/edicion/diario.js +51 -0
- package/dist/core/edicion/diario.js.map +1 -0
- package/dist/core/edicion/hashline.d.ts +71 -0
- package/dist/core/edicion/hashline.d.ts.map +1 -0
- package/dist/core/edicion/hashline.js +111 -0
- package/dist/core/edicion/hashline.js.map +1 -0
- package/dist/core/edicion/hueco.d.ts +64 -0
- package/dist/core/edicion/hueco.d.ts.map +1 -0
- package/dist/core/edicion/hueco.js +162 -0
- package/dist/core/edicion/hueco.js.map +1 -0
- package/dist/core/edicion/limpiar-carga.d.ts +39 -0
- package/dist/core/edicion/limpiar-carga.d.ts.map +1 -0
- package/dist/core/edicion/limpiar-carga.js +121 -0
- package/dist/core/edicion/limpiar-carga.js.map +1 -0
- package/dist/core/edicion/observador.d.ts +80 -0
- package/dist/core/edicion/observador.d.ts.map +1 -0
- package/dist/core/edicion/observador.js +183 -0
- package/dist/core/edicion/observador.js.map +1 -0
- package/dist/core/edicion/parecido.d.ts +53 -0
- package/dist/core/edicion/parecido.d.ts.map +1 -0
- package/dist/core/edicion/parecido.js +145 -0
- package/dist/core/edicion/parecido.js.map +1 -0
- package/dist/core/edicion/parseo.d.ts +58 -0
- package/dist/core/edicion/parseo.d.ts.map +1 -0
- package/dist/core/edicion/parseo.js +124 -0
- package/dist/core/edicion/parseo.js.map +1 -0
- package/dist/core/edicion/reparacion.d.ts +67 -0
- package/dist/core/edicion/reparacion.d.ts.map +1 -0
- package/dist/core/edicion/reparacion.js +202 -0
- package/dist/core/edicion/reparacion.js.map +1 -0
- package/dist/core/edicion/sangria.d.ts +121 -0
- package/dist/core/edicion/sangria.d.ts.map +1 -0
- package/dist/core/edicion/sangria.js +341 -0
- package/dist/core/edicion/sangria.js.map +1 -0
- package/dist/core/edicion/tipos.d.ts +58 -0
- package/dist/core/edicion/tipos.d.ts.map +1 -0
- package/dist/core/edicion/tipos.js +160 -0
- package/dist/core/edicion/tipos.js.map +1 -0
- package/dist/core/errores/proveedor.d.ts +53 -0
- package/dist/core/errores/proveedor.d.ts.map +1 -0
- package/dist/core/errores/proveedor.js +191 -0
- package/dist/core/errores/proveedor.js.map +1 -0
- package/dist/core/estructural/buscar.d.ts +61 -0
- package/dist/core/estructural/buscar.d.ts.map +1 -0
- package/dist/core/estructural/buscar.js +261 -0
- package/dist/core/estructural/buscar.js.map +1 -0
- package/dist/core/estructural/editar.d.ts +36 -0
- package/dist/core/estructural/editar.d.ts.map +1 -0
- package/dist/core/estructural/editar.js +123 -0
- package/dist/core/estructural/editar.js.map +1 -0
- package/dist/core/estructural/tools.d.ts +11 -0
- package/dist/core/estructural/tools.d.ts.map +1 -0
- package/dist/core/estructural/tools.js +100 -0
- package/dist/core/estructural/tools.js.map +1 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +10 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensiones/suplantacion.d.ts +49 -0
- package/dist/core/extensiones/suplantacion.d.ts.map +1 -0
- package/dist/core/extensiones/suplantacion.js +61 -0
- package/dist/core/extensiones/suplantacion.js.map +1 -0
- package/dist/core/extensiones/vigilancia.d.ts +54 -0
- package/dist/core/extensiones/vigilancia.d.ts.map +1 -0
- package/dist/core/extensiones/vigilancia.js +217 -0
- package/dist/core/extensiones/vigilancia.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +11 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/harness/fuentes-de-contexto.d.ts +29 -0
- package/dist/core/harness/fuentes-de-contexto.d.ts.map +1 -0
- package/dist/core/harness/fuentes-de-contexto.js +44 -0
- package/dist/core/harness/fuentes-de-contexto.js.map +1 -0
- package/dist/core/harness/refine.d.ts +40 -0
- package/dist/core/harness/refine.d.ts.map +1 -0
- package/dist/core/harness/refine.js +109 -0
- package/dist/core/harness/refine.js.map +1 -0
- package/dist/core/harness/store.d.ts +75 -0
- package/dist/core/harness/store.d.ts.map +1 -0
- package/dist/core/harness/store.js +149 -0
- package/dist/core/harness/store.js.map +1 -0
- package/dist/core/hooks/contract.d.ts +85 -0
- package/dist/core/hooks/contract.d.ts.map +1 -0
- package/dist/core/hooks/contract.js +140 -0
- package/dist/core/hooks/contract.js.map +1 -0
- package/dist/core/hooks/runner.d.ts +42 -0
- package/dist/core/hooks/runner.d.ts.map +1 -0
- package/dist/core/hooks/runner.js +85 -0
- package/dist/core/hooks/runner.js.map +1 -0
- package/dist/core/hooks/session-hooks.d.ts +62 -0
- package/dist/core/hooks/session-hooks.d.ts.map +1 -0
- package/dist/core/hooks/session-hooks.js +84 -0
- package/dist/core/hooks/session-hooks.js.map +1 -0
- package/dist/core/importar/formatos.d.ts +69 -0
- package/dist/core/importar/formatos.d.ts.map +1 -0
- package/dist/core/importar/formatos.js +235 -0
- package/dist/core/importar/formatos.js.map +1 -0
- package/dist/core/interactivo/deteccion.d.ts +44 -0
- package/dist/core/interactivo/deteccion.d.ts.map +1 -0
- package/dist/core/interactivo/deteccion.js +82 -0
- package/dist/core/interactivo/deteccion.js.map +1 -0
- package/dist/core/interactivo/sesion.d.ts +50 -0
- package/dist/core/interactivo/sesion.d.ts.map +1 -0
- package/dist/core/interactivo/sesion.js +156 -0
- package/dist/core/interactivo/sesion.js.map +1 -0
- package/dist/core/interactivo/tools.d.ts +21 -0
- package/dist/core/interactivo/tools.d.ts.map +1 -0
- package/dist/core/interactivo/tools.js +122 -0
- package/dist/core/interactivo/tools.js.map +1 -0
- package/dist/core/lectura/mapa.d.ts +70 -0
- package/dist/core/lectura/mapa.d.ts.map +1 -0
- package/dist/core/lectura/mapa.js +177 -0
- package/dist/core/lectura/mapa.js.map +1 -0
- package/dist/core/lectura/pdf.d.ts +49 -0
- package/dist/core/lectura/pdf.d.ts.map +1 -0
- package/dist/core/lectura/pdf.js +337 -0
- package/dist/core/lectura/pdf.js.map +1 -0
- package/dist/core/limpieza/comprobadores.d.ts +28 -0
- package/dist/core/limpieza/comprobadores.d.ts.map +1 -0
- package/dist/core/limpieza/comprobadores.js +311 -0
- package/dist/core/limpieza/comprobadores.js.map +1 -0
- package/dist/core/limpieza/parseo.d.ts +19 -0
- package/dist/core/limpieza/parseo.d.ts.map +1 -0
- package/dist/core/limpieza/parseo.js +124 -0
- package/dist/core/limpieza/parseo.js.map +1 -0
- package/dist/core/limpieza/reparacion.d.ts +77 -0
- package/dist/core/limpieza/reparacion.d.ts.map +1 -0
- package/dist/core/limpieza/reparacion.js +254 -0
- package/dist/core/limpieza/reparacion.js.map +1 -0
- package/dist/core/limpieza/tipos.d.ts +56 -0
- package/dist/core/limpieza/tipos.d.ts.map +1 -0
- package/dist/core/limpieza/tipos.js +9 -0
- package/dist/core/limpieza/tipos.js.map +1 -0
- package/dist/core/lsp/cliente.d.ts +52 -0
- package/dist/core/lsp/cliente.d.ts.map +1 -0
- package/dist/core/lsp/cliente.js +232 -0
- package/dist/core/lsp/cliente.js.map +1 -0
- package/dist/core/lsp/descubrimiento.d.ts +62 -0
- package/dist/core/lsp/descubrimiento.d.ts.map +1 -0
- package/dist/core/lsp/descubrimiento.js +152 -0
- package/dist/core/lsp/descubrimiento.js.map +1 -0
- package/dist/core/lsp/ediciones.d.ts +59 -0
- package/dist/core/lsp/ediciones.d.ts.map +1 -0
- package/dist/core/lsp/ediciones.js +89 -0
- package/dist/core/lsp/ediciones.js.map +1 -0
- package/dist/core/lsp/extension.d.ts +28 -0
- package/dist/core/lsp/extension.d.ts.map +1 -0
- package/dist/core/lsp/extension.js +34 -0
- package/dist/core/lsp/extension.js.map +1 -0
- package/dist/core/lsp/tools.d.ts +45 -0
- package/dist/core/lsp/tools.d.ts.map +1 -0
- package/dist/core/lsp/tools.js +265 -0
- package/dist/core/lsp/tools.js.map +1 -0
- package/dist/core/mcp/client.d.ts +60 -0
- package/dist/core/mcp/client.d.ts.map +1 -0
- package/dist/core/mcp/client.js +139 -0
- package/dist/core/mcp/client.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +86 -0
- package/dist/core/mcp/manager.d.ts.map +1 -0
- package/dist/core/mcp/manager.js +124 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/tools.d.ts +15 -0
- package/dist/core/mcp/tools.d.ts.map +1 -0
- package/dist/core/mcp/tools.js +84 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/memory-engine/audit-export.d.ts +12 -10
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -1
- package/dist/core/memory-engine/audit-export.js +15 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -1
- package/dist/core/memory-engine/audit-indice.d.ts +153 -0
- package/dist/core/memory-engine/audit-indice.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-indice.js +271 -0
- package/dist/core/memory-engine/audit-indice.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts +18 -6
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +25 -42
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +19 -1
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +71 -5
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +0 -2
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +4 -5
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/refinements.d.ts +51 -0
- package/dist/core/memory-engine/refinements.d.ts.map +1 -0
- package/dist/core/memory-engine/refinements.js +99 -0
- package/dist/core/memory-engine/refinements.js.map +1 -0
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +27 -1
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/types.d.ts +2 -0
- package/dist/core/memory-engine/types.d.ts.map +1 -1
- package/dist/core/memory-engine/types.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +7 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/muestreo-restringido.d.ts +49 -0
- package/dist/core/muestreo-restringido.d.ts.map +1 -0
- package/dist/core/muestreo-restringido.js +65 -0
- package/dist/core/muestreo-restringido.js.map +1 -0
- package/dist/core/orphan-process-journal.d.ts +48 -0
- package/dist/core/orphan-process-journal.d.ts.map +1 -0
- package/dist/core/orphan-process-journal.js +116 -0
- package/dist/core/orphan-process-journal.js.map +1 -0
- package/dist/core/privacidad/categorias-especiales.d.ts +186 -0
- package/dist/core/privacidad/categorias-especiales.d.ts.map +1 -0
- package/dist/core/privacidad/categorias-especiales.js +745 -0
- package/dist/core/privacidad/categorias-especiales.js.map +1 -0
- package/dist/core/privacidad/tapar.d.ts +48 -0
- package/dist/core/privacidad/tapar.d.ts.map +1 -0
- package/dist/core/privacidad/tapar.js +66 -0
- package/dist/core/privacidad/tapar.js.map +1 -0
- package/dist/core/prompt-cache/diagnostics.d.ts +33 -0
- package/dist/core/prompt-cache/diagnostics.d.ts.map +1 -0
- package/dist/core/prompt-cache/diagnostics.js +100 -0
- package/dist/core/prompt-cache/diagnostics.js.map +1 -0
- package/dist/core/prompt-cache/index.d.ts +33 -0
- package/dist/core/prompt-cache/index.d.ts.map +1 -0
- package/dist/core/prompt-cache/index.js +189 -0
- package/dist/core/prompt-cache/index.js.map +1 -0
- package/dist/core/prompt-cache/payload.d.ts +58 -0
- package/dist/core/prompt-cache/payload.d.ts.map +1 -0
- package/dist/core/prompt-cache/payload.js +122 -0
- package/dist/core/prompt-cache/payload.js.map +1 -0
- package/dist/core/prompt-cache/stabilize.d.ts +65 -0
- package/dist/core/prompt-cache/stabilize.d.ts.map +1 -0
- package/dist/core/prompt-cache/stabilize.js +137 -0
- package/dist/core/prompt-cache/stabilize.js.map +1 -0
- package/dist/core/prompt-cache/stats.d.ts +55 -0
- package/dist/core/prompt-cache/stats.d.ts.map +1 -0
- package/dist/core/prompt-cache/stats.js +158 -0
- package/dist/core/prompt-cache/stats.js.map +1 -0
- package/dist/core/prompt-eleccion.d.ts +38 -0
- package/dist/core/prompt-eleccion.d.ts.map +1 -0
- package/dist/core/prompt-eleccion.js +46 -0
- package/dist/core/prompt-eleccion.js.map +1 -0
- package/dist/core/prompts/montar.d.ts +75 -0
- package/dist/core/prompts/montar.d.ts.map +1 -0
- package/dist/core/prompts/montar.js +146 -0
- package/dist/core/prompts/montar.js.map +1 -0
- package/dist/core/prompts/plantilla.d.ts +54 -0
- package/dist/core/prompts/plantilla.d.ts.map +1 -0
- package/dist/core/prompts/plantilla.js +153 -0
- package/dist/core/prompts/plantilla.js.map +1 -0
- package/dist/core/prompts/sistema.md +134 -0
- package/dist/core/provider-attribution.d.ts +24 -2
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +24 -42
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remoto/destino.d.ts +38 -0
- package/dist/core/remoto/destino.d.ts.map +1 -0
- package/dist/core/remoto/destino.js +105 -0
- package/dist/core/remoto/destino.js.map +1 -0
- package/dist/core/remoto/ejecutor.d.ts +59 -0
- package/dist/core/remoto/ejecutor.d.ts.map +1 -0
- package/dist/core/remoto/ejecutor.js +225 -0
- package/dist/core/remoto/ejecutor.js.map +1 -0
- package/dist/core/remoto/ficheros.d.ts +29 -0
- package/dist/core/remoto/ficheros.d.ts.map +1 -0
- package/dist/core/remoto/ficheros.js +90 -0
- package/dist/core/remoto/ficheros.js.map +1 -0
- package/dist/core/remoto/registro-extension.d.ts +15 -0
- package/dist/core/remoto/registro-extension.d.ts.map +1 -0
- package/dist/core/remoto/registro-extension.js +17 -0
- package/dist/core/remoto/registro-extension.js.map +1 -0
- package/dist/core/remoto/tools.d.ts +28 -0
- package/dist/core/remoto/tools.d.ts.map +1 -0
- package/dist/core/remoto/tools.js +31 -0
- package/dist/core/remoto/tools.js.map +1 -0
- package/dist/core/resource-loader.d.ts +8 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +93 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/revision/hallazgo.d.ts +51 -0
- package/dist/core/revision/hallazgo.d.ts.map +1 -0
- package/dist/core/revision/hallazgo.js +73 -0
- package/dist/core/revision/hallazgo.js.map +1 -0
- package/dist/core/revision/revisor.d.ts +81 -0
- package/dist/core/revision/revisor.d.ts.map +1 -0
- package/dist/core/revision/revisor.js +132 -0
- package/dist/core/revision/revisor.js.map +1 -0
- package/dist/core/revision/sarif.d.ts +30 -0
- package/dist/core/revision/sarif.d.ts.map +1 -0
- package/dist/core/revision/sarif.js +83 -0
- package/dist/core/revision/sarif.js.map +1 -0
- package/dist/core/scheduler/scheduler.d.ts +87 -0
- package/dist/core/scheduler/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler/scheduler.js +178 -0
- package/dist/core/scheduler/scheduler.js.map +1 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts +49 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts.map +1 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js +77 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js.map +1 -0
- package/dist/core/settings-manager.d.ts +110 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +53 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -3
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +17 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +13 -5
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetria/otlp.d.ts +122 -0
- package/dist/core/telemetria/otlp.d.ts.map +1 -0
- package/dist/core/telemetria/otlp.js +373 -0
- package/dist/core/telemetria/otlp.js.map +1 -0
- package/dist/core/tools/coercion-argumentos.d.ts +48 -0
- package/dist/core/tools/coercion-argumentos.d.ts.map +1 -0
- package/dist/core/tools/coercion-argumentos.js +99 -0
- package/dist/core/tools/coercion-argumentos.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -7
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +232 -7
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +8 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +5 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/json-tolerante.d.ts +30 -0
- package/dist/core/tools/json-tolerante.d.ts.map +1 -0
- package/dist/core/tools/json-tolerante.js +70 -0
- package/dist/core/tools/json-tolerante.js.map +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +17 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +17 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/turno-vacio/detectar.d.ts +38 -0
- package/dist/core/turno-vacio/detectar.d.ts.map +1 -0
- package/dist/core/turno-vacio/detectar.js +66 -0
- package/dist/core/turno-vacio/detectar.js.map +1 -0
- package/dist/core/undo/journal.d.ts +57 -0
- package/dist/core/undo/journal.d.ts.map +1 -0
- package/dist/core/undo/journal.js +178 -0
- package/dist/core/undo/journal.js.map +1 -0
- package/dist/core/urls-internas/auditoria.d.ts +10 -0
- package/dist/core/urls-internas/auditoria.d.ts.map +1 -0
- package/dist/core/urls-internas/auditoria.js +42 -0
- package/dist/core/urls-internas/auditoria.js.map +1 -0
- package/dist/core/urls-internas/boveda.d.ts +13 -0
- package/dist/core/urls-internas/boveda.d.ts.map +1 -0
- package/dist/core/urls-internas/boveda.js +40 -0
- package/dist/core/urls-internas/boveda.js.map +1 -0
- package/dist/core/urls-internas/lector.d.ts +30 -0
- package/dist/core/urls-internas/lector.d.ts.map +1 -0
- package/dist/core/urls-internas/lector.js +56 -0
- package/dist/core/urls-internas/lector.js.map +1 -0
- package/dist/core/urls-internas/memoria.d.ts +11 -0
- package/dist/core/urls-internas/memoria.d.ts.map +1 -0
- package/dist/core/urls-internas/memoria.js +25 -0
- package/dist/core/urls-internas/memoria.js.map +1 -0
- package/dist/core/urls-internas/parse.d.ts +28 -0
- package/dist/core/urls-internas/parse.d.ts.map +1 -0
- package/dist/core/urls-internas/parse.js +32 -0
- package/dist/core/urls-internas/parse.js.map +1 -0
- package/dist/core/urls-internas/reglas.d.ts +10 -0
- package/dist/core/urls-internas/reglas.d.ts.map +1 -0
- package/dist/core/urls-internas/reglas.js +31 -0
- package/dist/core/urls-internas/reglas.js.map +1 -0
- package/dist/core/usage/aggregate.d.ts +68 -0
- package/dist/core/usage/aggregate.d.ts.map +1 -0
- package/dist/core/usage/aggregate.js +93 -0
- package/dist/core/usage/aggregate.js.map +1 -0
- package/dist/core/usage/cuota/anthropic.d.ts +10 -0
- package/dist/core/usage/cuota/anthropic.d.ts.map +1 -0
- package/dist/core/usage/cuota/anthropic.js +63 -0
- package/dist/core/usage/cuota/anthropic.js.map +1 -0
- package/dist/core/usage/cuota/cache.d.ts +20 -0
- package/dist/core/usage/cuota/cache.d.ts.map +1 -0
- package/dist/core/usage/cuota/cache.js +36 -0
- package/dist/core/usage/cuota/cache.js.map +1 -0
- package/dist/core/usage/cuota/github-copilot.d.ts +9 -0
- package/dist/core/usage/cuota/github-copilot.d.ts.map +1 -0
- package/dist/core/usage/cuota/github-copilot.js +67 -0
- package/dist/core/usage/cuota/github-copilot.js.map +1 -0
- package/dist/core/usage/cuota/google-gemini.d.ts +9 -0
- package/dist/core/usage/cuota/google-gemini.d.ts.map +1 -0
- package/dist/core/usage/cuota/google-gemini.js +72 -0
- package/dist/core/usage/cuota/google-gemini.js.map +1 -0
- package/dist/core/usage/cuota/index.d.ts +25 -0
- package/dist/core/usage/cuota/index.d.ts.map +1 -0
- package/dist/core/usage/cuota/index.js +50 -0
- package/dist/core/usage/cuota/index.js.map +1 -0
- package/dist/core/usage/cuota/openai-codex.d.ts +9 -0
- package/dist/core/usage/cuota/openai-codex.d.ts.map +1 -0
- package/dist/core/usage/cuota/openai-codex.js +59 -0
- package/dist/core/usage/cuota/openai-codex.js.map +1 -0
- package/dist/core/usage/cuota/openrouter.d.ts +10 -0
- package/dist/core/usage/cuota/openrouter.d.ts.map +1 -0
- package/dist/core/usage/cuota/openrouter.js +47 -0
- package/dist/core/usage/cuota/openrouter.js.map +1 -0
- package/dist/core/usage/cuota/tipos.d.ts +50 -0
- package/dist/core/usage/cuota/tipos.d.ts.map +1 -0
- package/dist/core/usage/cuota/tipos.js +25 -0
- package/dist/core/usage/cuota/tipos.js.map +1 -0
- package/dist/core/web/busqueda-nativa.d.ts +82 -0
- package/dist/core/web/busqueda-nativa.d.ts.map +1 -0
- package/dist/core/web/busqueda-nativa.js +163 -0
- package/dist/core/web/busqueda-nativa.js.map +1 -0
- package/dist/core/web/destino.d.ts +58 -0
- package/dist/core/web/destino.d.ts.map +1 -0
- package/dist/core/web/destino.js +127 -0
- package/dist/core/web/destino.js.map +1 -0
- package/dist/core/web/proveedores/brave.d.ts +6 -0
- package/dist/core/web/proveedores/brave.d.ts.map +1 -0
- package/dist/core/web/proveedores/brave.js +20 -0
- package/dist/core/web/proveedores/brave.js.map +1 -0
- package/dist/core/web/proveedores/claves.d.ts +19 -0
- package/dist/core/web/proveedores/claves.d.ts.map +1 -0
- package/dist/core/web/proveedores/claves.js +36 -0
- package/dist/core/web/proveedores/claves.js.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts +3 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.js +109 -0
- package/dist/core/web/proveedores/duckduckgo.js.map +1 -0
- package/dist/core/web/proveedores/ecosia.d.ts +3 -0
- package/dist/core/web/proveedores/ecosia.d.ts.map +1 -0
- package/dist/core/web/proveedores/ecosia.js +72 -0
- package/dist/core/web/proveedores/ecosia.js.map +1 -0
- package/dist/core/web/proveedores/exa.d.ts +6 -0
- package/dist/core/web/proveedores/exa.d.ts.map +1 -0
- package/dist/core/web/proveedores/exa.js +24 -0
- package/dist/core/web/proveedores/exa.js.map +1 -0
- package/dist/core/web/proveedores/mojeek.d.ts +3 -0
- package/dist/core/web/proveedores/mojeek.d.ts.map +1 -0
- package/dist/core/web/proveedores/mojeek.js +65 -0
- package/dist/core/web/proveedores/mojeek.js.map +1 -0
- package/dist/core/web/proveedores/navegador.d.ts +10 -0
- package/dist/core/web/proveedores/navegador.d.ts.map +1 -0
- package/dist/core/web/proveedores/navegador.js +13 -0
- package/dist/core/web/proveedores/navegador.js.map +1 -0
- package/dist/core/web/proveedores/registro.d.ts +43 -0
- package/dist/core/web/proveedores/registro.d.ts.map +1 -0
- package/dist/core/web/proveedores/registro.js +49 -0
- package/dist/core/web/proveedores/registro.js.map +1 -0
- package/dist/core/web/proveedores/searxng.d.ts +9 -0
- package/dist/core/web/proveedores/searxng.d.ts.map +1 -0
- package/dist/core/web/proveedores/searxng.js +17 -0
- package/dist/core/web/proveedores/searxng.js.map +1 -0
- package/dist/core/web/proveedores/serper.d.ts +9 -0
- package/dist/core/web/proveedores/serper.d.ts.map +1 -0
- package/dist/core/web/proveedores/serper.js +19 -0
- package/dist/core/web/proveedores/serper.js.map +1 -0
- package/dist/core/web/proveedores/tavily.d.ts +6 -0
- package/dist/core/web/proveedores/tavily.d.ts.map +1 -0
- package/dist/core/web/proveedores/tavily.js +19 -0
- package/dist/core/web/proveedores/tavily.js.map +1 -0
- package/dist/core/web/proveedores/tipos.d.ts +36 -0
- package/dist/core/web/proveedores/tipos.d.ts.map +1 -0
- package/dist/core/web/proveedores/tipos.js +10 -0
- package/dist/core/web/proveedores/tipos.js.map +1 -0
- package/dist/core/web/registro-red.d.ts +43 -0
- package/dist/core/web/registro-red.d.ts.map +1 -0
- package/dist/core/web/registro-red.js +86 -0
- package/dist/core/web/registro-red.js.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts +10 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.js +38 -0
- package/dist/core/web/scrapers/cisa-kev.js.map +1 -0
- package/dist/core/web/scrapers/crates-io.d.ts +11 -0
- package/dist/core/web/scrapers/crates-io.d.ts.map +1 -0
- package/dist/core/web/scrapers/crates-io.js +29 -0
- package/dist/core/web/scrapers/crates-io.js.map +1 -0
- package/dist/core/web/scrapers/docs-rs.d.ts +10 -0
- package/dist/core/web/scrapers/docs-rs.d.ts.map +1 -0
- package/dist/core/web/scrapers/docs-rs.js +35 -0
- package/dist/core/web/scrapers/docs-rs.js.map +1 -0
- package/dist/core/web/scrapers/github.d.ts +3 -0
- package/dist/core/web/scrapers/github.d.ts.map +1 -0
- package/dist/core/web/scrapers/github.js +72 -0
- package/dist/core/web/scrapers/github.js.map +1 -0
- package/dist/core/web/scrapers/go-pkg.d.ts +7 -0
- package/dist/core/web/scrapers/go-pkg.d.ts.map +1 -0
- package/dist/core/web/scrapers/go-pkg.js +30 -0
- package/dist/core/web/scrapers/go-pkg.js.map +1 -0
- package/dist/core/web/scrapers/hex.d.ts +6 -0
- package/dist/core/web/scrapers/hex.d.ts.map +1 -0
- package/dist/core/web/scrapers/hex.js +27 -0
- package/dist/core/web/scrapers/hex.js.map +1 -0
- package/dist/core/web/scrapers/maven.d.ts +8 -0
- package/dist/core/web/scrapers/maven.d.ts.map +1 -0
- package/dist/core/web/scrapers/maven.js +41 -0
- package/dist/core/web/scrapers/maven.js.map +1 -0
- package/dist/core/web/scrapers/mdn.d.ts +6 -0
- package/dist/core/web/scrapers/mdn.d.ts.map +1 -0
- package/dist/core/web/scrapers/mdn.js +28 -0
- package/dist/core/web/scrapers/mdn.js.map +1 -0
- package/dist/core/web/scrapers/npm.d.ts +11 -0
- package/dist/core/web/scrapers/npm.d.ts.map +1 -0
- package/dist/core/web/scrapers/npm.js +57 -0
- package/dist/core/web/scrapers/npm.js.map +1 -0
- package/dist/core/web/scrapers/nuget.d.ts +8 -0
- package/dist/core/web/scrapers/nuget.d.ts.map +1 -0
- package/dist/core/web/scrapers/nuget.js +22 -0
- package/dist/core/web/scrapers/nuget.js.map +1 -0
- package/dist/core/web/scrapers/nvd.d.ts +7 -0
- package/dist/core/web/scrapers/nvd.d.ts.map +1 -0
- package/dist/core/web/scrapers/nvd.js +37 -0
- package/dist/core/web/scrapers/nvd.js.map +1 -0
- package/dist/core/web/scrapers/pypi.d.ts +6 -0
- package/dist/core/web/scrapers/pypi.d.ts.map +1 -0
- package/dist/core/web/scrapers/pypi.js +31 -0
- package/dist/core/web/scrapers/pypi.js.map +1 -0
- package/dist/core/web/scrapers/registro.d.ts +13 -0
- package/dist/core/web/scrapers/registro.d.ts.map +1 -0
- package/dist/core/web/scrapers/registro.js +65 -0
- package/dist/core/web/scrapers/registro.js.map +1 -0
- package/dist/core/web/scrapers/rubygems.d.ts +6 -0
- package/dist/core/web/scrapers/rubygems.d.ts.map +1 -0
- package/dist/core/web/scrapers/rubygems.js +23 -0
- package/dist/core/web/scrapers/rubygems.js.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts +3 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.js +46 -0
- package/dist/core/web/scrapers/stackoverflow.js.map +1 -0
- package/dist/core/web/scrapers/tipos.d.ts +42 -0
- package/dist/core/web/scrapers/tipos.d.ts.map +1 -0
- package/dist/core/web/scrapers/tipos.js +23 -0
- package/dist/core/web/scrapers/tipos.js.map +1 -0
- package/dist/core/web/texto.d.ts +10 -0
- package/dist/core/web/texto.d.ts.map +1 -0
- package/dist/core/web/texto.js +26 -0
- package/dist/core/web/texto.js.map +1 -0
- package/dist/core/web/tools.d.ts +91 -0
- package/dist/core/web/tools.d.ts.map +1 -0
- package/dist/core/web/tools.js +304 -0
- package/dist/core/web/tools.js.map +1 -0
- package/dist/core/wiki/almacen.d.ts +33 -0
- package/dist/core/wiki/almacen.d.ts.map +1 -0
- package/dist/core/wiki/almacen.js +93 -0
- package/dist/core/wiki/almacen.js.map +1 -0
- package/dist/core/wiki/citas.d.ts +111 -0
- package/dist/core/wiki/citas.d.ts.map +1 -0
- package/dist/core/wiki/citas.js +146 -0
- package/dist/core/wiki/citas.js.map +1 -0
- package/dist/core/workflows/agent-runner.d.ts +2 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -1
- package/dist/core/workflows/agent-runner.js +131 -44
- package/dist/core/workflows/agent-runner.js.map +1 -1
- package/dist/core/workflows/builtins.d.ts.map +1 -1
- package/dist/core/workflows/builtins.js +1 -0
- package/dist/core/workflows/builtins.js.map +1 -1
- package/dist/core/workflows/contrato/esquema.d.ts +32 -0
- package/dist/core/workflows/contrato/esquema.d.ts.map +1 -0
- package/dist/core/workflows/contrato/esquema.js +25 -0
- package/dist/core/workflows/contrato/esquema.js.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts +69 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js +117 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js.map +1 -0
- package/dist/core/workflows/contrato/validador.d.ts +30 -0
- package/dist/core/workflows/contrato/validador.d.ts.map +1 -0
- package/dist/core/workflows/contrato/validador.js +56 -0
- package/dist/core/workflows/contrato/validador.js.map +1 -0
- package/dist/core/workflows/contrato/yield.d.ts +65 -0
- package/dist/core/workflows/contrato/yield.d.ts.map +1 -0
- package/dist/core/workflows/contrato/yield.js +80 -0
- package/dist/core/workflows/contrato/yield.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +17 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -1
- package/dist/core/workflows/goal-engine/engine.js +41 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -1
- package/dist/core/workflows/index.d.ts +8 -0
- package/dist/core/workflows/index.d.ts.map +1 -1
- package/dist/core/workflows/index.js +4 -0
- package/dist/core/workflows/index.js.map +1 -1
- package/dist/core/workflows/manager.d.ts +10 -0
- package/dist/core/workflows/manager.d.ts.map +1 -1
- package/dist/core/workflows/manager.js +35 -11
- package/dist/core/workflows/manager.js.map +1 -1
- package/dist/core/workflows/runtime.d.ts +13 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -1
- package/dist/core/workflows/runtime.js +80 -1
- package/dist/core/workflows/runtime.js.map +1 -1
- package/dist/core/workflows/save-as-skill.d.ts +27 -0
- package/dist/core/workflows/save-as-skill.d.ts.map +1 -0
- package/dist/core/workflows/save-as-skill.js +54 -0
- package/dist/core/workflows/save-as-skill.js.map +1 -0
- package/dist/core/workflows/types.d.ts +49 -0
- package/dist/core/workflows/types.d.ts.map +1 -1
- package/dist/core/workflows/types.js.map +1 -1
- package/dist/extensions/remoto/index.d.ts +22 -0
- package/dist/extensions/remoto/index.d.ts.map +1 -0
- package/dist/extensions/remoto/index.js +54 -0
- package/dist/extensions/remoto/index.js.map +1 -0
- package/dist/index.d.ts +1 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -16
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts +42 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +190 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/events.d.ts +74 -0
- package/dist/modes/acp/events.d.ts.map +1 -0
- package/dist/modes/acp/events.js +116 -0
- package/dist/modes/acp/events.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +8 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +41 -7
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +9 -86
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +48 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +137 -146
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +11 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +27 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/attach.d.ts +56 -0
- package/dist/server/attach.d.ts.map +1 -0
- package/dist/server/attach.js +130 -0
- package/dist/server/attach.js.map +1 -0
- package/dist/server/extension-ops.d.ts +40 -0
- package/dist/server/extension-ops.d.ts.map +1 -0
- package/dist/server/extension-ops.js +146 -0
- package/dist/server/extension-ops.js.map +1 -0
- package/dist/server/pi-server-service.d.ts +85 -0
- package/dist/server/pi-server-service.d.ts.map +1 -0
- package/dist/server/pi-server-service.js +213 -0
- package/dist/server/pi-server-service.js.map +1 -0
- package/dist/server/scheduler-tick.d.ts +32 -0
- package/dist/server/scheduler-tick.d.ts.map +1 -0
- package/dist/server/scheduler-tick.js +47 -0
- package/dist/server/scheduler-tick.js.map +1 -0
- package/dist/server/serve.d.ts +25 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/server/serve.js +83 -0
- package/dist/server/serve.js.map +1 -0
- package/dist/server/transcript.d.ts +38 -0
- package/dist/server/transcript.d.ts.map +1 -0
- package/dist/server/transcript.js +176 -0
- package/dist/server/transcript.js.map +1 -0
- package/dist/skills/skill-creator/SKILL.md +90 -0
- package/dist/telegram/api.d.ts +75 -0
- package/dist/telegram/api.d.ts.map +1 -0
- package/dist/telegram/api.js +104 -0
- package/dist/telegram/api.js.map +1 -0
- package/dist/telegram/bridge.d.ts +85 -0
- package/dist/telegram/bridge.d.ts.map +1 -0
- package/dist/telegram/bridge.js +182 -0
- package/dist/telegram/bridge.js.map +1 -0
- package/dist/telegram/journal.d.ts +67 -0
- package/dist/telegram/journal.d.ts.map +1 -0
- package/dist/telegram/journal.js +119 -0
- package/dist/telegram/journal.js.map +1 -0
- package/dist/telegram/servidor.d.ts +15 -0
- package/dist/telegram/servidor.d.ts.map +1 -0
- package/dist/telegram/servidor.js +74 -0
- package/dist/telegram/servidor.js.map +1 -0
- package/dist/utils/shell.d.ts +11 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +11 -0
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +29 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +10 -10
- package/docs/compliance.md +241 -0
- package/docs/containerization.md +24 -24
- package/docs/custom-provider.md +10 -10
- package/docs/development.md +47 -10
- package/docs/docs.json +14 -2
- package/docs/environment-variables.md +20 -17
- package/docs/extensions.md +51 -49
- package/docs/index.md +15 -21
- package/docs/json.md +3 -3
- package/docs/keybindings.md +5 -5
- package/docs/llama-cpp.md +7 -7
- package/docs/models.md +12 -12
- package/docs/packages.md +45 -45
- package/docs/prompt-templates.md +5 -5
- package/docs/providers.md +12 -12
- package/docs/quickstart.md +39 -39
- package/docs/rpc.md +12 -12
- package/docs/sdk.md +38 -38
- package/docs/security.md +26 -21
- package/docs/session-format.md +7 -7
- package/docs/sessions.md +14 -14
- package/docs/settings.md +45 -20
- package/docs/shell-aliases.md +2 -2
- package/docs/skills.md +11 -11
- package/docs/terminal-setup.md +14 -14
- package/docs/termux.md +7 -7
- package/docs/themes.md +11 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +3 -3
- package/docs/usage.md +54 -54
- package/docs/windows.md +2 -2
- package/examples/sdk/12-full-control.ts +9 -0
- package/npm-shrinkwrap.json +35 -251
- package/package.json +10 -4
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compara dos ejecuciones del banco: ¿el cambio de editor mejoró o empeoró?
|
|
3
|
+
*
|
|
4
|
+
* Sin esto, dos JSON de resultados son datos sueltos. Con esto son una
|
|
5
|
+
* respuesta a "¿esto que acabo de tocar edita mejor o peor que antes?".
|
|
6
|
+
*/
|
|
7
|
+
function delta(nombre, antes, despues) {
|
|
8
|
+
return { nombre, antes, despues, delta: Math.round((despues - antes) * 10) / 10 };
|
|
9
|
+
}
|
|
10
|
+
export function compararEjecuciones(a, b, rutaA, rutaB) {
|
|
11
|
+
return {
|
|
12
|
+
a: { archivo: rutaA, modelo: `${a.proveedor}/${a.modelo}`, ejecutadoEn: a.ejecutadoEn },
|
|
13
|
+
b: { archivo: rutaB, modelo: `${b.proveedor}/${b.modelo}`, ejecutadoEn: b.ejecutadoEn },
|
|
14
|
+
metricas: [
|
|
15
|
+
delta("tarea %", a.resumen.tareaOkPct, b.resumen.tareaOkPct),
|
|
16
|
+
delta("edición %", a.resumen.edicionOkPct, b.resumen.edicionOkPct),
|
|
17
|
+
delta("fantasma %", a.resumen.fantasmaPct, b.resumen.fantasmaPct),
|
|
18
|
+
delta("timeout %", a.resumen.timeoutPct, b.resumen.timeoutPct),
|
|
19
|
+
delta("error %", a.resumen.errorPct, b.resumen.errorPct),
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function formatearComparacion(c) {
|
|
24
|
+
const flecha = (d) => (d.delta > 0 ? "▲" : d.delta < 0 ? "▼" : "=");
|
|
25
|
+
const filas = c.metricas.map((m) => ` ${m.nombre.padEnd(12)} ${m.antes.toFixed(1)}% → ${m.despues.toFixed(1)}% ${flecha(m)} ${Math.abs(m.delta).toFixed(1)}`);
|
|
26
|
+
return [`A: ${c.a.modelo} (${c.a.archivo})`, `B: ${c.b.modelo} (${c.b.archivo})`, "", ...filas].join("\n");
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=comparar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparar.js","sourceRoot":"","sources":["../../../src/core/banco/comparar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,SAAS,KAAK,CAAC,MAAc,EAAE,KAAa,EAAE,OAAe,EAAgB;IAC5E,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;AAAA,CAClF;AAED,MAAM,UAAU,mBAAmB,CAClC,CAAsB,EACtB,CAAsB,EACtB,KAAa,EACb,KAAa,EACY;IACzB,OAAO;QACN,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE;QACvF,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE;QACvF,QAAQ,EAAE;YACT,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;YAC5D,KAAK,CAAC,YAAW,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;YAClE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;YACjE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;YAC9D,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;SACxD;KACD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAyB,EAAU;IACvE,MAAM,MAAM,GAAG,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAC3B,CAAC,CAAC,EAAE,EAAE,CACL,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAS,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAC9H,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CAC7G","sourcesContent":["/**\n * Compara dos ejecuciones del banco: ¿el cambio de editor mejoró o empeoró?\n *\n * Sin esto, dos JSON de resultados son datos sueltos. Con esto son una\n * respuesta a \"¿esto que acabo de tocar edita mejor o peor que antes?\".\n */\n\nimport type { ResultadosEjecucion } from \"./tipos.ts\";\n\nexport interface DeltaMetrica {\n\tnombre: string;\n\tantes: number;\n\tdespues: number;\n\tdelta: number;\n}\n\nexport interface ComparacionEjecuciones {\n\ta: { archivo: string; modelo: string; ejecutadoEn: string };\n\tb: { archivo: string; modelo: string; ejecutadoEn: string };\n\tmetricas: DeltaMetrica[];\n}\n\nfunction delta(nombre: string, antes: number, despues: number): DeltaMetrica {\n\treturn { nombre, antes, despues, delta: Math.round((despues - antes) * 10) / 10 };\n}\n\nexport function compararEjecuciones(\n\ta: ResultadosEjecucion,\n\tb: ResultadosEjecucion,\n\trutaA: string,\n\trutaB: string,\n): ComparacionEjecuciones {\n\treturn {\n\t\ta: { archivo: rutaA, modelo: `${a.proveedor}/${a.modelo}`, ejecutadoEn: a.ejecutadoEn },\n\t\tb: { archivo: rutaB, modelo: `${b.proveedor}/${b.modelo}`, ejecutadoEn: b.ejecutadoEn },\n\t\tmetricas: [\n\t\t\tdelta(\"tarea %\", a.resumen.tareaOkPct, b.resumen.tareaOkPct),\n\t\t\tdelta(\"edición %\", a.resumen.edicionOkPct, b.resumen.edicionOkPct),\n\t\t\tdelta(\"fantasma %\", a.resumen.fantasmaPct, b.resumen.fantasmaPct),\n\t\t\tdelta(\"timeout %\", a.resumen.timeoutPct, b.resumen.timeoutPct),\n\t\t\tdelta(\"error %\", a.resumen.errorPct, b.resumen.errorPct),\n\t\t],\n\t};\n}\n\nexport function formatearComparacion(c: ComparacionEjecuciones): string {\n\tconst flecha = (d: DeltaMetrica) => (d.delta > 0 ? \"▲\" : d.delta < 0 ? \"▼\" : \"=\");\n\tconst filas = c.metricas.map(\n\t\t(m) =>\n\t\t\t` ${m.nombre.padEnd(12)} ${m.antes.toFixed(1)}% → ${m.despues.toFixed(1)}% ${flecha(m)} ${Math.abs(m.delta).toFixed(1)}`,\n\t);\n\treturn [`A: ${c.a.modelo} (${c.a.archivo})`, `B: ${c.b.modelo} (${c.b.archivo})`, \"\", ...filas].join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ejecuta casos del banco contra un agente de verdad y separa las cuatro
|
|
3
|
+
* métricas que la tarea exige no mezclar: tarea, edición, fantasma, timeout.
|
|
4
|
+
*
|
|
5
|
+
* El agente que edita es INYECTABLE (`EjecutorDeCaso`) a propósito: la
|
|
6
|
+
* implementación real (`crearEjecutorReal`) llama al proveedor de verdad y
|
|
7
|
+
* cuesta dinero; los tests inyectan una versión determinista para probar que
|
|
8
|
+
* el propio banco DETECTA una edición rota sin gastar una sola llamada.
|
|
9
|
+
*/
|
|
10
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
11
|
+
import type { CasoBanco, ResultadoCaso, ResultadosEjecucion, ResumenMetricas } from "./tipos.ts";
|
|
12
|
+
export interface EjecucionCaso {
|
|
13
|
+
/** Alguna llamada a `edit`/`write` intentó tocar el fichero objetivo. */
|
|
14
|
+
tocoFichero: boolean;
|
|
15
|
+
/** De las que lo tocaron, al menos una terminó sin error. */
|
|
16
|
+
edicionOk: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* El modelo devolvió al menos un turno VACÍO (ni texto, ni razonamiento, ni
|
|
19
|
+
* llamadas). Opcional porque los ejecutores deterministas de los tests no
|
|
20
|
+
* hablan con ningún proveedor y no tienen turnos que mirar.
|
|
21
|
+
*/
|
|
22
|
+
turnoVacio?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface EjecutorDeCaso {
|
|
25
|
+
ejecutar(opciones: {
|
|
26
|
+
cwd: string;
|
|
27
|
+
rutaFichero: string;
|
|
28
|
+
prompt: string;
|
|
29
|
+
}): Promise<EjecucionCaso>;
|
|
30
|
+
}
|
|
31
|
+
export declare function resumirMetricas(resultados: ResultadoCaso[]): ResumenMetricas;
|
|
32
|
+
export declare function ejecutarCasos(casos: CasoBanco[], ejecutor: EjecutorDeCaso, opciones: {
|
|
33
|
+
proveedor: string;
|
|
34
|
+
modelo: string;
|
|
35
|
+
casosArchivo: string;
|
|
36
|
+
onProgreso?: (i: number, total: number, r: ResultadoCaso) => void;
|
|
37
|
+
}): Promise<ResultadosEjecucion>;
|
|
38
|
+
/** Implementación real: agente de Ada con `read`/`edit`/`write`, contra el proveedor de verdad. */
|
|
39
|
+
export declare function crearEjecutorReal(opciones: {
|
|
40
|
+
agentDir: string;
|
|
41
|
+
model?: Model<Api>;
|
|
42
|
+
timeoutMs: number;
|
|
43
|
+
}): EjecutorDeCaso;
|
|
44
|
+
//# sourceMappingURL=ejecutar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ejecutar.d.ts","sourceRoot":"","sources":["../../../src/core/banco/ejecutar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjG,MAAM,WAAW,aAAa;IAC7B,0EAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,8DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACjG;AA+DD,wBAAgB,eAAe,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,eAAe,CAuB5E;AAED,wBAAsB,aAAa,CAClC,KAAK,EAAE,SAAS,EAAE,EAClB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;CAClE,GACC,OAAO,CAAC,mBAAmB,CAAC,CAqB9B;AAED,oGAAmG;AACnG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB,GAAG,cAAc,CA0DjB","sourcesContent":["/**\n * Ejecuta casos del banco contra un agente de verdad y separa las cuatro\n * métricas que la tarea exige no mezclar: tarea, edición, fantasma, timeout.\n *\n * El agente que edita es INYECTABLE (`EjecutorDeCaso`) a propósito: la\n * implementación real (`crearEjecutorReal`) llama al proveedor de verdad y\n * cuesta dinero; los tests inyectan una versión determinista para probar que\n * el propio banco DETECTA una edición rota sin gastar una sola llamada.\n */\n\nimport { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { estadoDelTurno } from \"../turno-vacio/detectar.ts\";\nimport type { CasoBanco, ResultadoCaso, ResultadosEjecucion, ResumenMetricas } from \"./tipos.ts\";\n\nexport interface EjecucionCaso {\n\t/** Alguna llamada a `edit`/`write` intentó tocar el fichero objetivo. */\n\ttocoFichero: boolean;\n\t/** De las que lo tocaron, al menos una terminó sin error. */\n\tedicionOk: boolean;\n\t/**\n\t * El modelo devolvió al menos un turno VACÍO (ni texto, ni razonamiento, ni\n\t * llamadas). Opcional porque los ejecutores deterministas de los tests no\n\t * hablan con ningún proveedor y no tienen turnos que mirar.\n\t */\n\tturnoVacio?: boolean;\n}\n\nexport interface EjecutorDeCaso {\n\tejecutar(opciones: { cwd: string; rutaFichero: string; prompt: string }): Promise<EjecucionCaso>;\n}\n\n/** Normaliza el salto de línea final para no fallar por un `\\n` de más o de menos. */\nfunction normalizar(contenido: string): string {\n\treturn contenido.replace(/\\n*$/, \"\\n\");\n}\n\nasync function ejecutarUnCaso(caso: CasoBanco, ejecutor: EjecutorDeCaso, raizTemp: string): Promise<ResultadoCaso> {\n\tconst inicio = Date.now();\n\tconst cwd = mkdtempSync(join(raizTemp, \"caso-\"));\n\tconst rutaFichero = join(cwd, caso.ficheroRelativo);\n\tmkdirSync(dirname(rutaFichero), { recursive: true });\n\twriteFileSync(rutaFichero, caso.contenidoEntrada, \"utf-8\");\n\n\tlet timeout = false;\n\tlet tocoFichero = false;\n\tlet edicionOk = false;\n\tlet turnoVacio = false;\n\tlet error: string | undefined;\n\ttry {\n\t\tconst resultado = await ejecutor.ejecutar({ cwd, rutaFichero: caso.ficheroRelativo, prompt: caso.prompt });\n\t\ttocoFichero = resultado.tocoFichero;\n\t\tedicionOk = resultado.edicionOk;\n\t\tturnoVacio = resultado.turnoVacio === true;\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message === \"__timeout__\") {\n\t\t\ttimeout = true;\n\t\t} else {\n\t\t\terror = err instanceof Error ? err.message : String(err);\n\t\t}\n\t}\n\n\tlet tareaOk = false;\n\ttry {\n\t\ttareaOk = normalizar(readFileSync(rutaFichero, \"utf-8\")) === normalizar(caso.contenidoEsperado);\n\t} catch {\n\t\ttareaOk = false;\n\t}\n\n\trmSync(cwd, { recursive: true, force: true });\n\n\treturn {\n\t\tcasoId: caso.id,\n\t\tdificultad: caso.dificultad,\n\t\tmutacion: caso.mutacion,\n\t\ttareaOk,\n\t\tedicionOk: tocoFichero && edicionOk,\n\t\t// Fantasma: nunca tocó el fichero, Y el turno terminó de verdad. Un\n\t\t// timeout no es un fantasma (no dio tiempo a saberlo) y un ERROR\n\t\t// tampoco (no se pudo saberlo, punto — una llamada sin API key no\n\t\t// es un modelo \"que decidió no editar\").\n\t\t//\n\t\t// Un turno VACÍO tampoco: el modelo no contestó, así que no hay\n\t\t// decisión suya que contar. Es el mismo error de leer un fallo como\n\t\t// éxito que ya obligó a sacar `error` de esta cuenta.\n\t\tfantasma: !tocoFichero && !timeout && !error && !turnoVacio,\n\t\tvacio: turnoVacio,\n\t\ttimeout,\n\t\tduracionMs: Date.now() - inicio,\n\t\terror,\n\t};\n}\n\nexport function resumirMetricas(resultados: ResultadoCaso[]): ResumenMetricas {\n\tconst total = resultados.length;\n\tconst pct = (n: number) => (total === 0 ? 0 : Math.round((n / total) * 1000) / 10);\n\tconst porDificultad: ResumenMetricas[\"porDificultad\"] = {};\n\tfor (const dificultad of new Set(resultados.map((r) => r.dificultad))) {\n\t\tconst delGrupo = resultados.filter((r) => r.dificultad === dificultad);\n\t\tconst pctGrupo = (n: number) => (delGrupo.length === 0 ? 0 : Math.round((n / delGrupo.length) * 1000) / 10);\n\t\tporDificultad[dificultad] = {\n\t\t\ttotal: delGrupo.length,\n\t\t\ttareaOkPct: pctGrupo(delGrupo.filter((r) => r.tareaOk).length),\n\t\t\tedicionOkPct: pctGrupo(delGrupo.filter((r) => r.edicionOk).length),\n\t\t};\n\t}\n\treturn {\n\t\ttotal,\n\t\ttareaOkPct: pct(resultados.filter((r) => r.tareaOk).length),\n\t\tedicionOkPct: pct(resultados.filter((r) => r.edicionOk).length),\n\t\tfantasmaPct: pct(resultados.filter((r) => r.fantasma).length),\n\t\tvacioPct: pct(resultados.filter((r) => r.vacio).length),\n\t\ttimeoutPct: pct(resultados.filter((r) => r.timeout).length),\n\t\terrorPct: pct(resultados.filter((r) => Boolean(r.error)).length),\n\t\tporDificultad,\n\t};\n}\n\nexport async function ejecutarCasos(\n\tcasos: CasoBanco[],\n\tejecutor: EjecutorDeCaso,\n\topciones: {\n\t\tproveedor: string;\n\t\tmodelo: string;\n\t\tcasosArchivo: string;\n\t\tonProgreso?: (i: number, total: number, r: ResultadoCaso) => void;\n\t},\n): Promise<ResultadosEjecucion> {\n\tconst raizTemp = mkdtempSync(join(tmpdir(), \"ada-banco-\"));\n\tconst resultados: ResultadoCaso[] = [];\n\ttry {\n\t\tfor (let i = 0; i < casos.length; i++) {\n\t\t\tconst r = await ejecutarUnCaso(casos[i], ejecutor, raizTemp);\n\t\t\tresultados.push(r);\n\t\t\topciones.onProgreso?.(i + 1, casos.length, r);\n\t\t}\n\t} finally {\n\t\trmSync(raizTemp, { recursive: true, force: true });\n\t}\n\treturn {\n\t\tversion: 1,\n\t\tejecutadoEn: new Date().toISOString(),\n\t\tproveedor: opciones.proveedor,\n\t\tmodelo: opciones.modelo,\n\t\tcasosArchivo: opciones.casosArchivo,\n\t\tresultados,\n\t\tresumen: resumirMetricas(resultados),\n\t};\n}\n\n/** Implementación real: agente de Ada con `read`/`edit`/`write`, contra el proveedor de verdad. */\nexport function crearEjecutorReal(opciones: {\n\tagentDir: string;\n\tmodel?: Model<Api>;\n\ttimeoutMs: number;\n}): EjecutorDeCaso {\n\treturn {\n\t\tasync ejecutar({ cwd, rutaFichero, prompt }) {\n\t\t\tconst { createAgentSession } = await import(\"../sdk.ts\");\n\t\t\tconst { SessionManager } = await import(\"../session-manager.ts\");\n\t\t\tconst { session } = await createAgentSession({\n\t\t\t\tcwd,\n\t\t\t\tagentDir: opciones.agentDir,\n\t\t\t\tmodel: opciones.model,\n\t\t\t\ttools: [\"read\", \"edit\", \"write\"],\n\t\t\t\tsessionManager: SessionManager.inMemory(cwd),\n\t\t\t});\n\n\t\t\tconst objetivo = resolve(cwd, rutaFichero);\n\t\t\tconst pendientes = new Map<string, string | null>();\n\t\t\tlet tocoFichero = false;\n\t\t\tlet edicionOk = false;\n\t\t\tlet turnoVacio = false;\n\t\t\tconst desuscribir = session.subscribe((evento) => {\n\t\t\t\t// Un turno sin nada dentro se contaba como fantasma («el modelo\n\t\t\t\t// decidió no editar»). Se mira aquí, en el mismo sitio donde ya\n\t\t\t\t// se escuchan las ediciones, y con el MISMO detector que usa la\n\t\t\t\t// sesión interactiva.\n\t\t\t\tif (evento.type === \"message_end\" && evento.message.role === \"assistant\") {\n\t\t\t\t\tif (estadoDelTurno(evento.message) === \"vacio\") turnoVacio = true;\n\t\t\t\t}\n\t\t\t\tif (evento.type === \"tool_execution_start\" && (evento.toolName === \"edit\" || evento.toolName === \"write\")) {\n\t\t\t\t\tconst args = evento.args as { path?: unknown; file_path?: unknown } | undefined;\n\t\t\t\t\tconst cruda = args?.file_path ?? args?.path;\n\t\t\t\t\tpendientes.set(evento.toolCallId, typeof cruda === \"string\" ? resolve(cwd, cruda) : null);\n\t\t\t\t} else if (evento.type === \"tool_execution_end\") {\n\t\t\t\t\tconst ruta = pendientes.get(evento.toolCallId);\n\t\t\t\t\tpendientes.delete(evento.toolCallId);\n\t\t\t\t\tif (ruta !== objetivo) return;\n\t\t\t\t\ttocoFichero = true;\n\t\t\t\t\tif (!evento.isError) edicionOk = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlet expiro = false;\n\t\t\ttry {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tsession.prompt(prompt),\n\t\t\t\t\tnew Promise((_resolve, reject) => {\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\texpiro = true;\n\t\t\t\t\t\t\treject(new Error(\"__timeout__\"));\n\t\t\t\t\t\t}, opciones.timeoutMs);\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t} finally {\n\t\t\t\tdesuscribir();\n\t\t\t\tif (expiro) await session.abort();\n\t\t\t\tsession.dispose();\n\t\t\t}\n\t\t\treturn { tocoFichero, edicionOk, turnoVacio };\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ejecuta casos del banco contra un agente de verdad y separa las cuatro
|
|
3
|
+
* métricas que la tarea exige no mezclar: tarea, edición, fantasma, timeout.
|
|
4
|
+
*
|
|
5
|
+
* El agente que edita es INYECTABLE (`EjecutorDeCaso`) a propósito: la
|
|
6
|
+
* implementación real (`crearEjecutorReal`) llama al proveedor de verdad y
|
|
7
|
+
* cuesta dinero; los tests inyectan una versión determinista para probar que
|
|
8
|
+
* el propio banco DETECTA una edición rota sin gastar una sola llamada.
|
|
9
|
+
*/
|
|
10
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { estadoDelTurno } from "../turno-vacio/detectar.js";
|
|
14
|
+
/** Normaliza el salto de línea final para no fallar por un `\n` de más o de menos. */
|
|
15
|
+
function normalizar(contenido) {
|
|
16
|
+
return contenido.replace(/\n*$/, "\n");
|
|
17
|
+
}
|
|
18
|
+
async function ejecutarUnCaso(caso, ejecutor, raizTemp) {
|
|
19
|
+
const inicio = Date.now();
|
|
20
|
+
const cwd = mkdtempSync(join(raizTemp, "caso-"));
|
|
21
|
+
const rutaFichero = join(cwd, caso.ficheroRelativo);
|
|
22
|
+
mkdirSync(dirname(rutaFichero), { recursive: true });
|
|
23
|
+
writeFileSync(rutaFichero, caso.contenidoEntrada, "utf-8");
|
|
24
|
+
let timeout = false;
|
|
25
|
+
let tocoFichero = false;
|
|
26
|
+
let edicionOk = false;
|
|
27
|
+
let turnoVacio = false;
|
|
28
|
+
let error;
|
|
29
|
+
try {
|
|
30
|
+
const resultado = await ejecutor.ejecutar({ cwd, rutaFichero: caso.ficheroRelativo, prompt: caso.prompt });
|
|
31
|
+
tocoFichero = resultado.tocoFichero;
|
|
32
|
+
edicionOk = resultado.edicionOk;
|
|
33
|
+
turnoVacio = resultado.turnoVacio === true;
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
if (err instanceof Error && err.message === "__timeout__") {
|
|
37
|
+
timeout = true;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
error = err instanceof Error ? err.message : String(err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
let tareaOk = false;
|
|
44
|
+
try {
|
|
45
|
+
tareaOk = normalizar(readFileSync(rutaFichero, "utf-8")) === normalizar(caso.contenidoEsperado);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
tareaOk = false;
|
|
49
|
+
}
|
|
50
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
51
|
+
return {
|
|
52
|
+
casoId: caso.id,
|
|
53
|
+
dificultad: caso.dificultad,
|
|
54
|
+
mutacion: caso.mutacion,
|
|
55
|
+
tareaOk,
|
|
56
|
+
edicionOk: tocoFichero && edicionOk,
|
|
57
|
+
// Fantasma: nunca tocó el fichero, Y el turno terminó de verdad. Un
|
|
58
|
+
// timeout no es un fantasma (no dio tiempo a saberlo) y un ERROR
|
|
59
|
+
// tampoco (no se pudo saberlo, punto — una llamada sin API key no
|
|
60
|
+
// es un modelo "que decidió no editar").
|
|
61
|
+
//
|
|
62
|
+
// Un turno VACÍO tampoco: el modelo no contestó, así que no hay
|
|
63
|
+
// decisión suya que contar. Es el mismo error de leer un fallo como
|
|
64
|
+
// éxito que ya obligó a sacar `error` de esta cuenta.
|
|
65
|
+
fantasma: !tocoFichero && !timeout && !error && !turnoVacio,
|
|
66
|
+
vacio: turnoVacio,
|
|
67
|
+
timeout,
|
|
68
|
+
duracionMs: Date.now() - inicio,
|
|
69
|
+
error,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function resumirMetricas(resultados) {
|
|
73
|
+
const total = resultados.length;
|
|
74
|
+
const pct = (n) => (total === 0 ? 0 : Math.round((n / total) * 1000) / 10);
|
|
75
|
+
const porDificultad = {};
|
|
76
|
+
for (const dificultad of new Set(resultados.map((r) => r.dificultad))) {
|
|
77
|
+
const delGrupo = resultados.filter((r) => r.dificultad === dificultad);
|
|
78
|
+
const pctGrupo = (n) => (delGrupo.length === 0 ? 0 : Math.round((n / delGrupo.length) * 1000) / 10);
|
|
79
|
+
porDificultad[dificultad] = {
|
|
80
|
+
total: delGrupo.length,
|
|
81
|
+
tareaOkPct: pctGrupo(delGrupo.filter((r) => r.tareaOk).length),
|
|
82
|
+
edicionOkPct: pctGrupo(delGrupo.filter((r) => r.edicionOk).length),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
total,
|
|
87
|
+
tareaOkPct: pct(resultados.filter((r) => r.tareaOk).length),
|
|
88
|
+
edicionOkPct: pct(resultados.filter((r) => r.edicionOk).length),
|
|
89
|
+
fantasmaPct: pct(resultados.filter((r) => r.fantasma).length),
|
|
90
|
+
vacioPct: pct(resultados.filter((r) => r.vacio).length),
|
|
91
|
+
timeoutPct: pct(resultados.filter((r) => r.timeout).length),
|
|
92
|
+
errorPct: pct(resultados.filter((r) => Boolean(r.error)).length),
|
|
93
|
+
porDificultad,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export async function ejecutarCasos(casos, ejecutor, opciones) {
|
|
97
|
+
const raizTemp = mkdtempSync(join(tmpdir(), "ada-banco-"));
|
|
98
|
+
const resultados = [];
|
|
99
|
+
try {
|
|
100
|
+
for (let i = 0; i < casos.length; i++) {
|
|
101
|
+
const r = await ejecutarUnCaso(casos[i], ejecutor, raizTemp);
|
|
102
|
+
resultados.push(r);
|
|
103
|
+
opciones.onProgreso?.(i + 1, casos.length, r);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
rmSync(raizTemp, { recursive: true, force: true });
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
version: 1,
|
|
111
|
+
ejecutadoEn: new Date().toISOString(),
|
|
112
|
+
proveedor: opciones.proveedor,
|
|
113
|
+
modelo: opciones.modelo,
|
|
114
|
+
casosArchivo: opciones.casosArchivo,
|
|
115
|
+
resultados,
|
|
116
|
+
resumen: resumirMetricas(resultados),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Implementación real: agente de Ada con `read`/`edit`/`write`, contra el proveedor de verdad. */
|
|
120
|
+
export function crearEjecutorReal(opciones) {
|
|
121
|
+
return {
|
|
122
|
+
async ejecutar({ cwd, rutaFichero, prompt }) {
|
|
123
|
+
const { createAgentSession } = await import("../sdk.js");
|
|
124
|
+
const { SessionManager } = await import("../session-manager.js");
|
|
125
|
+
const { session } = await createAgentSession({
|
|
126
|
+
cwd,
|
|
127
|
+
agentDir: opciones.agentDir,
|
|
128
|
+
model: opciones.model,
|
|
129
|
+
tools: ["read", "edit", "write"],
|
|
130
|
+
sessionManager: SessionManager.inMemory(cwd),
|
|
131
|
+
});
|
|
132
|
+
const objetivo = resolve(cwd, rutaFichero);
|
|
133
|
+
const pendientes = new Map();
|
|
134
|
+
let tocoFichero = false;
|
|
135
|
+
let edicionOk = false;
|
|
136
|
+
let turnoVacio = false;
|
|
137
|
+
const desuscribir = session.subscribe((evento) => {
|
|
138
|
+
// Un turno sin nada dentro se contaba como fantasma («el modelo
|
|
139
|
+
// decidió no editar»). Se mira aquí, en el mismo sitio donde ya
|
|
140
|
+
// se escuchan las ediciones, y con el MISMO detector que usa la
|
|
141
|
+
// sesión interactiva.
|
|
142
|
+
if (evento.type === "message_end" && evento.message.role === "assistant") {
|
|
143
|
+
if (estadoDelTurno(evento.message) === "vacio")
|
|
144
|
+
turnoVacio = true;
|
|
145
|
+
}
|
|
146
|
+
if (evento.type === "tool_execution_start" && (evento.toolName === "edit" || evento.toolName === "write")) {
|
|
147
|
+
const args = evento.args;
|
|
148
|
+
const cruda = args?.file_path ?? args?.path;
|
|
149
|
+
pendientes.set(evento.toolCallId, typeof cruda === "string" ? resolve(cwd, cruda) : null);
|
|
150
|
+
}
|
|
151
|
+
else if (evento.type === "tool_execution_end") {
|
|
152
|
+
const ruta = pendientes.get(evento.toolCallId);
|
|
153
|
+
pendientes.delete(evento.toolCallId);
|
|
154
|
+
if (ruta !== objetivo)
|
|
155
|
+
return;
|
|
156
|
+
tocoFichero = true;
|
|
157
|
+
if (!evento.isError)
|
|
158
|
+
edicionOk = true;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
let expiro = false;
|
|
162
|
+
try {
|
|
163
|
+
await Promise.race([
|
|
164
|
+
session.prompt(prompt),
|
|
165
|
+
new Promise((_resolve, reject) => {
|
|
166
|
+
setTimeout(() => {
|
|
167
|
+
expiro = true;
|
|
168
|
+
reject(new Error("__timeout__"));
|
|
169
|
+
}, opciones.timeoutMs);
|
|
170
|
+
}),
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
desuscribir();
|
|
175
|
+
if (expiro)
|
|
176
|
+
await session.abort();
|
|
177
|
+
session.dispose();
|
|
178
|
+
}
|
|
179
|
+
return { tocoFichero, edicionOk, turnoVacio };
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=ejecutar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ejecutar.js","sourceRoot":"","sources":["../../../src/core/banco/ejecutar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ejecuta casos del banco contra un agente de verdad y separa las cuatro\n * métricas que la tarea exige no mezclar: tarea, edición, fantasma, timeout.\n *\n * El agente que edita es INYECTABLE (`EjecutorDeCaso`) a propósito: la\n * implementación real (`crearEjecutorReal`) llama al proveedor de verdad y\n * cuesta dinero; los tests inyectan una versión determinista para probar que\n * el propio banco DETECTA una edición rota sin gastar una sola llamada.\n */\n\nimport { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { estadoDelTurno } from \"../turno-vacio/detectar.ts\";\nimport type { CasoBanco, ResultadoCaso, ResultadosEjecucion, ResumenMetricas } from \"./tipos.ts\";\n\nexport interface EjecucionCaso {\n\t/** Alguna llamada a `edit`/`write` intentó tocar el fichero objetivo. */\n\ttocoFichero: boolean;\n\t/** De las que lo tocaron, al menos una terminó sin error. */\n\tedicionOk: boolean;\n\t/**\n\t * El modelo devolvió al menos un turno VACÍO (ni texto, ni razonamiento, ni\n\t * llamadas). Opcional porque los ejecutores deterministas de los tests no\n\t * hablan con ningún proveedor y no tienen turnos que mirar.\n\t */\n\tturnoVacio?: boolean;\n}\n\nexport interface EjecutorDeCaso {\n\tejecutar(opciones: { cwd: string; rutaFichero: string; prompt: string }): Promise<EjecucionCaso>;\n}\n\n/** Normaliza el salto de línea final para no fallar por un `\\n` de más o de menos. */\nfunction normalizar(contenido: string): string {\n\treturn contenido.replace(/\\n*$/, \"\\n\");\n}\n\nasync function ejecutarUnCaso(caso: CasoBanco, ejecutor: EjecutorDeCaso, raizTemp: string): Promise<ResultadoCaso> {\n\tconst inicio = Date.now();\n\tconst cwd = mkdtempSync(join(raizTemp, \"caso-\"));\n\tconst rutaFichero = join(cwd, caso.ficheroRelativo);\n\tmkdirSync(dirname(rutaFichero), { recursive: true });\n\twriteFileSync(rutaFichero, caso.contenidoEntrada, \"utf-8\");\n\n\tlet timeout = false;\n\tlet tocoFichero = false;\n\tlet edicionOk = false;\n\tlet turnoVacio = false;\n\tlet error: string | undefined;\n\ttry {\n\t\tconst resultado = await ejecutor.ejecutar({ cwd, rutaFichero: caso.ficheroRelativo, prompt: caso.prompt });\n\t\ttocoFichero = resultado.tocoFichero;\n\t\tedicionOk = resultado.edicionOk;\n\t\tturnoVacio = resultado.turnoVacio === true;\n\t} catch (err) {\n\t\tif (err instanceof Error && err.message === \"__timeout__\") {\n\t\t\ttimeout = true;\n\t\t} else {\n\t\t\terror = err instanceof Error ? err.message : String(err);\n\t\t}\n\t}\n\n\tlet tareaOk = false;\n\ttry {\n\t\ttareaOk = normalizar(readFileSync(rutaFichero, \"utf-8\")) === normalizar(caso.contenidoEsperado);\n\t} catch {\n\t\ttareaOk = false;\n\t}\n\n\trmSync(cwd, { recursive: true, force: true });\n\n\treturn {\n\t\tcasoId: caso.id,\n\t\tdificultad: caso.dificultad,\n\t\tmutacion: caso.mutacion,\n\t\ttareaOk,\n\t\tedicionOk: tocoFichero && edicionOk,\n\t\t// Fantasma: nunca tocó el fichero, Y el turno terminó de verdad. Un\n\t\t// timeout no es un fantasma (no dio tiempo a saberlo) y un ERROR\n\t\t// tampoco (no se pudo saberlo, punto — una llamada sin API key no\n\t\t// es un modelo \"que decidió no editar\").\n\t\t//\n\t\t// Un turno VACÍO tampoco: el modelo no contestó, así que no hay\n\t\t// decisión suya que contar. Es el mismo error de leer un fallo como\n\t\t// éxito que ya obligó a sacar `error` de esta cuenta.\n\t\tfantasma: !tocoFichero && !timeout && !error && !turnoVacio,\n\t\tvacio: turnoVacio,\n\t\ttimeout,\n\t\tduracionMs: Date.now() - inicio,\n\t\terror,\n\t};\n}\n\nexport function resumirMetricas(resultados: ResultadoCaso[]): ResumenMetricas {\n\tconst total = resultados.length;\n\tconst pct = (n: number) => (total === 0 ? 0 : Math.round((n / total) * 1000) / 10);\n\tconst porDificultad: ResumenMetricas[\"porDificultad\"] = {};\n\tfor (const dificultad of new Set(resultados.map((r) => r.dificultad))) {\n\t\tconst delGrupo = resultados.filter((r) => r.dificultad === dificultad);\n\t\tconst pctGrupo = (n: number) => (delGrupo.length === 0 ? 0 : Math.round((n / delGrupo.length) * 1000) / 10);\n\t\tporDificultad[dificultad] = {\n\t\t\ttotal: delGrupo.length,\n\t\t\ttareaOkPct: pctGrupo(delGrupo.filter((r) => r.tareaOk).length),\n\t\t\tedicionOkPct: pctGrupo(delGrupo.filter((r) => r.edicionOk).length),\n\t\t};\n\t}\n\treturn {\n\t\ttotal,\n\t\ttareaOkPct: pct(resultados.filter((r) => r.tareaOk).length),\n\t\tedicionOkPct: pct(resultados.filter((r) => r.edicionOk).length),\n\t\tfantasmaPct: pct(resultados.filter((r) => r.fantasma).length),\n\t\tvacioPct: pct(resultados.filter((r) => r.vacio).length),\n\t\ttimeoutPct: pct(resultados.filter((r) => r.timeout).length),\n\t\terrorPct: pct(resultados.filter((r) => Boolean(r.error)).length),\n\t\tporDificultad,\n\t};\n}\n\nexport async function ejecutarCasos(\n\tcasos: CasoBanco[],\n\tejecutor: EjecutorDeCaso,\n\topciones: {\n\t\tproveedor: string;\n\t\tmodelo: string;\n\t\tcasosArchivo: string;\n\t\tonProgreso?: (i: number, total: number, r: ResultadoCaso) => void;\n\t},\n): Promise<ResultadosEjecucion> {\n\tconst raizTemp = mkdtempSync(join(tmpdir(), \"ada-banco-\"));\n\tconst resultados: ResultadoCaso[] = [];\n\ttry {\n\t\tfor (let i = 0; i < casos.length; i++) {\n\t\t\tconst r = await ejecutarUnCaso(casos[i], ejecutor, raizTemp);\n\t\t\tresultados.push(r);\n\t\t\topciones.onProgreso?.(i + 1, casos.length, r);\n\t\t}\n\t} finally {\n\t\trmSync(raizTemp, { recursive: true, force: true });\n\t}\n\treturn {\n\t\tversion: 1,\n\t\tejecutadoEn: new Date().toISOString(),\n\t\tproveedor: opciones.proveedor,\n\t\tmodelo: opciones.modelo,\n\t\tcasosArchivo: opciones.casosArchivo,\n\t\tresultados,\n\t\tresumen: resumirMetricas(resultados),\n\t};\n}\n\n/** Implementación real: agente de Ada con `read`/`edit`/`write`, contra el proveedor de verdad. */\nexport function crearEjecutorReal(opciones: {\n\tagentDir: string;\n\tmodel?: Model<Api>;\n\ttimeoutMs: number;\n}): EjecutorDeCaso {\n\treturn {\n\t\tasync ejecutar({ cwd, rutaFichero, prompt }) {\n\t\t\tconst { createAgentSession } = await import(\"../sdk.ts\");\n\t\t\tconst { SessionManager } = await import(\"../session-manager.ts\");\n\t\t\tconst { session } = await createAgentSession({\n\t\t\t\tcwd,\n\t\t\t\tagentDir: opciones.agentDir,\n\t\t\t\tmodel: opciones.model,\n\t\t\t\ttools: [\"read\", \"edit\", \"write\"],\n\t\t\t\tsessionManager: SessionManager.inMemory(cwd),\n\t\t\t});\n\n\t\t\tconst objetivo = resolve(cwd, rutaFichero);\n\t\t\tconst pendientes = new Map<string, string | null>();\n\t\t\tlet tocoFichero = false;\n\t\t\tlet edicionOk = false;\n\t\t\tlet turnoVacio = false;\n\t\t\tconst desuscribir = session.subscribe((evento) => {\n\t\t\t\t// Un turno sin nada dentro se contaba como fantasma («el modelo\n\t\t\t\t// decidió no editar»). Se mira aquí, en el mismo sitio donde ya\n\t\t\t\t// se escuchan las ediciones, y con el MISMO detector que usa la\n\t\t\t\t// sesión interactiva.\n\t\t\t\tif (evento.type === \"message_end\" && evento.message.role === \"assistant\") {\n\t\t\t\t\tif (estadoDelTurno(evento.message) === \"vacio\") turnoVacio = true;\n\t\t\t\t}\n\t\t\t\tif (evento.type === \"tool_execution_start\" && (evento.toolName === \"edit\" || evento.toolName === \"write\")) {\n\t\t\t\t\tconst args = evento.args as { path?: unknown; file_path?: unknown } | undefined;\n\t\t\t\t\tconst cruda = args?.file_path ?? args?.path;\n\t\t\t\t\tpendientes.set(evento.toolCallId, typeof cruda === \"string\" ? resolve(cwd, cruda) : null);\n\t\t\t\t} else if (evento.type === \"tool_execution_end\") {\n\t\t\t\t\tconst ruta = pendientes.get(evento.toolCallId);\n\t\t\t\t\tpendientes.delete(evento.toolCallId);\n\t\t\t\t\tif (ruta !== objetivo) return;\n\t\t\t\t\ttocoFichero = true;\n\t\t\t\t\tif (!evento.isError) edicionOk = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlet expiro = false;\n\t\t\ttry {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tsession.prompt(prompt),\n\t\t\t\t\tnew Promise((_resolve, reject) => {\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\texpiro = true;\n\t\t\t\t\t\t\treject(new Error(\"__timeout__\"));\n\t\t\t\t\t\t}, opciones.timeoutMs);\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t} finally {\n\t\t\t\tdesuscribir();\n\t\t\t\tif (expiro) await session.abort();\n\t\t\t\tsession.dispose();\n\t\t\t}\n\t\t\treturn { tocoFichero, edicionOk, turnoVacio };\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orquesta la generación de casos: elige fichero, aplica una mutación,
|
|
3
|
+
* construye el bloque único y lo valida RESOLVIÉNDOLO antes de admitirlo.
|
|
4
|
+
*
|
|
5
|
+
* Un caso ambiguo (el bloque no se puede hacer único, o resolverlo no
|
|
6
|
+
* reproduce el fichero esperado byte a byte) se descarta y se cuenta — la
|
|
7
|
+
* puerta de la tarea exige poder enseñar ese número, no solo el de casos
|
|
8
|
+
* generados. Si `--casos 20` descarta cero, hay que poder decirlo y
|
|
9
|
+
* sospechar, no callarlo.
|
|
10
|
+
*/
|
|
11
|
+
import { TODAS_LAS_MUTACIONES } from "./mutaciones.ts";
|
|
12
|
+
import type { CasoBanco, ConjuntoCasos, Dificultad } from "./tipos.ts";
|
|
13
|
+
/** LCG determinista: misma semilla, misma secuencia de casos siempre. */
|
|
14
|
+
export declare function crearRngSemilla(semilla: number): () => number;
|
|
15
|
+
export interface OpcionesGeneracion {
|
|
16
|
+
corpus: string;
|
|
17
|
+
numCasos: number;
|
|
18
|
+
semilla?: number;
|
|
19
|
+
dificultades?: Dificultad[];
|
|
20
|
+
mutaciones?: typeof TODAS_LAS_MUTACIONES;
|
|
21
|
+
}
|
|
22
|
+
export declare function generarCasos(opciones: OpcionesGeneracion): ConjuntoCasos;
|
|
23
|
+
export declare function rutaAbsolutaDeCaso(caso: CasoBanco, corpus: string): string;
|
|
24
|
+
//# sourceMappingURL=generar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generar.d.ts","sourceRoot":"","sources":["../../../src/core/banco/generar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAA0B,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKvE,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,MAAM,CAM7D;AAmED,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,oBAAoB,CAAC;CACzC;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,CAwGxE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1E","sourcesContent":["/**\n * Orquesta la generación de casos: elige fichero, aplica una mutación,\n * construye el bloque único y lo valida RESOLVIÉNDOLO antes de admitirlo.\n *\n * Un caso ambiguo (el bloque no se puede hacer único, o resolverlo no\n * reproduce el fichero esperado byte a byte) se descarta y se cuenta — la\n * puerta de la tarea exige poder enseñar ese número, no solo el de casos\n * generados. Si `--casos 20` descarta cero, hay que poder decirlo y\n * sospechar, no callarlo.\n */\n\nimport { extname, join } from \"node:path\";\nimport { analizarCorpus, candidatosPara, type FicheroAnalizado, puntuarDificultad } from \"./analisis.ts\";\nimport { construirBloqueUnico, contarOcurrencias } from \"./bloques.ts\";\nimport { type CandidatoMutacion, TODAS_LAS_MUTACIONES } from \"./mutaciones.ts\";\nimport type { CasoBanco, ConjuntoCasos, Dificultad } from \"./tipos.ts\";\n\nconst DIFICULTADES_POR_DEFECTO: Dificultad[] = [\"facil\", \"medio\", \"dificil\", \"pesadilla\"];\nconst LENGUAJE: Record<string, string> = { \".ts\": \"ts\", \".tsx\": \"tsx\" };\n\n/** LCG determinista: misma semilla, misma secuencia de casos siempre. */\nexport function crearRngSemilla(semilla: number): () => number {\n\tlet estado = semilla >>> 0 || 1;\n\treturn () => {\n\t\testado = (estado * 1103515245 + 12345) & 0x7fffffff;\n\t\treturn estado / 0x7fffffff;\n\t};\n}\n\nfunction elegir<T>(lista: T[], rng: () => number): T {\n\treturn lista[Math.floor(rng() * lista.length)];\n}\n\n/** Región (fichero + línea) ya usada por otro caso, con margen para no solaparse. */\nfunction regionLibre(usadas: Map<string, number[]>, ruta: string, linea: number): boolean {\n\treturn !(usadas.get(ruta) ?? []).some((l) => Math.abs(l - linea) <= 3);\n}\nfunction marcarRegion(usadas: Map<string, number[]>, ruta: string, linea: number): void {\n\tconst lista = usadas.get(ruta) ?? [];\n\tlista.push(linea);\n\tusadas.set(ruta, lista);\n}\n\nfunction construirPrompt(\n\tfichero: FicheroAnalizado,\n\tdificultad: Dificultad,\n\tmutacionNombre: string,\n\tbloqueEntrada: string[],\n\tbloqueEsperado: string[],\n\tlineaInicio: number,\n\tesNightmare: boolean,\n): string {\n\tconst lenguaje = LENGUAJE[extname(fichero.relativa)] ?? \"\";\n\tconst descripciones: Record<string, string> = {\n\t\t\"invertir-booleano\": \"Un literal booleano está invertido.\",\n\t\t\"intercambiar-igualdad\": \"Un operador de igualdad está invertido (=== / !==).\",\n\t\t\"intercambiar-logico\": \"Un operador lógico es el que no toca (&& / ||).\",\n\t\t\"intercambiar-nullish\": \"Un `??` se cambió por `||` (o al revés).\",\n\t\t\"intercambiar-incremento\": \"Un incremento/decremento apunta al sentido contrario.\",\n\t\t\"quitar-negacion\": \"Se quitó una negación (`!`) que hacía falta.\",\n\t\t\"off-by-one\": \"Un límite numérico tiene un error de uno de más.\",\n\t};\n\tconst lineas: string[] = [\n\t\t`# Arregla un bug en \\`${fichero.relativa}\\``,\n\t\t\"\",\n\t\tdescripciones[mutacionNombre] ?? \"Hay un bug.\",\n\t];\n\tif (dificultad === \"facil\") lineas.push(\"\", `Está en la línea ${lineaInicio}.`);\n\n\tlineas.push(\n\t\t\"\",\n\t\t`Sustituye este bloque${dificultad === \"facil\" ? ` (empieza en la línea ${lineaInicio})` : \"\"}:`,\n\t\t\"\",\n\t);\n\tlineas.push(\n\t\t`\\`\\`\\`${lenguaje}`,\n\t\tbloqueEntrada.join(\"\\n\"),\n\t\t\"```\",\n\t\t\"\",\n\t\t\"por este:\",\n\t\t\"\",\n\t\t`\\`\\`\\`${lenguaje}`,\n\t\tbloqueEsperado.join(\"\\n\"),\n\t\t\"```\",\n\t);\n\tlineas.push(\n\t\t\"\",\n\t\tesNightmare\n\t\t\t? \"Este fichero tiene bloques casi idénticos en varios sitios: edita EXACTAMENTE el bloque de arriba, ninguno más.\"\n\t\t\t: \"Haz exactamente este cambio; no toques nada más.\",\n\t);\n\treturn lineas.join(\"\\n\");\n}\n\nexport interface OpcionesGeneracion {\n\tcorpus: string;\n\tnumCasos: number;\n\tsemilla?: number;\n\tdificultades?: Dificultad[];\n\tmutaciones?: typeof TODAS_LAS_MUTACIONES;\n}\n\nconst INTENTOS_POR_CASO = 80;\n\nexport function generarCasos(opciones: OpcionesGeneracion): ConjuntoCasos {\n\tconst semilla = opciones.semilla ?? 42;\n\tconst rng = crearRngSemilla(semilla);\n\tconst ficheros = analizarCorpus(opciones.corpus);\n\tconst dificultades = opciones.dificultades ?? DIFICULTADES_POR_DEFECTO;\n\tconst mutaciones = opciones.mutaciones ?? TODAS_LAS_MUTACIONES;\n\n\tconst usadas = new Map<string, number[]>();\n\tconst casos: CasoBanco[] = [];\n\tlet descartadosPorAmbiguos = 0;\n\tlet descartadosPorNoAplicable = 0;\n\tlet intentosTotales = 0;\n\n\tfor (let indice = 0; indice < opciones.numCasos; indice++) {\n\t\tconst dificultad = dificultades[indice % dificultades.length];\n\t\tconst candidatosFichero = candidatosPara(ficheros, dificultad);\n\t\tconst pool = candidatosFichero.length > 0 ? candidatosFichero : ficheros;\n\t\tif (pool.length === 0) break;\n\n\t\tlet generado: CasoBanco | null = null;\n\t\tfor (let intento = 0; intento < INTENTOS_POR_CASO && !generado; intento++) {\n\t\t\tintentosTotales++;\n\t\t\tconst fichero = elegir(pool, rng);\n\t\t\tconst mutacion = elegir(mutaciones, rng);\n\t\t\tconst candidatos = mutacion.candidatos(fichero.lineas);\n\t\t\tif (candidatos.length === 0) {\n\t\t\t\tdescartadosPorNoAplicable++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst cand: CandidatoMutacion = elegir(candidatos, rng);\n\t\t\tif (!regionLibre(usadas, fichero.ruta, cand.numeroLinea)) continue;\n\n\t\t\tif (dificultad === \"pesadilla\") {\n\t\t\t\tconst repetida = fichero.lineasRepetidas.has(cand.lineaOriginal.trim());\n\t\t\t\tif (!repetida) continue;\n\t\t\t}\n\n\t\t\tconst lineasEntrada = [...fichero.lineas];\n\t\t\tlineasEntrada[cand.numeroLinea - 1] = cand.lineaMutada;\n\t\t\tconst contenidoEntrada = `${lineasEntrada.join(\"\\n\")}`;\n\n\t\t\tconst bloque = construirBloqueUnico(fichero.lineas, lineasEntrada, cand.numeroLinea - 1);\n\t\t\tif (!bloque.unico) {\n\t\t\t\tdescartadosPorAmbiguos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Puerta obligatoria: nunca se admite un caso sin re-resolverlo desde\n\t\t\t// cero contra el fichero esperado.\n\t\t\tconst bloqueOk = contarOcurrencias(lineasEntrada, bloque.bloqueEntrada) === 1;\n\t\t\tconst resultado = bloqueOk\n\t\t\t\t? [\n\t\t\t\t\t\t...lineasEntrada.slice(0, bloque.lineaInicio - 1),\n\t\t\t\t\t\t...bloque.bloqueEsperado,\n\t\t\t\t\t\t...lineasEntrada.slice(bloque.lineaInicio - 1 + bloque.bloqueEntrada.length),\n\t\t\t\t\t].join(\"\\n\")\n\t\t\t\t: null;\n\t\t\tif (resultado !== fichero.contenido) {\n\t\t\t\tdescartadosPorAmbiguos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmarcarRegion(usadas, fichero.ruta, cand.numeroLinea);\n\t\t\tconst puntuacion = puntuarDificultad(fichero, cand.numeroLinea);\n\t\t\tconst id = `${dificultad}-${mutacion.nombre}-${String(indice + 1).padStart(3, \"0\")}`;\n\t\t\tgenerado = {\n\t\t\t\tid,\n\t\t\t\tdificultad,\n\t\t\t\tmutacion: mutacion.nombre,\n\t\t\t\tficheroRelativo: fichero.relativa,\n\t\t\t\tcontenidoEntrada,\n\t\t\t\tcontenidoEsperado: fichero.contenido,\n\t\t\t\tnumeroLinea: cand.numeroLinea,\n\t\t\t\tprompt: construirPrompt(\n\t\t\t\t\tfichero,\n\t\t\t\t\tdificultad,\n\t\t\t\t\tmutacion.nombre,\n\t\t\t\t\tbloque.bloqueEntrada,\n\t\t\t\t\tbloque.bloqueEsperado,\n\t\t\t\t\tbloque.lineaInicio,\n\t\t\t\t\tdificultad === \"pesadilla\",\n\t\t\t\t),\n\t\t\t\tpuntuacion,\n\t\t\t\tcontexto: {\n\t\t\t\t\tlineasFichero: fichero.lineas.length,\n\t\t\t\t\tesLineaRepetida: fichero.lineasRepetidas.has(cand.lineaOriginal.trim()),\n\t\t\t\t\tvecesRepetida: fichero.lineasRepetidas.get(cand.lineaOriginal.trim())?.length ?? 0,\n\t\t\t\t\tbloquesSimilares: fichero.bloquesSimilares,\n\t\t\t\t\tdensidad: Math.round(fichero.densidad * 1000) / 1000,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (generado) casos.push(generado);\n\t}\n\n\treturn {\n\t\tversion: 1,\n\t\tgeneradoEn: new Date().toISOString(),\n\t\tsemilla,\n\t\tcorpus: opciones.corpus,\n\t\tcasos,\n\t\tdescartadosPorAmbiguos,\n\t\tdescartadosPorNoAplicable,\n\t\tintentos: intentosTotales,\n\t};\n}\n\nexport function rutaAbsolutaDeCaso(caso: CasoBanco, corpus: string): string {\n\treturn join(corpus, caso.ficheroRelativo);\n}\n"]}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orquesta la generación de casos: elige fichero, aplica una mutación,
|
|
3
|
+
* construye el bloque único y lo valida RESOLVIÉNDOLO antes de admitirlo.
|
|
4
|
+
*
|
|
5
|
+
* Un caso ambiguo (el bloque no se puede hacer único, o resolverlo no
|
|
6
|
+
* reproduce el fichero esperado byte a byte) se descarta y se cuenta — la
|
|
7
|
+
* puerta de la tarea exige poder enseñar ese número, no solo el de casos
|
|
8
|
+
* generados. Si `--casos 20` descarta cero, hay que poder decirlo y
|
|
9
|
+
* sospechar, no callarlo.
|
|
10
|
+
*/
|
|
11
|
+
import { extname, join } from "node:path";
|
|
12
|
+
import { analizarCorpus, candidatosPara, puntuarDificultad } from "./analisis.js";
|
|
13
|
+
import { construirBloqueUnico, contarOcurrencias } from "./bloques.js";
|
|
14
|
+
import { TODAS_LAS_MUTACIONES } from "./mutaciones.js";
|
|
15
|
+
const DIFICULTADES_POR_DEFECTO = ["facil", "medio", "dificil", "pesadilla"];
|
|
16
|
+
const LENGUAJE = { ".ts": "ts", ".tsx": "tsx" };
|
|
17
|
+
/** LCG determinista: misma semilla, misma secuencia de casos siempre. */
|
|
18
|
+
export function crearRngSemilla(semilla) {
|
|
19
|
+
let estado = semilla >>> 0 || 1;
|
|
20
|
+
return () => {
|
|
21
|
+
estado = (estado * 1103515245 + 12345) & 0x7fffffff;
|
|
22
|
+
return estado / 0x7fffffff;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function elegir(lista, rng) {
|
|
26
|
+
return lista[Math.floor(rng() * lista.length)];
|
|
27
|
+
}
|
|
28
|
+
/** Región (fichero + línea) ya usada por otro caso, con margen para no solaparse. */
|
|
29
|
+
function regionLibre(usadas, ruta, linea) {
|
|
30
|
+
return !(usadas.get(ruta) ?? []).some((l) => Math.abs(l - linea) <= 3);
|
|
31
|
+
}
|
|
32
|
+
function marcarRegion(usadas, ruta, linea) {
|
|
33
|
+
const lista = usadas.get(ruta) ?? [];
|
|
34
|
+
lista.push(linea);
|
|
35
|
+
usadas.set(ruta, lista);
|
|
36
|
+
}
|
|
37
|
+
function construirPrompt(fichero, dificultad, mutacionNombre, bloqueEntrada, bloqueEsperado, lineaInicio, esNightmare) {
|
|
38
|
+
const lenguaje = LENGUAJE[extname(fichero.relativa)] ?? "";
|
|
39
|
+
const descripciones = {
|
|
40
|
+
"invertir-booleano": "Un literal booleano está invertido.",
|
|
41
|
+
"intercambiar-igualdad": "Un operador de igualdad está invertido (=== / !==).",
|
|
42
|
+
"intercambiar-logico": "Un operador lógico es el que no toca (&& / ||).",
|
|
43
|
+
"intercambiar-nullish": "Un `??` se cambió por `||` (o al revés).",
|
|
44
|
+
"intercambiar-incremento": "Un incremento/decremento apunta al sentido contrario.",
|
|
45
|
+
"quitar-negacion": "Se quitó una negación (`!`) que hacía falta.",
|
|
46
|
+
"off-by-one": "Un límite numérico tiene un error de uno de más.",
|
|
47
|
+
};
|
|
48
|
+
const lineas = [
|
|
49
|
+
`# Arregla un bug en \`${fichero.relativa}\``,
|
|
50
|
+
"",
|
|
51
|
+
descripciones[mutacionNombre] ?? "Hay un bug.",
|
|
52
|
+
];
|
|
53
|
+
if (dificultad === "facil")
|
|
54
|
+
lineas.push("", `Está en la línea ${lineaInicio}.`);
|
|
55
|
+
lineas.push("", `Sustituye este bloque${dificultad === "facil" ? ` (empieza en la línea ${lineaInicio})` : ""}:`, "");
|
|
56
|
+
lineas.push(`\`\`\`${lenguaje}`, bloqueEntrada.join("\n"), "```", "", "por este:", "", `\`\`\`${lenguaje}`, bloqueEsperado.join("\n"), "```");
|
|
57
|
+
lineas.push("", esNightmare
|
|
58
|
+
? "Este fichero tiene bloques casi idénticos en varios sitios: edita EXACTAMENTE el bloque de arriba, ninguno más."
|
|
59
|
+
: "Haz exactamente este cambio; no toques nada más.");
|
|
60
|
+
return lineas.join("\n");
|
|
61
|
+
}
|
|
62
|
+
const INTENTOS_POR_CASO = 80;
|
|
63
|
+
export function generarCasos(opciones) {
|
|
64
|
+
const semilla = opciones.semilla ?? 42;
|
|
65
|
+
const rng = crearRngSemilla(semilla);
|
|
66
|
+
const ficheros = analizarCorpus(opciones.corpus);
|
|
67
|
+
const dificultades = opciones.dificultades ?? DIFICULTADES_POR_DEFECTO;
|
|
68
|
+
const mutaciones = opciones.mutaciones ?? TODAS_LAS_MUTACIONES;
|
|
69
|
+
const usadas = new Map();
|
|
70
|
+
const casos = [];
|
|
71
|
+
let descartadosPorAmbiguos = 0;
|
|
72
|
+
let descartadosPorNoAplicable = 0;
|
|
73
|
+
let intentosTotales = 0;
|
|
74
|
+
for (let indice = 0; indice < opciones.numCasos; indice++) {
|
|
75
|
+
const dificultad = dificultades[indice % dificultades.length];
|
|
76
|
+
const candidatosFichero = candidatosPara(ficheros, dificultad);
|
|
77
|
+
const pool = candidatosFichero.length > 0 ? candidatosFichero : ficheros;
|
|
78
|
+
if (pool.length === 0)
|
|
79
|
+
break;
|
|
80
|
+
let generado = null;
|
|
81
|
+
for (let intento = 0; intento < INTENTOS_POR_CASO && !generado; intento++) {
|
|
82
|
+
intentosTotales++;
|
|
83
|
+
const fichero = elegir(pool, rng);
|
|
84
|
+
const mutacion = elegir(mutaciones, rng);
|
|
85
|
+
const candidatos = mutacion.candidatos(fichero.lineas);
|
|
86
|
+
if (candidatos.length === 0) {
|
|
87
|
+
descartadosPorNoAplicable++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const cand = elegir(candidatos, rng);
|
|
91
|
+
if (!regionLibre(usadas, fichero.ruta, cand.numeroLinea))
|
|
92
|
+
continue;
|
|
93
|
+
if (dificultad === "pesadilla") {
|
|
94
|
+
const repetida = fichero.lineasRepetidas.has(cand.lineaOriginal.trim());
|
|
95
|
+
if (!repetida)
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const lineasEntrada = [...fichero.lineas];
|
|
99
|
+
lineasEntrada[cand.numeroLinea - 1] = cand.lineaMutada;
|
|
100
|
+
const contenidoEntrada = `${lineasEntrada.join("\n")}`;
|
|
101
|
+
const bloque = construirBloqueUnico(fichero.lineas, lineasEntrada, cand.numeroLinea - 1);
|
|
102
|
+
if (!bloque.unico) {
|
|
103
|
+
descartadosPorAmbiguos++;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
// Puerta obligatoria: nunca se admite un caso sin re-resolverlo desde
|
|
107
|
+
// cero contra el fichero esperado.
|
|
108
|
+
const bloqueOk = contarOcurrencias(lineasEntrada, bloque.bloqueEntrada) === 1;
|
|
109
|
+
const resultado = bloqueOk
|
|
110
|
+
? [
|
|
111
|
+
...lineasEntrada.slice(0, bloque.lineaInicio - 1),
|
|
112
|
+
...bloque.bloqueEsperado,
|
|
113
|
+
...lineasEntrada.slice(bloque.lineaInicio - 1 + bloque.bloqueEntrada.length),
|
|
114
|
+
].join("\n")
|
|
115
|
+
: null;
|
|
116
|
+
if (resultado !== fichero.contenido) {
|
|
117
|
+
descartadosPorAmbiguos++;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
marcarRegion(usadas, fichero.ruta, cand.numeroLinea);
|
|
121
|
+
const puntuacion = puntuarDificultad(fichero, cand.numeroLinea);
|
|
122
|
+
const id = `${dificultad}-${mutacion.nombre}-${String(indice + 1).padStart(3, "0")}`;
|
|
123
|
+
generado = {
|
|
124
|
+
id,
|
|
125
|
+
dificultad,
|
|
126
|
+
mutacion: mutacion.nombre,
|
|
127
|
+
ficheroRelativo: fichero.relativa,
|
|
128
|
+
contenidoEntrada,
|
|
129
|
+
contenidoEsperado: fichero.contenido,
|
|
130
|
+
numeroLinea: cand.numeroLinea,
|
|
131
|
+
prompt: construirPrompt(fichero, dificultad, mutacion.nombre, bloque.bloqueEntrada, bloque.bloqueEsperado, bloque.lineaInicio, dificultad === "pesadilla"),
|
|
132
|
+
puntuacion,
|
|
133
|
+
contexto: {
|
|
134
|
+
lineasFichero: fichero.lineas.length,
|
|
135
|
+
esLineaRepetida: fichero.lineasRepetidas.has(cand.lineaOriginal.trim()),
|
|
136
|
+
vecesRepetida: fichero.lineasRepetidas.get(cand.lineaOriginal.trim())?.length ?? 0,
|
|
137
|
+
bloquesSimilares: fichero.bloquesSimilares,
|
|
138
|
+
densidad: Math.round(fichero.densidad * 1000) / 1000,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (generado)
|
|
143
|
+
casos.push(generado);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
version: 1,
|
|
147
|
+
generadoEn: new Date().toISOString(),
|
|
148
|
+
semilla,
|
|
149
|
+
corpus: opciones.corpus,
|
|
150
|
+
casos,
|
|
151
|
+
descartadosPorAmbiguos,
|
|
152
|
+
descartadosPorNoAplicable,
|
|
153
|
+
intentos: intentosTotales,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export function rutaAbsolutaDeCaso(caso, corpus) {
|
|
157
|
+
return join(corpus, caso.ficheroRelativo);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=generar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generar.js","sourceRoot":"","sources":["../../../src/core/banco/generar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Orquesta la generación de casos: elige fichero, aplica una mutación,\n * construye el bloque único y lo valida RESOLVIÉNDOLO antes de admitirlo.\n *\n * Un caso ambiguo (el bloque no se puede hacer único, o resolverlo no\n * reproduce el fichero esperado byte a byte) se descarta y se cuenta — la\n * puerta de la tarea exige poder enseñar ese número, no solo el de casos\n * generados. Si `--casos 20` descarta cero, hay que poder decirlo y\n * sospechar, no callarlo.\n */\n\nimport { extname, join } from \"node:path\";\nimport { analizarCorpus, candidatosPara, type FicheroAnalizado, puntuarDificultad } from \"./analisis.ts\";\nimport { construirBloqueUnico, contarOcurrencias } from \"./bloques.ts\";\nimport { type CandidatoMutacion, TODAS_LAS_MUTACIONES } from \"./mutaciones.ts\";\nimport type { CasoBanco, ConjuntoCasos, Dificultad } from \"./tipos.ts\";\n\nconst DIFICULTADES_POR_DEFECTO: Dificultad[] = [\"facil\", \"medio\", \"dificil\", \"pesadilla\"];\nconst LENGUAJE: Record<string, string> = { \".ts\": \"ts\", \".tsx\": \"tsx\" };\n\n/** LCG determinista: misma semilla, misma secuencia de casos siempre. */\nexport function crearRngSemilla(semilla: number): () => number {\n\tlet estado = semilla >>> 0 || 1;\n\treturn () => {\n\t\testado = (estado * 1103515245 + 12345) & 0x7fffffff;\n\t\treturn estado / 0x7fffffff;\n\t};\n}\n\nfunction elegir<T>(lista: T[], rng: () => number): T {\n\treturn lista[Math.floor(rng() * lista.length)];\n}\n\n/** Región (fichero + línea) ya usada por otro caso, con margen para no solaparse. */\nfunction regionLibre(usadas: Map<string, number[]>, ruta: string, linea: number): boolean {\n\treturn !(usadas.get(ruta) ?? []).some((l) => Math.abs(l - linea) <= 3);\n}\nfunction marcarRegion(usadas: Map<string, number[]>, ruta: string, linea: number): void {\n\tconst lista = usadas.get(ruta) ?? [];\n\tlista.push(linea);\n\tusadas.set(ruta, lista);\n}\n\nfunction construirPrompt(\n\tfichero: FicheroAnalizado,\n\tdificultad: Dificultad,\n\tmutacionNombre: string,\n\tbloqueEntrada: string[],\n\tbloqueEsperado: string[],\n\tlineaInicio: number,\n\tesNightmare: boolean,\n): string {\n\tconst lenguaje = LENGUAJE[extname(fichero.relativa)] ?? \"\";\n\tconst descripciones: Record<string, string> = {\n\t\t\"invertir-booleano\": \"Un literal booleano está invertido.\",\n\t\t\"intercambiar-igualdad\": \"Un operador de igualdad está invertido (=== / !==).\",\n\t\t\"intercambiar-logico\": \"Un operador lógico es el que no toca (&& / ||).\",\n\t\t\"intercambiar-nullish\": \"Un `??` se cambió por `||` (o al revés).\",\n\t\t\"intercambiar-incremento\": \"Un incremento/decremento apunta al sentido contrario.\",\n\t\t\"quitar-negacion\": \"Se quitó una negación (`!`) que hacía falta.\",\n\t\t\"off-by-one\": \"Un límite numérico tiene un error de uno de más.\",\n\t};\n\tconst lineas: string[] = [\n\t\t`# Arregla un bug en \\`${fichero.relativa}\\``,\n\t\t\"\",\n\t\tdescripciones[mutacionNombre] ?? \"Hay un bug.\",\n\t];\n\tif (dificultad === \"facil\") lineas.push(\"\", `Está en la línea ${lineaInicio}.`);\n\n\tlineas.push(\n\t\t\"\",\n\t\t`Sustituye este bloque${dificultad === \"facil\" ? ` (empieza en la línea ${lineaInicio})` : \"\"}:`,\n\t\t\"\",\n\t);\n\tlineas.push(\n\t\t`\\`\\`\\`${lenguaje}`,\n\t\tbloqueEntrada.join(\"\\n\"),\n\t\t\"```\",\n\t\t\"\",\n\t\t\"por este:\",\n\t\t\"\",\n\t\t`\\`\\`\\`${lenguaje}`,\n\t\tbloqueEsperado.join(\"\\n\"),\n\t\t\"```\",\n\t);\n\tlineas.push(\n\t\t\"\",\n\t\tesNightmare\n\t\t\t? \"Este fichero tiene bloques casi idénticos en varios sitios: edita EXACTAMENTE el bloque de arriba, ninguno más.\"\n\t\t\t: \"Haz exactamente este cambio; no toques nada más.\",\n\t);\n\treturn lineas.join(\"\\n\");\n}\n\nexport interface OpcionesGeneracion {\n\tcorpus: string;\n\tnumCasos: number;\n\tsemilla?: number;\n\tdificultades?: Dificultad[];\n\tmutaciones?: typeof TODAS_LAS_MUTACIONES;\n}\n\nconst INTENTOS_POR_CASO = 80;\n\nexport function generarCasos(opciones: OpcionesGeneracion): ConjuntoCasos {\n\tconst semilla = opciones.semilla ?? 42;\n\tconst rng = crearRngSemilla(semilla);\n\tconst ficheros = analizarCorpus(opciones.corpus);\n\tconst dificultades = opciones.dificultades ?? DIFICULTADES_POR_DEFECTO;\n\tconst mutaciones = opciones.mutaciones ?? TODAS_LAS_MUTACIONES;\n\n\tconst usadas = new Map<string, number[]>();\n\tconst casos: CasoBanco[] = [];\n\tlet descartadosPorAmbiguos = 0;\n\tlet descartadosPorNoAplicable = 0;\n\tlet intentosTotales = 0;\n\n\tfor (let indice = 0; indice < opciones.numCasos; indice++) {\n\t\tconst dificultad = dificultades[indice % dificultades.length];\n\t\tconst candidatosFichero = candidatosPara(ficheros, dificultad);\n\t\tconst pool = candidatosFichero.length > 0 ? candidatosFichero : ficheros;\n\t\tif (pool.length === 0) break;\n\n\t\tlet generado: CasoBanco | null = null;\n\t\tfor (let intento = 0; intento < INTENTOS_POR_CASO && !generado; intento++) {\n\t\t\tintentosTotales++;\n\t\t\tconst fichero = elegir(pool, rng);\n\t\t\tconst mutacion = elegir(mutaciones, rng);\n\t\t\tconst candidatos = mutacion.candidatos(fichero.lineas);\n\t\t\tif (candidatos.length === 0) {\n\t\t\t\tdescartadosPorNoAplicable++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst cand: CandidatoMutacion = elegir(candidatos, rng);\n\t\t\tif (!regionLibre(usadas, fichero.ruta, cand.numeroLinea)) continue;\n\n\t\t\tif (dificultad === \"pesadilla\") {\n\t\t\t\tconst repetida = fichero.lineasRepetidas.has(cand.lineaOriginal.trim());\n\t\t\t\tif (!repetida) continue;\n\t\t\t}\n\n\t\t\tconst lineasEntrada = [...fichero.lineas];\n\t\t\tlineasEntrada[cand.numeroLinea - 1] = cand.lineaMutada;\n\t\t\tconst contenidoEntrada = `${lineasEntrada.join(\"\\n\")}`;\n\n\t\t\tconst bloque = construirBloqueUnico(fichero.lineas, lineasEntrada, cand.numeroLinea - 1);\n\t\t\tif (!bloque.unico) {\n\t\t\t\tdescartadosPorAmbiguos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Puerta obligatoria: nunca se admite un caso sin re-resolverlo desde\n\t\t\t// cero contra el fichero esperado.\n\t\t\tconst bloqueOk = contarOcurrencias(lineasEntrada, bloque.bloqueEntrada) === 1;\n\t\t\tconst resultado = bloqueOk\n\t\t\t\t? [\n\t\t\t\t\t\t...lineasEntrada.slice(0, bloque.lineaInicio - 1),\n\t\t\t\t\t\t...bloque.bloqueEsperado,\n\t\t\t\t\t\t...lineasEntrada.slice(bloque.lineaInicio - 1 + bloque.bloqueEntrada.length),\n\t\t\t\t\t].join(\"\\n\")\n\t\t\t\t: null;\n\t\t\tif (resultado !== fichero.contenido) {\n\t\t\t\tdescartadosPorAmbiguos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmarcarRegion(usadas, fichero.ruta, cand.numeroLinea);\n\t\t\tconst puntuacion = puntuarDificultad(fichero, cand.numeroLinea);\n\t\t\tconst id = `${dificultad}-${mutacion.nombre}-${String(indice + 1).padStart(3, \"0\")}`;\n\t\t\tgenerado = {\n\t\t\t\tid,\n\t\t\t\tdificultad,\n\t\t\t\tmutacion: mutacion.nombre,\n\t\t\t\tficheroRelativo: fichero.relativa,\n\t\t\t\tcontenidoEntrada,\n\t\t\t\tcontenidoEsperado: fichero.contenido,\n\t\t\t\tnumeroLinea: cand.numeroLinea,\n\t\t\t\tprompt: construirPrompt(\n\t\t\t\t\tfichero,\n\t\t\t\t\tdificultad,\n\t\t\t\t\tmutacion.nombre,\n\t\t\t\t\tbloque.bloqueEntrada,\n\t\t\t\t\tbloque.bloqueEsperado,\n\t\t\t\t\tbloque.lineaInicio,\n\t\t\t\t\tdificultad === \"pesadilla\",\n\t\t\t\t),\n\t\t\t\tpuntuacion,\n\t\t\t\tcontexto: {\n\t\t\t\t\tlineasFichero: fichero.lineas.length,\n\t\t\t\t\tesLineaRepetida: fichero.lineasRepetidas.has(cand.lineaOriginal.trim()),\n\t\t\t\t\tvecesRepetida: fichero.lineasRepetidas.get(cand.lineaOriginal.trim())?.length ?? 0,\n\t\t\t\t\tbloquesSimilares: fichero.bloquesSimilares,\n\t\t\t\t\tdensidad: Math.round(fichero.densidad * 1000) / 1000,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (generado) casos.push(generado);\n\t}\n\n\treturn {\n\t\tversion: 1,\n\t\tgeneradoEn: new Date().toISOString(),\n\t\tsemilla,\n\t\tcorpus: opciones.corpus,\n\t\tcasos,\n\t\tdescartadosPorAmbiguos,\n\t\tdescartadosPorNoAplicable,\n\t\tintentos: intentosTotales,\n\t};\n}\n\nexport function rutaAbsolutaDeCaso(caso: CasoBanco, corpus: string): string {\n\treturn join(corpus, caso.ficheroRelativo);\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catálogo de mutaciones: bugs deterministas de una línea.
|
|
3
|
+
*
|
|
4
|
+
* ponytail: mutaciones por regex sobre texto, no por AST (a diferencia de
|
|
5
|
+
* oh-my-pi, que parsea con Babel). Para medir precisión de EDICIÓN basta con
|
|
6
|
+
* un bug sintácticamente trivial en un sitio adverso — la dificultad la pone
|
|
7
|
+
* la selección de fichero y línea, no la sutileza del bug. Sube a un
|
|
8
|
+
* mutador AST si algún día hace falta que el bug sea semánticamente sutil
|
|
9
|
+
* (p.ej. no reventar con `!isFoo` dentro de un string).
|
|
10
|
+
*
|
|
11
|
+
* Cada mutación busca TODAS las posiciones aplicables en el fichero y una
|
|
12
|
+
* `rng` elige una: mismo fichero, misma semilla, mismo caso siempre.
|
|
13
|
+
*/
|
|
14
|
+
export interface CandidatoMutacion {
|
|
15
|
+
numeroLinea: number;
|
|
16
|
+
lineaOriginal: string;
|
|
17
|
+
lineaMutada: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Mutacion {
|
|
20
|
+
nombre: string;
|
|
21
|
+
/** Candidatos aplicables en el fichero (línea original -> línea con el bug). */
|
|
22
|
+
candidatos(lineas: string[]): CandidatoMutacion[];
|
|
23
|
+
}
|
|
24
|
+
export declare const TODAS_LAS_MUTACIONES: Mutacion[];
|
|
25
|
+
//# sourceMappingURL=mutaciones.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutaciones.d.ts","sourceRoot":"","sources":["../../../src/core/banco/mutaciones.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,kFAAgF;IAChF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;CAClD;AAkMD,eAAO,MAAM,oBAAoB,EAAE,QAAQ,EAQ1C,CAAC","sourcesContent":["/**\n * Catálogo de mutaciones: bugs deterministas de una línea.\n *\n * ponytail: mutaciones por regex sobre texto, no por AST (a diferencia de\n * oh-my-pi, que parsea con Babel). Para medir precisión de EDICIÓN basta con\n * un bug sintácticamente trivial en un sitio adverso — la dificultad la pone\n * la selección de fichero y línea, no la sutileza del bug. Sube a un\n * mutador AST si algún día hace falta que el bug sea semánticamente sutil\n * (p.ej. no reventar con `!isFoo` dentro de un string).\n *\n * Cada mutación busca TODAS las posiciones aplicables en el fichero y una\n * `rng` elige una: mismo fichero, misma semilla, mismo caso siempre.\n */\n\nexport interface CandidatoMutacion {\n\tnumeroLinea: number; // 1-based\n\tlineaOriginal: string;\n\tlineaMutada: string;\n}\n\nexport interface Mutacion {\n\tnombre: string;\n\t/** Candidatos aplicables en el fichero (línea original -> línea con el bug). */\n\tcandidatos(lineas: string[]): CandidatoMutacion[];\n}\n\n/**\n * Rangos [inicio, fin) de todo literal de cadena o de expresión regular en la\n * línea. Tokenizador de una pasada, no un parser: basta para decidir si una\n * posición cae DENTRO de un literal, que es todo lo que este módulo necesita.\n *\n * Encontrado auditando: la guarda anterior (`entreComillas`) solo miraba el\n * carácter pegado al match, así que `\"the value is true today\"` mutaba a\n * `\"...is false today\"` — el bug caía en medio de la cadena, no en su borde.\n * Y no cubría literales de regex en absoluto: `/-----BEGIN...KEY-----/`\n * (política de secretos en `core/computer/politica.ts`) se corrompía a\n * `--++-` sin que ninguna guarda lo viera venir.\n */\nfunction rangosDeLiterales(linea: string): Array<[number, number]> {\n\tconst rangos: Array<[number, number]> = [];\n\tlet i = 0;\n\twhile (i < linea.length) {\n\t\tconst ch = linea[i];\n\t\tif (ch === \"'\" || ch === '\"' || ch === \"`\") {\n\t\t\tconst inicio = i;\n\t\t\ti++;\n\t\t\twhile (i < linea.length && linea[i] !== ch) {\n\t\t\t\ti += linea[i] === \"\\\\\" ? 2 : 1;\n\t\t\t}\n\t\t\ti++; // consume la comilla de cierre (o el final de línea si no cierra)\n\t\t\trangos.push([inicio, i]);\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"/\" && linea[i + 1] !== \"/\" && linea[i + 1] !== \"*\") {\n\t\t\t// Heurística estándar de tokenizador: `/` abre regex salvo que el\n\t\t\t// carácter no-espacio anterior sugiera división (identificador,\n\t\t\t// número, `)` o `]`).\n\t\t\tconst anterior = linea.slice(0, i).trimEnd();\n\t\t\tconst esDivision = /[A-Za-z0-9_$)\\]]$/.test(anterior);\n\t\t\tif (!esDivision) {\n\t\t\t\tconst inicio = i;\n\t\t\t\ti++;\n\t\t\t\twhile (i < linea.length && linea[i] !== \"/\") {\n\t\t\t\t\ti += linea[i] === \"\\\\\" ? 2 : 1;\n\t\t\t\t}\n\t\t\t\ti++; // consume el `/` de cierre\n\t\t\t\twhile (i < linea.length && /[a-z]/i.test(linea[i])) i++; // flags\n\t\t\t\trangos.push([inicio, i]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\treturn rangos;\n}\n\n/** ¿El rango [inicio, fin) cae dentro de algún literal de cadena o regex de la línea? */\nfunction dentroDeLiteral(linea: string, inicio: number, fin: number): boolean {\n\treturn rangosDeLiterales(linea).some(([a, b]) => inicio < b && fin > a);\n}\n\n/**\n * Para cada línea, ¿es puramente comentario? Cubre `//` (ya cubierto antes)\n * Y `/* ... *\\/` de una o varias líneas — que NO estaba cubierto: una línea\n * JSDoc de una sola línea como `/** If true, ... *\\/` mutaba igual que\n * código real. Simplificación deliberada, igual que el resto del módulo:\n * trata la línea entera como comentario si EMPIEZA por `//` o `/*` tras\n * recortar espacios; no separa código y comentario en la misma línea\n * (`const x = 1; /* nota *\\/`), caso raro en este corpus con biome.\n */\nfunction lineasComentadas(lineas: string[]): boolean[] {\n\tconst resultado: boolean[] = [];\n\tlet dentroDeBloque = false;\n\tfor (const linea of lineas) {\n\t\tconst t = linea.trimStart();\n\t\tif (dentroDeBloque) {\n\t\t\tresultado.push(true);\n\t\t\tif (linea.includes(\"*/\")) dentroDeBloque = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (t.startsWith(\"//\")) {\n\t\t\tresultado.push(true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (t.startsWith(\"/*\")) {\n\t\t\tresultado.push(true);\n\t\t\tdentroDeBloque = !linea.includes(\"*/\", linea.indexOf(\"/*\") + 2);\n\t\t\tcontinue;\n\t\t}\n\t\tresultado.push(false);\n\t}\n\treturn resultado;\n}\n\nfunction candidatosPorPalabra(lineas: string[], palabra: string, reemplazo: string): CandidatoMutacion[] {\n\tconst re = new RegExp(`(?<![A-Za-z0-9_$])${palabra}(?![A-Za-z0-9_$])`, \"g\");\n\tconst comentadas = lineasComentadas(lineas);\n\tconst salida: CandidatoMutacion[] = [];\n\tlineas.forEach((linea, i) => {\n\t\tif (comentadas[i]) return;\n\t\tfor (const m of linea.matchAll(re)) {\n\t\t\tif (m.index === undefined) continue;\n\t\t\tif (dentroDeLiteral(linea, m.index, m.index + m[0].length)) continue;\n\t\t\tconst mutada = linea.slice(0, m.index) + reemplazo + linea.slice(m.index + m[0].length);\n\t\t\tsalida.push({ numeroLinea: i + 1, lineaOriginal: linea, lineaMutada: mutada });\n\t\t}\n\t});\n\treturn salida;\n}\n\nfunction candidatosPorToken(lineas: string[], token: string, reemplazo: string): CandidatoMutacion[] {\n\tconst comentadas = lineasComentadas(lineas);\n\tconst salida: CandidatoMutacion[] = [];\n\tlineas.forEach((linea, i) => {\n\t\tif (comentadas[i]) return;\n\t\tlet desde = 0;\n\t\tlet idx = linea.indexOf(token, desde);\n\t\twhile (idx !== -1) {\n\t\t\tif (!dentroDeLiteral(linea, idx, idx + token.length)) {\n\t\t\t\tconst mutada = linea.slice(0, idx) + reemplazo + linea.slice(idx + token.length);\n\t\t\t\tsalida.push({ numeroLinea: i + 1, lineaOriginal: linea, lineaMutada: mutada });\n\t\t\t}\n\t\t\tdesde = idx + token.length;\n\t\t\tidx = linea.indexOf(token, desde);\n\t\t}\n\t});\n\treturn salida;\n}\n\nconst invertirBooleano: Mutacion = {\n\tnombre: \"invertir-booleano\",\n\tcandidatos: (lineas) => [\n\t\t...candidatosPorPalabra(lineas, \"true\", \"false\"),\n\t\t...candidatosPorPalabra(lineas, \"false\", \"true\"),\n\t],\n};\n\nconst intercambiarIgualdad: Mutacion = {\n\tnombre: \"intercambiar-igualdad\",\n\tcandidatos: (lineas) => [...candidatosPorToken(lineas, \"===\", \"!==\"), ...candidatosPorToken(lineas, \"!==\", \"===\")],\n};\n\nconst intercambiarLogico: Mutacion = {\n\tnombre: \"intercambiar-logico\",\n\tcandidatos: (lineas) => [...candidatosPorToken(lineas, \"&&\", \"||\"), ...candidatosPorToken(lineas, \"||\", \"&&\")],\n};\n\nconst intercambiarNullish: Mutacion = {\n\tnombre: \"intercambiar-nullish\",\n\tcandidatos: (lineas) => candidatosPorToken(lineas, \"??\", \"||\"),\n};\n\nconst intercambiarIncremento: Mutacion = {\n\tnombre: \"intercambiar-incremento\",\n\tcandidatos: (lineas) => [...candidatosPorToken(lineas, \"++\", \"--\"), ...candidatosPorToken(lineas, \"--\", \"++\")],\n};\n\n/** `!identificador` -> `identificador`. Nunca toca `!=`/`!==` porque esos ya llevan un `=` detrás. */\nconst quitarNegacion: Mutacion = {\n\tnombre: \"quitar-negacion\",\n\tcandidatos: (lineas) => {\n\t\tconst re = /(?<![=!])!(?=[A-Za-z_$(])/g;\n\t\tconst comentadas = lineasComentadas(lineas);\n\t\tconst salida: CandidatoMutacion[] = [];\n\t\tlineas.forEach((linea, i) => {\n\t\t\tif (comentadas[i]) return;\n\t\t\tfor (const m of linea.matchAll(re)) {\n\t\t\t\tif (m.index === undefined) continue;\n\t\t\t\tif (dentroDeLiteral(linea, m.index, m.index + 1)) continue;\n\t\t\t\tconst mutada = linea.slice(0, m.index) + linea.slice(m.index + 1);\n\t\t\t\tsalida.push({ numeroLinea: i + 1, lineaOriginal: linea, lineaMutada: mutada });\n\t\t\t}\n\t\t});\n\t\treturn salida;\n\t},\n};\n\n/** Literal entero aislado (ni parte de un identificador ni de un decimal) +1. */\nconst offByOne: Mutacion = {\n\tnombre: \"off-by-one\",\n\tcandidatos: (lineas) => {\n\t\tconst re = /(?<![\\w.])(\\d+)(?![\\w.])/g;\n\t\tconst comentadas = lineasComentadas(lineas);\n\t\tconst salida: CandidatoMutacion[] = [];\n\t\tlineas.forEach((linea, i) => {\n\t\t\tif (comentadas[i]) return;\n\t\t\tfor (const m of linea.matchAll(re)) {\n\t\t\t\tif (m.index === undefined) continue;\n\t\t\t\tif (dentroDeLiteral(linea, m.index, m.index + m[0].length)) continue;\n\t\t\t\tconst valor = Number(m[1]);\n\t\t\t\tconst mutada = `${linea.slice(0, m.index)}${valor + 1}${linea.slice(m.index + m[0].length)}`;\n\t\t\t\tsalida.push({ numeroLinea: i + 1, lineaOriginal: linea, lineaMutada: mutada });\n\t\t\t}\n\t\t});\n\t\treturn salida;\n\t},\n};\n\nexport const TODAS_LAS_MUTACIONES: Mutacion[] = [\n\tinvertirBooleano,\n\tintercambiarIgualdad,\n\tintercambiarLogico,\n\tintercambiarNullish,\n\tintercambiarIncremento,\n\tquitarNegacion,\n\toffByOne,\n];\n"]}
|