@hoilab/ada-cli 0.84.21 → 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 +49 -2
- package/README.es.md +174 -0
- package/README.md +203 -658
- 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/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- 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/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- 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/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- 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/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- 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 +3 -2
- 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 +85 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +862 -78
- 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 +21 -8
- 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/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- 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/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- 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/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.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/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +21 -6
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.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/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- 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 +56 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +100 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- 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 +32 -50
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +21 -4
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +219 -55
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +0 -1
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +40 -12
- 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/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +41 -8
- 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/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +19 -7
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.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/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- 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/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.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/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.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 +58 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +326 -8
- 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/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- 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/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +156 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +255 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- 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 -12
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +234 -12
- 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 +28 -5
- 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/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.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/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- 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/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.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 +88 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +312 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +283 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- 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 +151 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +503 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +26 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +18 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +122 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +351 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +62 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +380 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- 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/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +191 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.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 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -13
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +26 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.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/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +9 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +56 -12
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +180 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +21 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +709 -75
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.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/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.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/ada-engine/SKILL.md +153 -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/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- 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/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- 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 +25 -10
- package/docs/compliance.md +241 -0
- package/docs/containerization.md +24 -24
- package/docs/custom-provider.md +15 -12
- package/docs/development.md +47 -10
- package/docs/docs.json +14 -2
- package/docs/environment-variables.md +20 -17
- package/docs/extensions.md +62 -51
- package/docs/index.md +15 -21
- package/docs/json.md +10 -5
- package/docs/keybindings.md +5 -5
- package/docs/llama-cpp.md +9 -7
- package/docs/models.md +18 -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 +21 -15
- 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 +47 -22
- package/docs/shell-aliases.md +2 -2
- package/docs/skills.md +14 -13
- 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/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/12-full-control.ts +9 -0
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +35 -261
- package/package.json +9 -3
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Libro de sesión — qué HIZO el agente, en una cadena de hashes verificable.
|
|
3
|
+
*
|
|
4
|
+
* `memory-engine/audit.ts` ya tenía el mecanismo: JSONL append-only donde cada
|
|
5
|
+
* entrada lleva el hash de la anterior, de modo que alterar un registro se
|
|
6
|
+
* detecta reverificando la cadena. Lo que no tenía era ALCANCE: solo lo usaba
|
|
7
|
+
* el motor de memoria, así que auditábamos escrituras de memoria y no
|
|
8
|
+
* ejecuciones de tool, llamadas al modelo, ficheros tocados ni comandos.
|
|
9
|
+
*
|
|
10
|
+
* Este módulo aplica el mismo mecanismo a lo que un DPO pregunta de verdad, que
|
|
11
|
+
* es el registro del artículo 12 del AI Act y el 30 del RGPD.
|
|
12
|
+
*
|
|
13
|
+
* Dos decisiones de diseño que conviene no deshacer sin pensarlo:
|
|
14
|
+
*
|
|
15
|
+
* 1. **Minimización por defecto.** El libro guarda la FORMA de lo que pasó, no
|
|
16
|
+
* su contenido: del fichero, su hash antes y después, nunca el texto. Un
|
|
17
|
+
* registro de cumplimiento que copiara los datos sería un segundo almacén de
|
|
18
|
+
* justo aquello que el RGPD quiere minimizar.
|
|
19
|
+
* 2. **Una sola canonicalización.** `memory-engine/audit.ts` construye la carga
|
|
20
|
+
* a hashear dos veces, en `append` y en `verify`, con dos listas de campos
|
|
21
|
+
* escritas a mano. Añadir un campo a una y olvidar la otra rompe la
|
|
22
|
+
* verificación en silencio y solo para las entradas nuevas. Aquí la
|
|
23
|
+
* verificación reconstruye la carga con un rest (`{hash, prevHash, ...resto}`),
|
|
24
|
+
* así que un campo nuevo entra solo y las dos caras no pueden divergir.
|
|
25
|
+
*/
|
|
26
|
+
import { createHash } from "node:crypto";
|
|
27
|
+
import { appendFileSync, linkSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
28
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
29
|
+
import { basename, join } from "node:path";
|
|
30
|
+
import { taparAntesDeEscribir } from "../privacidad/tapar.js";
|
|
31
|
+
import { ficherosPurgados } from "./retencion.js";
|
|
32
|
+
import { DIR_INDICE, DIR_SESION } from "./rutas.js";
|
|
33
|
+
/** Hash de un contenido de fichero. `null` = el fichero no existía. */
|
|
34
|
+
function hashContenido(texto) {
|
|
35
|
+
return texto === null ? null : createHash("sha256").update(texto).digest("hex").slice(0, 16);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Redacta cada hoja de texto por separado.
|
|
39
|
+
*
|
|
40
|
+
* Se hace hoja a hoja y no sobre el JSON ya serializado a propósito: un patrón
|
|
41
|
+
* que se pasara de largo sobre el texto serializado podría comerse una comilla
|
|
42
|
+
* y dejar el registro sin parsear. Sobre la hoja, lo peor que puede pasar es
|
|
43
|
+
* que redacte de más.
|
|
44
|
+
*/
|
|
45
|
+
function redactarHoja(valor) {
|
|
46
|
+
if (typeof valor === "string")
|
|
47
|
+
return taparAntesDeEscribir(valor, "strict");
|
|
48
|
+
if (Array.isArray(valor))
|
|
49
|
+
return valor.map(redactarHoja);
|
|
50
|
+
if (valor && typeof valor === "object") {
|
|
51
|
+
return Object.fromEntries(Object.entries(valor).map(([k, v]) => [k, redactarHoja(v)]));
|
|
52
|
+
}
|
|
53
|
+
return valor;
|
|
54
|
+
}
|
|
55
|
+
/** Pasa del suceso que da quien llama al registro que se guarda. */
|
|
56
|
+
function aRegistro(suceso) {
|
|
57
|
+
const base = suceso.tipo === "fichero"
|
|
58
|
+
? { ...suceso, antes: hashContenido(suceso.antes), despues: hashContenido(suceso.despues) }
|
|
59
|
+
: suceso;
|
|
60
|
+
return redactarHoja(base);
|
|
61
|
+
}
|
|
62
|
+
function hashDe(prevHash, carga) {
|
|
63
|
+
return createHash("sha256")
|
|
64
|
+
.update(JSON.stringify({ prevHash, ...carga }))
|
|
65
|
+
.digest("hex");
|
|
66
|
+
}
|
|
67
|
+
export class LibroDeSesion {
|
|
68
|
+
dir;
|
|
69
|
+
/** El índice: un enlace duro por fichero de sesión. Ver `DIR_INDICE`. */
|
|
70
|
+
dirIndice;
|
|
71
|
+
sesion;
|
|
72
|
+
seq = 0;
|
|
73
|
+
ultimoHash = null;
|
|
74
|
+
/** Fijado en la primera escritura por `reservarFichero`; no cambia despues. */
|
|
75
|
+
rutaFichero = null;
|
|
76
|
+
constructor(raiz, sesionId) {
|
|
77
|
+
this.dir = join(raiz, DIR_SESION);
|
|
78
|
+
this.dirIndice = join(raiz, DIR_INDICE);
|
|
79
|
+
this.sesion = sesionId;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Un fichero por sesión, no uno por día.
|
|
83
|
+
*
|
|
84
|
+
* Compartir fichero entre sesiones parecía más ordenado y hacía el libro
|
|
85
|
+
* INVERIFICABLE, cosa que solo se vio ejecutando: cada proceso arranca su
|
|
86
|
+
* `seq` en 1 y su hash anterior en `null`, así que tres sesiones seguidas
|
|
87
|
+
* dejaban tres cadenas encadenadas dentro del mismo fichero y `verificar`
|
|
88
|
+
* fallaba en la primera entrada de la segunda.
|
|
89
|
+
*
|
|
90
|
+
* Arreglarlo cargando el último hash al abrir no habría bastado: el CLI y el
|
|
91
|
+
* escritorio corren a la vez, y dos procesos que leyeran el mismo hash
|
|
92
|
+
* anterior escribirían dos entradas con el mismo `prevHash`.
|
|
93
|
+
*
|
|
94
|
+
* El límite que esto dejaba, y que era el agujero: borrar el fichero de una
|
|
95
|
+
* sesión entera no lo detecta la cadena, que solo ve la modificación DENTRO
|
|
96
|
+
* de una sesión. Se documentaba aquí mientras el veredicto seguía diciendo
|
|
97
|
+
* `valido: true` — o sea, un fallo que se leía como éxito en la pieza que se
|
|
98
|
+
* vende como prueba. Lo cierra el índice de `reservarFichero`.
|
|
99
|
+
*
|
|
100
|
+
* «Un fichero, un escritor» es la PRECONDICIÓN de todo lo anterior, y por eso
|
|
101
|
+
* `reservarFichero` la impone en vez de confiar en ella. Se rompía por dos
|
|
102
|
+
* caminos distintos, los dos encontrados sobre el libro real de esta máquina:
|
|
103
|
+
*
|
|
104
|
+
* 1. Dos escritores en un fichero. El escritorio usa el id fijo `desktop`,
|
|
105
|
+
* así que cada encarnación del proceso —cada recompilación de Next—
|
|
106
|
+
* abría el MISMO fichero creyéndose la primera y escribía otra entrada
|
|
107
|
+
* con `seq 1` y `prevHash null`. Encontrado en
|
|
108
|
+
* `sesion-2026-08-24-desktop.jsonl`: dos entradas, las dos `seq 1`.
|
|
109
|
+
* 2. Un escritor que cruza la medianoche. El nombre salía de la fecha de
|
|
110
|
+
* CADA entrada, así que a las 00:00 la sesión saltaba a un fichero nuevo
|
|
111
|
+
* cuya primera entrada llevaba el `prevHash` del fichero anterior —
|
|
112
|
+
* mientras `verificar` arranca cada fichero esperando `null`.
|
|
113
|
+
*
|
|
114
|
+
* Los dos daban `CADENA ALTERADA` sobre un libro que nadie había tocado. Y el
|
|
115
|
+
* daño no es el ruido: es que una alteración de verdad queda indistinguible
|
|
116
|
+
* del caso benigno, y un medidor que grita siempre deja de leerse.
|
|
117
|
+
*/
|
|
118
|
+
nombreBase(fecha) {
|
|
119
|
+
const id = this.sesion.replace(/[^a-zA-Z0-9-]/g, "_").slice(0, 40);
|
|
120
|
+
return `sesion-${fecha}-${id}.jsonl`;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Reserva el fichero de ESTA instancia, una sola vez, y no lo suelta.
|
|
124
|
+
*
|
|
125
|
+
* Fijarlo en la primera escritura mata el caso 2 de golpe: la sesión se queda
|
|
126
|
+
* en su fichero aunque cambie el día.
|
|
127
|
+
*
|
|
128
|
+
* Para el caso 1 se reclama el nombre con `wx` —crear-o-fallar—, que es
|
|
129
|
+
* atómico en el sistema de ficheros. Quien lo gana lo tiene; quien lo pierde
|
|
130
|
+
* prueba el siguiente. Así el «un escritor por fichero» deja de ser un
|
|
131
|
+
* acuerdo entre quienes llaman y pasa a ser cierto por construcción, incluso
|
|
132
|
+
* entre procesos distintos que no se conocen.
|
|
133
|
+
*
|
|
134
|
+
* Se prefiere partir en dos ficheros antes que leer la cola del ajeno y
|
|
135
|
+
* continuarlo: dos procesos que leyeran el mismo último hash escribirían dos
|
|
136
|
+
* entradas con el mismo `prevHash`, que es otra vez una cadena rota sin nadie
|
|
137
|
+
* manipulando nada. Dos ficheros íntegros son mejor que uno dudoso, y
|
|
138
|
+
* `verificar` ya los trata por separado.
|
|
139
|
+
*
|
|
140
|
+
* EL ANCLA. El nombre se reclama en el ÍNDICE y el fichero de `sesion/` es un
|
|
141
|
+
* ENLACE DURO al del índice, no una copia. Tres propiedades que hacen falta
|
|
142
|
+
* las tres:
|
|
143
|
+
*
|
|
144
|
+
* 1. `rm -rf sesion/` —el movimiento del agente que quiere tapar sus
|
|
145
|
+
* pasos— borra un NOMBRE, no el fichero: los bytes siguen ahí bajo el
|
|
146
|
+
* otro nombre, así que `verificar` no solo detecta la desaparición sino
|
|
147
|
+
* que puede seguir leyendo lo que se quiso esconder.
|
|
148
|
+
* 2. El ancla no puede desincronizarse del libro, porque no es un
|
|
149
|
+
* resumen que haya que mantener al día: es el mismo inodo. Un índice
|
|
150
|
+
* con su propio contador tendría que escribirse en cada anotación, y
|
|
151
|
+
* dos procesos escribiendo el mismo índice es la carrera que ya nos
|
|
152
|
+
* dejó el libro inverificable una vez.
|
|
153
|
+
* 3. El nombre se reclama en el índice y no en `sesion/`, así que un
|
|
154
|
+
* nombre gastado no se puede reutilizar aunque su fichero de sesión
|
|
155
|
+
* haya desaparecido. Sin esto, borrar y reescribir con una entrada
|
|
156
|
+
* dejaba el libro con el mismo aspecto que uno legítimo de una entrada.
|
|
157
|
+
*
|
|
158
|
+
* Hasta dónde llega, dicho sin adornos: quien borre los DOS directorios deja
|
|
159
|
+
* un libro vacío indistinguible de una instalación nueva. Contra eso está la
|
|
160
|
+
* otra mitad del trabajo —la política, que deniega la carpeta al agente
|
|
161
|
+
* incluso en `yolo`— y no un tercer ancla, porque un ancla que viva en el
|
|
162
|
+
* mismo disco y con los mismos permisos siempre se puede borrar igual. Lo que
|
|
163
|
+
* esto elimina es que un solo `rm` pase desapercibido.
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* El fichero que esta sesión está escribiendo, o `null` si aún no ha escrito.
|
|
167
|
+
*
|
|
168
|
+
* La purga lo necesita para no llevarse el suelo de un libro vivo, y tiene que
|
|
169
|
+
* saberlo por IDENTIDAD, no por fecha: fiarlo a «su última entrada es de hoy»
|
|
170
|
+
* deja el caso raro —un reloj movido, una sesión larga— rompiendo la cadena en
|
|
171
|
+
* memoria sin avisar.
|
|
172
|
+
*/
|
|
173
|
+
get ficheroEnCurso() {
|
|
174
|
+
return this.rutaFichero ? basename(this.rutaFichero) : null;
|
|
175
|
+
}
|
|
176
|
+
reservarFichero(fecha) {
|
|
177
|
+
if (this.rutaFichero)
|
|
178
|
+
return this.rutaFichero;
|
|
179
|
+
mkdirSync(this.dirIndice, { recursive: true });
|
|
180
|
+
const base = this.nombreBase(fecha);
|
|
181
|
+
for (let n = 1;; n++) {
|
|
182
|
+
const nombre = n === 1 ? base : base.replace(/\.jsonl$/, `-${n}.jsonl`);
|
|
183
|
+
const ancla = join(this.dirIndice, nombre);
|
|
184
|
+
try {
|
|
185
|
+
writeFileSync(ancla, "", { flag: "wx" });
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
if (error.code !== "EEXIST")
|
|
189
|
+
throw error;
|
|
190
|
+
continue; // nombre gastado (otro escritor, u otra ejecución): el siguiente
|
|
191
|
+
}
|
|
192
|
+
const ruta = join(this.dir, nombre);
|
|
193
|
+
try {
|
|
194
|
+
linkSync(ancla, ruta);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
// El nombre estaba libre en el índice pero ocupado en `sesion/`: es un
|
|
198
|
+
// libro escrito ANTES de que el índice existiera. Se suelta el ancla
|
|
199
|
+
// vacía y se prueba el siguiente nombre. Soltarla no es cosmético:
|
|
200
|
+
// dejar un ancla de 0 bytes junto a un fichero de sesión con
|
|
201
|
+
// contenido son dos inodos con el mismo nombre, y `verificar` lo
|
|
202
|
+
// leería como suplantación en toda instalación que se actualice.
|
|
203
|
+
rmSync(ancla, { force: true });
|
|
204
|
+
if (error.code === "EEXIST")
|
|
205
|
+
continue;
|
|
206
|
+
// Sin enlaces duros (FS exótico, montaje raro) el libro sigue
|
|
207
|
+
// funcionando SIN ancla, porque un libro que no se escribe es peor
|
|
208
|
+
// que uno sin ancla; `verificar` lo dirá como `sinAncla`, que es un
|
|
209
|
+
// tercer estado y no una acusación.
|
|
210
|
+
writeFileSync(ruta, "", { flag: "wx" });
|
|
211
|
+
}
|
|
212
|
+
this.rutaFichero = ruta;
|
|
213
|
+
return ruta;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Anota un suceso. Nunca lanza: un fallo del libro no puede tumbar la
|
|
218
|
+
* conversación, igual que en el audit del motor de memoria.
|
|
219
|
+
*/
|
|
220
|
+
anotar(suceso) {
|
|
221
|
+
// SÍNCRONO, y no es una simplificación perezosa: es lo correcto aquí.
|
|
222
|
+
//
|
|
223
|
+
// Antes esto encolaba una escritura asíncrona y devolvía la promesa, y casi
|
|
224
|
+
// todos los llamantes hacen `void libro.anotar(...)` — no la esperan, porque
|
|
225
|
+
// un fallo del libro no puede tumbar la conversación. Eso deja dos agujeros:
|
|
226
|
+
//
|
|
227
|
+
// 1. Las últimas entradas se pierden si el proceso termina antes de que
|
|
228
|
+
// la cola se vacíe. En un registro de cumplimiento, perder justo lo
|
|
229
|
+
// último que hizo el agente es perder lo que más se va a mirar.
|
|
230
|
+
// 2. Escrituras que aterrizan DESPUÉS de que la sesión se haya cerrado.
|
|
231
|
+
// Salió en una prueba de regresión de upstream: al borrar su
|
|
232
|
+
// directorio temporal, el libro seguía creando ficheros dentro y
|
|
233
|
+
// `rmSync` fallaba con ENOTEMPTY. La prueba pasaba en HEAD~1 y falló
|
|
234
|
+
// al fusionar el índice — el ancla ensanchó una carrera que ya existía.
|
|
235
|
+
//
|
|
236
|
+
// El coste está MEDIDO, y sale a favor: 40 µs por entrada en síncrono
|
|
237
|
+
// frente a 56 µs en asíncrono (1.000 escrituras de 268 bytes). Es más
|
|
238
|
+
// rápido porque para una escritura tan pequeña la promesa pesa más que el
|
|
239
|
+
// `write`. Y 40 µs contra una llamada a herramienta que tarda milisegundos
|
|
240
|
+
// o segundos no se nota.
|
|
241
|
+
//
|
|
242
|
+
// Además desaparece la cola entera: JavaScript es de un solo hilo, así que
|
|
243
|
+
// dos `anotar` seguidos ya no pueden leer el mismo `ultimoHash`. La carrera
|
|
244
|
+
// que la cola existía para evitar deja de ser posible por construcción, que
|
|
245
|
+
// es mejor que evitarla con disciplina.
|
|
246
|
+
//
|
|
247
|
+
// Se mantiene la firma `Promise<void>` para no tocar a los llamantes.
|
|
248
|
+
this.escribir(suceso);
|
|
249
|
+
return Promise.resolve();
|
|
250
|
+
}
|
|
251
|
+
escribir(suceso) {
|
|
252
|
+
try {
|
|
253
|
+
mkdirSync(this.dir, { recursive: true });
|
|
254
|
+
const carga = {
|
|
255
|
+
seq: ++this.seq,
|
|
256
|
+
ts: new Date().toISOString(),
|
|
257
|
+
sesion: this.sesion,
|
|
258
|
+
suceso: aRegistro(suceso),
|
|
259
|
+
};
|
|
260
|
+
const hash = hashDe(this.ultimoHash, carga);
|
|
261
|
+
const entrada = { ...carga, hash, prevHash: this.ultimoHash };
|
|
262
|
+
this.ultimoHash = hash;
|
|
263
|
+
const ruta = this.reservarFichero(carga.ts.slice(0, 10));
|
|
264
|
+
appendFileSync(ruta, `${JSON.stringify(entrada)}\n`, "utf-8");
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// El libro nunca rompe la sesión.
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async listar(dir) {
|
|
271
|
+
try {
|
|
272
|
+
return (await readdir(dir)).filter((f) => /^sesion-.*\.jsonl$/.test(f)).sort();
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Los ficheros del libro vistos desde los DOS directorios.
|
|
280
|
+
*
|
|
281
|
+
* Esta es la comparación que antes no existía: `readdir(sesion/)` solo puede
|
|
282
|
+
* contestar «lo que hay», nunca «lo que debería haber», y por eso un borrado
|
|
283
|
+
* salía como un libro vacío.
|
|
284
|
+
*/
|
|
285
|
+
async inventario() {
|
|
286
|
+
const enSesion = new Set(await this.listar(this.dir));
|
|
287
|
+
const enIndice = new Set(await this.listar(this.dirIndice));
|
|
288
|
+
const out = [];
|
|
289
|
+
for (const nombre of [...new Set([...enSesion, ...enIndice])].sort()) {
|
|
290
|
+
const s = enSesion.has(nombre);
|
|
291
|
+
const i = enIndice.has(nombre);
|
|
292
|
+
// Con los dos nombres presentes tienen que ser el MISMO inodo, porque
|
|
293
|
+
// así los creó `reservarFichero`. Si no lo son, alguien borró el de
|
|
294
|
+
// `sesion/` y puso otro en su sitio — y como el algoritmo de la cadena
|
|
295
|
+
// es público, ese otro puede tener una cadena interna perfecta. Sin
|
|
296
|
+
// esta comprobación la suplantación se leería como «cadena íntegra».
|
|
297
|
+
let suplantado = false;
|
|
298
|
+
if (s && i) {
|
|
299
|
+
try {
|
|
300
|
+
const [a, b] = await Promise.all([stat(join(this.dir, nombre)), stat(join(this.dirIndice, nombre))]);
|
|
301
|
+
suplantado = a.ino !== b.ino;
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// No se pudo mirar: no se acusa. «No lo he podido comprobar» no es
|
|
305
|
+
// «está manipulado», y el fichero se verifica igual más abajo.
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
out.push({
|
|
309
|
+
nombre,
|
|
310
|
+
// Se lee del índice cuando el de `sesion/` no está (es el caso del
|
|
311
|
+
// borrado) o cuando no coincide con él: el índice es el ancla.
|
|
312
|
+
ruta: s && !suplantado ? join(this.dir, nombre) : join(this.dirIndice, nombre),
|
|
313
|
+
falta: i && !s,
|
|
314
|
+
sinAncla: s && !i,
|
|
315
|
+
suplantado,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
/** Las últimas entradas, de la más reciente hacia atrás. */
|
|
321
|
+
async leer(limite = 50) {
|
|
322
|
+
const out = [];
|
|
323
|
+
for (const f of (await this.inventario()).reverse()) {
|
|
324
|
+
let crudo;
|
|
325
|
+
try {
|
|
326
|
+
// Por `f.ruta` y no por `sesion/`: las entradas de un fichero borrado
|
|
327
|
+
// sobreviven en el índice y quien investiga tiene que poder verlas.
|
|
328
|
+
crudo = await readFile(f.ruta, "utf-8");
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
for (const linea of crudo.split("\n").filter(Boolean).reverse()) {
|
|
334
|
+
try {
|
|
335
|
+
out.push(JSON.parse(linea));
|
|
336
|
+
if (out.length >= limite)
|
|
337
|
+
return out;
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
// Línea ilegible: la verificación es quien lo denuncia, no la lectura.
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return out;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Reverifica la cadena entera y contesta TRES estados, no dos.
|
|
348
|
+
*
|
|
349
|
+
* «Íntegra», «alterada» y «FALTA algo que debería estar». El tercero es el
|
|
350
|
+
* que faltaba: la cadena de hashes detecta la modificación DENTRO de un
|
|
351
|
+
* fichero y no puede, por construcción, notar la desaparición del fichero —
|
|
352
|
+
* para eso hace falta saber qué debería haber, que es lo que aporta el índice
|
|
353
|
+
* (ver `reservarFichero`).
|
|
354
|
+
*
|
|
355
|
+
* De la cadena rota devuelve en la PRIMERA entrada que no cuadra, y
|
|
356
|
+
* `comprobadas` cuenta las que sí cuadraban antes de ella — así el número
|
|
357
|
+
* dice dónde empieza la manipulación, no cuántas hay en total. Lo que ya se
|
|
358
|
+
* hubiera detectado como ausente viaja con esa respuesta: no se pierde por
|
|
359
|
+
* salir antes.
|
|
360
|
+
*/
|
|
361
|
+
async verificar() {
|
|
362
|
+
let comprobadas = 0;
|
|
363
|
+
const faltan = [];
|
|
364
|
+
const reinicios = [];
|
|
365
|
+
const sinAncla = [];
|
|
366
|
+
// Las lápidas se leen ANTES de recorrer: una purga anotada en el fichero de
|
|
367
|
+
// hoy explica un hueco de un fichero de hace un año.
|
|
368
|
+
const purgados = ficherosPurgados(await this.leer());
|
|
369
|
+
for (const f of await this.inventario()) {
|
|
370
|
+
if (f.suplantado) {
|
|
371
|
+
return {
|
|
372
|
+
valido: false,
|
|
373
|
+
comprobadas,
|
|
374
|
+
ficheroAlterado: f.nombre,
|
|
375
|
+
motivo: "el fichero de sesión ya no es el mismo que el del índice: lo han sustituido",
|
|
376
|
+
...(faltan.length ? { faltan } : {}),
|
|
377
|
+
...(sinAncla.length ? { sinAncla } : {}),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
// La cadena empieza de cero en CADA fichero, porque cada fichero es una
|
|
381
|
+
// sesión y su primera entrada lleva `prevHash: null`. Arrastrar el hash
|
|
382
|
+
// de un fichero al siguiente es lo que hacía fallar la verificación en
|
|
383
|
+
// cuanto había más de una sesión.
|
|
384
|
+
let prevHash = null;
|
|
385
|
+
let enEste = 0;
|
|
386
|
+
let crudo;
|
|
387
|
+
try {
|
|
388
|
+
crudo = await readFile(f.ruta, "utf-8");
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
return {
|
|
392
|
+
valido: false,
|
|
393
|
+
comprobadas,
|
|
394
|
+
ficheroAlterado: f.nombre,
|
|
395
|
+
motivo: "no se ha podido leer el fichero: no es «está bien», es «no lo sé»",
|
|
396
|
+
...(faltan.length ? { faltan } : {}),
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
for (const linea of crudo.split("\n").filter(Boolean)) {
|
|
400
|
+
let entrada;
|
|
401
|
+
try {
|
|
402
|
+
entrada = JSON.parse(linea);
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
return {
|
|
406
|
+
valido: false,
|
|
407
|
+
comprobadas,
|
|
408
|
+
ficheroAlterado: f.nombre,
|
|
409
|
+
motivo: "hay una línea que no es JSON válido",
|
|
410
|
+
...(faltan.length ? { faltan } : {}),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
// El rest es lo que impide que esta lista y la de `escribir`
|
|
414
|
+
// se separen: aquí no hay lista.
|
|
415
|
+
const { hash, prevHash: declarado, ...resto } = entrada;
|
|
416
|
+
// Se separan DOS preguntas que antes iban juntas y contestaban lo
|
|
417
|
+
// mismo, acusando siempre de lo primero:
|
|
418
|
+
//
|
|
419
|
+
// · ¿el hash cuadra con SU PROPIO contenido? Si no, alguien editó la
|
|
420
|
+
// entrada. Eso es manipulación y se dice así.
|
|
421
|
+
// · ¿su `prevHash` apunta a la entrada anterior? Si no, el enlace
|
|
422
|
+
// está roto, que es otra cosa: faltan entradas o están cambiadas
|
|
423
|
+
// de orden.
|
|
424
|
+
//
|
|
425
|
+
// Medido sobre el libro real de esta máquina: un fichero de dos
|
|
426
|
+
// entradas, las dos con `seq: 1` y `prevHash: null`, salía como «el
|
|
427
|
+
// hash de una entrada no cuadra con su contenido». Cuadraba
|
|
428
|
+
// perfectamente. Eran dos procesos del escritorio escribiendo el mismo
|
|
429
|
+
// fichero antes de que `reservarFichero` diera nombres distintos.
|
|
430
|
+
if (hash !== hashDe(declarado, resto)) {
|
|
431
|
+
return {
|
|
432
|
+
valido: false,
|
|
433
|
+
comprobadas,
|
|
434
|
+
alteradaEn: entrada.ts,
|
|
435
|
+
ficheroAlterado: f.nombre,
|
|
436
|
+
motivo: "el hash de una entrada no cuadra con su contenido: la han editado",
|
|
437
|
+
...(faltan.length ? { faltan } : {}),
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
if (declarado !== prevHash) {
|
|
441
|
+
// Una cadena que vuelve a empezar dentro del mismo fichero. Lo
|
|
442
|
+
// produce un reinicio del proceso —y lo produce igual quien quite
|
|
443
|
+
// entradas del medio y escriba una cadena nueva—. Desde el fichero
|
|
444
|
+
// no se distinguen, así que NO se llama manipulación ni se da por
|
|
445
|
+
// bueno: es el tercer estado, y se dice entero en `reinicios`.
|
|
446
|
+
if (declarado === null && prevHash !== null) {
|
|
447
|
+
reinicios.push({ fichero: f.nombre, ts: entrada.ts, entradasAntes: enEste });
|
|
448
|
+
prevHash = hash;
|
|
449
|
+
comprobadas++;
|
|
450
|
+
enEste++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
return {
|
|
454
|
+
valido: false,
|
|
455
|
+
comprobadas,
|
|
456
|
+
alteradaEn: entrada.ts,
|
|
457
|
+
ficheroAlterado: f.nombre,
|
|
458
|
+
motivo: "el enlace de una entrada no apunta a la anterior: faltan entradas o están cambiadas de orden",
|
|
459
|
+
...(faltan.length ? { faltan } : {}),
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
prevHash = hash;
|
|
463
|
+
comprobadas++;
|
|
464
|
+
enEste++;
|
|
465
|
+
}
|
|
466
|
+
// Un fichero VACÍO que falta no es una ausencia: es una reserva de
|
|
467
|
+
// nombre que nunca llegó a escribirse (la sesión murió entre reservar y
|
|
468
|
+
// anotar). Contarlo habría hecho que una sesión nueva y legítima, sin
|
|
469
|
+
// una sola entrada todavía, se reportara como manipulada — la mitad que
|
|
470
|
+
// decide, porque un detector que grita siempre no distingue nada.
|
|
471
|
+
if (enEste === 0)
|
|
472
|
+
continue;
|
|
473
|
+
// Un hueco EXPLICADO no es una manipulación.
|
|
474
|
+
//
|
|
475
|
+
// Si el propio libro lleva una lápida diciendo que ese fichero se purgó
|
|
476
|
+
// —cuándo, cuántas entradas, bajo qué política y con qué hash de
|
|
477
|
+
// cierre—, la ausencia es un hecho declarado y no una desaparición. Sin
|
|
478
|
+
// esto, cumplir el art. 5.1.e del RGPD hacía que `verificar` contestara
|
|
479
|
+
// «alguien los ha borrado»: la ley nos acusaba de manipular. Ver
|
|
480
|
+
// `audit/retencion.ts`.
|
|
481
|
+
if (f.falta && !purgados.has(f.nombre))
|
|
482
|
+
faltan.push({ fichero: f.nombre, entradas: enEste });
|
|
483
|
+
if (f.sinAncla)
|
|
484
|
+
sinAncla.push(f.nombre);
|
|
485
|
+
}
|
|
486
|
+
// Las lápidas se enseñan TODAS, no solo las que tapan un hueco del
|
|
487
|
+
// inventario. Una purga completa se lleva el fichero Y su ancla, así que no
|
|
488
|
+
// deja hueco ninguno: si solo se informara de las que explican una ausencia,
|
|
489
|
+
// el caso normal —el que de verdad ocurre— saldría mudo y el DPO leería
|
|
490
|
+
// «cadena íntegra, 1 entrada» sin enterarse de que se purgaron tres. Que es
|
|
491
|
+
// exactamente el «desaparece sin rastro» que este mecanismo existe para
|
|
492
|
+
// impedir.
|
|
493
|
+
const explicados = [...purgados.values()].map((l) => ({
|
|
494
|
+
fichero: l.fichero,
|
|
495
|
+
entradas: l.entradas,
|
|
496
|
+
politica: l.politica,
|
|
497
|
+
}));
|
|
498
|
+
return {
|
|
499
|
+
valido: faltan.length === 0,
|
|
500
|
+
...(explicados.length ? { purgados: explicados } : {}),
|
|
501
|
+
...(reinicios.length ? { reinicios } : {}),
|
|
502
|
+
comprobadas,
|
|
503
|
+
...(faltan.length ? { faltan } : {}),
|
|
504
|
+
...(sinAncla.length ? { sinAncla } : {}),
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
//# sourceMappingURL=libro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"libro.js","sourceRoot":"","sources":["../../../src/core/audit/libro.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Libro de sesión — qué HIZO el agente, en una cadena de hashes verificable.\n *\n * `memory-engine/audit.ts` ya tenía el mecanismo: JSONL append-only donde cada\n * entrada lleva el hash de la anterior, de modo que alterar un registro se\n * detecta reverificando la cadena. Lo que no tenía era ALCANCE: solo lo usaba\n * el motor de memoria, así que auditábamos escrituras de memoria y no\n * ejecuciones de tool, llamadas al modelo, ficheros tocados ni comandos.\n *\n * Este módulo aplica el mismo mecanismo a lo que un DPO pregunta de verdad, que\n * es el registro del artículo 12 del AI Act y el 30 del RGPD.\n *\n * Dos decisiones de diseño que conviene no deshacer sin pensarlo:\n *\n * 1. **Minimización por defecto.** El libro guarda la FORMA de lo que pasó, no\n * su contenido: del fichero, su hash antes y después, nunca el texto. Un\n * registro de cumplimiento que copiara los datos sería un segundo almacén de\n * justo aquello que el RGPD quiere minimizar.\n * 2. **Una sola canonicalización.** `memory-engine/audit.ts` construye la carga\n * a hashear dos veces, en `append` y en `verify`, con dos listas de campos\n * escritas a mano. Añadir un campo a una y olvidar la otra rompe la\n * verificación en silencio y solo para las entradas nuevas. Aquí la\n * verificación reconstruye la carga con un rest (`{hash, prevHash, ...resto}`),\n * así que un campo nuevo entra solo y las dos caras no pueden divergir.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { appendFileSync, linkSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport { taparAntesDeEscribir } from \"../privacidad/tapar.ts\";\nimport { ficherosPurgados } from \"./retencion.ts\";\nimport { DIR_INDICE, DIR_SESION } from \"./rutas.ts\";\n\n/** Lo que se le puede pedir al libro que anote. */\nexport type SucesoDeSesion =\n\t| { tipo: \"tool\"; nombre: string; ok: boolean; decision?: string; motivo?: string }\n\t| {\n\t\t\ttipo: \"modelo\";\n\t\t\tproveedor: string;\n\t\t\tmodelo: string;\n\t\t\tentrada: number;\n\t\t\tsalida: number;\n\t\t\tcoste?: number;\n\t\t\t/** `stop`, `toolUse`, `error`, `aborted`… Un fallo del modelo también es auditable. */\n\t\t\tmotivoParada?: string;\n\t }\n\t| {\n\t\t\ttipo: \"comando\";\n\t\t\targv: string[];\n\t\t\tcodigo: number;\n\t\t\tsandbox?: \"permitido\" | \"bloqueado\";\n\t\t\tviolaciones?: string[];\n\t\t\t/**\n\t\t\t * Quién escribió el comando: el agente (por defecto, si se omite), el\n\t\t\t * usuario desde la terminal integrada del escritorio, o una extensión\n\t\t\t * a través de `pi.exec`.\n\t\t\t *\n\t\t\t * La terminal ejecuta lo que el usuario teclea SIN pasar por la\n\t\t\t * política de aprobación — es su shell, no la del agente — así que este\n\t\t\t * campo es lo único que evita que un registro de cumplimiento confunda\n\t\t\t * \"lo que decidió el agente\" con \"lo que tecleó la persona\". Omitirlo\n\t\t\t * en vez de dar por defecto \"agente\" habría dejado pasar en silencio\n\t\t\t * una terminal que se le olvida anotarse.\n\t\t\t *\n\t\t\t * `extension` es el tercer estado, y hasta hoy faltaba: `pi.exec` no\n\t\t\t * pasaba por la política NI dejaba rastro, así que una extensión leía\n\t\t\t * el vault y el libro no lo sabía. Atribuirlo al \"agente\" habría sido\n\t\t\t * peor que no anotarlo: quien audite tiene que poder distinguir lo que\n\t\t\t * decidió el modelo de lo que hizo código de terceros cargado en el\n\t\t\t * proceso.\n\t\t\t */\n\t\t\torigen?: \"agente\" | \"usuario\" | \"extension\";\n\t\t\t/** Ruta de la extensión, cuando `origen` es `extension`. Sin ella el aviso no es accionable. */\n\t\t\textension?: string;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * Una purga por retención, anotada como HECHO en vez de dejada como\n\t\t\t * hueco. Sin esto, cumplir el art. 5.1.e del RGPD hacía que\n\t\t\t * `verificar` acusara de manipulación; y borrar también el índice\n\t\t\t * hacía desaparecer la purga sin rastro. Ver `audit/retencion.ts`.\n\t\t\t */\n\t\t\ttipo: \"purga\";\n\t\t\tfichero: string;\n\t\t\tentradas: number;\n\t\t\tdesde: string;\n\t\t\thasta: string;\n\t\t\thashDeCierre: string;\n\t\t\tpolitica: string;\n\t }\n\t| { tipo: \"fichero\"; ruta: string; antes: string | null; despues: string | null; tool: string }\n\t| { tipo: \"red\"; dominio: string; permitido: boolean; motivo?: string }\n\t| {\n\t\t\t/** El broker de credenciales (core/credenciales/) es lo que oh-my-pi no\n\t\t\t * tiene: un registro de quién usó qué cuenta y cuándo. `accion` distingue\n\t\t\t * PEDIR una credencial de REPORTAR cómo fue usarla. */\n\t\t\ttipo: \"credencial\";\n\t\t\taccion: \"resuelta\" | \"uso\";\n\t\t\tproveedor: string;\n\t\t\t/** `null` en \"resuelta\" = no había ninguna credencial activa (no es que fallara el libro). */\n\t\t\tcredencialId: string | null;\n\t\t\t/** \"ok\" | \"sin-credencial-activa\" | una `ClaseDeError` de errores/proveedor.ts. */\n\t\t\tresultado: string;\n\t\t\tcliente?: string;\n\t };\n\nexport interface EntradaDelLibro {\n\tseq: number;\n\tts: string;\n\tsesion: string;\n\tsuceso: Record<string, unknown>;\n\thash: string;\n\tprevHash: string | null;\n}\n\nexport interface Veredicto {\n\tvalido: boolean;\n\tcomprobadas: number;\n\t/** Sello de tiempo de la primera entrada que no cuadra. */\n\talteradaEn?: string;\n\t/**\n\t * Fichero donde está esa entrada.\n\t *\n\t * Sin esto el veredicto decía «alterada en la del 03:09:55» sobre un\n\t * directorio con 26 ficheros de sesión: cierto, verificable y no accionable.\n\t * Quien recibe un aviso de manipulación necesita saber DÓNDE mirar, o el\n\t * aviso se queda en susto.\n\t */\n\tficheroAlterado?: string;\n\t/**\n\t * Por qué no verifica, en una frase estable.\n\t *\n\t * Existe para no confundir «lo he mirado y no cuadra» con «no lo he podido\n\t * mirar»: un fichero ilegible y un hash que no coincide daban el mismo\n\t * veredicto y el mismo mensaje, y son dos cosas distintas para quien\n\t * responde a una auditoría.\n\t */\n\tmotivo?: string;\n\t/**\n\t * Lo que FALTA: ficheros que el índice recuerda y que ya no están en\n\t * `sesion/`, con cuántas entradas tenía cada uno.\n\t *\n\t * Es el tercer estado, y es el que faltaba. Antes de esto la cadena\n\t * distinguía «íntegra» de «alterada» y nada más, así que borrar el fichero\n\t * entero —lo que haría un agente tapando sus pasos— salía como\n\t * `{valido: true, comprobadas: 0}`: un fallo que se lee como éxito en la\n\t * pieza que se vende como prueba. Medido ejecutando el CLI: con tres\n\t * comandos anotados decía «cadena íntegra: 3 entradas», y tras un `rm`\n\t * decía «el libro está vacío» y salía con código 0.\n\t */\n\tfaltan?: { fichero: string; entradas: number }[];\n\t/**\n\t * Ficheros que ya no están y cuya ausencia el libro EXPLICA con una lápida\n\t * de purga. No cuentan como manipulación: son el art. 5.1.e cumplido.\n\t */\n\tpurgados?: { fichero: string; entradas: number; politica: string }[];\n\t/**\n\t * Sitios donde la cadena vuelve a empezar dentro de un mismo fichero.\n\t *\n\t * Ni íntegro ni alterado: el TERCER estado. Un reinicio del proceso lo\n\t * produce, y quien quite entradas del medio y escriba una cadena nueva\n\t * produce exactamente lo mismo. Desde el fichero no se distinguen, así que se\n\t * dice dónde está y se deja que lo juzgue quien audita, en vez de acusar o de\n\t * absolver por nuestra cuenta.\n\t */\n\treinicios?: { fichero: string; ts: string; entradasAntes: number }[];\n\t/**\n\t * Ficheros presentes en `sesion/` sin ancla en el índice.\n\t *\n\t * NO cuenta como manipulación y por eso va aparte de `faltan`: son los\n\t * libros escritos antes de que el índice existiera, y también lo que queda\n\t * en un sistema de ficheros sin enlaces duros. Meterlo en `valido: false`\n\t * habría hecho que toda instalación ya existente gritara «manipulado» el\n\t * día de la actualización — un detector que grita siempre no vale, y\n\t * además volvería indistinguible la manipulación real.\n\t */\n\tsinAncla?: string[];\n}\n\n/** Un fichero del libro, mirado desde los dos directorios a la vez. */\ninterface FicheroDelLibro {\n\tnombre: string;\n\t/** De dónde se leen las entradas: la copia que exista. */\n\truta: string;\n\t/** Está en el índice y ya NO en `sesion/`: alguien lo borró. */\n\tfalta: boolean;\n\t/** Está en `sesion/` y no en el índice: libro antiguo o FS sin enlaces duros. */\n\tsinAncla: boolean;\n\t/** Están los dos nombres pero NO son el mismo fichero: sustitución. */\n\tsuplantado: boolean;\n}\n\n/** Hash de un contenido de fichero. `null` = el fichero no existía. */\nfunction hashContenido(texto: string | null): string | null {\n\treturn texto === null ? null : createHash(\"sha256\").update(texto).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Redacta cada hoja de texto por separado.\n *\n * Se hace hoja a hoja y no sobre el JSON ya serializado a propósito: un patrón\n * que se pasara de largo sobre el texto serializado podría comerse una comilla\n * y dejar el registro sin parsear. Sobre la hoja, lo peor que puede pasar es\n * que redacte de más.\n */\nfunction redactarHoja(valor: unknown): unknown {\n\tif (typeof valor === \"string\") return taparAntesDeEscribir(valor, \"strict\");\n\tif (Array.isArray(valor)) return valor.map(redactarHoja);\n\tif (valor && typeof valor === \"object\") {\n\t\treturn Object.fromEntries(Object.entries(valor).map(([k, v]) => [k, redactarHoja(v)]));\n\t}\n\treturn valor;\n}\n\n/** Pasa del suceso que da quien llama al registro que se guarda. */\nfunction aRegistro(suceso: SucesoDeSesion): Record<string, unknown> {\n\tconst base =\n\t\tsuceso.tipo === \"fichero\"\n\t\t\t? { ...suceso, antes: hashContenido(suceso.antes), despues: hashContenido(suceso.despues) }\n\t\t\t: suceso;\n\treturn redactarHoja(base) as Record<string, unknown>;\n}\n\nfunction hashDe(prevHash: string | null, carga: Omit<EntradaDelLibro, \"hash\" | \"prevHash\">): string {\n\treturn createHash(\"sha256\")\n\t\t.update(JSON.stringify({ prevHash, ...carga }))\n\t\t.digest(\"hex\");\n}\n\nexport class LibroDeSesion {\n\tprivate readonly dir: string;\n\t/** El índice: un enlace duro por fichero de sesión. Ver `DIR_INDICE`. */\n\tprivate readonly dirIndice: string;\n\tprivate readonly sesion: string;\n\tprivate seq = 0;\n\tprivate ultimoHash: string | null = null;\n\t/** Fijado en la primera escritura por `reservarFichero`; no cambia despues. */\n\tprivate rutaFichero: string | null = null;\n\n\tconstructor(raiz: string, sesionId: string) {\n\t\tthis.dir = join(raiz, DIR_SESION);\n\t\tthis.dirIndice = join(raiz, DIR_INDICE);\n\t\tthis.sesion = sesionId;\n\t}\n\n\t/**\n\t * Un fichero por sesión, no uno por día.\n\t *\n\t * Compartir fichero entre sesiones parecía más ordenado y hacía el libro\n\t * INVERIFICABLE, cosa que solo se vio ejecutando: cada proceso arranca su\n\t * `seq` en 1 y su hash anterior en `null`, así que tres sesiones seguidas\n\t * dejaban tres cadenas encadenadas dentro del mismo fichero y `verificar`\n\t * fallaba en la primera entrada de la segunda.\n\t *\n\t * Arreglarlo cargando el último hash al abrir no habría bastado: el CLI y el\n\t * escritorio corren a la vez, y dos procesos que leyeran el mismo hash\n\t * anterior escribirían dos entradas con el mismo `prevHash`.\n\t *\n\t * El límite que esto dejaba, y que era el agujero: borrar el fichero de una\n\t * sesión entera no lo detecta la cadena, que solo ve la modificación DENTRO\n\t * de una sesión. Se documentaba aquí mientras el veredicto seguía diciendo\n\t * `valido: true` — o sea, un fallo que se leía como éxito en la pieza que se\n\t * vende como prueba. Lo cierra el índice de `reservarFichero`.\n\t *\n\t * «Un fichero, un escritor» es la PRECONDICIÓN de todo lo anterior, y por eso\n\t * `reservarFichero` la impone en vez de confiar en ella. Se rompía por dos\n\t * caminos distintos, los dos encontrados sobre el libro real de esta máquina:\n\t *\n\t * 1. Dos escritores en un fichero. El escritorio usa el id fijo `desktop`,\n\t * así que cada encarnación del proceso —cada recompilación de Next—\n\t * abría el MISMO fichero creyéndose la primera y escribía otra entrada\n\t * con `seq 1` y `prevHash null`. Encontrado en\n\t * `sesion-2026-08-24-desktop.jsonl`: dos entradas, las dos `seq 1`.\n\t * 2. Un escritor que cruza la medianoche. El nombre salía de la fecha de\n\t * CADA entrada, así que a las 00:00 la sesión saltaba a un fichero nuevo\n\t * cuya primera entrada llevaba el `prevHash` del fichero anterior —\n\t * mientras `verificar` arranca cada fichero esperando `null`.\n\t *\n\t * Los dos daban `CADENA ALTERADA` sobre un libro que nadie había tocado. Y el\n\t * daño no es el ruido: es que una alteración de verdad queda indistinguible\n\t * del caso benigno, y un medidor que grita siempre deja de leerse.\n\t */\n\tprivate nombreBase(fecha: string): string {\n\t\tconst id = this.sesion.replace(/[^a-zA-Z0-9-]/g, \"_\").slice(0, 40);\n\t\treturn `sesion-${fecha}-${id}.jsonl`;\n\t}\n\n\t/**\n\t * Reserva el fichero de ESTA instancia, una sola vez, y no lo suelta.\n\t *\n\t * Fijarlo en la primera escritura mata el caso 2 de golpe: la sesión se queda\n\t * en su fichero aunque cambie el día.\n\t *\n\t * Para el caso 1 se reclama el nombre con `wx` —crear-o-fallar—, que es\n\t * atómico en el sistema de ficheros. Quien lo gana lo tiene; quien lo pierde\n\t * prueba el siguiente. Así el «un escritor por fichero» deja de ser un\n\t * acuerdo entre quienes llaman y pasa a ser cierto por construcción, incluso\n\t * entre procesos distintos que no se conocen.\n\t *\n\t * Se prefiere partir en dos ficheros antes que leer la cola del ajeno y\n\t * continuarlo: dos procesos que leyeran el mismo último hash escribirían dos\n\t * entradas con el mismo `prevHash`, que es otra vez una cadena rota sin nadie\n\t * manipulando nada. Dos ficheros íntegros son mejor que uno dudoso, y\n\t * `verificar` ya los trata por separado.\n\t *\n\t * EL ANCLA. El nombre se reclama en el ÍNDICE y el fichero de `sesion/` es un\n\t * ENLACE DURO al del índice, no una copia. Tres propiedades que hacen falta\n\t * las tres:\n\t *\n\t * 1. `rm -rf sesion/` —el movimiento del agente que quiere tapar sus\n\t * pasos— borra un NOMBRE, no el fichero: los bytes siguen ahí bajo el\n\t * otro nombre, así que `verificar` no solo detecta la desaparición sino\n\t * que puede seguir leyendo lo que se quiso esconder.\n\t * 2. El ancla no puede desincronizarse del libro, porque no es un\n\t * resumen que haya que mantener al día: es el mismo inodo. Un índice\n\t * con su propio contador tendría que escribirse en cada anotación, y\n\t * dos procesos escribiendo el mismo índice es la carrera que ya nos\n\t * dejó el libro inverificable una vez.\n\t * 3. El nombre se reclama en el índice y no en `sesion/`, así que un\n\t * nombre gastado no se puede reutilizar aunque su fichero de sesión\n\t * haya desaparecido. Sin esto, borrar y reescribir con una entrada\n\t * dejaba el libro con el mismo aspecto que uno legítimo de una entrada.\n\t *\n\t * Hasta dónde llega, dicho sin adornos: quien borre los DOS directorios deja\n\t * un libro vacío indistinguible de una instalación nueva. Contra eso está la\n\t * otra mitad del trabajo —la política, que deniega la carpeta al agente\n\t * incluso en `yolo`— y no un tercer ancla, porque un ancla que viva en el\n\t * mismo disco y con los mismos permisos siempre se puede borrar igual. Lo que\n\t * esto elimina es que un solo `rm` pase desapercibido.\n\t */\n\t/**\n\t * El fichero que esta sesión está escribiendo, o `null` si aún no ha escrito.\n\t *\n\t * La purga lo necesita para no llevarse el suelo de un libro vivo, y tiene que\n\t * saberlo por IDENTIDAD, no por fecha: fiarlo a «su última entrada es de hoy»\n\t * deja el caso raro —un reloj movido, una sesión larga— rompiendo la cadena en\n\t * memoria sin avisar.\n\t */\n\tget ficheroEnCurso(): string | null {\n\t\treturn this.rutaFichero ? basename(this.rutaFichero) : null;\n\t}\n\n\tprivate reservarFichero(fecha: string): string {\n\t\tif (this.rutaFichero) return this.rutaFichero;\n\t\tmkdirSync(this.dirIndice, { recursive: true });\n\t\tconst base = this.nombreBase(fecha);\n\t\tfor (let n = 1; ; n++) {\n\t\t\tconst nombre = n === 1 ? base : base.replace(/\\.jsonl$/, `-${n}.jsonl`);\n\t\t\tconst ancla = join(this.dirIndice, nombre);\n\t\t\ttry {\n\t\t\t\twriteFileSync(ancla, \"\", { flag: \"wx\" });\n\t\t\t} catch (error) {\n\t\t\t\tif ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n\t\t\t\tcontinue; // nombre gastado (otro escritor, u otra ejecución): el siguiente\n\t\t\t}\n\t\t\tconst ruta = join(this.dir, nombre);\n\t\t\ttry {\n\t\t\t\tlinkSync(ancla, ruta);\n\t\t\t} catch (error) {\n\t\t\t\t// El nombre estaba libre en el índice pero ocupado en `sesion/`: es un\n\t\t\t\t// libro escrito ANTES de que el índice existiera. Se suelta el ancla\n\t\t\t\t// vacía y se prueba el siguiente nombre. Soltarla no es cosmético:\n\t\t\t\t// dejar un ancla de 0 bytes junto a un fichero de sesión con\n\t\t\t\t// contenido son dos inodos con el mismo nombre, y `verificar` lo\n\t\t\t\t// leería como suplantación en toda instalación que se actualice.\n\t\t\t\trmSync(ancla, { force: true });\n\t\t\t\tif ((error as NodeJS.ErrnoException).code === \"EEXIST\") continue;\n\t\t\t\t// Sin enlaces duros (FS exótico, montaje raro) el libro sigue\n\t\t\t\t// funcionando SIN ancla, porque un libro que no se escribe es peor\n\t\t\t\t// que uno sin ancla; `verificar` lo dirá como `sinAncla`, que es un\n\t\t\t\t// tercer estado y no una acusación.\n\t\t\t\twriteFileSync(ruta, \"\", { flag: \"wx\" });\n\t\t\t}\n\t\t\tthis.rutaFichero = ruta;\n\t\t\treturn ruta;\n\t\t}\n\t}\n\n\t/**\n\t * Anota un suceso. Nunca lanza: un fallo del libro no puede tumbar la\n\t * conversación, igual que en el audit del motor de memoria.\n\t */\n\tanotar(suceso: SucesoDeSesion): Promise<void> {\n\t\t// SÍNCRONO, y no es una simplificación perezosa: es lo correcto aquí.\n\t\t//\n\t\t// Antes esto encolaba una escritura asíncrona y devolvía la promesa, y casi\n\t\t// todos los llamantes hacen `void libro.anotar(...)` — no la esperan, porque\n\t\t// un fallo del libro no puede tumbar la conversación. Eso deja dos agujeros:\n\t\t//\n\t\t// 1. Las últimas entradas se pierden si el proceso termina antes de que\n\t\t// la cola se vacíe. En un registro de cumplimiento, perder justo lo\n\t\t// último que hizo el agente es perder lo que más se va a mirar.\n\t\t// 2. Escrituras que aterrizan DESPUÉS de que la sesión se haya cerrado.\n\t\t// Salió en una prueba de regresión de upstream: al borrar su\n\t\t// directorio temporal, el libro seguía creando ficheros dentro y\n\t\t// `rmSync` fallaba con ENOTEMPTY. La prueba pasaba en HEAD~1 y falló\n\t\t// al fusionar el índice — el ancla ensanchó una carrera que ya existía.\n\t\t//\n\t\t// El coste está MEDIDO, y sale a favor: 40 µs por entrada en síncrono\n\t\t// frente a 56 µs en asíncrono (1.000 escrituras de 268 bytes). Es más\n\t\t// rápido porque para una escritura tan pequeña la promesa pesa más que el\n\t\t// `write`. Y 40 µs contra una llamada a herramienta que tarda milisegundos\n\t\t// o segundos no se nota.\n\t\t//\n\t\t// Además desaparece la cola entera: JavaScript es de un solo hilo, así que\n\t\t// dos `anotar` seguidos ya no pueden leer el mismo `ultimoHash`. La carrera\n\t\t// que la cola existía para evitar deja de ser posible por construcción, que\n\t\t// es mejor que evitarla con disciplina.\n\t\t//\n\t\t// Se mantiene la firma `Promise<void>` para no tocar a los llamantes.\n\t\tthis.escribir(suceso);\n\t\treturn Promise.resolve();\n\t}\n\n\tprivate escribir(suceso: SucesoDeSesion): void {\n\t\ttry {\n\t\t\tmkdirSync(this.dir, { recursive: true });\n\t\t\tconst carga = {\n\t\t\t\tseq: ++this.seq,\n\t\t\t\tts: new Date().toISOString(),\n\t\t\t\tsesion: this.sesion,\n\t\t\t\tsuceso: aRegistro(suceso),\n\t\t\t};\n\t\t\tconst hash = hashDe(this.ultimoHash, carga);\n\t\t\tconst entrada: EntradaDelLibro = { ...carga, hash, prevHash: this.ultimoHash };\n\t\t\tthis.ultimoHash = hash;\n\t\t\tconst ruta = this.reservarFichero(carga.ts.slice(0, 10));\n\t\t\tappendFileSync(ruta, `${JSON.stringify(entrada)}\\n`, \"utf-8\");\n\t\t} catch {\n\t\t\t// El libro nunca rompe la sesión.\n\t\t}\n\t}\n\n\tprivate async listar(dir: string): Promise<string[]> {\n\t\ttry {\n\t\t\treturn (await readdir(dir)).filter((f) => /^sesion-.*\\.jsonl$/.test(f)).sort();\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Los ficheros del libro vistos desde los DOS directorios.\n\t *\n\t * Esta es la comparación que antes no existía: `readdir(sesion/)` solo puede\n\t * contestar «lo que hay», nunca «lo que debería haber», y por eso un borrado\n\t * salía como un libro vacío.\n\t */\n\tprivate async inventario(): Promise<FicheroDelLibro[]> {\n\t\tconst enSesion = new Set(await this.listar(this.dir));\n\t\tconst enIndice = new Set(await this.listar(this.dirIndice));\n\t\tconst out: FicheroDelLibro[] = [];\n\t\tfor (const nombre of [...new Set([...enSesion, ...enIndice])].sort()) {\n\t\t\tconst s = enSesion.has(nombre);\n\t\t\tconst i = enIndice.has(nombre);\n\t\t\t// Con los dos nombres presentes tienen que ser el MISMO inodo, porque\n\t\t\t// así los creó `reservarFichero`. Si no lo son, alguien borró el de\n\t\t\t// `sesion/` y puso otro en su sitio — y como el algoritmo de la cadena\n\t\t\t// es público, ese otro puede tener una cadena interna perfecta. Sin\n\t\t\t// esta comprobación la suplantación se leería como «cadena íntegra».\n\t\t\tlet suplantado = false;\n\t\t\tif (s && i) {\n\t\t\t\ttry {\n\t\t\t\t\tconst [a, b] = await Promise.all([stat(join(this.dir, nombre)), stat(join(this.dirIndice, nombre))]);\n\t\t\t\t\tsuplantado = a.ino !== b.ino;\n\t\t\t\t} catch {\n\t\t\t\t\t// No se pudo mirar: no se acusa. «No lo he podido comprobar» no es\n\t\t\t\t\t// «está manipulado», y el fichero se verifica igual más abajo.\n\t\t\t\t}\n\t\t\t}\n\t\t\tout.push({\n\t\t\t\tnombre,\n\t\t\t\t// Se lee del índice cuando el de `sesion/` no está (es el caso del\n\t\t\t\t// borrado) o cuando no coincide con él: el índice es el ancla.\n\t\t\t\truta: s && !suplantado ? join(this.dir, nombre) : join(this.dirIndice, nombre),\n\t\t\t\tfalta: i && !s,\n\t\t\t\tsinAncla: s && !i,\n\t\t\t\tsuplantado,\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}\n\n\t/** Las últimas entradas, de la más reciente hacia atrás. */\n\tasync leer(limite = 50): Promise<EntradaDelLibro[]> {\n\t\tconst out: EntradaDelLibro[] = [];\n\t\tfor (const f of (await this.inventario()).reverse()) {\n\t\t\tlet crudo: string;\n\t\t\ttry {\n\t\t\t\t// Por `f.ruta` y no por `sesion/`: las entradas de un fichero borrado\n\t\t\t\t// sobreviven en el índice y quien investiga tiene que poder verlas.\n\t\t\t\tcrudo = await readFile(f.ruta, \"utf-8\");\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const linea of crudo.split(\"\\n\").filter(Boolean).reverse()) {\n\t\t\t\ttry {\n\t\t\t\t\tout.push(JSON.parse(linea) as EntradaDelLibro);\n\t\t\t\t\tif (out.length >= limite) return out;\n\t\t\t\t} catch {\n\t\t\t\t\t// Línea ilegible: la verificación es quien lo denuncia, no la lectura.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n\n\t/**\n\t * Reverifica la cadena entera y contesta TRES estados, no dos.\n\t *\n\t * «Íntegra», «alterada» y «FALTA algo que debería estar». El tercero es el\n\t * que faltaba: la cadena de hashes detecta la modificación DENTRO de un\n\t * fichero y no puede, por construcción, notar la desaparición del fichero —\n\t * para eso hace falta saber qué debería haber, que es lo que aporta el índice\n\t * (ver `reservarFichero`).\n\t *\n\t * De la cadena rota devuelve en la PRIMERA entrada que no cuadra, y\n\t * `comprobadas` cuenta las que sí cuadraban antes de ella — así el número\n\t * dice dónde empieza la manipulación, no cuántas hay en total. Lo que ya se\n\t * hubiera detectado como ausente viaja con esa respuesta: no se pierde por\n\t * salir antes.\n\t */\n\tasync verificar(): Promise<Veredicto> {\n\t\tlet comprobadas = 0;\n\t\tconst faltan: { fichero: string; entradas: number }[] = [];\n\t\tconst reinicios: { fichero: string; ts: string; entradasAntes: number }[] = [];\n\t\tconst sinAncla: string[] = [];\n\t\t// Las lápidas se leen ANTES de recorrer: una purga anotada en el fichero de\n\t\t// hoy explica un hueco de un fichero de hace un año.\n\t\tconst purgados = ficherosPurgados(await this.leer());\n\t\tfor (const f of await this.inventario()) {\n\t\t\tif (f.suplantado) {\n\t\t\t\treturn {\n\t\t\t\t\tvalido: false,\n\t\t\t\t\tcomprobadas,\n\t\t\t\t\tficheroAlterado: f.nombre,\n\t\t\t\t\tmotivo: \"el fichero de sesión ya no es el mismo que el del índice: lo han sustituido\",\n\t\t\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t\t\t...(sinAncla.length ? { sinAncla } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\t// La cadena empieza de cero en CADA fichero, porque cada fichero es una\n\t\t\t// sesión y su primera entrada lleva `prevHash: null`. Arrastrar el hash\n\t\t\t// de un fichero al siguiente es lo que hacía fallar la verificación en\n\t\t\t// cuanto había más de una sesión.\n\t\t\tlet prevHash: string | null = null;\n\t\t\tlet enEste = 0;\n\t\t\tlet crudo: string;\n\t\t\ttry {\n\t\t\t\tcrudo = await readFile(f.ruta, \"utf-8\");\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tvalido: false,\n\t\t\t\t\tcomprobadas,\n\t\t\t\t\tficheroAlterado: f.nombre,\n\t\t\t\t\tmotivo: \"no se ha podido leer el fichero: no es «está bien», es «no lo sé»\",\n\t\t\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\tfor (const linea of crudo.split(\"\\n\").filter(Boolean)) {\n\t\t\t\tlet entrada: EntradaDelLibro;\n\t\t\t\ttry {\n\t\t\t\t\tentrada = JSON.parse(linea) as EntradaDelLibro;\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalido: false,\n\t\t\t\t\t\tcomprobadas,\n\t\t\t\t\t\tficheroAlterado: f.nombre,\n\t\t\t\t\t\tmotivo: \"hay una línea que no es JSON válido\",\n\t\t\t\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// El rest es lo que impide que esta lista y la de `escribir`\n\t\t\t\t// se separen: aquí no hay lista.\n\t\t\t\tconst { hash, prevHash: declarado, ...resto } = entrada;\n\t\t\t\t// Se separan DOS preguntas que antes iban juntas y contestaban lo\n\t\t\t\t// mismo, acusando siempre de lo primero:\n\t\t\t\t//\n\t\t\t\t// · ¿el hash cuadra con SU PROPIO contenido? Si no, alguien editó la\n\t\t\t\t// entrada. Eso es manipulación y se dice así.\n\t\t\t\t// · ¿su `prevHash` apunta a la entrada anterior? Si no, el enlace\n\t\t\t\t// está roto, que es otra cosa: faltan entradas o están cambiadas\n\t\t\t\t// de orden.\n\t\t\t\t//\n\t\t\t\t// Medido sobre el libro real de esta máquina: un fichero de dos\n\t\t\t\t// entradas, las dos con `seq: 1` y `prevHash: null`, salía como «el\n\t\t\t\t// hash de una entrada no cuadra con su contenido». Cuadraba\n\t\t\t\t// perfectamente. Eran dos procesos del escritorio escribiendo el mismo\n\t\t\t\t// fichero antes de que `reservarFichero` diera nombres distintos.\n\t\t\t\tif (hash !== hashDe(declarado, resto)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalido: false,\n\t\t\t\t\t\tcomprobadas,\n\t\t\t\t\t\talteradaEn: entrada.ts,\n\t\t\t\t\t\tficheroAlterado: f.nombre,\n\t\t\t\t\t\tmotivo: \"el hash de una entrada no cuadra con su contenido: la han editado\",\n\t\t\t\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (declarado !== prevHash) {\n\t\t\t\t\t// Una cadena que vuelve a empezar dentro del mismo fichero. Lo\n\t\t\t\t\t// produce un reinicio del proceso —y lo produce igual quien quite\n\t\t\t\t\t// entradas del medio y escriba una cadena nueva—. Desde el fichero\n\t\t\t\t\t// no se distinguen, así que NO se llama manipulación ni se da por\n\t\t\t\t\t// bueno: es el tercer estado, y se dice entero en `reinicios`.\n\t\t\t\t\tif (declarado === null && prevHash !== null) {\n\t\t\t\t\t\treinicios.push({ fichero: f.nombre, ts: entrada.ts, entradasAntes: enEste });\n\t\t\t\t\t\tprevHash = hash;\n\t\t\t\t\t\tcomprobadas++;\n\t\t\t\t\t\tenEste++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalido: false,\n\t\t\t\t\t\tcomprobadas,\n\t\t\t\t\t\talteradaEn: entrada.ts,\n\t\t\t\t\t\tficheroAlterado: f.nombre,\n\t\t\t\t\t\tmotivo:\n\t\t\t\t\t\t\t\"el enlace de una entrada no apunta a la anterior: faltan entradas o están cambiadas de orden\",\n\t\t\t\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tprevHash = hash;\n\t\t\t\tcomprobadas++;\n\t\t\t\tenEste++;\n\t\t\t}\n\t\t\t// Un fichero VACÍO que falta no es una ausencia: es una reserva de\n\t\t\t// nombre que nunca llegó a escribirse (la sesión murió entre reservar y\n\t\t\t// anotar). Contarlo habría hecho que una sesión nueva y legítima, sin\n\t\t\t// una sola entrada todavía, se reportara como manipulada — la mitad que\n\t\t\t// decide, porque un detector que grita siempre no distingue nada.\n\t\t\tif (enEste === 0) continue;\n\t\t\t// Un hueco EXPLICADO no es una manipulación.\n\t\t\t//\n\t\t\t// Si el propio libro lleva una lápida diciendo que ese fichero se purgó\n\t\t\t// —cuándo, cuántas entradas, bajo qué política y con qué hash de\n\t\t\t// cierre—, la ausencia es un hecho declarado y no una desaparición. Sin\n\t\t\t// esto, cumplir el art. 5.1.e del RGPD hacía que `verificar` contestara\n\t\t\t// «alguien los ha borrado»: la ley nos acusaba de manipular. Ver\n\t\t\t// `audit/retencion.ts`.\n\t\t\tif (f.falta && !purgados.has(f.nombre)) faltan.push({ fichero: f.nombre, entradas: enEste });\n\t\t\tif (f.sinAncla) sinAncla.push(f.nombre);\n\t\t}\n\t\t// Las lápidas se enseñan TODAS, no solo las que tapan un hueco del\n\t\t// inventario. Una purga completa se lleva el fichero Y su ancla, así que no\n\t\t// deja hueco ninguno: si solo se informara de las que explican una ausencia,\n\t\t// el caso normal —el que de verdad ocurre— saldría mudo y el DPO leería\n\t\t// «cadena íntegra, 1 entrada» sin enterarse de que se purgaron tres. Que es\n\t\t// exactamente el «desaparece sin rastro» que este mecanismo existe para\n\t\t// impedir.\n\t\tconst explicados = [...purgados.values()].map((l) => ({\n\t\t\tfichero: l.fichero,\n\t\t\tentradas: l.entradas,\n\t\t\tpolitica: l.politica,\n\t\t}));\n\t\treturn {\n\t\t\tvalido: faltan.length === 0,\n\t\t\t...(explicados.length ? { purgados: explicados } : {}),\n\t\t\t...(reinicios.length ? { reinicios } : {}),\n\t\t\tcomprobadas,\n\t\t\t...(faltan.length ? { faltan } : {}),\n\t\t\t...(sinAncla.length ? { sinAncla } : {}),\n\t\t};\n\t}\n}\n"]}
|