@hoilab/ada-cli 0.84.22 → 0.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -2
- package/README.es.md +17 -6
- package/README.md +109 -11
- package/dist/ada-publico.d.ts +35 -0
- package/dist/ada-publico.d.ts.map +1 -0
- package/dist/ada-publico.js +40 -0
- package/dist/ada-publico.js.map +1 -0
- package/dist/cli/audit-command.d.ts +15 -0
- package/dist/cli/audit-command.d.ts.map +1 -0
- package/dist/cli/audit-command.js +280 -0
- package/dist/cli/audit-command.js.map +1 -0
- package/dist/cli/banco-command.d.ts +15 -0
- package/dist/cli/banco-command.d.ts.map +1 -0
- package/dist/cli/banco-command.js +213 -0
- package/dist/cli/banco-command.js.map +1 -0
- package/dist/cli/cleanse-command.d.ts +11 -0
- package/dist/cli/cleanse-command.d.ts.map +1 -0
- package/dist/cli/cleanse-command.js +101 -0
- package/dist/cli/cleanse-command.js.map +1 -0
- package/dist/cli/commit-command.d.ts +31 -0
- package/dist/cli/commit-command.d.ts.map +1 -0
- package/dist/cli/commit-command.js +158 -0
- package/dist/cli/commit-command.js.map +1 -0
- package/dist/cli/computer-command.d.ts +12 -0
- package/dist/cli/computer-command.d.ts.map +1 -0
- package/dist/cli/computer-command.js +141 -0
- package/dist/cli/computer-command.js.map +1 -0
- package/dist/cli/discover-command.d.ts +18 -0
- package/dist/cli/discover-command.d.ts.map +1 -0
- package/dist/cli/discover-command.js +108 -0
- package/dist/cli/discover-command.js.map +1 -0
- package/dist/cli/hashline-command.d.ts +11 -0
- package/dist/cli/hashline-command.d.ts.map +1 -0
- package/dist/cli/hashline-command.js +106 -0
- package/dist/cli/hashline-command.js.map +1 -0
- package/dist/cli/import-command.d.ts +35 -0
- package/dist/cli/import-command.d.ts.map +1 -0
- package/dist/cli/import-command.js +164 -0
- package/dist/cli/import-command.js.map +1 -0
- package/dist/cli/politica-command.d.ts +20 -0
- package/dist/cli/politica-command.d.ts.map +1 -0
- package/dist/cli/politica-command.js +93 -0
- package/dist/cli/politica-command.js.map +1 -0
- package/dist/cli/refine-command.d.ts +18 -0
- package/dist/cli/refine-command.d.ts.map +1 -0
- package/dist/cli/refine-command.js +101 -0
- package/dist/cli/refine-command.js.map +1 -0
- package/dist/cli/review-command.d.ts +24 -0
- package/dist/cli/review-command.d.ts.map +1 -0
- package/dist/cli/review-command.js +168 -0
- package/dist/cli/review-command.js.map +1 -0
- package/dist/cli/schedule-command.d.ts +17 -0
- package/dist/cli/schedule-command.d.ts.map +1 -0
- package/dist/cli/schedule-command.js +117 -0
- package/dist/cli/schedule-command.js.map +1 -0
- package/dist/cli/serve-command.d.ts +72 -0
- package/dist/cli/serve-command.d.ts.map +1 -0
- package/dist/cli/serve-command.js +568 -0
- package/dist/cli/serve-command.js.map +1 -0
- package/dist/cli/telegram-command.d.ts +18 -0
- package/dist/cli/telegram-command.d.ts.map +1 -0
- package/dist/cli/telegram-command.js +137 -0
- package/dist/cli/telegram-command.js.map +1 -0
- package/dist/cli/telemetria-command.d.ts +22 -0
- package/dist/cli/telemetria-command.d.ts.map +1 -0
- package/dist/cli/telemetria-command.js +127 -0
- package/dist/cli/telemetria-command.js.map +1 -0
- package/dist/cli/undo-command.d.ts +9 -0
- package/dist/cli/undo-command.d.ts.map +1 -0
- package/dist/cli/undo-command.js +56 -0
- package/dist/cli/undo-command.js.map +1 -0
- package/dist/cli/usage-command.d.ts +10 -0
- package/dist/cli/usage-command.d.ts.map +1 -0
- package/dist/cli/usage-command.js +209 -0
- package/dist/cli/usage-command.js.map +1 -0
- package/dist/cli/wiki-command.d.ts +9 -0
- package/dist/cli/wiki-command.d.ts.map +1 -0
- package/dist/cli/wiki-command.js +76 -0
- package/dist/cli/wiki-command.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -11
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/ada.d.ts +58 -0
- package/dist/core/ada.d.ts.map +1 -0
- package/dist/core/ada.js +61 -0
- package/dist/core/ada.js.map +1 -0
- package/dist/core/advisor/guarda.d.ts +66 -0
- package/dist/core/advisor/guarda.d.ts.map +1 -0
- package/dist/core/advisor/guarda.js +191 -0
- package/dist/core/advisor/guarda.js.map +1 -0
- package/dist/core/advisor/runtime.d.ts +66 -0
- package/dist/core/advisor/runtime.d.ts.map +1 -0
- package/dist/core/advisor/runtime.js +121 -0
- package/dist/core/advisor/runtime.js.map +1 -0
- package/dist/core/advisor/sesion.d.ts +109 -0
- package/dist/core/advisor/sesion.d.ts.map +1 -0
- package/dist/core/advisor/sesion.js +139 -0
- package/dist/core/advisor/sesion.js.map +1 -0
- package/dist/core/agent-session.d.ts +30 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +430 -22
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents/loader.d.ts +77 -0
- package/dist/core/agents/loader.d.ts.map +1 -0
- package/dist/core/agents/loader.js +154 -0
- package/dist/core/agents/loader.js.map +1 -0
- package/dist/core/aprobacion/generados.d.ts +37 -0
- package/dist/core/aprobacion/generados.d.ts.map +1 -0
- package/dist/core/aprobacion/generados.js +85 -0
- package/dist/core/aprobacion/generados.js.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts +90 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.js +212 -0
- package/dist/core/aprobacion/politica-de-maquina.js.map +1 -0
- package/dist/core/aprobacion/politica.d.ts +90 -0
- package/dist/core/aprobacion/politica.d.ts.map +1 -0
- package/dist/core/aprobacion/politica.js +375 -0
- package/dist/core/aprobacion/politica.js.map +1 -0
- package/dist/core/arranque/atajos.d.ts +46 -0
- package/dist/core/arranque/atajos.d.ts.map +1 -0
- package/dist/core/arranque/atajos.js +113 -0
- package/dist/core/arranque/atajos.js.map +1 -0
- package/dist/core/audit/exportacion.d.ts +54 -0
- package/dist/core/audit/exportacion.d.ts.map +1 -0
- package/dist/core/audit/exportacion.js +265 -0
- package/dist/core/audit/exportacion.js.map +1 -0
- package/dist/core/audit/libro.d.ts +318 -0
- package/dist/core/audit/libro.d.ts.map +1 -0
- package/dist/core/audit/libro.js +508 -0
- package/dist/core/audit/libro.js.map +1 -0
- package/dist/core/audit/registro-sesion.d.ts +78 -0
- package/dist/core/audit/registro-sesion.d.ts.map +1 -0
- package/dist/core/audit/registro-sesion.js +202 -0
- package/dist/core/audit/registro-sesion.js.map +1 -0
- package/dist/core/audit/retencion.d.ts +82 -0
- package/dist/core/audit/retencion.d.ts.map +1 -0
- package/dist/core/audit/retencion.js +152 -0
- package/dist/core/audit/retencion.js.map +1 -0
- package/dist/core/audit/rutas.d.ts +23 -0
- package/dist/core/audit/rutas.d.ts.map +1 -0
- package/dist/core/audit/rutas.js +23 -0
- package/dist/core/audit/rutas.js.map +1 -0
- package/dist/core/auth-storage.d.ts +0 -3
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -5
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/banco/almacenamiento.d.ts +18 -0
- package/dist/core/banco/almacenamiento.d.ts.map +1 -0
- package/dist/core/banco/almacenamiento.js +50 -0
- package/dist/core/banco/almacenamiento.js.map +1 -0
- package/dist/core/banco/analisis.d.ts +37 -0
- package/dist/core/banco/analisis.d.ts.map +1 -0
- package/dist/core/banco/analisis.js +164 -0
- package/dist/core/banco/analisis.js.map +1 -0
- package/dist/core/banco/bloques.d.ts +39 -0
- package/dist/core/banco/bloques.d.ts.map +1 -0
- package/dist/core/banco/bloques.js +84 -0
- package/dist/core/banco/bloques.js.map +1 -0
- package/dist/core/banco/cargas.d.ts +84 -0
- package/dist/core/banco/cargas.d.ts.map +1 -0
- package/dist/core/banco/cargas.js +520 -0
- package/dist/core/banco/cargas.js.map +1 -0
- package/dist/core/banco/comparar.d.ts +29 -0
- package/dist/core/banco/comparar.d.ts.map +1 -0
- package/dist/core/banco/comparar.js +28 -0
- package/dist/core/banco/comparar.js.map +1 -0
- package/dist/core/banco/ejecutar.d.ts +44 -0
- package/dist/core/banco/ejecutar.d.ts.map +1 -0
- package/dist/core/banco/ejecutar.js +183 -0
- package/dist/core/banco/ejecutar.js.map +1 -0
- package/dist/core/banco/generar.d.ts +24 -0
- package/dist/core/banco/generar.d.ts.map +1 -0
- package/dist/core/banco/generar.js +159 -0
- package/dist/core/banco/generar.js.map +1 -0
- package/dist/core/banco/mutaciones.d.ts +25 -0
- package/dist/core/banco/mutaciones.d.ts.map +1 -0
- package/dist/core/banco/mutaciones.js +215 -0
- package/dist/core/banco/mutaciones.js.map +1 -0
- package/dist/core/banco/tipos.d.ts +121 -0
- package/dist/core/banco/tipos.d.ts.map +1 -0
- package/dist/core/banco/tipos.js +16 -0
- package/dist/core/banco/tipos.js.map +1 -0
- package/dist/core/blobs/almacen.d.ts +81 -0
- package/dist/core/blobs/almacen.d.ts.map +1 -0
- package/dist/core/blobs/almacen.js +198 -0
- package/dist/core/blobs/almacen.js.map +1 -0
- package/dist/core/blobs/broker.d.ts +103 -0
- package/dist/core/blobs/broker.d.ts.map +1 -0
- package/dist/core/blobs/broker.js +204 -0
- package/dist/core/blobs/broker.js.map +1 -0
- package/dist/core/blobs/index.d.ts +70 -0
- package/dist/core/blobs/index.d.ts.map +1 -0
- package/dist/core/blobs/index.js +232 -0
- package/dist/core/blobs/index.js.map +1 -0
- package/dist/core/blobs/payload.d.ts +55 -0
- package/dist/core/blobs/payload.d.ts.map +1 -0
- package/dist/core/blobs/payload.js +255 -0
- package/dist/core/blobs/payload.js.map +1 -0
- package/dist/core/blobs/proveedor.d.ts +85 -0
- package/dist/core/blobs/proveedor.d.ts.map +1 -0
- package/dist/core/blobs/proveedor.js +196 -0
- package/dist/core/blobs/proveedor.js.map +1 -0
- package/dist/core/browser/cdp.d.ts +41 -0
- package/dist/core/browser/cdp.d.ts.map +1 -0
- package/dist/core/browser/cdp.js +119 -0
- package/dist/core/browser/cdp.js.map +1 -0
- package/dist/core/browser/politica.d.ts +51 -0
- package/dist/core/browser/politica.d.ts.map +1 -0
- package/dist/core/browser/politica.js +123 -0
- package/dist/core/browser/politica.js.map +1 -0
- package/dist/core/browser/sesion.d.ts +52 -0
- package/dist/core/browser/sesion.d.ts.map +1 -0
- package/dist/core/browser/sesion.js +176 -0
- package/dist/core/browser/sesion.js.map +1 -0
- package/dist/core/browser/tools.d.ts +16 -0
- package/dist/core/browser/tools.d.ts.map +1 -0
- package/dist/core/browser/tools.js +279 -0
- package/dist/core/browser/tools.js.map +1 -0
- package/dist/core/commit/diff.d.ts +56 -0
- package/dist/core/commit/diff.d.ts.map +1 -0
- package/dist/core/commit/diff.js +145 -0
- package/dist/core/commit/diff.js.map +1 -0
- package/dist/core/commit/mensaje.d.ts +80 -0
- package/dist/core/commit/mensaje.d.ts.map +1 -0
- package/dist/core/commit/mensaje.js +207 -0
- package/dist/core/commit/mensaje.js.map +1 -0
- package/dist/core/compactar/index.d.ts +52 -0
- package/dist/core/compactar/index.d.ts.map +1 -0
- package/dist/core/compactar/index.js +91 -0
- package/dist/core/compactar/index.js.map +1 -0
- package/dist/core/compactar/registro-denso.d.ts +160 -0
- package/dist/core/compactar/registro-denso.d.ts.map +1 -0
- package/dist/core/compactar/registro-denso.js +620 -0
- package/dist/core/compactar/registro-denso.js.map +1 -0
- package/dist/core/computer/captura.d.ts +35 -0
- package/dist/core/computer/captura.d.ts.map +1 -0
- package/dist/core/computer/captura.js +140 -0
- package/dist/core/computer/captura.js.map +1 -0
- package/dist/core/computer/driver.d.ts +130 -0
- package/dist/core/computer/driver.d.ts.map +1 -0
- package/dist/core/computer/driver.js +206 -0
- package/dist/core/computer/driver.js.map +1 -0
- package/dist/core/computer/motor/actions.d.ts +109 -0
- package/dist/core/computer/motor/actions.d.ts.map +1 -0
- package/dist/core/computer/motor/actions.js +157 -0
- package/dist/core/computer/motor/actions.js.map +1 -0
- package/dist/core/computer/motor/bridge.d.ts +232 -0
- package/dist/core/computer/motor/bridge.d.ts.map +1 -0
- package/dist/core/computer/motor/bridge.js +2335 -0
- package/dist/core/computer/motor/bridge.js.map +1 -0
- package/dist/core/computer/motor/cdp.d.ts +107 -0
- package/dist/core/computer/motor/cdp.d.ts.map +1 -0
- package/dist/core/computer/motor/cdp.js +659 -0
- package/dist/core/computer/motor/cdp.js.map +1 -0
- package/dist/core/computer/motor/config.d.ts +23 -0
- package/dist/core/computer/motor/config.d.ts.map +1 -0
- package/dist/core/computer/motor/config.js +100 -0
- package/dist/core/computer/motor/config.js.map +1 -0
- package/dist/core/computer/motor/contract.d.ts +81 -0
- package/dist/core/computer/motor/contract.d.ts.map +1 -0
- package/dist/core/computer/motor/contract.js +14 -0
- package/dist/core/computer/motor/contract.js.map +1 -0
- package/dist/core/computer/motor/note.d.ts +37 -0
- package/dist/core/computer/motor/note.d.ts.map +1 -0
- package/dist/core/computer/motor/note.js +162 -0
- package/dist/core/computer/motor/note.js.map +1 -0
- package/dist/core/computer/motor/outline.d.ts +155 -0
- package/dist/core/computer/motor/outline.d.ts.map +1 -0
- package/dist/core/computer/motor/outline.js +590 -0
- package/dist/core/computer/motor/outline.js.map +1 -0
- package/dist/core/computer/motor/output.d.ts +18 -0
- package/dist/core/computer/motor/output.d.ts.map +1 -0
- package/dist/core/computer/motor/output.js +148 -0
- package/dist/core/computer/motor/output.js.map +1 -0
- package/dist/core/computer/motor/permissions.d.ts +41 -0
- package/dist/core/computer/motor/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/permissions.js +51 -0
- package/dist/core/computer/motor/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/architecture.d.ts +5 -0
- package/dist/core/computer/motor/platform/architecture.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/architecture.js +21 -0
- package/dist/core/computer/motor/platform/architecture.js.map +1 -0
- package/dist/core/computer/motor/platform/coerce.d.ts +4 -0
- package/dist/core/computer/motor/platform/coerce.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/coerce.js +17 -0
- package/dist/core/computer/motor/platform/coerce.js.map +1 -0
- package/dist/core/computer/motor/platform/index.d.ts +4 -0
- package/dist/core/computer/motor/platform/index.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/index.js +79 -0
- package/dist/core/computer/motor/platform/index.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.js +173 -0
- package/dist/core/computer/motor/platform/linux/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts +29 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.js +261 -0
- package/dist/core/computer/motor/platform/linux/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.js +124 -0
- package/dist/core/computer/motor/platform/macos/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts +7 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.js +101 -0
- package/dist/core/computer/motor/platform/macos/browser.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper-path.mjs +34 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts +32 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper.js +277 -0
- package/dist/core/computer/motor/platform/macos/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts +4 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.js +118 -0
- package/dist/core/computer/motor/platform/macos/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/types.d.ts +263 -0
- package/dist/core/computer/motor/platform/types.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/types.js +2 -0
- package/dist/core/computer/motor/platform/types.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.js +163 -0
- package/dist/core/computer/motor/platform/windows/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts +18 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.js +174 -0
- package/dist/core/computer/motor/platform/windows/helper.js.map +1 -0
- package/dist/core/computer/motor/root-selection.d.ts +6 -0
- package/dist/core/computer/motor/root-selection.d.ts.map +1 -0
- package/dist/core/computer/motor/root-selection.js +28 -0
- package/dist/core/computer/motor/root-selection.js.map +1 -0
- package/dist/core/computer/motor/runtime.d.ts +50 -0
- package/dist/core/computer/motor/runtime.d.ts.map +1 -0
- package/dist/core/computer/motor/runtime.js +119 -0
- package/dist/core/computer/motor/runtime.js.map +1 -0
- package/dist/core/computer/motor/state.d.ts +68 -0
- package/dist/core/computer/motor/state.d.ts.map +1 -0
- package/dist/core/computer/motor/state.js +100 -0
- package/dist/core/computer/motor/state.js.map +1 -0
- package/dist/core/computer/motor/view.d.ts +6 -0
- package/dist/core/computer/motor/view.d.ts.map +1 -0
- package/dist/core/computer/motor/view.js +185 -0
- package/dist/core/computer/motor/view.js.map +1 -0
- package/dist/core/computer/motor-ada.d.ts +159 -0
- package/dist/core/computer/motor-ada.d.ts.map +1 -0
- package/dist/core/computer/motor-ada.js +412 -0
- package/dist/core/computer/motor-ada.js.map +1 -0
- package/dist/core/computer/politica.d.ts +56 -0
- package/dist/core/computer/politica.d.ts.map +1 -0
- package/dist/core/computer/politica.js +163 -0
- package/dist/core/computer/politica.js.map +1 -0
- package/dist/core/computer/tools.d.ts +26 -0
- package/dist/core/computer/tools.d.ts.map +1 -0
- package/dist/core/computer/tools.js +399 -0
- package/dist/core/computer/tools.js.map +1 -0
- package/dist/core/context-breakdown.d.ts +80 -0
- package/dist/core/context-breakdown.d.ts.map +1 -0
- package/dist/core/context-breakdown.js +87 -0
- package/dist/core/context-breakdown.js.map +1 -0
- package/dist/core/credenciales/cliente.d.ts +60 -0
- package/dist/core/credenciales/cliente.d.ts.map +1 -0
- package/dist/core/credenciales/cliente.js +81 -0
- package/dist/core/credenciales/cliente.js.map +1 -0
- package/dist/core/credenciales/pool.d.ts +96 -0
- package/dist/core/credenciales/pool.d.ts.map +1 -0
- package/dist/core/credenciales/pool.js +128 -0
- package/dist/core/credenciales/pool.js.map +1 -0
- package/dist/core/credenciales/reposo.d.ts +93 -0
- package/dist/core/credenciales/reposo.d.ts.map +1 -0
- package/dist/core/credenciales/reposo.js +489 -0
- package/dist/core/credenciales/reposo.js.map +1 -0
- package/dist/core/credenciales/servidor.d.ts +55 -0
- package/dist/core/credenciales/servidor.d.ts.map +1 -0
- package/dist/core/credenciales/servidor.js +205 -0
- package/dist/core/credenciales/servidor.js.map +1 -0
- package/dist/core/descubrimiento/comandos.d.ts +30 -0
- package/dist/core/descubrimiento/comandos.d.ts.map +1 -0
- package/dist/core/descubrimiento/comandos.js +76 -0
- package/dist/core/descubrimiento/comandos.js.map +1 -0
- package/dist/core/descubrimiento/mcp.d.ts +42 -0
- package/dist/core/descubrimiento/mcp.d.ts.map +1 -0
- package/dist/core/descubrimiento/mcp.js +130 -0
- package/dist/core/descubrimiento/mcp.js.map +1 -0
- package/dist/core/descubrimiento/reglas.d.ts +61 -0
- package/dist/core/descubrimiento/reglas.d.ts.map +1 -0
- package/dist/core/descubrimiento/reglas.js +134 -0
- package/dist/core/descubrimiento/reglas.js.map +1 -0
- package/dist/core/descubrimiento/skills.d.ts +57 -0
- package/dist/core/descubrimiento/skills.d.ts.map +1 -0
- package/dist/core/descubrimiento/skills.js +113 -0
- package/dist/core/descubrimiento/skills.js.map +1 -0
- package/dist/core/dificultad/clasificador.d.ts +133 -0
- package/dist/core/dificultad/clasificador.d.ts.map +1 -0
- package/dist/core/dificultad/clasificador.js +288 -0
- package/dist/core/dificultad/clasificador.js.map +1 -0
- package/dist/core/edicion/diario.d.ts +37 -0
- package/dist/core/edicion/diario.d.ts.map +1 -0
- package/dist/core/edicion/diario.js +51 -0
- package/dist/core/edicion/diario.js.map +1 -0
- package/dist/core/edicion/hashline.d.ts +71 -0
- package/dist/core/edicion/hashline.d.ts.map +1 -0
- package/dist/core/edicion/hashline.js +111 -0
- package/dist/core/edicion/hashline.js.map +1 -0
- package/dist/core/edicion/hueco.d.ts +64 -0
- package/dist/core/edicion/hueco.d.ts.map +1 -0
- package/dist/core/edicion/hueco.js +162 -0
- package/dist/core/edicion/hueco.js.map +1 -0
- package/dist/core/edicion/limpiar-carga.d.ts +39 -0
- package/dist/core/edicion/limpiar-carga.d.ts.map +1 -0
- package/dist/core/edicion/limpiar-carga.js +121 -0
- package/dist/core/edicion/limpiar-carga.js.map +1 -0
- package/dist/core/edicion/observador.d.ts +80 -0
- package/dist/core/edicion/observador.d.ts.map +1 -0
- package/dist/core/edicion/observador.js +183 -0
- package/dist/core/edicion/observador.js.map +1 -0
- package/dist/core/edicion/parecido.d.ts +53 -0
- package/dist/core/edicion/parecido.d.ts.map +1 -0
- package/dist/core/edicion/parecido.js +145 -0
- package/dist/core/edicion/parecido.js.map +1 -0
- package/dist/core/edicion/parseo.d.ts +58 -0
- package/dist/core/edicion/parseo.d.ts.map +1 -0
- package/dist/core/edicion/parseo.js +124 -0
- package/dist/core/edicion/parseo.js.map +1 -0
- package/dist/core/edicion/reparacion.d.ts +67 -0
- package/dist/core/edicion/reparacion.d.ts.map +1 -0
- package/dist/core/edicion/reparacion.js +202 -0
- package/dist/core/edicion/reparacion.js.map +1 -0
- package/dist/core/edicion/sangria.d.ts +121 -0
- package/dist/core/edicion/sangria.d.ts.map +1 -0
- package/dist/core/edicion/sangria.js +341 -0
- package/dist/core/edicion/sangria.js.map +1 -0
- package/dist/core/edicion/tipos.d.ts +58 -0
- package/dist/core/edicion/tipos.d.ts.map +1 -0
- package/dist/core/edicion/tipos.js +160 -0
- package/dist/core/edicion/tipos.js.map +1 -0
- package/dist/core/errores/proveedor.d.ts +53 -0
- package/dist/core/errores/proveedor.d.ts.map +1 -0
- package/dist/core/errores/proveedor.js +191 -0
- package/dist/core/errores/proveedor.js.map +1 -0
- package/dist/core/estructural/buscar.d.ts +61 -0
- package/dist/core/estructural/buscar.d.ts.map +1 -0
- package/dist/core/estructural/buscar.js +261 -0
- package/dist/core/estructural/buscar.js.map +1 -0
- package/dist/core/estructural/editar.d.ts +36 -0
- package/dist/core/estructural/editar.d.ts.map +1 -0
- package/dist/core/estructural/editar.js +123 -0
- package/dist/core/estructural/editar.js.map +1 -0
- package/dist/core/estructural/tools.d.ts +11 -0
- package/dist/core/estructural/tools.d.ts.map +1 -0
- package/dist/core/estructural/tools.js +100 -0
- package/dist/core/estructural/tools.js.map +1 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +10 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensiones/suplantacion.d.ts +49 -0
- package/dist/core/extensiones/suplantacion.d.ts.map +1 -0
- package/dist/core/extensiones/suplantacion.js +61 -0
- package/dist/core/extensiones/suplantacion.js.map +1 -0
- package/dist/core/extensiones/vigilancia.d.ts +54 -0
- package/dist/core/extensiones/vigilancia.d.ts.map +1 -0
- package/dist/core/extensiones/vigilancia.js +217 -0
- package/dist/core/extensiones/vigilancia.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +11 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/harness/fuentes-de-contexto.d.ts +29 -0
- package/dist/core/harness/fuentes-de-contexto.d.ts.map +1 -0
- package/dist/core/harness/fuentes-de-contexto.js +44 -0
- package/dist/core/harness/fuentes-de-contexto.js.map +1 -0
- package/dist/core/harness/refine.d.ts +40 -0
- package/dist/core/harness/refine.d.ts.map +1 -0
- package/dist/core/harness/refine.js +109 -0
- package/dist/core/harness/refine.js.map +1 -0
- package/dist/core/harness/store.d.ts +75 -0
- package/dist/core/harness/store.d.ts.map +1 -0
- package/dist/core/harness/store.js +149 -0
- package/dist/core/harness/store.js.map +1 -0
- package/dist/core/hooks/contract.d.ts +85 -0
- package/dist/core/hooks/contract.d.ts.map +1 -0
- package/dist/core/hooks/contract.js +140 -0
- package/dist/core/hooks/contract.js.map +1 -0
- package/dist/core/hooks/runner.d.ts +42 -0
- package/dist/core/hooks/runner.d.ts.map +1 -0
- package/dist/core/hooks/runner.js +85 -0
- package/dist/core/hooks/runner.js.map +1 -0
- package/dist/core/hooks/session-hooks.d.ts +62 -0
- package/dist/core/hooks/session-hooks.d.ts.map +1 -0
- package/dist/core/hooks/session-hooks.js +84 -0
- package/dist/core/hooks/session-hooks.js.map +1 -0
- package/dist/core/importar/formatos.d.ts +69 -0
- package/dist/core/importar/formatos.d.ts.map +1 -0
- package/dist/core/importar/formatos.js +235 -0
- package/dist/core/importar/formatos.js.map +1 -0
- package/dist/core/interactivo/deteccion.d.ts +44 -0
- package/dist/core/interactivo/deteccion.d.ts.map +1 -0
- package/dist/core/interactivo/deteccion.js +82 -0
- package/dist/core/interactivo/deteccion.js.map +1 -0
- package/dist/core/interactivo/sesion.d.ts +50 -0
- package/dist/core/interactivo/sesion.d.ts.map +1 -0
- package/dist/core/interactivo/sesion.js +156 -0
- package/dist/core/interactivo/sesion.js.map +1 -0
- package/dist/core/interactivo/tools.d.ts +21 -0
- package/dist/core/interactivo/tools.d.ts.map +1 -0
- package/dist/core/interactivo/tools.js +122 -0
- package/dist/core/interactivo/tools.js.map +1 -0
- package/dist/core/lectura/mapa.d.ts +70 -0
- package/dist/core/lectura/mapa.d.ts.map +1 -0
- package/dist/core/lectura/mapa.js +177 -0
- package/dist/core/lectura/mapa.js.map +1 -0
- package/dist/core/lectura/pdf.d.ts +49 -0
- package/dist/core/lectura/pdf.d.ts.map +1 -0
- package/dist/core/lectura/pdf.js +337 -0
- package/dist/core/lectura/pdf.js.map +1 -0
- package/dist/core/limpieza/comprobadores.d.ts +28 -0
- package/dist/core/limpieza/comprobadores.d.ts.map +1 -0
- package/dist/core/limpieza/comprobadores.js +311 -0
- package/dist/core/limpieza/comprobadores.js.map +1 -0
- package/dist/core/limpieza/parseo.d.ts +19 -0
- package/dist/core/limpieza/parseo.d.ts.map +1 -0
- package/dist/core/limpieza/parseo.js +124 -0
- package/dist/core/limpieza/parseo.js.map +1 -0
- package/dist/core/limpieza/reparacion.d.ts +77 -0
- package/dist/core/limpieza/reparacion.d.ts.map +1 -0
- package/dist/core/limpieza/reparacion.js +254 -0
- package/dist/core/limpieza/reparacion.js.map +1 -0
- package/dist/core/limpieza/tipos.d.ts +56 -0
- package/dist/core/limpieza/tipos.d.ts.map +1 -0
- package/dist/core/limpieza/tipos.js +9 -0
- package/dist/core/limpieza/tipos.js.map +1 -0
- package/dist/core/lsp/cliente.d.ts +52 -0
- package/dist/core/lsp/cliente.d.ts.map +1 -0
- package/dist/core/lsp/cliente.js +232 -0
- package/dist/core/lsp/cliente.js.map +1 -0
- package/dist/core/lsp/descubrimiento.d.ts +62 -0
- package/dist/core/lsp/descubrimiento.d.ts.map +1 -0
- package/dist/core/lsp/descubrimiento.js +152 -0
- package/dist/core/lsp/descubrimiento.js.map +1 -0
- package/dist/core/lsp/ediciones.d.ts +59 -0
- package/dist/core/lsp/ediciones.d.ts.map +1 -0
- package/dist/core/lsp/ediciones.js +89 -0
- package/dist/core/lsp/ediciones.js.map +1 -0
- package/dist/core/lsp/extension.d.ts +28 -0
- package/dist/core/lsp/extension.d.ts.map +1 -0
- package/dist/core/lsp/extension.js +34 -0
- package/dist/core/lsp/extension.js.map +1 -0
- package/dist/core/lsp/tools.d.ts +45 -0
- package/dist/core/lsp/tools.d.ts.map +1 -0
- package/dist/core/lsp/tools.js +265 -0
- package/dist/core/lsp/tools.js.map +1 -0
- package/dist/core/mcp/client.d.ts +60 -0
- package/dist/core/mcp/client.d.ts.map +1 -0
- package/dist/core/mcp/client.js +139 -0
- package/dist/core/mcp/client.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +86 -0
- package/dist/core/mcp/manager.d.ts.map +1 -0
- package/dist/core/mcp/manager.js +124 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/tools.d.ts +15 -0
- package/dist/core/mcp/tools.d.ts.map +1 -0
- package/dist/core/mcp/tools.js +84 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/memory-engine/audit-export.d.ts +12 -10
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -1
- package/dist/core/memory-engine/audit-export.js +15 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -1
- package/dist/core/memory-engine/audit-indice.d.ts +153 -0
- package/dist/core/memory-engine/audit-indice.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-indice.js +271 -0
- package/dist/core/memory-engine/audit-indice.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts +18 -6
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +25 -42
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +19 -1
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +71 -5
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +0 -2
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +4 -5
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/refinements.d.ts +51 -0
- package/dist/core/memory-engine/refinements.d.ts.map +1 -0
- package/dist/core/memory-engine/refinements.js +99 -0
- package/dist/core/memory-engine/refinements.js.map +1 -0
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +27 -1
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/types.d.ts +2 -0
- package/dist/core/memory-engine/types.d.ts.map +1 -1
- package/dist/core/memory-engine/types.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +7 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/muestreo-restringido.d.ts +49 -0
- package/dist/core/muestreo-restringido.d.ts.map +1 -0
- package/dist/core/muestreo-restringido.js +65 -0
- package/dist/core/muestreo-restringido.js.map +1 -0
- package/dist/core/orphan-process-journal.d.ts +48 -0
- package/dist/core/orphan-process-journal.d.ts.map +1 -0
- package/dist/core/orphan-process-journal.js +116 -0
- package/dist/core/orphan-process-journal.js.map +1 -0
- package/dist/core/privacidad/categorias-especiales.d.ts +186 -0
- package/dist/core/privacidad/categorias-especiales.d.ts.map +1 -0
- package/dist/core/privacidad/categorias-especiales.js +745 -0
- package/dist/core/privacidad/categorias-especiales.js.map +1 -0
- package/dist/core/privacidad/tapar.d.ts +48 -0
- package/dist/core/privacidad/tapar.d.ts.map +1 -0
- package/dist/core/privacidad/tapar.js +66 -0
- package/dist/core/privacidad/tapar.js.map +1 -0
- package/dist/core/prompt-cache/diagnostics.d.ts +33 -0
- package/dist/core/prompt-cache/diagnostics.d.ts.map +1 -0
- package/dist/core/prompt-cache/diagnostics.js +100 -0
- package/dist/core/prompt-cache/diagnostics.js.map +1 -0
- package/dist/core/prompt-cache/index.d.ts +33 -0
- package/dist/core/prompt-cache/index.d.ts.map +1 -0
- package/dist/core/prompt-cache/index.js +189 -0
- package/dist/core/prompt-cache/index.js.map +1 -0
- package/dist/core/prompt-cache/payload.d.ts +58 -0
- package/dist/core/prompt-cache/payload.d.ts.map +1 -0
- package/dist/core/prompt-cache/payload.js +122 -0
- package/dist/core/prompt-cache/payload.js.map +1 -0
- package/dist/core/prompt-cache/stabilize.d.ts +65 -0
- package/dist/core/prompt-cache/stabilize.d.ts.map +1 -0
- package/dist/core/prompt-cache/stabilize.js +137 -0
- package/dist/core/prompt-cache/stabilize.js.map +1 -0
- package/dist/core/prompt-cache/stats.d.ts +55 -0
- package/dist/core/prompt-cache/stats.d.ts.map +1 -0
- package/dist/core/prompt-cache/stats.js +158 -0
- package/dist/core/prompt-cache/stats.js.map +1 -0
- package/dist/core/prompt-eleccion.d.ts +38 -0
- package/dist/core/prompt-eleccion.d.ts.map +1 -0
- package/dist/core/prompt-eleccion.js +46 -0
- package/dist/core/prompt-eleccion.js.map +1 -0
- package/dist/core/prompts/montar.d.ts +75 -0
- package/dist/core/prompts/montar.d.ts.map +1 -0
- package/dist/core/prompts/montar.js +146 -0
- package/dist/core/prompts/montar.js.map +1 -0
- package/dist/core/prompts/plantilla.d.ts +54 -0
- package/dist/core/prompts/plantilla.d.ts.map +1 -0
- package/dist/core/prompts/plantilla.js +153 -0
- package/dist/core/prompts/plantilla.js.map +1 -0
- package/dist/core/prompts/sistema.md +134 -0
- package/dist/core/provider-attribution.d.ts +24 -2
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +24 -42
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remoto/destino.d.ts +38 -0
- package/dist/core/remoto/destino.d.ts.map +1 -0
- package/dist/core/remoto/destino.js +105 -0
- package/dist/core/remoto/destino.js.map +1 -0
- package/dist/core/remoto/ejecutor.d.ts +59 -0
- package/dist/core/remoto/ejecutor.d.ts.map +1 -0
- package/dist/core/remoto/ejecutor.js +225 -0
- package/dist/core/remoto/ejecutor.js.map +1 -0
- package/dist/core/remoto/ficheros.d.ts +29 -0
- package/dist/core/remoto/ficheros.d.ts.map +1 -0
- package/dist/core/remoto/ficheros.js +90 -0
- package/dist/core/remoto/ficheros.js.map +1 -0
- package/dist/core/remoto/registro-extension.d.ts +15 -0
- package/dist/core/remoto/registro-extension.d.ts.map +1 -0
- package/dist/core/remoto/registro-extension.js +17 -0
- package/dist/core/remoto/registro-extension.js.map +1 -0
- package/dist/core/remoto/tools.d.ts +28 -0
- package/dist/core/remoto/tools.d.ts.map +1 -0
- package/dist/core/remoto/tools.js +31 -0
- package/dist/core/remoto/tools.js.map +1 -0
- package/dist/core/resource-loader.d.ts +8 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +93 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/revision/hallazgo.d.ts +51 -0
- package/dist/core/revision/hallazgo.d.ts.map +1 -0
- package/dist/core/revision/hallazgo.js +73 -0
- package/dist/core/revision/hallazgo.js.map +1 -0
- package/dist/core/revision/revisor.d.ts +81 -0
- package/dist/core/revision/revisor.d.ts.map +1 -0
- package/dist/core/revision/revisor.js +132 -0
- package/dist/core/revision/revisor.js.map +1 -0
- package/dist/core/revision/sarif.d.ts +30 -0
- package/dist/core/revision/sarif.d.ts.map +1 -0
- package/dist/core/revision/sarif.js +83 -0
- package/dist/core/revision/sarif.js.map +1 -0
- package/dist/core/scheduler/scheduler.d.ts +87 -0
- package/dist/core/scheduler/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler/scheduler.js +178 -0
- package/dist/core/scheduler/scheduler.js.map +1 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts +49 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts.map +1 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js +77 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js.map +1 -0
- package/dist/core/settings-manager.d.ts +110 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +53 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -3
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +17 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +13 -5
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetria/otlp.d.ts +122 -0
- package/dist/core/telemetria/otlp.d.ts.map +1 -0
- package/dist/core/telemetria/otlp.js +373 -0
- package/dist/core/telemetria/otlp.js.map +1 -0
- package/dist/core/tools/coercion-argumentos.d.ts +48 -0
- package/dist/core/tools/coercion-argumentos.d.ts.map +1 -0
- package/dist/core/tools/coercion-argumentos.js +99 -0
- package/dist/core/tools/coercion-argumentos.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -7
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +232 -7
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +8 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +5 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/json-tolerante.d.ts +30 -0
- package/dist/core/tools/json-tolerante.d.ts.map +1 -0
- package/dist/core/tools/json-tolerante.js +70 -0
- package/dist/core/tools/json-tolerante.js.map +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +17 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +17 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/turno-vacio/detectar.d.ts +38 -0
- package/dist/core/turno-vacio/detectar.d.ts.map +1 -0
- package/dist/core/turno-vacio/detectar.js +66 -0
- package/dist/core/turno-vacio/detectar.js.map +1 -0
- package/dist/core/undo/journal.d.ts +57 -0
- package/dist/core/undo/journal.d.ts.map +1 -0
- package/dist/core/undo/journal.js +178 -0
- package/dist/core/undo/journal.js.map +1 -0
- package/dist/core/urls-internas/auditoria.d.ts +10 -0
- package/dist/core/urls-internas/auditoria.d.ts.map +1 -0
- package/dist/core/urls-internas/auditoria.js +42 -0
- package/dist/core/urls-internas/auditoria.js.map +1 -0
- package/dist/core/urls-internas/boveda.d.ts +13 -0
- package/dist/core/urls-internas/boveda.d.ts.map +1 -0
- package/dist/core/urls-internas/boveda.js +40 -0
- package/dist/core/urls-internas/boveda.js.map +1 -0
- package/dist/core/urls-internas/lector.d.ts +30 -0
- package/dist/core/urls-internas/lector.d.ts.map +1 -0
- package/dist/core/urls-internas/lector.js +56 -0
- package/dist/core/urls-internas/lector.js.map +1 -0
- package/dist/core/urls-internas/memoria.d.ts +11 -0
- package/dist/core/urls-internas/memoria.d.ts.map +1 -0
- package/dist/core/urls-internas/memoria.js +25 -0
- package/dist/core/urls-internas/memoria.js.map +1 -0
- package/dist/core/urls-internas/parse.d.ts +28 -0
- package/dist/core/urls-internas/parse.d.ts.map +1 -0
- package/dist/core/urls-internas/parse.js +32 -0
- package/dist/core/urls-internas/parse.js.map +1 -0
- package/dist/core/urls-internas/reglas.d.ts +10 -0
- package/dist/core/urls-internas/reglas.d.ts.map +1 -0
- package/dist/core/urls-internas/reglas.js +31 -0
- package/dist/core/urls-internas/reglas.js.map +1 -0
- package/dist/core/usage/aggregate.d.ts +68 -0
- package/dist/core/usage/aggregate.d.ts.map +1 -0
- package/dist/core/usage/aggregate.js +93 -0
- package/dist/core/usage/aggregate.js.map +1 -0
- package/dist/core/usage/cuota/anthropic.d.ts +10 -0
- package/dist/core/usage/cuota/anthropic.d.ts.map +1 -0
- package/dist/core/usage/cuota/anthropic.js +63 -0
- package/dist/core/usage/cuota/anthropic.js.map +1 -0
- package/dist/core/usage/cuota/cache.d.ts +20 -0
- package/dist/core/usage/cuota/cache.d.ts.map +1 -0
- package/dist/core/usage/cuota/cache.js +36 -0
- package/dist/core/usage/cuota/cache.js.map +1 -0
- package/dist/core/usage/cuota/github-copilot.d.ts +9 -0
- package/dist/core/usage/cuota/github-copilot.d.ts.map +1 -0
- package/dist/core/usage/cuota/github-copilot.js +67 -0
- package/dist/core/usage/cuota/github-copilot.js.map +1 -0
- package/dist/core/usage/cuota/google-gemini.d.ts +9 -0
- package/dist/core/usage/cuota/google-gemini.d.ts.map +1 -0
- package/dist/core/usage/cuota/google-gemini.js +72 -0
- package/dist/core/usage/cuota/google-gemini.js.map +1 -0
- package/dist/core/usage/cuota/index.d.ts +25 -0
- package/dist/core/usage/cuota/index.d.ts.map +1 -0
- package/dist/core/usage/cuota/index.js +50 -0
- package/dist/core/usage/cuota/index.js.map +1 -0
- package/dist/core/usage/cuota/openai-codex.d.ts +9 -0
- package/dist/core/usage/cuota/openai-codex.d.ts.map +1 -0
- package/dist/core/usage/cuota/openai-codex.js +59 -0
- package/dist/core/usage/cuota/openai-codex.js.map +1 -0
- package/dist/core/usage/cuota/openrouter.d.ts +10 -0
- package/dist/core/usage/cuota/openrouter.d.ts.map +1 -0
- package/dist/core/usage/cuota/openrouter.js +47 -0
- package/dist/core/usage/cuota/openrouter.js.map +1 -0
- package/dist/core/usage/cuota/tipos.d.ts +50 -0
- package/dist/core/usage/cuota/tipos.d.ts.map +1 -0
- package/dist/core/usage/cuota/tipos.js +25 -0
- package/dist/core/usage/cuota/tipos.js.map +1 -0
- package/dist/core/web/busqueda-nativa.d.ts +82 -0
- package/dist/core/web/busqueda-nativa.d.ts.map +1 -0
- package/dist/core/web/busqueda-nativa.js +163 -0
- package/dist/core/web/busqueda-nativa.js.map +1 -0
- package/dist/core/web/destino.d.ts +58 -0
- package/dist/core/web/destino.d.ts.map +1 -0
- package/dist/core/web/destino.js +127 -0
- package/dist/core/web/destino.js.map +1 -0
- package/dist/core/web/proveedores/brave.d.ts +6 -0
- package/dist/core/web/proveedores/brave.d.ts.map +1 -0
- package/dist/core/web/proveedores/brave.js +20 -0
- package/dist/core/web/proveedores/brave.js.map +1 -0
- package/dist/core/web/proveedores/claves.d.ts +19 -0
- package/dist/core/web/proveedores/claves.d.ts.map +1 -0
- package/dist/core/web/proveedores/claves.js +36 -0
- package/dist/core/web/proveedores/claves.js.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts +3 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.js +109 -0
- package/dist/core/web/proveedores/duckduckgo.js.map +1 -0
- package/dist/core/web/proveedores/ecosia.d.ts +3 -0
- package/dist/core/web/proveedores/ecosia.d.ts.map +1 -0
- package/dist/core/web/proveedores/ecosia.js +72 -0
- package/dist/core/web/proveedores/ecosia.js.map +1 -0
- package/dist/core/web/proveedores/exa.d.ts +6 -0
- package/dist/core/web/proveedores/exa.d.ts.map +1 -0
- package/dist/core/web/proveedores/exa.js +24 -0
- package/dist/core/web/proveedores/exa.js.map +1 -0
- package/dist/core/web/proveedores/mojeek.d.ts +3 -0
- package/dist/core/web/proveedores/mojeek.d.ts.map +1 -0
- package/dist/core/web/proveedores/mojeek.js +65 -0
- package/dist/core/web/proveedores/mojeek.js.map +1 -0
- package/dist/core/web/proveedores/navegador.d.ts +10 -0
- package/dist/core/web/proveedores/navegador.d.ts.map +1 -0
- package/dist/core/web/proveedores/navegador.js +13 -0
- package/dist/core/web/proveedores/navegador.js.map +1 -0
- package/dist/core/web/proveedores/registro.d.ts +43 -0
- package/dist/core/web/proveedores/registro.d.ts.map +1 -0
- package/dist/core/web/proveedores/registro.js +49 -0
- package/dist/core/web/proveedores/registro.js.map +1 -0
- package/dist/core/web/proveedores/searxng.d.ts +9 -0
- package/dist/core/web/proveedores/searxng.d.ts.map +1 -0
- package/dist/core/web/proveedores/searxng.js +17 -0
- package/dist/core/web/proveedores/searxng.js.map +1 -0
- package/dist/core/web/proveedores/serper.d.ts +9 -0
- package/dist/core/web/proveedores/serper.d.ts.map +1 -0
- package/dist/core/web/proveedores/serper.js +19 -0
- package/dist/core/web/proveedores/serper.js.map +1 -0
- package/dist/core/web/proveedores/tavily.d.ts +6 -0
- package/dist/core/web/proveedores/tavily.d.ts.map +1 -0
- package/dist/core/web/proveedores/tavily.js +19 -0
- package/dist/core/web/proveedores/tavily.js.map +1 -0
- package/dist/core/web/proveedores/tipos.d.ts +36 -0
- package/dist/core/web/proveedores/tipos.d.ts.map +1 -0
- package/dist/core/web/proveedores/tipos.js +10 -0
- package/dist/core/web/proveedores/tipos.js.map +1 -0
- package/dist/core/web/registro-red.d.ts +43 -0
- package/dist/core/web/registro-red.d.ts.map +1 -0
- package/dist/core/web/registro-red.js +86 -0
- package/dist/core/web/registro-red.js.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts +10 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.js +38 -0
- package/dist/core/web/scrapers/cisa-kev.js.map +1 -0
- package/dist/core/web/scrapers/crates-io.d.ts +11 -0
- package/dist/core/web/scrapers/crates-io.d.ts.map +1 -0
- package/dist/core/web/scrapers/crates-io.js +29 -0
- package/dist/core/web/scrapers/crates-io.js.map +1 -0
- package/dist/core/web/scrapers/docs-rs.d.ts +10 -0
- package/dist/core/web/scrapers/docs-rs.d.ts.map +1 -0
- package/dist/core/web/scrapers/docs-rs.js +35 -0
- package/dist/core/web/scrapers/docs-rs.js.map +1 -0
- package/dist/core/web/scrapers/github.d.ts +3 -0
- package/dist/core/web/scrapers/github.d.ts.map +1 -0
- package/dist/core/web/scrapers/github.js +72 -0
- package/dist/core/web/scrapers/github.js.map +1 -0
- package/dist/core/web/scrapers/go-pkg.d.ts +7 -0
- package/dist/core/web/scrapers/go-pkg.d.ts.map +1 -0
- package/dist/core/web/scrapers/go-pkg.js +30 -0
- package/dist/core/web/scrapers/go-pkg.js.map +1 -0
- package/dist/core/web/scrapers/hex.d.ts +6 -0
- package/dist/core/web/scrapers/hex.d.ts.map +1 -0
- package/dist/core/web/scrapers/hex.js +27 -0
- package/dist/core/web/scrapers/hex.js.map +1 -0
- package/dist/core/web/scrapers/maven.d.ts +8 -0
- package/dist/core/web/scrapers/maven.d.ts.map +1 -0
- package/dist/core/web/scrapers/maven.js +41 -0
- package/dist/core/web/scrapers/maven.js.map +1 -0
- package/dist/core/web/scrapers/mdn.d.ts +6 -0
- package/dist/core/web/scrapers/mdn.d.ts.map +1 -0
- package/dist/core/web/scrapers/mdn.js +28 -0
- package/dist/core/web/scrapers/mdn.js.map +1 -0
- package/dist/core/web/scrapers/npm.d.ts +11 -0
- package/dist/core/web/scrapers/npm.d.ts.map +1 -0
- package/dist/core/web/scrapers/npm.js +57 -0
- package/dist/core/web/scrapers/npm.js.map +1 -0
- package/dist/core/web/scrapers/nuget.d.ts +8 -0
- package/dist/core/web/scrapers/nuget.d.ts.map +1 -0
- package/dist/core/web/scrapers/nuget.js +22 -0
- package/dist/core/web/scrapers/nuget.js.map +1 -0
- package/dist/core/web/scrapers/nvd.d.ts +7 -0
- package/dist/core/web/scrapers/nvd.d.ts.map +1 -0
- package/dist/core/web/scrapers/nvd.js +37 -0
- package/dist/core/web/scrapers/nvd.js.map +1 -0
- package/dist/core/web/scrapers/pypi.d.ts +6 -0
- package/dist/core/web/scrapers/pypi.d.ts.map +1 -0
- package/dist/core/web/scrapers/pypi.js +31 -0
- package/dist/core/web/scrapers/pypi.js.map +1 -0
- package/dist/core/web/scrapers/registro.d.ts +13 -0
- package/dist/core/web/scrapers/registro.d.ts.map +1 -0
- package/dist/core/web/scrapers/registro.js +65 -0
- package/dist/core/web/scrapers/registro.js.map +1 -0
- package/dist/core/web/scrapers/rubygems.d.ts +6 -0
- package/dist/core/web/scrapers/rubygems.d.ts.map +1 -0
- package/dist/core/web/scrapers/rubygems.js +23 -0
- package/dist/core/web/scrapers/rubygems.js.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts +3 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.js +46 -0
- package/dist/core/web/scrapers/stackoverflow.js.map +1 -0
- package/dist/core/web/scrapers/tipos.d.ts +42 -0
- package/dist/core/web/scrapers/tipos.d.ts.map +1 -0
- package/dist/core/web/scrapers/tipos.js +23 -0
- package/dist/core/web/scrapers/tipos.js.map +1 -0
- package/dist/core/web/texto.d.ts +10 -0
- package/dist/core/web/texto.d.ts.map +1 -0
- package/dist/core/web/texto.js +26 -0
- package/dist/core/web/texto.js.map +1 -0
- package/dist/core/web/tools.d.ts +91 -0
- package/dist/core/web/tools.d.ts.map +1 -0
- package/dist/core/web/tools.js +304 -0
- package/dist/core/web/tools.js.map +1 -0
- package/dist/core/wiki/almacen.d.ts +33 -0
- package/dist/core/wiki/almacen.d.ts.map +1 -0
- package/dist/core/wiki/almacen.js +93 -0
- package/dist/core/wiki/almacen.js.map +1 -0
- package/dist/core/wiki/citas.d.ts +111 -0
- package/dist/core/wiki/citas.d.ts.map +1 -0
- package/dist/core/wiki/citas.js +146 -0
- package/dist/core/wiki/citas.js.map +1 -0
- package/dist/core/workflows/agent-runner.d.ts +2 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -1
- package/dist/core/workflows/agent-runner.js +131 -44
- package/dist/core/workflows/agent-runner.js.map +1 -1
- package/dist/core/workflows/builtins.d.ts.map +1 -1
- package/dist/core/workflows/builtins.js +1 -0
- package/dist/core/workflows/builtins.js.map +1 -1
- package/dist/core/workflows/contrato/esquema.d.ts +32 -0
- package/dist/core/workflows/contrato/esquema.d.ts.map +1 -0
- package/dist/core/workflows/contrato/esquema.js +25 -0
- package/dist/core/workflows/contrato/esquema.js.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts +69 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js +117 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js.map +1 -0
- package/dist/core/workflows/contrato/validador.d.ts +30 -0
- package/dist/core/workflows/contrato/validador.d.ts.map +1 -0
- package/dist/core/workflows/contrato/validador.js +56 -0
- package/dist/core/workflows/contrato/validador.js.map +1 -0
- package/dist/core/workflows/contrato/yield.d.ts +65 -0
- package/dist/core/workflows/contrato/yield.d.ts.map +1 -0
- package/dist/core/workflows/contrato/yield.js +80 -0
- package/dist/core/workflows/contrato/yield.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +17 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -1
- package/dist/core/workflows/goal-engine/engine.js +41 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -1
- package/dist/core/workflows/index.d.ts +8 -0
- package/dist/core/workflows/index.d.ts.map +1 -1
- package/dist/core/workflows/index.js +4 -0
- package/dist/core/workflows/index.js.map +1 -1
- package/dist/core/workflows/manager.d.ts +10 -0
- package/dist/core/workflows/manager.d.ts.map +1 -1
- package/dist/core/workflows/manager.js +35 -11
- package/dist/core/workflows/manager.js.map +1 -1
- package/dist/core/workflows/runtime.d.ts +13 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -1
- package/dist/core/workflows/runtime.js +80 -1
- package/dist/core/workflows/runtime.js.map +1 -1
- package/dist/core/workflows/save-as-skill.d.ts +27 -0
- package/dist/core/workflows/save-as-skill.d.ts.map +1 -0
- package/dist/core/workflows/save-as-skill.js +54 -0
- package/dist/core/workflows/save-as-skill.js.map +1 -0
- package/dist/core/workflows/types.d.ts +49 -0
- package/dist/core/workflows/types.d.ts.map +1 -1
- package/dist/core/workflows/types.js.map +1 -1
- package/dist/extensions/remoto/index.d.ts +22 -0
- package/dist/extensions/remoto/index.d.ts.map +1 -0
- package/dist/extensions/remoto/index.js +54 -0
- package/dist/extensions/remoto/index.js.map +1 -0
- package/dist/index.d.ts +1 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -16
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts +42 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +190 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/events.d.ts +74 -0
- package/dist/modes/acp/events.d.ts.map +1 -0
- package/dist/modes/acp/events.js +116 -0
- package/dist/modes/acp/events.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +8 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +41 -7
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +9 -86
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +48 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +137 -146
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +11 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +27 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/attach.d.ts +56 -0
- package/dist/server/attach.d.ts.map +1 -0
- package/dist/server/attach.js +130 -0
- package/dist/server/attach.js.map +1 -0
- package/dist/server/extension-ops.d.ts +40 -0
- package/dist/server/extension-ops.d.ts.map +1 -0
- package/dist/server/extension-ops.js +146 -0
- package/dist/server/extension-ops.js.map +1 -0
- package/dist/server/pi-server-service.d.ts +85 -0
- package/dist/server/pi-server-service.d.ts.map +1 -0
- package/dist/server/pi-server-service.js +213 -0
- package/dist/server/pi-server-service.js.map +1 -0
- package/dist/server/scheduler-tick.d.ts +32 -0
- package/dist/server/scheduler-tick.d.ts.map +1 -0
- package/dist/server/scheduler-tick.js +47 -0
- package/dist/server/scheduler-tick.js.map +1 -0
- package/dist/server/serve.d.ts +25 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/server/serve.js +83 -0
- package/dist/server/serve.js.map +1 -0
- package/dist/server/transcript.d.ts +38 -0
- package/dist/server/transcript.d.ts.map +1 -0
- package/dist/server/transcript.js +176 -0
- package/dist/server/transcript.js.map +1 -0
- package/dist/skills/skill-creator/SKILL.md +90 -0
- package/dist/telegram/api.d.ts +75 -0
- package/dist/telegram/api.d.ts.map +1 -0
- package/dist/telegram/api.js +104 -0
- package/dist/telegram/api.js.map +1 -0
- package/dist/telegram/bridge.d.ts +85 -0
- package/dist/telegram/bridge.d.ts.map +1 -0
- package/dist/telegram/bridge.js +182 -0
- package/dist/telegram/bridge.js.map +1 -0
- package/dist/telegram/journal.d.ts +67 -0
- package/dist/telegram/journal.d.ts.map +1 -0
- package/dist/telegram/journal.js +119 -0
- package/dist/telegram/journal.js.map +1 -0
- package/dist/telegram/servidor.d.ts +15 -0
- package/dist/telegram/servidor.d.ts.map +1 -0
- package/dist/telegram/servidor.js +74 -0
- package/dist/telegram/servidor.js.map +1 -0
- package/dist/utils/shell.d.ts +11 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +11 -0
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +29 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +10 -10
- package/docs/compliance.md +241 -0
- package/docs/containerization.md +24 -24
- package/docs/custom-provider.md +10 -10
- package/docs/development.md +47 -10
- package/docs/docs.json +14 -2
- package/docs/environment-variables.md +20 -17
- package/docs/extensions.md +51 -49
- package/docs/index.md +15 -21
- package/docs/json.md +3 -3
- package/docs/keybindings.md +5 -5
- package/docs/llama-cpp.md +7 -7
- package/docs/models.md +12 -12
- package/docs/packages.md +45 -45
- package/docs/prompt-templates.md +5 -5
- package/docs/providers.md +12 -12
- package/docs/quickstart.md +39 -39
- package/docs/rpc.md +12 -12
- package/docs/sdk.md +38 -38
- package/docs/security.md +26 -21
- package/docs/session-format.md +7 -7
- package/docs/sessions.md +14 -14
- package/docs/settings.md +45 -20
- package/docs/shell-aliases.md +2 -2
- package/docs/skills.md +11 -11
- package/docs/terminal-setup.md +14 -14
- package/docs/termux.md +7 -7
- package/docs/themes.md +11 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +3 -3
- package/docs/usage.md +54 -54
- package/docs/windows.md +2 -2
- package/examples/sdk/12-full-control.ts +9 -0
- package/npm-shrinkwrap.json +35 -251
- package/package.json +10 -4
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Búsqueda web con la credencial que el usuario YA tiene.
|
|
3
|
+
*
|
|
4
|
+
* Hasta ahora `web_search` exigía una clave de Serper aparte, así que la
|
|
5
|
+
* respuesta de fábrica era «Búsqueda web no configurada». Un agente de código
|
|
6
|
+
* que no puede mirar la documentación de una librería está cojo, y pedir una
|
|
7
|
+
* segunda cuenta para eso es una fricción que el usuario paga antes de haber
|
|
8
|
+
* visto ningún valor.
|
|
9
|
+
*
|
|
10
|
+
* Los modelos de Anthropic traen búsqueda de servidor (`web_search_20250305`).
|
|
11
|
+
* Si hay credencial de Anthropic —y la hay, porque es con lo que corre el
|
|
12
|
+
* agente— buscar puede funcionar sin configurar nada.
|
|
13
|
+
*
|
|
14
|
+
* Dos detalles que no son evidentes y que se descubrieron probándolo:
|
|
15
|
+
*
|
|
16
|
+
* 1. **Los resultados no llegan por el contenido del mensaje.** Nuestra capa de
|
|
17
|
+
* modelos normaliza la respuesta a texto/razonamiento/llamadas, y los
|
|
18
|
+
* bloques `web_search_tool_result` se pierden por el camino. Pedirle al
|
|
19
|
+
* modelo que los liste en el texto tampoco vale: se probó, y contesta la
|
|
20
|
+
* pregunta en vez de listar fuentes. Hay que leer el flujo crudo.
|
|
21
|
+
*
|
|
22
|
+
* 2. **Se lee sin tocar la capa de modelos**, pasando un `fetch` propio que
|
|
23
|
+
* duplica el cuerpo con `tee()`: una rama sigue al SDK intacta y la otra se
|
|
24
|
+
* analiza aquí. `agent-session.ts` y `packages/ai` son de upstream y el
|
|
25
|
+
* presupuesto de fork está en el tope; esto no cuesta ni un hunk.
|
|
26
|
+
*/
|
|
27
|
+
/** La tool de servidor de Anthropic. */
|
|
28
|
+
const TOOL_BUSQUEDA = "web_search_20250305";
|
|
29
|
+
/** Proveedores cuyo modelo sabe buscar por su cuenta. */
|
|
30
|
+
export function soportaBusquedaNativa(proveedor) {
|
|
31
|
+
return proveedor === "anthropic";
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Añade la tool de búsqueda a la carga de la petición, sin pisar las que haya.
|
|
35
|
+
*
|
|
36
|
+
* Pura y separada para poder probarla: si esto machacara `tools`, el modelo se
|
|
37
|
+
* quedaría sin sus herramientas y el fallo aparecería en cualquier otro sitio.
|
|
38
|
+
*/
|
|
39
|
+
export function conToolDeBusqueda(carga, maxUsos = 5) {
|
|
40
|
+
if (!carga || typeof carga !== "object")
|
|
41
|
+
return carga;
|
|
42
|
+
const p = carga;
|
|
43
|
+
p.tools = [...(p.tools ?? []), { type: TOOL_BUSQUEDA, name: "web_search", max_uses: maxUsos }];
|
|
44
|
+
return p;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Recorre cualquier estructura y recoge los resultados de búsqueda.
|
|
48
|
+
*
|
|
49
|
+
* Se busca por el campo `type` en vez de por la ruta exacta del evento a
|
|
50
|
+
* propósito: el formato de los eventos SSE puede cambiar de sitio los bloques,
|
|
51
|
+
* y un recolector que dependa de la ruta se rompe en silencio —devolviendo cero
|
|
52
|
+
* resultados, que se lee igual que «no hay nada»—.
|
|
53
|
+
*/
|
|
54
|
+
export function recolectarResultados(valor, acumulado = []) {
|
|
55
|
+
if (Array.isArray(valor)) {
|
|
56
|
+
for (const v of valor)
|
|
57
|
+
recolectarResultados(v, acumulado);
|
|
58
|
+
return acumulado;
|
|
59
|
+
}
|
|
60
|
+
if (!valor || typeof valor !== "object")
|
|
61
|
+
return acumulado;
|
|
62
|
+
const o = valor;
|
|
63
|
+
if (o.type === "web_search_result" && typeof o.url === "string") {
|
|
64
|
+
acumulado.push({
|
|
65
|
+
titulo: typeof o.title === "string" ? o.title : o.url,
|
|
66
|
+
url: o.url,
|
|
67
|
+
edad: typeof o.page_age === "string" ? o.page_age : undefined,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
for (const v of Object.values(o))
|
|
71
|
+
recolectarResultados(v, acumulado);
|
|
72
|
+
return acumulado;
|
|
73
|
+
}
|
|
74
|
+
/** Quita repetidos por URL, conservando el orden de aparición. */
|
|
75
|
+
export function sinRepetidos(resultados) {
|
|
76
|
+
const vistas = new Set();
|
|
77
|
+
const unicos = [];
|
|
78
|
+
for (const r of resultados) {
|
|
79
|
+
if (vistas.has(r.url))
|
|
80
|
+
continue;
|
|
81
|
+
vistas.add(r.url);
|
|
82
|
+
unicos.push(r);
|
|
83
|
+
}
|
|
84
|
+
return unicos;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Envuelve un `fetch` para leer los resultados sin estorbar a quien lo usa.
|
|
88
|
+
*
|
|
89
|
+
* `tee()` da dos flujos: uno se devuelve intacto —el SDK tiene que recibir
|
|
90
|
+
* exactamente lo que habría recibido— y el otro se analiza aquí. Si el análisis
|
|
91
|
+
* falla, falla solo: una búsqueda sin fuentes es peor que una con fuentes, pero
|
|
92
|
+
* una sesión rota por el analizador es mucho peor que las dos.
|
|
93
|
+
*/
|
|
94
|
+
export function fetchQueRecolecta(base, destino) {
|
|
95
|
+
return async (...args) => {
|
|
96
|
+
const respuesta = await base(...args);
|
|
97
|
+
if (!respuesta.body)
|
|
98
|
+
return respuesta;
|
|
99
|
+
const [paraElSdk, paraNosotros] = respuesta.body.tee();
|
|
100
|
+
void (async () => {
|
|
101
|
+
const lector = paraNosotros.getReader();
|
|
102
|
+
const decodificador = new TextDecoder();
|
|
103
|
+
let pendiente = "";
|
|
104
|
+
try {
|
|
105
|
+
for (;;) {
|
|
106
|
+
const { done, value } = await lector.read();
|
|
107
|
+
if (done)
|
|
108
|
+
break;
|
|
109
|
+
pendiente += decodificador.decode(value, { stream: true });
|
|
110
|
+
const lineas = pendiente.split("\n");
|
|
111
|
+
// La última puede estar a medias: se queda para la próxima vuelta.
|
|
112
|
+
pendiente = lineas.pop() ?? "";
|
|
113
|
+
for (const linea of lineas) {
|
|
114
|
+
if (!linea.startsWith("data: "))
|
|
115
|
+
continue;
|
|
116
|
+
try {
|
|
117
|
+
recolectarResultados(JSON.parse(linea.slice(6)), destino);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Una línea que no es JSON no dice nada del resto del flujo.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// El flujo puede acabar sin salto final, y entonces el último evento
|
|
125
|
+
// se queda en `pendiente`. Perderlo silenciosamente equivaldría a
|
|
126
|
+
// devolver una fuente menos sin que nadie lo note.
|
|
127
|
+
if (pendiente.startsWith("data: ")) {
|
|
128
|
+
try {
|
|
129
|
+
recolectarResultados(JSON.parse(pendiente.slice(6)), destino);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Una cola incompleta no es un error: es una cola incompleta.
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// La rama de análisis nunca puede tumbar la petición.
|
|
138
|
+
}
|
|
139
|
+
})();
|
|
140
|
+
return new Response(paraElSdk, {
|
|
141
|
+
status: respuesta.status,
|
|
142
|
+
statusText: respuesta.statusText,
|
|
143
|
+
headers: respuesta.headers,
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Busca y devuelve las fuentes.
|
|
149
|
+
*
|
|
150
|
+
* No devuelve la síntesis del modelo a propósito: quien llama es el agente, que
|
|
151
|
+
* ya sabe leer. Lo que necesita de una búsqueda son URLs a las que ir con
|
|
152
|
+
* `web_fetch`, no un resumen de segunda mano que ya viene con la
|
|
153
|
+
* interpretación de otro modelo encima.
|
|
154
|
+
*/
|
|
155
|
+
export async function buscarConElModelo(consulta, deps) {
|
|
156
|
+
const encontrados = [];
|
|
157
|
+
await deps.completar(consulta, {
|
|
158
|
+
fetch: fetchQueRecolecta(deps.fetchBase ?? fetch, encontrados),
|
|
159
|
+
onPayload: (carga) => conToolDeBusqueda(carga),
|
|
160
|
+
});
|
|
161
|
+
return sinRepetidos(encontrados).slice(0, deps.maxResultados ?? 10);
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=busqueda-nativa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"busqueda-nativa.js","sourceRoot":"","sources":["../../../src/core/web/busqueda-nativa.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Búsqueda web con la credencial que el usuario YA tiene.\n *\n * Hasta ahora `web_search` exigía una clave de Serper aparte, así que la\n * respuesta de fábrica era «Búsqueda web no configurada». Un agente de código\n * que no puede mirar la documentación de una librería está cojo, y pedir una\n * segunda cuenta para eso es una fricción que el usuario paga antes de haber\n * visto ningún valor.\n *\n * Los modelos de Anthropic traen búsqueda de servidor (`web_search_20250305`).\n * Si hay credencial de Anthropic —y la hay, porque es con lo que corre el\n * agente— buscar puede funcionar sin configurar nada.\n *\n * Dos detalles que no son evidentes y que se descubrieron probándolo:\n *\n * 1. **Los resultados no llegan por el contenido del mensaje.** Nuestra capa de\n * modelos normaliza la respuesta a texto/razonamiento/llamadas, y los\n * bloques `web_search_tool_result` se pierden por el camino. Pedirle al\n * modelo que los liste en el texto tampoco vale: se probó, y contesta la\n * pregunta en vez de listar fuentes. Hay que leer el flujo crudo.\n *\n * 2. **Se lee sin tocar la capa de modelos**, pasando un `fetch` propio que\n * duplica el cuerpo con `tee()`: una rama sigue al SDK intacta y la otra se\n * analiza aquí. `agent-session.ts` y `packages/ai` son de upstream y el\n * presupuesto de fork está en el tope; esto no cuesta ni un hunk.\n */\n\n/** Un resultado, ya normalizado. */\nexport interface ResultadoWeb {\n\ttitulo: string;\n\turl: string;\n\t/** Antigüedad tal y como la da el proveedor (\"3 weeks ago\", \"June 8, 2026\"). */\n\tedad?: string;\n}\n\n/** La tool de servidor de Anthropic. */\nconst TOOL_BUSQUEDA = \"web_search_20250305\";\n\n/** Proveedores cuyo modelo sabe buscar por su cuenta. */\nexport function soportaBusquedaNativa(proveedor: string): boolean {\n\treturn proveedor === \"anthropic\";\n}\n\n/**\n * Añade la tool de búsqueda a la carga de la petición, sin pisar las que haya.\n *\n * Pura y separada para poder probarla: si esto machacara `tools`, el modelo se\n * quedaría sin sus herramientas y el fallo aparecería en cualquier otro sitio.\n */\nexport function conToolDeBusqueda(carga: unknown, maxUsos = 5): unknown {\n\tif (!carga || typeof carga !== \"object\") return carga;\n\tconst p = carga as { tools?: unknown[] };\n\tp.tools = [...(p.tools ?? []), { type: TOOL_BUSQUEDA, name: \"web_search\", max_uses: maxUsos }];\n\treturn p;\n}\n\n/**\n * Recorre cualquier estructura y recoge los resultados de búsqueda.\n *\n * Se busca por el campo `type` en vez de por la ruta exacta del evento a\n * propósito: el formato de los eventos SSE puede cambiar de sitio los bloques,\n * y un recolector que dependa de la ruta se rompe en silencio —devolviendo cero\n * resultados, que se lee igual que «no hay nada»—.\n */\nexport function recolectarResultados(valor: unknown, acumulado: ResultadoWeb[] = []): ResultadoWeb[] {\n\tif (Array.isArray(valor)) {\n\t\tfor (const v of valor) recolectarResultados(v, acumulado);\n\t\treturn acumulado;\n\t}\n\tif (!valor || typeof valor !== \"object\") return acumulado;\n\tconst o = valor as Record<string, unknown>;\n\tif (o.type === \"web_search_result\" && typeof o.url === \"string\") {\n\t\tacumulado.push({\n\t\t\ttitulo: typeof o.title === \"string\" ? o.title : o.url,\n\t\t\turl: o.url,\n\t\t\tedad: typeof o.page_age === \"string\" ? o.page_age : undefined,\n\t\t});\n\t}\n\tfor (const v of Object.values(o)) recolectarResultados(v, acumulado);\n\treturn acumulado;\n}\n\n/** Quita repetidos por URL, conservando el orden de aparición. */\nexport function sinRepetidos(resultados: ResultadoWeb[]): ResultadoWeb[] {\n\tconst vistas = new Set<string>();\n\tconst unicos: ResultadoWeb[] = [];\n\tfor (const r of resultados) {\n\t\tif (vistas.has(r.url)) continue;\n\t\tvistas.add(r.url);\n\t\tunicos.push(r);\n\t}\n\treturn unicos;\n}\n\n/**\n * Envuelve un `fetch` para leer los resultados sin estorbar a quien lo usa.\n *\n * `tee()` da dos flujos: uno se devuelve intacto —el SDK tiene que recibir\n * exactamente lo que habría recibido— y el otro se analiza aquí. Si el análisis\n * falla, falla solo: una búsqueda sin fuentes es peor que una con fuentes, pero\n * una sesión rota por el analizador es mucho peor que las dos.\n */\nexport function fetchQueRecolecta(base: typeof fetch, destino: ResultadoWeb[]): typeof fetch {\n\treturn async (...args) => {\n\t\tconst respuesta = await base(...args);\n\t\tif (!respuesta.body) return respuesta;\n\t\tconst [paraElSdk, paraNosotros] = respuesta.body.tee();\n\n\t\tvoid (async () => {\n\t\t\tconst lector = paraNosotros.getReader();\n\t\t\tconst decodificador = new TextDecoder();\n\t\t\tlet pendiente = \"\";\n\t\t\ttry {\n\t\t\t\tfor (;;) {\n\t\t\t\t\tconst { done, value } = await lector.read();\n\t\t\t\t\tif (done) break;\n\t\t\t\t\tpendiente += decodificador.decode(value, { stream: true });\n\t\t\t\t\tconst lineas = pendiente.split(\"\\n\");\n\t\t\t\t\t// La última puede estar a medias: se queda para la próxima vuelta.\n\t\t\t\t\tpendiente = lineas.pop() ?? \"\";\n\t\t\t\t\tfor (const linea of lineas) {\n\t\t\t\t\t\tif (!linea.startsWith(\"data: \")) continue;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\trecolectarResultados(JSON.parse(linea.slice(6)), destino);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Una línea que no es JSON no dice nada del resto del flujo.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// El flujo puede acabar sin salto final, y entonces el último evento\n\t\t\t\t// se queda en `pendiente`. Perderlo silenciosamente equivaldría a\n\t\t\t\t// devolver una fuente menos sin que nadie lo note.\n\t\t\t\tif (pendiente.startsWith(\"data: \")) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\trecolectarResultados(JSON.parse(pendiente.slice(6)), destino);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Una cola incompleta no es un error: es una cola incompleta.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// La rama de análisis nunca puede tumbar la petición.\n\t\t\t}\n\t\t})();\n\n\t\treturn new Response(paraElSdk, {\n\t\t\tstatus: respuesta.status,\n\t\t\tstatusText: respuesta.statusText,\n\t\t\theaders: respuesta.headers,\n\t\t});\n\t};\n}\n\n/** Lo que hace falta para buscar, inyectado para poder probarlo sin red. */\nexport interface DependenciasBusqueda {\n\t/** Ejecuta una consulta contra el modelo con las opciones dadas. */\n\tcompletar: (\n\t\tconsulta: string,\n\t\topciones: { fetch: typeof fetch; onPayload: (c: unknown) => unknown },\n\t) => Promise<void>;\n\tfetchBase?: typeof fetch;\n\tmaxResultados?: number;\n}\n\n/**\n * Busca y devuelve las fuentes.\n *\n * No devuelve la síntesis del modelo a propósito: quien llama es el agente, que\n * ya sabe leer. Lo que necesita de una búsqueda son URLs a las que ir con\n * `web_fetch`, no un resumen de segunda mano que ya viene con la\n * interpretación de otro modelo encima.\n */\nexport async function buscarConElModelo(consulta: string, deps: DependenciasBusqueda): Promise<ResultadoWeb[]> {\n\tconst encontrados: ResultadoWeb[] = [];\n\tawait deps.completar(consulta, {\n\t\tfetch: fetchQueRecolecta(deps.fetchBase ?? fetch, encontrados),\n\t\tonPayload: (carga) => conToolDeBusqueda(carga),\n\t});\n\treturn sinRepetidos(encontrados).slice(0, deps.maxResultados ?? 10);\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ¿A dónde va de verdad esta URL?
|
|
3
|
+
*
|
|
4
|
+
* EL FALLO. `assertFetchableUrl` compara el NOMBRE del host contra una lista y
|
|
5
|
+
* unas expresiones regulares. Eso para lo evidente y deja pasar todo lo que
|
|
6
|
+
* llega a la misma dirección por otro camino. Medido sobre nuestra guarda:
|
|
7
|
+
*
|
|
8
|
+
* http://127.0.0.1:8080/secreto bloqueado
|
|
9
|
+
* http://localhost:8080/secreto bloqueado
|
|
10
|
+
* http://[::1]:8080/secreto bloqueado
|
|
11
|
+
* http://[::ffff:127.0.0.1]:8080/secreto PASA ← IPv4 mapeada en IPv6
|
|
12
|
+
* http://localtest.me:8080/secreto PASA ← resuelve a 127.0.0.1
|
|
13
|
+
*
|
|
14
|
+
* Y había un tercero: `redirect: "follow"`. Una URL pública que responde 302
|
|
15
|
+
* hacia loopback llega igual, porque la guarda solo mira la primera.
|
|
16
|
+
*
|
|
17
|
+
* Para un agente esto es serio: el modelo puede pedir una descarga con una URL
|
|
18
|
+
* que parece de internet y acabar leyendo el panel de administración de la red
|
|
19
|
+
* interna, o el endpoint de metadatos de la nube — que es donde viven las
|
|
20
|
+
* credenciales de la máquina.
|
|
21
|
+
*
|
|
22
|
+
* LA CAUSA RAÍZ, y por eso este módulo existe aparte: un nombre no es un
|
|
23
|
+
* destino. Lo único que dice a dónde va una petición es la DIRECCIÓN a la que
|
|
24
|
+
* resuelve, así que hay que resolverla y mirarla. Las comprobaciones por nombre
|
|
25
|
+
* se quedan, pero como filtro barato de primera pasada, no como la defensa.
|
|
26
|
+
*
|
|
27
|
+
* LO QUE NO RESUELVE, dicho antes de que lo descubra nadie: entre que
|
|
28
|
+
* resolvemos y que la petición sale, el DNS puede cambiar de respuesta —el
|
|
29
|
+
* ataque clásico de «rebind». Cerrarlo del todo exige fijar la dirección
|
|
30
|
+
* resuelta al abrir la conexión, que es cosa del agente HTTP y no de aquí.
|
|
31
|
+
* Contra un servidor hostil que controle su propio DNS esto sube el listón; no
|
|
32
|
+
* lo cierra.
|
|
33
|
+
*/
|
|
34
|
+
/** Por qué se rechaza un destino. Nunca una lista vacía silenciosa. */
|
|
35
|
+
export interface DestinoRechazado {
|
|
36
|
+
motivo: string;
|
|
37
|
+
/** La dirección concreta que lo delató, cuando la hay. */
|
|
38
|
+
direccion?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* ¿Esta dirección IP es de una red que no debe alcanzarse desde una tool web?
|
|
42
|
+
*
|
|
43
|
+
* Se trabaja sobre la dirección ya resuelta, así que da igual cómo se escribió
|
|
44
|
+
* el host: decimal, octal, mapeada en IPv6 o un dominio que apunta ahí.
|
|
45
|
+
*/
|
|
46
|
+
export declare function direccionInterna(ip: string): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Resuelve el host y comprueba TODAS las direcciones que devuelve.
|
|
49
|
+
*
|
|
50
|
+
* Todas, no la primera: un dominio puede devolver una dirección pública y otra
|
|
51
|
+
* interna, y quedarse con una sola convierte la defensa en una moneda al aire.
|
|
52
|
+
*
|
|
53
|
+
* Un fallo de resolución NO es un permiso. Se devuelve rechazo con su motivo:
|
|
54
|
+
* «no he podido comprobarlo» y «está bien» son cosas distintas, y aquí
|
|
55
|
+
* confundirlas es abrir la puerta.
|
|
56
|
+
*/
|
|
57
|
+
export declare function destinoPermitido(url: URL): Promise<DestinoRechazado | null>;
|
|
58
|
+
//# sourceMappingURL=destino.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destino.d.ts","sourceRoot":"","sources":["../../../src/core/web/destino.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,yEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwC1D;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAwBjF","sourcesContent":["/**\n * ¿A dónde va de verdad esta URL?\n *\n * EL FALLO. `assertFetchableUrl` compara el NOMBRE del host contra una lista y\n * unas expresiones regulares. Eso para lo evidente y deja pasar todo lo que\n * llega a la misma dirección por otro camino. Medido sobre nuestra guarda:\n *\n * http://127.0.0.1:8080/secreto bloqueado\n * http://localhost:8080/secreto bloqueado\n * http://[::1]:8080/secreto bloqueado\n * http://[::ffff:127.0.0.1]:8080/secreto PASA ← IPv4 mapeada en IPv6\n * http://localtest.me:8080/secreto PASA ← resuelve a 127.0.0.1\n *\n * Y había un tercero: `redirect: \"follow\"`. Una URL pública que responde 302\n * hacia loopback llega igual, porque la guarda solo mira la primera.\n *\n * Para un agente esto es serio: el modelo puede pedir una descarga con una URL\n * que parece de internet y acabar leyendo el panel de administración de la red\n * interna, o el endpoint de metadatos de la nube — que es donde viven las\n * credenciales de la máquina.\n *\n * LA CAUSA RAÍZ, y por eso este módulo existe aparte: un nombre no es un\n * destino. Lo único que dice a dónde va una petición es la DIRECCIÓN a la que\n * resuelve, así que hay que resolverla y mirarla. Las comprobaciones por nombre\n * se quedan, pero como filtro barato de primera pasada, no como la defensa.\n *\n * LO QUE NO RESUELVE, dicho antes de que lo descubra nadie: entre que\n * resolvemos y que la petición sale, el DNS puede cambiar de respuesta —el\n * ataque clásico de «rebind». Cerrarlo del todo exige fijar la dirección\n * resuelta al abrir la conexión, que es cosa del agente HTTP y no de aquí.\n * Contra un servidor hostil que controle su propio DNS esto sube el listón; no\n * lo cierra.\n */\n\nimport { lookup } from \"node:dns/promises\";\n\n/** Por qué se rechaza un destino. Nunca una lista vacía silenciosa. */\nexport interface DestinoRechazado {\n\tmotivo: string;\n\t/** La dirección concreta que lo delató, cuando la hay. */\n\tdireccion?: string;\n}\n\n/**\n * ¿Esta dirección IP es de una red que no debe alcanzarse desde una tool web?\n *\n * Se trabaja sobre la dirección ya resuelta, así que da igual cómo se escribió\n * el host: decimal, octal, mapeada en IPv6 o un dominio que apunta ahí.\n */\nexport function direccionInterna(ip: string): string | null {\n\tconst limpia = ip.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n\t// IPv4 mapeada en IPv6: se desenvuelve y se juzga como IPv4, que es lo que\n\t// era. Sin esto, `[::ffff:127.0.0.1]` pasaba entera.\n\t//\n\t// Hay que cubrir LAS DOS FORMAS, y esto casi se me escapa: `new URL()`\n\t// normaliza `[::ffff:127.0.0.1]` a `[::ffff:7f00:1]`, en hexadecimal. Una\n\t// guarda que solo mirara la forma decimal daría verde sobre la única forma\n\t// que llega de verdad desde una URL.\n\tlet dir = limpia;\n\tconst decimal = limpia.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\n\tif (decimal) {\n\t\tdir = decimal[1];\n\t} else {\n\t\tconst hex = limpia.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n\t\tif (hex) {\n\t\t\tconst alto = Number.parseInt(hex[1], 16);\n\t\t\tconst bajo = Number.parseInt(hex[2], 16);\n\t\t\tdir = `${alto >> 8}.${alto & 0xff}.${bajo >> 8}.${bajo & 0xff}`;\n\t\t}\n\t}\n\n\tif (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(dir)) {\n\t\tconst [a, b] = dir.split(\".\").map(Number);\n\t\tif (a === 127) return \"loopback\";\n\t\tif (a === 10) return \"red privada (10/8)\";\n\t\tif (a === 172 && b >= 16 && b <= 31) return \"red privada (172.16/12)\";\n\t\tif (a === 192 && b === 168) return \"red privada (192.168/16)\";\n\t\tif (a === 169 && b === 254) return \"enlace local (169.254/16), donde vive el endpoint de metadatos\";\n\t\tif (a === 100 && b >= 64 && b <= 127) return \"CGNAT (100.64/10)\";\n\t\tif (a === 0) return \"esta red (0/8)\";\n\t\treturn null;\n\t}\n\n\tif (dir === \"::1\" || dir === \"::\") return \"loopback IPv6\";\n\t// `fc00::/7` son las direcciones únicas locales; `fe80::/10`, el enlace local.\n\tif (/^f[cd]/.test(dir)) return \"red privada IPv6 (fc00::/7)\";\n\tif (/^fe[89ab]/.test(dir)) return \"enlace local IPv6 (fe80::/10)\";\n\treturn null;\n}\n\n/**\n * Resuelve el host y comprueba TODAS las direcciones que devuelve.\n *\n * Todas, no la primera: un dominio puede devolver una dirección pública y otra\n * interna, y quedarse con una sola convierte la defensa en una moneda al aire.\n *\n * Un fallo de resolución NO es un permiso. Se devuelve rechazo con su motivo:\n * «no he podido comprobarlo» y «está bien» son cosas distintas, y aquí\n * confundirlas es abrir la puerta.\n */\nexport async function destinoPermitido(url: URL): Promise<DestinoRechazado | null> {\n\tconst host = url.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n\t// Si el host YA es una dirección, no hay nada que resolver.\n\tconst directa = direccionInterna(host);\n\tif (directa) return { motivo: directa, direccion: host };\n\tif (/^[\\d.]+$/.test(host) || host.includes(\":\")) return null;\n\n\tlet direcciones: Array<{ address: string }>;\n\ttry {\n\t\tdirecciones = await lookup(host, { all: true });\n\t} catch (error) {\n\t\treturn {\n\t\t\tmotivo: `no se ha podido resolver el nombre (${(error as NodeJS.ErrnoException).code ?? \"error\"}), y sin saber a dónde apunta no se descarga`,\n\t\t};\n\t}\n\tif (direcciones.length === 0) {\n\t\treturn { motivo: \"el nombre no resuelve a ninguna dirección\" };\n\t}\n\tfor (const { address } of direcciones) {\n\t\tconst que = direccionInterna(address);\n\t\tif (que) return { motivo: `el nombre resuelve a ${que}`, direccion: address };\n\t}\n\treturn null;\n}\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ¿A dónde va de verdad esta URL?
|
|
3
|
+
*
|
|
4
|
+
* EL FALLO. `assertFetchableUrl` compara el NOMBRE del host contra una lista y
|
|
5
|
+
* unas expresiones regulares. Eso para lo evidente y deja pasar todo lo que
|
|
6
|
+
* llega a la misma dirección por otro camino. Medido sobre nuestra guarda:
|
|
7
|
+
*
|
|
8
|
+
* http://127.0.0.1:8080/secreto bloqueado
|
|
9
|
+
* http://localhost:8080/secreto bloqueado
|
|
10
|
+
* http://[::1]:8080/secreto bloqueado
|
|
11
|
+
* http://[::ffff:127.0.0.1]:8080/secreto PASA ← IPv4 mapeada en IPv6
|
|
12
|
+
* http://localtest.me:8080/secreto PASA ← resuelve a 127.0.0.1
|
|
13
|
+
*
|
|
14
|
+
* Y había un tercero: `redirect: "follow"`. Una URL pública que responde 302
|
|
15
|
+
* hacia loopback llega igual, porque la guarda solo mira la primera.
|
|
16
|
+
*
|
|
17
|
+
* Para un agente esto es serio: el modelo puede pedir una descarga con una URL
|
|
18
|
+
* que parece de internet y acabar leyendo el panel de administración de la red
|
|
19
|
+
* interna, o el endpoint de metadatos de la nube — que es donde viven las
|
|
20
|
+
* credenciales de la máquina.
|
|
21
|
+
*
|
|
22
|
+
* LA CAUSA RAÍZ, y por eso este módulo existe aparte: un nombre no es un
|
|
23
|
+
* destino. Lo único que dice a dónde va una petición es la DIRECCIÓN a la que
|
|
24
|
+
* resuelve, así que hay que resolverla y mirarla. Las comprobaciones por nombre
|
|
25
|
+
* se quedan, pero como filtro barato de primera pasada, no como la defensa.
|
|
26
|
+
*
|
|
27
|
+
* LO QUE NO RESUELVE, dicho antes de que lo descubra nadie: entre que
|
|
28
|
+
* resolvemos y que la petición sale, el DNS puede cambiar de respuesta —el
|
|
29
|
+
* ataque clásico de «rebind». Cerrarlo del todo exige fijar la dirección
|
|
30
|
+
* resuelta al abrir la conexión, que es cosa del agente HTTP y no de aquí.
|
|
31
|
+
* Contra un servidor hostil que controle su propio DNS esto sube el listón; no
|
|
32
|
+
* lo cierra.
|
|
33
|
+
*/
|
|
34
|
+
import { lookup } from "node:dns/promises";
|
|
35
|
+
/**
|
|
36
|
+
* ¿Esta dirección IP es de una red que no debe alcanzarse desde una tool web?
|
|
37
|
+
*
|
|
38
|
+
* Se trabaja sobre la dirección ya resuelta, así que da igual cómo se escribió
|
|
39
|
+
* el host: decimal, octal, mapeada en IPv6 o un dominio que apunta ahí.
|
|
40
|
+
*/
|
|
41
|
+
export function direccionInterna(ip) {
|
|
42
|
+
const limpia = ip.toLowerCase().replace(/^\[|\]$/g, "");
|
|
43
|
+
// IPv4 mapeada en IPv6: se desenvuelve y se juzga como IPv4, que es lo que
|
|
44
|
+
// era. Sin esto, `[::ffff:127.0.0.1]` pasaba entera.
|
|
45
|
+
//
|
|
46
|
+
// Hay que cubrir LAS DOS FORMAS, y esto casi se me escapa: `new URL()`
|
|
47
|
+
// normaliza `[::ffff:127.0.0.1]` a `[::ffff:7f00:1]`, en hexadecimal. Una
|
|
48
|
+
// guarda que solo mirara la forma decimal daría verde sobre la única forma
|
|
49
|
+
// que llega de verdad desde una URL.
|
|
50
|
+
let dir = limpia;
|
|
51
|
+
const decimal = limpia.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
52
|
+
if (decimal) {
|
|
53
|
+
dir = decimal[1];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const hex = limpia.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
|
|
57
|
+
if (hex) {
|
|
58
|
+
const alto = Number.parseInt(hex[1], 16);
|
|
59
|
+
const bajo = Number.parseInt(hex[2], 16);
|
|
60
|
+
dir = `${alto >> 8}.${alto & 0xff}.${bajo >> 8}.${bajo & 0xff}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(dir)) {
|
|
64
|
+
const [a, b] = dir.split(".").map(Number);
|
|
65
|
+
if (a === 127)
|
|
66
|
+
return "loopback";
|
|
67
|
+
if (a === 10)
|
|
68
|
+
return "red privada (10/8)";
|
|
69
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
70
|
+
return "red privada (172.16/12)";
|
|
71
|
+
if (a === 192 && b === 168)
|
|
72
|
+
return "red privada (192.168/16)";
|
|
73
|
+
if (a === 169 && b === 254)
|
|
74
|
+
return "enlace local (169.254/16), donde vive el endpoint de metadatos";
|
|
75
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
76
|
+
return "CGNAT (100.64/10)";
|
|
77
|
+
if (a === 0)
|
|
78
|
+
return "esta red (0/8)";
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (dir === "::1" || dir === "::")
|
|
82
|
+
return "loopback IPv6";
|
|
83
|
+
// `fc00::/7` son las direcciones únicas locales; `fe80::/10`, el enlace local.
|
|
84
|
+
if (/^f[cd]/.test(dir))
|
|
85
|
+
return "red privada IPv6 (fc00::/7)";
|
|
86
|
+
if (/^fe[89ab]/.test(dir))
|
|
87
|
+
return "enlace local IPv6 (fe80::/10)";
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Resuelve el host y comprueba TODAS las direcciones que devuelve.
|
|
92
|
+
*
|
|
93
|
+
* Todas, no la primera: un dominio puede devolver una dirección pública y otra
|
|
94
|
+
* interna, y quedarse con una sola convierte la defensa en una moneda al aire.
|
|
95
|
+
*
|
|
96
|
+
* Un fallo de resolución NO es un permiso. Se devuelve rechazo con su motivo:
|
|
97
|
+
* «no he podido comprobarlo» y «está bien» son cosas distintas, y aquí
|
|
98
|
+
* confundirlas es abrir la puerta.
|
|
99
|
+
*/
|
|
100
|
+
export async function destinoPermitido(url) {
|
|
101
|
+
const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
102
|
+
// Si el host YA es una dirección, no hay nada que resolver.
|
|
103
|
+
const directa = direccionInterna(host);
|
|
104
|
+
if (directa)
|
|
105
|
+
return { motivo: directa, direccion: host };
|
|
106
|
+
if (/^[\d.]+$/.test(host) || host.includes(":"))
|
|
107
|
+
return null;
|
|
108
|
+
let direcciones;
|
|
109
|
+
try {
|
|
110
|
+
direcciones = await lookup(host, { all: true });
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return {
|
|
114
|
+
motivo: `no se ha podido resolver el nombre (${error.code ?? "error"}), y sin saber a dónde apunta no se descarga`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (direcciones.length === 0) {
|
|
118
|
+
return { motivo: "el nombre no resuelve a ninguna dirección" };
|
|
119
|
+
}
|
|
120
|
+
for (const { address } of direcciones) {
|
|
121
|
+
const que = direccionInterna(address);
|
|
122
|
+
if (que)
|
|
123
|
+
return { motivo: `el nombre resuelve a ${que}`, direccion: address };
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=destino.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destino.js","sourceRoot":"","sources":["../../../src/core/web/destino.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ¿A dónde va de verdad esta URL?\n *\n * EL FALLO. `assertFetchableUrl` compara el NOMBRE del host contra una lista y\n * unas expresiones regulares. Eso para lo evidente y deja pasar todo lo que\n * llega a la misma dirección por otro camino. Medido sobre nuestra guarda:\n *\n * http://127.0.0.1:8080/secreto bloqueado\n * http://localhost:8080/secreto bloqueado\n * http://[::1]:8080/secreto bloqueado\n * http://[::ffff:127.0.0.1]:8080/secreto PASA ← IPv4 mapeada en IPv6\n * http://localtest.me:8080/secreto PASA ← resuelve a 127.0.0.1\n *\n * Y había un tercero: `redirect: \"follow\"`. Una URL pública que responde 302\n * hacia loopback llega igual, porque la guarda solo mira la primera.\n *\n * Para un agente esto es serio: el modelo puede pedir una descarga con una URL\n * que parece de internet y acabar leyendo el panel de administración de la red\n * interna, o el endpoint de metadatos de la nube — que es donde viven las\n * credenciales de la máquina.\n *\n * LA CAUSA RAÍZ, y por eso este módulo existe aparte: un nombre no es un\n * destino. Lo único que dice a dónde va una petición es la DIRECCIÓN a la que\n * resuelve, así que hay que resolverla y mirarla. Las comprobaciones por nombre\n * se quedan, pero como filtro barato de primera pasada, no como la defensa.\n *\n * LO QUE NO RESUELVE, dicho antes de que lo descubra nadie: entre que\n * resolvemos y que la petición sale, el DNS puede cambiar de respuesta —el\n * ataque clásico de «rebind». Cerrarlo del todo exige fijar la dirección\n * resuelta al abrir la conexión, que es cosa del agente HTTP y no de aquí.\n * Contra un servidor hostil que controle su propio DNS esto sube el listón; no\n * lo cierra.\n */\n\nimport { lookup } from \"node:dns/promises\";\n\n/** Por qué se rechaza un destino. Nunca una lista vacía silenciosa. */\nexport interface DestinoRechazado {\n\tmotivo: string;\n\t/** La dirección concreta que lo delató, cuando la hay. */\n\tdireccion?: string;\n}\n\n/**\n * ¿Esta dirección IP es de una red que no debe alcanzarse desde una tool web?\n *\n * Se trabaja sobre la dirección ya resuelta, así que da igual cómo se escribió\n * el host: decimal, octal, mapeada en IPv6 o un dominio que apunta ahí.\n */\nexport function direccionInterna(ip: string): string | null {\n\tconst limpia = ip.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n\t// IPv4 mapeada en IPv6: se desenvuelve y se juzga como IPv4, que es lo que\n\t// era. Sin esto, `[::ffff:127.0.0.1]` pasaba entera.\n\t//\n\t// Hay que cubrir LAS DOS FORMAS, y esto casi se me escapa: `new URL()`\n\t// normaliza `[::ffff:127.0.0.1]` a `[::ffff:7f00:1]`, en hexadecimal. Una\n\t// guarda que solo mirara la forma decimal daría verde sobre la única forma\n\t// que llega de verdad desde una URL.\n\tlet dir = limpia;\n\tconst decimal = limpia.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\n\tif (decimal) {\n\t\tdir = decimal[1];\n\t} else {\n\t\tconst hex = limpia.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n\t\tif (hex) {\n\t\t\tconst alto = Number.parseInt(hex[1], 16);\n\t\t\tconst bajo = Number.parseInt(hex[2], 16);\n\t\t\tdir = `${alto >> 8}.${alto & 0xff}.${bajo >> 8}.${bajo & 0xff}`;\n\t\t}\n\t}\n\n\tif (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(dir)) {\n\t\tconst [a, b] = dir.split(\".\").map(Number);\n\t\tif (a === 127) return \"loopback\";\n\t\tif (a === 10) return \"red privada (10/8)\";\n\t\tif (a === 172 && b >= 16 && b <= 31) return \"red privada (172.16/12)\";\n\t\tif (a === 192 && b === 168) return \"red privada (192.168/16)\";\n\t\tif (a === 169 && b === 254) return \"enlace local (169.254/16), donde vive el endpoint de metadatos\";\n\t\tif (a === 100 && b >= 64 && b <= 127) return \"CGNAT (100.64/10)\";\n\t\tif (a === 0) return \"esta red (0/8)\";\n\t\treturn null;\n\t}\n\n\tif (dir === \"::1\" || dir === \"::\") return \"loopback IPv6\";\n\t// `fc00::/7` son las direcciones únicas locales; `fe80::/10`, el enlace local.\n\tif (/^f[cd]/.test(dir)) return \"red privada IPv6 (fc00::/7)\";\n\tif (/^fe[89ab]/.test(dir)) return \"enlace local IPv6 (fe80::/10)\";\n\treturn null;\n}\n\n/**\n * Resuelve el host y comprueba TODAS las direcciones que devuelve.\n *\n * Todas, no la primera: un dominio puede devolver una dirección pública y otra\n * interna, y quedarse con una sola convierte la defensa en una moneda al aire.\n *\n * Un fallo de resolución NO es un permiso. Se devuelve rechazo con su motivo:\n * «no he podido comprobarlo» y «está bien» son cosas distintas, y aquí\n * confundirlas es abrir la puerta.\n */\nexport async function destinoPermitido(url: URL): Promise<DestinoRechazado | null> {\n\tconst host = url.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n\t// Si el host YA es una dirección, no hay nada que resolver.\n\tconst directa = direccionInterna(host);\n\tif (directa) return { motivo: directa, direccion: host };\n\tif (/^[\\d.]+$/.test(host) || host.includes(\":\")) return null;\n\n\tlet direcciones: Array<{ address: string }>;\n\ttry {\n\t\tdirecciones = await lookup(host, { all: true });\n\t} catch (error) {\n\t\treturn {\n\t\t\tmotivo: `no se ha podido resolver el nombre (${(error as NodeJS.ErrnoException).code ?? \"error\"}), y sin saber a dónde apunta no se descarga`,\n\t\t};\n\t}\n\tif (direcciones.length === 0) {\n\t\treturn { motivo: \"el nombre no resuelve a ninguna dirección\" };\n\t}\n\tfor (const { address } of direcciones) {\n\t\tconst que = direccionInterna(address);\n\t\tif (que) return { motivo: `el nombre resuelve a ${que}`, direccion: address };\n\t}\n\treturn null;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brave.d.ts","sourceRoot":"","sources":["../../../../src/core/web/proveedores/brave.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,YAAY,CAAC;AAQpE,eAAO,MAAM,MAAM,EAAE,aAepB,CAAC","sourcesContent":["/**\n * Brave Search API. Requiere clave (`brave` en el vault, o BRAVE_API_KEY).\n */\nimport type { FuncionBuscar, ResultadoProveedor } from \"./tipos.ts\";\n\nconst ENDPOINT = \"https://api.search.brave.com/res/v1/web/search\";\n\ninterface RespuestaBrave {\n\tweb?: { results?: Array<{ title?: string; url?: string; description?: string }> };\n}\n\nexport const buscar: FuncionBuscar = async (consulta, maximo, clave, fetchImpl, signal) => {\n\tif (!clave) throw new Error(\"Brave requiere clave.\");\n\tconst url = new URL(ENDPOINT);\n\turl.searchParams.set(\"q\", consulta);\n\turl.searchParams.set(\"count\", String(Math.min(Math.max(maximo, 1), 20)));\n\tconst respuesta = await fetchImpl(url, {\n\t\theaders: { Accept: \"application/json\", \"X-Subscription-Token\": clave },\n\t\tsignal,\n\t});\n\tif (!respuesta.ok) throw new Error(`Brave respondió HTTP ${respuesta.status}.`);\n\tconst datos = (await respuesta.json()) as RespuestaBrave;\n\tconst resultados: ResultadoProveedor[] = (datos.web?.results ?? [])\n\t\t.filter((r) => typeof r.url === \"string\" && r.url)\n\t\t.map((r) => ({ titulo: r.title || r.url!, url: r.url!, resumen: r.description }));\n\treturn resultados.slice(0, maximo);\n};\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const ENDPOINT = "https://api.search.brave.com/res/v1/web/search";
|
|
2
|
+
export const buscar = async (consulta, maximo, clave, fetchImpl, signal) => {
|
|
3
|
+
if (!clave)
|
|
4
|
+
throw new Error("Brave requiere clave.");
|
|
5
|
+
const url = new URL(ENDPOINT);
|
|
6
|
+
url.searchParams.set("q", consulta);
|
|
7
|
+
url.searchParams.set("count", String(Math.min(Math.max(maximo, 1), 20)));
|
|
8
|
+
const respuesta = await fetchImpl(url, {
|
|
9
|
+
headers: { Accept: "application/json", "X-Subscription-Token": clave },
|
|
10
|
+
signal,
|
|
11
|
+
});
|
|
12
|
+
if (!respuesta.ok)
|
|
13
|
+
throw new Error(`Brave respondió HTTP ${respuesta.status}.`);
|
|
14
|
+
const datos = (await respuesta.json());
|
|
15
|
+
const resultados = (datos.web?.results ?? [])
|
|
16
|
+
.filter((r) => typeof r.url === "string" && r.url)
|
|
17
|
+
.map((r) => ({ titulo: r.title || r.url, url: r.url, resumen: r.description }));
|
|
18
|
+
return resultados.slice(0, maximo);
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=brave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brave.js","sourceRoot":"","sources":["../../../../src/core/web/proveedores/brave.ts"],"names":[],"mappings":"AAKA,MAAM,QAAQ,GAAG,gDAAgD,CAAC;AAMlE,MAAM,CAAC,MAAM,MAAM,GAAkB,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;IAC1F,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QACtC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,KAAK,EAAE;QACtE,MAAM;KACN,CAAC,CAAC;IACH,IAAI,CAAC,SAAS,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAwB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,CAAmB,CAAC;IACzD,MAAM,UAAU,GAAyB,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC;SACjE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;SACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAI,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAAA,CACnC,CAAC","sourcesContent":["/**\n * Brave Search API. Requiere clave (`brave` en el vault, o BRAVE_API_KEY).\n */\nimport type { FuncionBuscar, ResultadoProveedor } from \"./tipos.ts\";\n\nconst ENDPOINT = \"https://api.search.brave.com/res/v1/web/search\";\n\ninterface RespuestaBrave {\n\tweb?: { results?: Array<{ title?: string; url?: string; description?: string }> };\n}\n\nexport const buscar: FuncionBuscar = async (consulta, maximo, clave, fetchImpl, signal) => {\n\tif (!clave) throw new Error(\"Brave requiere clave.\");\n\tconst url = new URL(ENDPOINT);\n\turl.searchParams.set(\"q\", consulta);\n\turl.searchParams.set(\"count\", String(Math.min(Math.max(maximo, 1), 20)));\n\tconst respuesta = await fetchImpl(url, {\n\t\theaders: { Accept: \"application/json\", \"X-Subscription-Token\": clave },\n\t\tsignal,\n\t});\n\tif (!respuesta.ok) throw new Error(`Brave respondió HTTP ${respuesta.status}.`);\n\tconst datos = (await respuesta.json()) as RespuestaBrave;\n\tconst resultados: ResultadoProveedor[] = (datos.web?.results ?? [])\n\t\t.filter((r) => typeof r.url === \"string\" && r.url)\n\t\t.map((r) => ({ titulo: r.title || r.url!, url: r.url!, resumen: r.description }));\n\treturn resultados.slice(0, maximo);\n};\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resuelve la clave de un proveedor de búsqueda: vault primero, variable de
|
|
3
|
+
* entorno después (la que usa CI, donde no hay vault desbloqueado).
|
|
4
|
+
*
|
|
5
|
+
* Vive separado del registro para que `agent-session.ts` —de upstream, con el
|
|
6
|
+
* presupuesto de sincronización agotado— pueda enchufarlo con una sola
|
|
7
|
+
* llamada en vez de repetir aquí la lógica try/vault/env por cada proveedor.
|
|
8
|
+
*/
|
|
9
|
+
/** Lo mínimo que hace falta del vault: buscar un secreto por nombre. */
|
|
10
|
+
export interface FuenteDeVault {
|
|
11
|
+
getSecret(nombre: string): string | null | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Construye el `obtenerClave` que espera `createWebTools`, atado a un vault
|
|
15
|
+
* concreto. `obtenerVault` se llama en cada búsqueda, no una vez: el vault
|
|
16
|
+
* puede desbloquearse o bloquearse durante la sesión.
|
|
17
|
+
*/
|
|
18
|
+
export declare function crearObtenerClave(obtenerVault: () => FuenteDeVault | null | undefined): (nombreProveedor: string) => Promise<string | undefined>;
|
|
19
|
+
//# sourceMappingURL=claves.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claves.d.ts","sourceRoot":"","sources":["../../../../src/core/web/proveedores/claves.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,yEAAwE;AACxE,MAAM,WAAW,aAAa;IAC7B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,YAAY,EAAE,MAAM,aAAa,GAAG,IAAI,GAAG,SAAS,GAClD,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW1D","sourcesContent":["/**\n * Resuelve la clave de un proveedor de búsqueda: vault primero, variable de\n * entorno después (la que usa CI, donde no hay vault desbloqueado).\n *\n * Vive separado del registro para que `agent-session.ts` —de upstream, con el\n * presupuesto de sincronización agotado— pueda enchufarlo con una sola\n * llamada en vez de repetir aquí la lógica try/vault/env por cada proveedor.\n */\n\n/** Nombre de proveedor → variable de entorno donde puede vivir su clave. */\nconst VARIABLE_ENTORNO: Record<string, string> = {\n\tserper: \"SERPER_API_KEY\",\n\tbrave: \"BRAVE_API_KEY\",\n\ttavily: \"TAVILY_API_KEY\",\n\texa: \"EXA_API_KEY\",\n\tsearxng: \"SEARXNG_URL\",\n};\n\n/** Lo mínimo que hace falta del vault: buscar un secreto por nombre. */\nexport interface FuenteDeVault {\n\tgetSecret(nombre: string): string | null | undefined;\n}\n\n/**\n * Construye el `obtenerClave` que espera `createWebTools`, atado a un vault\n * concreto. `obtenerVault` se llama en cada búsqueda, no una vez: el vault\n * puede desbloquearse o bloquearse durante la sesión.\n */\nexport function crearObtenerClave(\n\tobtenerVault: () => FuenteDeVault | null | undefined,\n): (nombreProveedor: string) => Promise<string | undefined> {\n\treturn async (nombreProveedor: string) => {\n\t\tconst variable = VARIABLE_ENTORNO[nombreProveedor];\n\t\ttry {\n\t\t\tconst delVault = obtenerVault()?.getSecret(nombreProveedor);\n\t\t\tif (delVault) return delVault;\n\t\t} catch {\n\t\t\t// Vault bloqueado o no inicializado: caer a la variable de entorno.\n\t\t}\n\t\treturn variable ? process.env[variable] : undefined;\n\t};\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resuelve la clave de un proveedor de búsqueda: vault primero, variable de
|
|
3
|
+
* entorno después (la que usa CI, donde no hay vault desbloqueado).
|
|
4
|
+
*
|
|
5
|
+
* Vive separado del registro para que `agent-session.ts` —de upstream, con el
|
|
6
|
+
* presupuesto de sincronización agotado— pueda enchufarlo con una sola
|
|
7
|
+
* llamada en vez de repetir aquí la lógica try/vault/env por cada proveedor.
|
|
8
|
+
*/
|
|
9
|
+
/** Nombre de proveedor → variable de entorno donde puede vivir su clave. */
|
|
10
|
+
const VARIABLE_ENTORNO = {
|
|
11
|
+
serper: "SERPER_API_KEY",
|
|
12
|
+
brave: "BRAVE_API_KEY",
|
|
13
|
+
tavily: "TAVILY_API_KEY",
|
|
14
|
+
exa: "EXA_API_KEY",
|
|
15
|
+
searxng: "SEARXNG_URL",
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Construye el `obtenerClave` que espera `createWebTools`, atado a un vault
|
|
19
|
+
* concreto. `obtenerVault` se llama en cada búsqueda, no una vez: el vault
|
|
20
|
+
* puede desbloquearse o bloquearse durante la sesión.
|
|
21
|
+
*/
|
|
22
|
+
export function crearObtenerClave(obtenerVault) {
|
|
23
|
+
return async (nombreProveedor) => {
|
|
24
|
+
const variable = VARIABLE_ENTORNO[nombreProveedor];
|
|
25
|
+
try {
|
|
26
|
+
const delVault = obtenerVault()?.getSecret(nombreProveedor);
|
|
27
|
+
if (delVault)
|
|
28
|
+
return delVault;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Vault bloqueado o no inicializado: caer a la variable de entorno.
|
|
32
|
+
}
|
|
33
|
+
return variable ? process.env[variable] : undefined;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=claves.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claves.js","sourceRoot":"","sources":["../../../../src/core/web/proveedores/claves.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,8EAA4E;AAC5E,MAAM,gBAAgB,GAA2B;IAChD,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,gBAAgB;IACxB,GAAG,EAAE,aAAa;IAClB,OAAO,EAAE,aAAa;CACtB,CAAC;AAOF;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAChC,YAAoD,EACO;IAC3D,OAAO,KAAK,EAAE,eAAuB,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACnD,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,YAAY,EAAE,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;YAC5D,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACR,oEAAoE;QACrE,CAAC;QACD,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAAA,CACpD,CAAC;AAAA,CACF","sourcesContent":["/**\n * Resuelve la clave de un proveedor de búsqueda: vault primero, variable de\n * entorno después (la que usa CI, donde no hay vault desbloqueado).\n *\n * Vive separado del registro para que `agent-session.ts` —de upstream, con el\n * presupuesto de sincronización agotado— pueda enchufarlo con una sola\n * llamada en vez de repetir aquí la lógica try/vault/env por cada proveedor.\n */\n\n/** Nombre de proveedor → variable de entorno donde puede vivir su clave. */\nconst VARIABLE_ENTORNO: Record<string, string> = {\n\tserper: \"SERPER_API_KEY\",\n\tbrave: \"BRAVE_API_KEY\",\n\ttavily: \"TAVILY_API_KEY\",\n\texa: \"EXA_API_KEY\",\n\tsearxng: \"SEARXNG_URL\",\n};\n\n/** Lo mínimo que hace falta del vault: buscar un secreto por nombre. */\nexport interface FuenteDeVault {\n\tgetSecret(nombre: string): string | null | undefined;\n}\n\n/**\n * Construye el `obtenerClave` que espera `createWebTools`, atado a un vault\n * concreto. `obtenerVault` se llama en cada búsqueda, no una vez: el vault\n * puede desbloquearse o bloquearse durante la sesión.\n */\nexport function crearObtenerClave(\n\tobtenerVault: () => FuenteDeVault | null | undefined,\n): (nombreProveedor: string) => Promise<string | undefined> {\n\treturn async (nombreProveedor: string) => {\n\t\tconst variable = VARIABLE_ENTORNO[nombreProveedor];\n\t\ttry {\n\t\t\tconst delVault = obtenerVault()?.getSecret(nombreProveedor);\n\t\t\tif (delVault) return delVault;\n\t\t} catch {\n\t\t\t// Vault bloqueado o no inicializado: caer a la variable de entorno.\n\t\t}\n\t\treturn variable ? process.env[variable] : undefined;\n\t};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckduckgo.d.ts","sourceRoot":"","sources":["../../../../src/core/web/proveedores/duckduckgo.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,YAAY,CAAC;AA8EpE,eAAO,MAAM,MAAM,EAAE,aAepB,CAAC","sourcesContent":["/**\n * DuckDuckGo, vía su frontend HTML sin JS (`html.duckduckgo.com/html/`).\n *\n * Sin clave: es el único de los tres proveedores gratuitos que responde con\n * resultados reales desde una red de centro de datos en la práctica —Mojeek y\n * Ecosia sirven un captcha o un firewall a cualquier cliente sin navegador\n * real la mayoría de las veces—. Por eso va primero en el grupo sin clave: es\n * el que de verdad sostiene la puerta «sin ninguna clave, hay resultados».\n *\n * DuckDuckGo enruta cada resultado por `//duckduckgo.com/l/?uddg=<url>` para\n * medir clics; hay que desenvolverlo o el agente termina con enlaces inútiles.\n */\nimport { CABECERAS_NAVEGADOR } from \"./navegador.ts\";\nimport type { FuncionBuscar, ResultadoProveedor } from \"./tipos.ts\";\n\nconst ENDPOINT = \"https://html.duckduckgo.com/html/\";\n\n/** `true` cuando la página es el modal anti-bot, no resultados. DDG mezcla 200 y 202 en este caso. */\nfunction esBloqueoAntiBot(html: string): boolean {\n\treturn html.includes(\"anomaly-modal\") || html.includes(\"anomaly.js\");\n}\n\n/**\n * Desenvuelve la URL real de un resultado. Los orgánicos van envueltos en\n * `uddg=`; los ANUNCIOS (`//duckduckgo.com/y.js?ad_domain=…`) no llevan ese\n * envoltorio porque no apuntan a un destino final, sino al propio tracker de\n * clics de DDG — por eso, tras desenvolver, cualquier URL que SIGA en\n * duckduckgo.com se descarta: es un anuncio, no un resultado.\n */\nfunction desenvolverUrl(href: string): string | undefined {\n\tconst decodificado = href.replace(/&/gi, \"&\");\n\tlet resuelta: string | undefined;\n\tconst match = decodificado.match(/[?&]uddg=([^&]+)/);\n\tif (match) {\n\t\ttry {\n\t\t\tresuelta = decodeURIComponent(match[1]);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t} else if (decodificado.startsWith(\"//\")) {\n\t\tresuelta = `https:${decodificado}`;\n\t} else if (decodificado.startsWith(\"http://\") || decodificado.startsWith(\"https://\")) {\n\t\tresuelta = decodificado;\n\t} else {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\tif (new URL(resuelta).hostname.endsWith(\"duckduckgo.com\")) return undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn resuelta;\n}\n\nfunction limpiarTexto(html: string): string {\n\treturn html\n\t\t.replace(/<[^>]*>/g, \" \")\n\t\t.replace(/&/gi, \"&\")\n\t\t.replace(/</gi, \"<\")\n\t\t.replace(/>/gi, \">\")\n\t\t.replace(/"/gi, '\"')\n\t\t.replace(/'|'/gi, \"'\")\n\t\t.replace(/ /gi, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nconst RE_BLOQUE =\n\t/<div\\b[^>]*\\bclass=\"[^\"]*\\bresult\\b[^\"]*\"[^>]*>([\\s\\S]*?)(?=<div\\b[^>]*\\bclass=\"[^\"]*\\bresult\\b|<div\\b[^>]*\\bclass=\"[^\"]*\\bnav-link\\b|$)/g;\nconst RE_TITULO = /<a\\b[^>]*\\bclass=\"[^\"]*\\bresult__a\\b[^\"]*\"[^>]*\\bhref=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/a>/;\nconst RE_SNIPPET = /<(?:a|div|span)\\b[^>]*\\bclass=\"[^\"]*\\bresult__snippet\\b[^\"]*\"[^>]*>([\\s\\S]*?)<\\/(?:a|div|span)>/;\n\nfunction parsear(html: string): ResultadoProveedor[] {\n\tconst resultados: ResultadoProveedor[] = [];\n\tfor (const bloque of html.matchAll(RE_BLOQUE)) {\n\t\tconst titulo = bloque[1].match(RE_TITULO);\n\t\tif (!titulo) continue;\n\t\tconst url = desenvolverUrl(titulo[1]);\n\t\tif (!url) continue;\n\t\tconst tituloTexto = limpiarTexto(titulo[2]);\n\t\tif (!tituloTexto) continue;\n\t\tconst snippet = bloque[1].match(RE_SNIPPET);\n\t\tresultados.push({\n\t\t\ttitulo: tituloTexto,\n\t\t\turl,\n\t\t\tresumen: snippet ? limpiarTexto(snippet[1]) || undefined : undefined,\n\t\t});\n\t}\n\treturn resultados;\n}\n\nexport const buscar: FuncionBuscar = async (consulta, maximo, _clave, fetchImpl, signal) => {\n\t// GET, no POST: probado en vivo contra `html.duckduckgo.com` — el mismo\n\t// endpoint trata el POST (el envío \"de formulario real\" que usan otros\n\t// scrapers) con más sospecha que un GET con la consulta en la query, al\n\t// menos desde redes de centro de datos. Con GET responde con resultados\n\t// reales de forma consistente; con POST, con el modal anti-bot.\n\tconst url = new URL(ENDPOINT);\n\turl.searchParams.set(\"q\", consulta);\n\tconst respuesta = await fetchImpl(url, { headers: CABECERAS_NAVEGADOR, signal });\n\tif (!respuesta.ok) throw new Error(`DuckDuckGo respondió HTTP ${respuesta.status}.`);\n\tconst html = await respuesta.text();\n\tif (esBloqueoAntiBot(html)) {\n\t\tthrow new Error(\"DuckDuckGo bloqueó la petición con su captcha anti-bot.\");\n\t}\n\treturn parsear(html).slice(0, maximo);\n};\n"]}
|