xonecode 0.38.44 → 0.39.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/cloudstudio/cloudstudioClient.d.ts +29 -0
- package/dist/agent/cloudstudio/cloudstudioMcp.d.ts +414 -0
- package/dist/agent/cloudstudio/conexionDeServidor.d.ts +37 -0
- package/dist/agent/cloudstudio/conexionDeServidor.js +63 -0
- package/dist/agent/cloudstudio/conexionDeServidor.js.map +1 -0
- package/dist/agent/cloudstudio/crearRama.d.ts +15 -0
- package/dist/agent/cloudstudio/crearRama.js +16 -0
- package/dist/agent/cloudstudio/crearRama.js.map +1 -0
- package/dist/agent/cloudstudio/descarga.d.ts +44 -0
- package/dist/agent/cloudstudio/manifiesto.d.ts +25 -0
- package/dist/agent/cloudstudio/ramaActiva.d.ts +24 -0
- package/dist/agent/cloudstudio/subida.d.ts +61 -0
- package/dist/agent/cloudstudio/subida.js +7 -1
- package/dist/agent/cloudstudio/subida.js.map +1 -1
- package/dist/agent/cloudstudio/validarTrasDescarga.d.ts +13 -0
- package/dist/agent/cloudstudio/zip.d.ts +13 -0
- package/dist/agent/conectores/conectoresEnDisco.d.ts +47 -0
- package/dist/agent/conectores/gestorJira.d.ts +50 -0
- package/dist/agent/conectores/gestorNotion.d.ts +45 -0
- package/dist/agent/conectores/proveedorDeConector.d.ts +43 -0
- package/dist/agent/conectores/servicioDeConectores.d.ts +112 -0
- package/dist/agent/config/authEnDisco.d.ts +43 -0
- package/dist/agent/config/catalogoModelos.d.ts +79 -0
- package/dist/agent/config/configEnDisco.d.ts +235 -0
- package/dist/agent/config/crearProyecto.d.ts +20 -0
- package/dist/agent/config/diagnosticoDeNodeEnMaquina.d.ts +44 -0
- package/dist/agent/config/ecoDeRazonamiento.d.ts +104 -0
- package/dist/agent/config/entorno.d.ts +83 -0
- package/dist/agent/config/fuentesEnRed.d.ts +12 -0
- package/dist/agent/config/gemini.d.ts +5 -0
- package/dist/agent/config/iconosEnRed.d.ts +10 -0
- package/dist/agent/config/identidadEnDisco.d.ts +27 -0
- package/dist/agent/config/modelos.d.ts +77 -0
- package/dist/agent/config/modelosDeMotor.d.ts +52 -0
- package/dist/agent/config/mudanzaEnDisco.d.ts +99 -0
- package/dist/agent/config/persona.d.ts +1 -0
- package/dist/agent/config/selectorEnMaquina.d.ts +35 -0
- package/dist/agent/config/settingsEnDisco.d.ts +206 -0
- package/dist/agent/config/versionEnDisco.d.ts +17 -0
- package/dist/agent/dispositivos/arranqueDeEmulador.d.ts +60 -0
- package/dist/agent/dispositivos/cajasDeMaqueta.d.ts +61 -0
- package/dist/agent/dispositivos/decodificarImagen.d.ts +21 -0
- package/dist/agent/dispositivos/descargaDeHerramientas.d.ts +44 -0
- package/dist/agent/dispositivos/dispositivosEnMaquina.d.ts +161 -0
- package/dist/agent/dispositivos/geometriaEnDisco.d.ts +17 -0
- package/dist/agent/dispositivos/hotswap.d.ts +194 -0
- package/dist/agent/dispositivos/instalacionEnMaquina.d.ts +156 -0
- package/dist/agent/dispositivos/juezVisual.d.ts +144 -0
- package/dist/agent/dispositivos/lanzamientoEnMaquina.d.ts +197 -0
- package/dist/agent/dispositivos/paqueteDelProyecto.d.ts +28 -0
- package/dist/agent/dispositivos/procesosEnMaquina.d.ts +154 -0
- package/dist/agent/dispositivos/recargaEnAparato.d.ts +30 -0
- package/dist/agent/dispositivos/sensorDeArranque.d.ts +42 -0
- package/dist/agent/exportarPdf.d.ts +72 -0
- package/dist/agent/grafo/aprendido.d.ts +28 -0
- package/dist/agent/grafo/arbolDeProyecto.d.ts +205 -0
- package/dist/agent/grafo/artefactosEnDisco.d.ts +35 -0
- package/dist/agent/grafo/atributosXone.d.ts +31 -0
- package/dist/agent/grafo/buscarIcono.d.ts +32 -0
- package/dist/agent/grafo/busquedaRegex.d.ts +56 -0
- package/dist/agent/grafo/codificacionDelProyecto.d.ts +7 -0
- package/dist/agent/grafo/compararCapturas.d.ts +22 -0
- package/dist/agent/grafo/copiarArtefacto.d.ts +64 -0
- package/dist/agent/grafo/criticaVisual.d.ts +60 -0
- package/dist/agent/grafo/describirImagen.d.ts +79 -0
- package/dist/agent/grafo/diferenciaDeCapturas.d.ts +33 -0
- package/dist/agent/grafo/ejecucionCancelable.d.ts +45 -0
- package/dist/agent/grafo/escriturasEnSerie.d.ts +31 -0
- package/dist/agent/grafo/excluirTools.d.ts +37 -0
- package/dist/agent/grafo/fuentesDeGoogle.d.ts +37 -0
- package/dist/agent/grafo/generarFondoSvg.d.ts +52 -0
- package/dist/agent/grafo/incorporarAdjunto.d.ts +98 -0
- package/dist/agent/grafo/lectorDeReferencias.d.ts +28 -0
- package/dist/agent/grafo/marcarCriteriosDelPlan.d.ts +47 -0
- package/dist/agent/grafo/memoriaDeProyecto.d.ts +15 -0
- package/dist/agent/grafo/navegacionXone.d.ts +60 -0
- package/dist/agent/grafo/opcionesDeFicheros.d.ts +23 -0
- package/dist/agent/grafo/perfiles.d.ts +225 -0
- package/dist/agent/grafo/proyecto.d.ts +450 -0
- package/dist/agent/grafo/skills.d.ts +181 -0
- package/dist/agent/grafo/traerDeLaMaquina.d.ts +60 -0
- package/dist/agent/grafo/unirSecciones.d.ts +20 -0
- package/dist/agent/grafo/validacionXone.d.ts +35 -0
- package/dist/agent/grafo/validarFicheroXone.d.ts +33 -0
- package/dist/agent/grafo/xoneAgent.d.ts +166 -0
- package/dist/agent/motores/motoresLocales.d.ts +87 -0
- package/dist/agent/motores/trueforge/capacidades.d.ts +183 -0
- package/dist/agent/motores/trueforge/convertirAP.d.ts +38 -0
- package/dist/agent/motores/trueforge/detencion.d.ts +70 -0
- package/dist/agent/motores/trueforge/esperas.d.ts +38 -0
- package/dist/agent/motores/trueforge/eventosTrueforge.d.ts +56 -0
- package/dist/agent/motores/trueforge/informesDeHijos.d.ts +48 -0
- package/dist/agent/motores/trueforge/medidaAutomatica.d.ts +37 -0
- package/dist/agent/motores/trueforge/memoriaDeEspecialistas.d.ts +60 -0
- package/dist/agent/motores/trueforge/memoriaTrueforge.d.ts +131 -0
- package/dist/agent/motores/trueforge/metricasTrueforge.d.ts +45 -0
- package/dist/agent/motores/trueforge/modeloExterno.d.ts +9 -0
- package/dist/agent/motores/trueforge/modeloLangchain.d.ts +69 -0
- package/dist/agent/motores/trueforge/notas.d.ts +48 -0
- package/dist/agent/motores/trueforge/proponerTareas.d.ts +30 -0
- package/dist/agent/motores/trueforge/recortes.d.ts +47 -0
- package/dist/agent/motores/trueforge/resumenSeguro.d.ts +33 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.d.ts +273 -0
- package/dist/agent/motores/trueforge/skillsTrueforge.d.ts +16 -0
- package/dist/agent/motores/trueforge/toolsDeConectores.d.ts +36 -0
- package/dist/agent/motores/trueforge/toolsDeFichero.d.ts +146 -0
- package/dist/agent/motores/trueforge/toolsPropias.d.ts +38 -0
- package/dist/agent/motores/trueforge/traerDeStitch.d.ts +63 -0
- package/dist/agent/motores/trueforge/trueforge.d.ts +35 -0
- package/dist/agent/navegacion/estilosEnDisco.d.ts +41 -0
- package/dist/agent/navegacion/hechosEnDisco.d.ts +19 -0
- package/dist/agent/navegacion/indiceEnDisco.d.ts +50 -0
- package/dist/agent/navegacion/modeloDeProyecto.d.ts +86 -0
- package/dist/agent/planesEnDisco.d.ts +18 -0
- package/dist/agent/publicarPlan.d.ts +20 -0
- package/dist/agent/raizDelPaquete.d.ts +9 -0
- package/dist/agent/remoto/ngrokEnMaquina.d.ts +44 -0
- package/dist/agent/remoto/puenteWebSocket.d.ts +59 -0
- package/dist/agent/remoto/tunelNgrok.d.ts +31 -0
- package/dist/agent/renombrarSobre.d.ts +14 -0
- package/dist/agent/sesiones/adjuntosDeSesion.d.ts +64 -0
- package/dist/agent/sesiones/baseDeFichero.d.ts +9 -0
- package/dist/agent/sesiones/checkpointer.d.ts +146 -0
- package/dist/agent/sesiones/git.d.ts +66 -0
- package/dist/agent/sesiones/gitSync.d.ts +264 -0
- package/dist/agent/sesiones/memoriaDeHilo.d.ts +4 -0
- package/dist/agent/sesiones/modeloDelCambio.d.ts +7 -0
- package/dist/agent/sesiones/parcheEnTexto.d.ts +9 -0
- package/dist/agent/sesiones/sesionGit.d.ts +155 -0
- package/dist/agent/subagentes/actividadDeCodex.d.ts +8 -0
- package/dist/agent/subagentes/agentesEnDisco.d.ts +198 -0
- package/dist/agent/subagentes/consumoExterno.d.ts +83 -0
- package/dist/agent/subagentes/ejecutableEnWindows.d.ts +53 -0
- package/dist/agent/subagentes/escrituraDeCodex.d.ts +94 -0
- package/dist/agent/subagentes/escrituraDeOpencode.d.ts +67 -0
- package/dist/agent/subagentes/escrituraExterna.d.ts +419 -0
- package/dist/agent/subagentes/pluginDeSkills.d.ts +84 -0
- package/dist/agent/subagentes/subagenteCodex.d.ts +76 -0
- package/dist/agent/subagentes/subagenteExterno.d.ts +169 -0
- package/dist/agent/subagentes/subagenteOpencode.d.ts +126 -0
- package/dist/agent/tareas/aumentador.d.ts +99 -0
- package/dist/agent/tareas/juezDeTarea.d.ts +64 -0
- package/dist/agent/tareas/reflejoEnElGestor.d.ts +38 -0
- package/dist/agent/tareas/sondeoDelGestor.d.ts +49 -0
- package/dist/agent/tareas/tareasEnDisco.d.ts +141 -0
- package/dist/agent/trazaDeErroresEnDisco.d.ts +10 -0
- package/dist/agent/turno/depuracion.d.ts +1 -0
- package/dist/agent/turno/diagnosticoDeTools.d.ts +124 -0
- package/dist/agent/turno/ficherosDelProyecto.d.ts +10 -0
- package/dist/agent/turno/guionizado.d.ts +18 -0
- package/dist/agent/turno/informeDeTraza.d.ts +220 -0
- package/dist/agent/turno/inspectorDePrompt.d.ts +150 -0
- package/dist/agent/turno/instantanea.d.ts +16 -0
- package/dist/agent/turno/interrupts.d.ts +54 -0
- package/dist/agent/turno/juezDelTurnoConModelo.d.ts +26 -0
- package/dist/agent/turno/mensajes.d.ts +23 -0
- package/dist/agent/turno/normalizar.d.ts +15 -0
- package/dist/agent/turno/puente.d.ts +196 -0
- package/dist/agent/turno/registroDeFallos.d.ts +39 -0
- package/dist/agent/turno/resumenDeContexto.d.ts +269 -0
- package/dist/agent/turno/resumenDeTool.d.ts +33 -0
- package/dist/agent/turno/rubrica.d.ts +35 -0
- package/dist/agent/turno/sesionReal.d.ts +89 -0
- package/dist/agent/turno/textoDeTool.d.ts +19 -0
- package/dist/agent/turno/turnoReal.d.ts +210 -0
- package/dist/agent/turno/verificacion.d.ts +85 -0
- package/dist/agent/turno/verificador.d.ts +66 -0
- package/dist/bin.d.ts +2 -0
- package/dist/cli/acuseDeModelo.d.ts +18 -0
- package/dist/cli/aprobar.d.ts +162 -0
- package/dist/cli/config.d.ts +17 -0
- package/dist/cli/consola.d.ts +473 -0
- package/dist/cli/describe.d.ts +7 -0
- package/dist/cli/doctor.d.ts +8 -0
- package/dist/cli/fuentesDeDisco.d.ts +25 -0
- package/dist/cli/main.d.ts +291 -0
- package/dist/cli/markdown.d.ts +126 -0
- package/dist/cli/panel.d.ts +38 -0
- package/dist/cli/podar.d.ts +38 -0
- package/dist/cli/run.d.ts +30 -0
- package/dist/cli/spinner.d.ts +37 -0
- package/dist/cli/stdio.d.ts +94 -0
- package/dist/cli/tema.d.ts +68 -0
- package/dist/cli/tokens.d.ts +16 -0
- package/dist/cli/traza.d.ts +19 -0
- package/dist/cli/tui/app.d.ts +23 -0
- package/dist/cli/tui/aprobarTui.d.ts +46 -0
- package/dist/cli/tui/barra.d.ts +43 -0
- package/dist/cli/tui/correrTui.d.ts +119 -0
- package/dist/cli/tui/entrada.d.ts +14 -0
- package/dist/cli/tui/filas.d.ts +13 -0
- package/dist/cli/tui/logo.d.ts +20 -0
- package/dist/cli/tui/pielTui.d.ts +15 -0
- package/dist/cli/tui/raton.d.ts +68 -0
- package/dist/cli/tui/sidebar.d.ts +63 -0
- package/dist/cli/tui/store.d.ts +102 -0
- package/dist/cli/tui/tarjeta.d.ts +8 -0
- package/dist/cli/tui/temaInk.d.ts +67 -0
- package/dist/cli/tui/transcript.d.ts +32 -0
- package/dist/cli/verify.d.ts +9 -0
- package/dist/cli/wizardInicial.d.ts +59 -0
- package/dist/core/actos.d.ts +437 -0
- package/dist/core/adjuntos.d.ts +77 -0
- package/dist/core/agentes.d.ts +353 -0
- package/dist/core/analisisDeSesion.d.ts +63 -0
- package/dist/core/aprendido.d.ts +41 -0
- package/dist/core/artefactos.d.ts +74 -0
- package/dist/core/atributosXone.d.ts +53 -0
- package/dist/core/bitacora.d.ts +21 -0
- package/dist/core/cloudstudio.d.ts +168 -0
- package/dist/core/codificacion.d.ts +81 -0
- package/dist/core/comandoExterno.d.ts +49 -0
- package/dist/core/compararCapturas.d.ts +136 -0
- package/dist/core/conectores.d.ts +296 -0
- package/dist/core/config.d.ts +148 -0
- package/dist/core/contextos.d.ts +54 -0
- package/dist/core/convertirAP.d.ts +56 -0
- package/dist/core/copiaDeAvd.d.ts +44 -0
- package/dist/core/cssBienFormado.d.ts +22 -0
- package/dist/core/deps.d.ts +28 -0
- package/dist/core/descargas.d.ts +61 -0
- package/dist/core/descripcionDePantalla.d.ts +121 -0
- package/dist/core/descriptoresDeApp.d.ts +108 -0
- package/dist/core/diagnosticoDeNode.d.ts +51 -0
- package/dist/core/diff.d.ts +26 -0
- package/dist/core/diffDeColecciones.d.ts +54 -0
- package/dist/core/disenoVinculado.d.ts +17 -0
- package/dist/core/dispositivoDeSesion.d.ts +22 -0
- package/dist/core/dispositivoElegido.d.ts +17 -0
- package/dist/core/dispositivos.d.ts +469 -0
- package/dist/core/entrega.d.ts +341 -0
- package/dist/core/entrelazar.d.ts +48 -0
- package/dist/core/esfuerzo.d.ts +120 -0
- package/dist/core/esqueleto.d.ts +38 -0
- package/dist/core/estiloMedido.d.ts +70 -0
- package/dist/core/estilos.d.ts +76 -0
- package/dist/core/events.d.ts +218 -0
- package/dist/core/exportacion.d.ts +88 -0
- package/dist/core/fallos.d.ts +79 -0
- package/dist/core/fondosSvg.d.ts +115 -0
- package/dist/core/fotoDeColecciones.d.ts +45 -0
- package/dist/core/fuentes.d.ts +96 -0
- package/dist/core/geometriaDePantalla.d.ts +171 -0
- package/dist/core/gestorDeTareas.d.ts +295 -0
- package/dist/core/hechosDelProyecto.d.ts +70 -0
- package/dist/core/hotswap.d.ts +30 -0
- package/dist/core/iconos.d.ts +86 -0
- package/dist/core/identidadDeProveedor.d.ts +20 -0
- package/dist/core/idiomaDeLaRespuesta.d.ts +26 -0
- package/dist/core/imagenesDeDocumento.d.ts +40 -0
- package/dist/core/jsParaRhino.d.ts +3 -0
- package/dist/core/juezDelTurno.d.ts +95 -0
- package/dist/core/logDeDispositivo.d.ts +67 -0
- package/dist/core/memoria.d.ts +18 -0
- package/dist/core/metodoDeComparacionVisual.d.ts +20 -0
- package/dist/core/modelos.d.ts +198 -0
- package/dist/core/modoDeEscritura.d.ts +155 -0
- package/dist/core/motor.d.ts +43 -0
- package/dist/core/motoresLocales.d.ts +113 -0
- package/dist/core/mudanzaDeWorkspace.d.ts +112 -0
- package/dist/core/navegacion.d.ts +172 -0
- package/dist/core/notify.d.ts +77 -0
- package/dist/core/nucleoXone.d.ts +28 -0
- package/dist/core/panorama.d.ts +68 -0
- package/dist/core/paqueteDeSoporte.d.ts +100 -0
- package/dist/core/planDeSubida.d.ts +56 -0
- package/dist/core/planes.d.ts +53 -0
- package/dist/core/podaDeCheckpoint.d.ts +75 -0
- package/dist/core/ports.d.ts +1034 -0
- package/dist/core/puedeLanzarse.d.ts +181 -0
- package/dist/core/puertosDeAvd.d.ts +59 -0
- package/dist/core/recargaEnCaliente.d.ts +52 -0
- package/dist/core/referenciasDeImagen.d.ts +36 -0
- package/dist/core/remoto.d.ts +76 -0
- package/dist/core/repartoDeEncargo.d.ts +80 -0
- package/dist/core/rubrica.d.ts +78 -0
- package/dist/core/rutaVirtual.d.ts +29 -0
- package/dist/core/selectorDeCarpeta.d.ts +59 -0
- package/dist/core/serieDeEscrituras.d.ts +58 -0
- package/dist/core/settings.d.ts +421 -0
- package/dist/core/shellDeAgente.d.ts +177 -0
- package/dist/core/skills.d.ts +129 -0
- package/dist/core/stitch.d.ts +114 -0
- package/dist/core/tareas.d.ts +412 -0
- package/dist/core/tareasDelPlan.d.ts +123 -0
- package/dist/core/tareasEnElGestor.d.ts +117 -0
- package/dist/core/textos.d.ts +8 -0
- package/dist/core/topeAgotado.d.ts +55 -0
- package/dist/core/traerDeLaMaquina.d.ts +33 -0
- package/dist/core/trazaDeErrores.d.ts +83 -0
- package/dist/core/tunel.d.ts +45 -0
- package/dist/core/turno.d.ts +154 -0
- package/dist/core/validacionDeEscritura.d.ts +95 -0
- package/dist/core/verificacionDeSubida.d.ts +14 -0
- package/dist/core/version.d.ts +35 -0
- package/dist/core/xmlBienFormado.d.ts +23 -0
- package/dist/core/zipDeAdjunto.d.ts +28 -0
- package/dist/core/zipDeSkill.d.ts +74 -0
- package/dist/lib/tareaAutonoma.d.ts +36 -0
- package/dist/lib/tareaAutonoma.js +259 -0
- package/dist/lib/tareaAutonoma.js.map +1 -0
- package/dist/lib.d.ts +31 -0
- package/dist/lib.js +28 -0
- package/dist/lib.js.map +1 -0
- package/dist/vendor/hitl.d.ts +69 -0
- package/dist/vendor/skillLoaders/catalog.d.ts +27 -0
- package/dist/vendor/sqliteSaver.d.ts +22 -0
- package/dist/vendor/tokenTracking.d.ts +22 -0
- package/dist/web/servidor/arranque.d.ts +1372 -0
- package/dist/web/servidor/consolaDeTarea.d.ts +166 -0
- package/dist/web/servidor/consolaWeb.d.ts +142 -0
- package/dist/web/servidor/corredorDeTareas.d.ts +395 -0
- package/dist/web/servidor/datosDeCierre.d.ts +4 -0
- package/dist/web/servidor/interrupcion.d.ts +39 -0
- package/dist/web/servidor/pielWeb.d.ts +32 -0
- package/dist/web/servidor/puenteRemoto.d.ts +80 -0
- package/dist/web/servidor/servidor.d.ts +53 -0
- package/dist/web/servidor/sesiones.d.ts +342 -0
- package/dist/web/servidor/soporte.d.ts +65 -0
- package/dist/web/servidor/transporte.d.ts +2751 -0
- package/dist/web/servidor/vestibulo.d.ts +952 -0
- package/dist/web/servidor/visorOpenui.d.ts +33 -0
- package/package.json +9 -1
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qué puede hacer un agente EXTERNO (Claude Code) dentro de la carpeta del proyecto.
|
|
3
|
+
*
|
|
4
|
+
* Este fichero existe porque conceder escritura a un agente externo no es levantar una
|
|
5
|
+
* bandera: sus `Write`/`Edit` van **directos al disco con una ruta ABSOLUTA**, así que se
|
|
6
|
+
* saltan por completo las cuatro capas que protegen al proyecto por el camino de LangGraph
|
|
7
|
+
* —`permisosDe`, el `virtualMode` del backend, las vistas aplanadas y las guardas de
|
|
8
|
+
* artefactos y descargas—. Sin volver a aplicarlas aquí, «el agente externo ya puede
|
|
9
|
+
* escribir» significaría también «ya puede escribir `.env`, `.git` y cualquier sitio fuera
|
|
10
|
+
* del proyecto», y eso no es una capacidad nueva: es el agujero más grande que este repo
|
|
11
|
+
* puede tener.
|
|
12
|
+
*
|
|
13
|
+
* Tres piezas, y las tres son puras o con su dependencia inyectada, para que `npm test` las
|
|
14
|
+
* pruebe sin lanzar un Claude Code:
|
|
15
|
+
* 1. **Tres listas** de tools (`claseDeToolExterna`): lectura, escritura y denegadas. Tres y
|
|
16
|
+
* no dos, porque conceder escritura NO puede conceder `Bash` ni `WebFetch`.
|
|
17
|
+
* 2. **El veredicto de una ruta** (`veredictoDeRuta`), que vuelve a aplicar las guardas del
|
|
18
|
+
* proyecto sobre la ruta absoluta del hijo — y las aplica DOS veces, sobre el texto y
|
|
19
|
+
* sobre el `realpath`, que es la misma regla que ya sostiene `arbolDeProyecto.ts`.
|
|
20
|
+
* 3. **El adaptador de política** (`politicaDeAprobacionExterna`), que convierte el
|
|
21
|
+
* `pedirAprobacion` que ya existe en la política de escritura del hijo.
|
|
22
|
+
*/
|
|
23
|
+
import type { LineaDeDiff } from "../../core/diff.js";
|
|
24
|
+
import type { PendienteDeAprobacion } from "../../core/events.js";
|
|
25
|
+
import type { ColaDeEventos } from "../../core/entrelazar.js";
|
|
26
|
+
import type { ConsumoExterno, EjecucionExterna, EscrituraExternaPedida, PoliticaDeEscrituraExterna, ToolDeUnHijo } from "../../core/ports.js";
|
|
27
|
+
import type { Decision } from "../../vendor/hitl.js";
|
|
28
|
+
/**
|
|
29
|
+
* Las tools del hijo que solo LEEN.
|
|
30
|
+
*
|
|
31
|
+
* Los nombres salen del SDK instalado y no de la memoria: se comprobaron contra
|
|
32
|
+
* `sdk-tools.d.ts` de `@anthropic-ai/claude-agent-sdk`, cuya unión `ToolInputSchemas`
|
|
33
|
+
* enumera hoy **cuarenta y cuatro** tools —`REPL`, `Workflow`, `Cron*`, `Artifact`,
|
|
34
|
+
* `RemoteTrigger`, `Monitor`, `Mcp`, `EnterWorktree`…— y crece con cada versión del
|
|
35
|
+
* producto. Esa cifra es el argumento entero de este fichero: con una lista negra, la tool
|
|
36
|
+
* que Claude Code añada mañana entraría permitida.
|
|
37
|
+
*
|
|
38
|
+
* `TodoWrite` está dentro pese al nombre: es la lista de tareas del propio hijo, vive en su
|
|
39
|
+
* memoria y no toca el disco del proyecto.
|
|
40
|
+
*/
|
|
41
|
+
export declare const TOOLS_EXTERNAS_DE_LECTURA: ReadonlySet<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Las que escriben en el proyecto, y por tanto pasan por la política.
|
|
44
|
+
*
|
|
45
|
+
* **Solo `Write` y `Edit`**, y las dos por una razón que se puede comprobar: son las únicas
|
|
46
|
+
* cuyos argumentos encajan en `cambioDe()`, o sea las únicas de las que se puede COMPONER
|
|
47
|
+
* el diff que una persona tiene que ver antes de decidir. Medido en `sdk-tools.d.ts`:
|
|
48
|
+
* `FileWriteInput` es `{file_path, content}` y `FileEditInput` es
|
|
49
|
+
* `{file_path, old_string, new_string, replace_all?}`, que son exactamente las claves que
|
|
50
|
+
* `write_file` y `edit_file` ya traen por el camino de LangGraph.
|
|
51
|
+
*
|
|
52
|
+
* Lo que se queda fuera y por qué, dicho aquí para que no parezca un olvido:
|
|
53
|
+
* - **`NotebookEdit`** no lleva `file_path` sino `notebook_path`, y un proyecto XOne no
|
|
54
|
+
* tiene cuadernos de Jupyter. Conceder una escritura de la que no se sabe componer el
|
|
55
|
+
* diff sería aprobar a ciegas.
|
|
56
|
+
* - **`MultiEdit`** ya no existe en este SDK (cero apariciones en su unión de tools), y el
|
|
57
|
+
* día que vuelva tampoco entra de rebote: es una LISTA de ediciones, así que una sola
|
|
58
|
+
* aprobación cubriría N cambios — o se expande a N decisiones o se deniega. Hoy, denegada.
|
|
59
|
+
*/
|
|
60
|
+
export declare const TOOLS_EXTERNAS_DE_ESCRITURA: ReadonlySet<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Las que se deniegan SIEMPRE, con escritura concedida o sin ella.
|
|
63
|
+
*
|
|
64
|
+
* Aquí está la mitad del arreglo. Antes la decisión era
|
|
65
|
+
* `permitirEscritura || esDeLectura(nombre)`, o sea que el día que se concediera la
|
|
66
|
+
* escritura se concedía **todo**: `Bash` sola basta para escribir el proyecto entero
|
|
67
|
+
* —saltándose de paso la política, el diff y las guardas de ruta de este fichero—, y
|
|
68
|
+
* `WebFetch`/`WebSearch` no escriben pero sacan el contenido del proyecto fuera de la
|
|
69
|
+
* máquina, que no lo decide un especialista.
|
|
70
|
+
*
|
|
71
|
+
* La lista es ILUSTRATIVA y no la barrera: la barrera es que lo que no esté en las dos
|
|
72
|
+
* listas de arriba se deniega igual (`claseDeToolExterna` contesta «desconocida»). Existe
|
|
73
|
+
* para que el motivo pueda decir POR QUÉ se deniega esta en concreto, que es lo que evita
|
|
74
|
+
* que el hijo insista.
|
|
75
|
+
*/
|
|
76
|
+
export declare const TOOLS_EXTERNAS_DENEGADAS: ReadonlySet<string>;
|
|
77
|
+
export type ClaseDeToolExterna = "lectura" | "escritura" | "denegada" | "desconocida";
|
|
78
|
+
/**
|
|
79
|
+
* En qué lista cae una tool. **Deniega por omisión**: lo que no se reconoce es
|
|
80
|
+
* «desconocida», que no es un tercer estado benigno — se trata igual que «denegada».
|
|
81
|
+
*/
|
|
82
|
+
export declare function claseDeToolExterna(nombre: string): ClaseDeToolExterna;
|
|
83
|
+
/** Admitida trae la ruta VIRTUAL (`/app/Clientes.xne`); denegada trae el motivo. */
|
|
84
|
+
export type VeredictoDeRuta = {
|
|
85
|
+
admitida: true;
|
|
86
|
+
ruta: string;
|
|
87
|
+
} | {
|
|
88
|
+
admitida: false;
|
|
89
|
+
motivo: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* La ruta virtual de una ruta absoluta del hijo, o `undefined` si no se puede afirmar que
|
|
93
|
+
* cae dentro del proyecto.
|
|
94
|
+
*
|
|
95
|
+
* Una relativa se rechaza en vez de resolverse contra el `cwd`: el SDK documenta que
|
|
96
|
+
* `file_path` es absoluta («must be absolute, not relative»), así que una relativa es algo
|
|
97
|
+
* que no entendemos, y lo que no se entiende se deniega.
|
|
98
|
+
*/
|
|
99
|
+
export declare function rutaVirtualDeEscritura(cwd: string, filePath: string): string | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* ¿Puede el hijo escribir en esta ruta? **Las guardas del proyecto, reaplicadas.**
|
|
102
|
+
*
|
|
103
|
+
* Y se aplican DOS veces, que es la lección de `arbolDeProyecto.ts` medida en su día: sobre
|
|
104
|
+
* el TEXTO —de balde, antes de tocar el disco— y sobre el camino REAL. Sin la segunda no
|
|
105
|
+
* era verdad: en un sistema que no distingue mayúsculas (APFS, NTFS) `.ENV` no es `/.env`
|
|
106
|
+
* para `puedeLeerRuta` pero abre `.env`, y un enlace simbólico dentro de la raíz que apunte
|
|
107
|
+
* a un fichero denegado o a fuera del proyecto pasa la comprobación de «sigue dentro»
|
|
108
|
+
* porque su texto sí lo está. Lo que falla no es el sitio, es el destino.
|
|
109
|
+
*
|
|
110
|
+
* Del fichero que se va a escribir se canonicaliza el PADRE y no él: una escritura normal
|
|
111
|
+
* crea un fichero que todavía no existe, así que su `realpath` lanzaría y esto denegaría
|
|
112
|
+
* toda creación de ficheros nuevos.
|
|
113
|
+
*
|
|
114
|
+
* `real` entra por parámetro como el `leer` de `cambioDe`: en producción es `realpathSync`,
|
|
115
|
+
* y un test puede darle un doble. Que lance —el padre no existe— no es admitir: es denegar,
|
|
116
|
+
* porque entonces no se sabe dónde cae.
|
|
117
|
+
*/
|
|
118
|
+
export declare function veredictoDeRuta(opciones: {
|
|
119
|
+
cwd: string;
|
|
120
|
+
ruta: unknown;
|
|
121
|
+
/** Las del proyecto, para reconocer una vista aplanada (`X.xml` con un `X.xne` al lado). */
|
|
122
|
+
ficheros: ReadonlySet<string>;
|
|
123
|
+
real?: (ruta: string) => string;
|
|
124
|
+
/**
|
|
125
|
+
* `true` para una LECTURA: se comprueba el confinamiento y lo que no se puede ni leer,
|
|
126
|
+
* pero no las reglas que solo gobiernan escrituras (un artefacto mal puesto de antes hay
|
|
127
|
+
* que poder leerlo para moverlo, y `/skills/` y `/adjuntos/` existen para leerse).
|
|
128
|
+
*/
|
|
129
|
+
soloConfinamiento?: boolean;
|
|
130
|
+
}): VeredictoDeRuta;
|
|
131
|
+
/**
|
|
132
|
+
* La decisión del hook `PreToolUse`, que es la que NO se puede ensombrecer.
|
|
133
|
+
*
|
|
134
|
+
* **Esto no es un cinturón de más: es el único sitio donde la denegación es cierta**, y sale
|
|
135
|
+
* de leer el SDK instalado en vez de suponerlo. Tres frases suyas, textuales:
|
|
136
|
+
* - «Allow rules from settings files can also shadow the callback» — o sea que `canUseTool`
|
|
137
|
+
* puede no invocarse nunca.
|
|
138
|
+
* - «Denials that resolve before canUseTool runs — PreToolUse hook denies, and deny-rule
|
|
139
|
+
* overrides of hook allow/ask decisions — are not covered here» — o sea que un deny del
|
|
140
|
+
* hook resuelve ANTES y gana.
|
|
141
|
+
* - «With a permission prompt surface (stdio/SDK canUseTool), the 'ask' path surfaces via a
|
|
142
|
+
* can_use_tool control_request» — o sea que `ask` es cómo se llega a nuestro callback.
|
|
143
|
+
*
|
|
144
|
+
* Y de ahí sale el reparto: el hook contesta las TRES clases explícitamente —`allow` para
|
|
145
|
+
* leer, `deny` para todo lo que no está en las listas, y `ask` para escribir, que es lo que
|
|
146
|
+
* empuja la decisión hacia `canUseTool`, donde sí se puede esperar a una persona— y no deja
|
|
147
|
+
* ninguna sin decidir. Dejar una sin decidir sería dejar que la decida el `permissionMode`,
|
|
148
|
+
* cuyas semánticas exactas NO están medidas: `dontAsk` («deny if not pre-approved») podría
|
|
149
|
+
* denegar la escritura antes del callback y dejar la función muerta con todo en verde, y
|
|
150
|
+
* `default` («prompts for dangerous operations») podría aprobar `WebSearch` por su cuenta
|
|
151
|
+
* sin consultarnos — que es el fallo en la dirección mala.
|
|
152
|
+
*/
|
|
153
|
+
export declare function decisionDePreToolUse(opciones: {
|
|
154
|
+
nombre: string;
|
|
155
|
+
entrada: Record<string, unknown>;
|
|
156
|
+
cwd: string;
|
|
157
|
+
ficheros: ReadonlySet<string>;
|
|
158
|
+
real?: (ruta: string) => string;
|
|
159
|
+
/** La ejecución concedida a ESTE hijo (`PeticionExterna.ejecucion`). Ausente: `Bash` se deniega. */
|
|
160
|
+
ejecucion?: Pick<EjecucionExterna, "scripts" | "lecturas">;
|
|
161
|
+
/** Las carpetas de las skills montadas (`pluginDeSkills.ts#carpetasDeLecturaDeSkills`): se pueden LEER enteras. */
|
|
162
|
+
lecturasDeSkills?: readonly string[];
|
|
163
|
+
/** Las carpetas de la sesión que puede leer aunque no ejecute (`PeticionExterna.lecturas`). */
|
|
164
|
+
lecturasDeSesion?: readonly string[];
|
|
165
|
+
}): {
|
|
166
|
+
hookEventName: "PreToolUse";
|
|
167
|
+
permissionDecision: "allow" | "deny" | "ask";
|
|
168
|
+
permissionDecisionReason: string;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* **Las tools de LECTURA también llevan guarda de ruta, y esto salió de correrlo.**
|
|
172
|
+
*
|
|
173
|
+
* Medido en la segunda ejecución viva (11-09-2026), dicho por el propio hijo: «`.env` — sí
|
|
174
|
+
* pude leerlo: contiene una línea `CLAVE=secreta`». La lista blanca permitía `Read` a secas,
|
|
175
|
+
* sin mirar la ruta — y era así desde el primer día, o sea que el agujero no lo abrió la
|
|
176
|
+
* escritura: ya estaba. Por el camino de LangGraph esto no pasa porque `DENEGADO_SIEMPRE`
|
|
177
|
+
* deniega `read` sobre `/.env`, `/.git` y `/.xonecode`; ahí dentro además vive el
|
|
178
|
+
* `checkpoint.sqlite`, que lleva la lista de mensajes ENTERA de cada conversación.
|
|
179
|
+
*
|
|
180
|
+
* Qué se deniega leer, y por qué no es la misma lista que para escribir:
|
|
181
|
+
* - `/.env`, `/.git`, `/.xonecode`: las de `DENEGADO_SIEMPRE` para `read`, por lo mismo.
|
|
182
|
+
* - Las **vistas aplanadas**: el backend se las RETIRA al agente entero
|
|
183
|
+
* (`sinVistasAplanadas`), no solo para escribir — si las ve, edita el fichero equivocado.
|
|
184
|
+
* - Y lo que caiga **fuera de la carpeta del proyecto**, que es la mitad que nadie había
|
|
185
|
+
* comprobado: el `file_path` de `Read` es absoluto y puede nombrar cualquier cosa.
|
|
186
|
+
* - `/skills/`, `/adjuntos/` y `/artefactos/` NO se deniegan: leerlos es su razón de ser.
|
|
187
|
+
*
|
|
188
|
+
* `Glob` y `Grep` llevan `path` OPCIONAL (medido en `sdk-tools.d.ts`), y ausente significa
|
|
189
|
+
* la raíz: entonces no hay nada que comprobar. **Límite declarado**: un `Grep` sobre la raíz
|
|
190
|
+
* puede devolver líneas de un fichero denegado, porque `canUseTool` decide sobre la LLAMADA
|
|
191
|
+
* y no puede filtrar su salida. Cerrarlo exigiría un hook `PostToolUse`, que no está puesto.
|
|
192
|
+
*/
|
|
193
|
+
export declare function veredictoDeLectura(opciones: {
|
|
194
|
+
cwd: string;
|
|
195
|
+
nombre: string;
|
|
196
|
+
entrada: Record<string, unknown>;
|
|
197
|
+
ficheros: ReadonlySet<string>;
|
|
198
|
+
real?: (ruta: string) => string;
|
|
199
|
+
/** Carpetas de FUERA del proyecto que este hijo puede leer (`EjecucionExterna.lecturas`). */
|
|
200
|
+
lecturas?: readonly string[];
|
|
201
|
+
}): {
|
|
202
|
+
admitida: true;
|
|
203
|
+
} | {
|
|
204
|
+
admitida: false;
|
|
205
|
+
motivo: string;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* El motivo de NO dejar correr ese `Bash`, o `undefined` si se deja: su `command` tiene que pasar
|
|
209
|
+
* `motivoDeComandoExternoInaceptable`, y no puede ir en segundo plano (`BashOutput` y `KillShell`
|
|
210
|
+
* siguen cerrados: un comando que se queda vivo no lo para nadie).
|
|
211
|
+
*/
|
|
212
|
+
export declare function motivoDeBashExterno(entrada: Record<string, unknown>, scripts: readonly string[]): string | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Todo lo de FUERA del proyecto que un hijo puede leer: las carpetas de su sesión si ejecuta (capturas, hotswap) y las de
|
|
215
|
+
* las skills montadas. Una sola función para el hook y para `canUseTool`: las dos llaves tienen que decir lo mismo.
|
|
216
|
+
*/
|
|
217
|
+
export declare function lecturasDelHijo(ejecucion: Pick<EjecucionExterna, "lecturas"> | undefined, lecturasDeSkills: readonly string[] | undefined, lecturasDeSesion?: readonly string[]): string[];
|
|
218
|
+
/**
|
|
219
|
+
* ¿Cae esta ruta dentro de una de las carpetas de la sesión que el hijo con ejecución puede leer
|
|
220
|
+
* (sus capturas en artefactos, lo de hotswap)? Por TEXTO —`resolve` deshace un `..`— Y por el
|
|
221
|
+
* camino REAL —un enlace dentro de la carpeta que apunte a `checkpoint.sqlite` no pasa—, las dos,
|
|
222
|
+
* como el resto de guardas. Lo que no se puede canonicalizar no está dentro.
|
|
223
|
+
*/
|
|
224
|
+
export declare function dentroDeUnaLectura(ruta: string, lecturas: readonly string[], real: (ruta: string) => string): boolean;
|
|
225
|
+
/** El motivo que se le devuelve al hijo cuando la tool entera no está concedida. */
|
|
226
|
+
export declare function motivoDeToolDenegada(nombre: string, clase: ClaseDeToolExterna): string;
|
|
227
|
+
/** Por qué `correr` rechaza cuando se paró el turno: el hijo se mató, no terminó su encargo. */
|
|
228
|
+
export declare const MOTIVO_DE_CANCELACION_EXTERNA = "el turno se cancel\u00F3 y el agente externo se ha detenido";
|
|
229
|
+
/** Y el motivo cuando el propio SDK abortó mientras se esperaba la decisión. */
|
|
230
|
+
export declare const MOTIVO_DE_ESCRITURA_ABORTADA = "la petici\u00F3n se cancel\u00F3 antes de que nadie autorizara esa escritura, as\u00ED que no se ha escrito nada.";
|
|
231
|
+
/** El motivo cuando la escritura se pidió bien y quien decide dijo que no. */
|
|
232
|
+
export declare const MOTIVO_DE_ESCRITURA_RECHAZADA = "la escritura no se ha autorizado. No la intentes por otro camino: explica qu\u00E9 quer\u00EDas cambiar y por qu\u00E9.";
|
|
233
|
+
/**
|
|
234
|
+
* El MODO de escritura de la sesión, tal y como lo ve la política de un motor externo.
|
|
235
|
+
*
|
|
236
|
+
* Es una función y no un booleano porque se pregunta en cada tanda (`/aprobacion` cambia el
|
|
237
|
+
* modo con la sesión en marcha), y el apunte es opcional porque quien monta la política en
|
|
238
|
+
* un test no tiene aviso de honestidad que alimentar.
|
|
239
|
+
*/
|
|
240
|
+
export interface ModoDeLaSesion {
|
|
241
|
+
/** ¿Se aplica sin enseñar el diff, AHORA? Ver `core/modoDeEscritura.ts#seEscribeSinPreguntar`. */
|
|
242
|
+
sinPreguntar: () => boolean;
|
|
243
|
+
/** Las rutas que se acaban de aplicar sin preguntar, para el aviso del turno. */
|
|
244
|
+
alAplicarSinPreguntar?: (rutas: readonly string[]) => void;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* El `pedirAprobacion` de la sesión, convertido en la política de escritura del hijo.
|
|
248
|
+
*
|
|
249
|
+
* **Y aquí está la mitad buena del diseño: la política ya existía.** `pedirAprobacion` es el
|
|
250
|
+
* hueco que `abrirSesionReal` declara y que cada piel rellena, y sus implementaciones son
|
|
251
|
+
* exactamente las dos que hacían falta:
|
|
252
|
+
* - **La interactiva** (`consolaWeb.aprobacionesTui`, el modal de la TUI, `pedirDecisiones`
|
|
253
|
+
* por readline): enseña el diff y espera. Nace RECHAZADA entera, tiene plazo, y sin
|
|
254
|
+
* cliente enganchado contesta rechazo sin preguntar. Fail-closed por construcción, ya
|
|
255
|
+
* probado, ya cableado en las tres pieles.
|
|
256
|
+
* - **La autónoma** (`consolaDeTarea.aprobacionesTui`): concede —la autorización fue crear
|
|
257
|
+
* la tarea—, lo ANUNCIA con los nombres en el transcript y lo mete en `Tarea.autorizadas`
|
|
258
|
+
* por su callback `autorizado`. O sea que la escritura de un agente externo dentro de una
|
|
259
|
+
* tarea de fondo no puede ser muda ni quedarse fuera de la cuenta que lee el juez.
|
|
260
|
+
* Escribir un segundo tipo de política habría sido escribir una segunda forma de decidir
|
|
261
|
+
* sobre lo mismo, con dos sitios donde el fail-closed puede dejar de estarlo.
|
|
262
|
+
*
|
|
263
|
+
* Lo que esto añade es la TRADUCCIÓN, y nada más: un `PendienteDeAprobacion` sintético por
|
|
264
|
+
* escritura, con su ruta virtual y su diff, por los mismos dos mapas que ya viajan
|
|
265
|
+
* (`ficheros`, `diffs`).
|
|
266
|
+
* El id lleva el prefijo `externo:` para que no pueda colisionar con el de un interrupt del
|
|
267
|
+
* grafo — de esas claves se construye el `resume`, y una colisión resolvería el interrupt
|
|
268
|
+
* equivocado.
|
|
269
|
+
*
|
|
270
|
+
* **Fail-closed hasta el final**: si la promesa revienta, o si el mapa no trae `approve`
|
|
271
|
+
* para nuestro id, la respuesta es NO. Nunca se deja salir la excepción hacia el SDK, cuyo
|
|
272
|
+
* comportamiento ante un `canUseTool` que lanza no está medido.
|
|
273
|
+
*/
|
|
274
|
+
export declare function politicaDeAprobacionExterna(pedirAprobacion: (pendientes: PendienteDeAprobacion[], ficheros: Map<string, string>, diffs: Map<string, LineaDeDiff[]>) => Promise<Map<string, Decision>>, modo?: ModoDeLaSesion): PoliticaDeEscrituraExterna;
|
|
275
|
+
/**
|
|
276
|
+
* Una escritura que un motor externo PROPONE, antes de pasar por ninguna guarda.
|
|
277
|
+
*
|
|
278
|
+
* La ruta llega `unknown` a propósito: viene de fuera, y quien decide si es una ruta es
|
|
279
|
+
* `veredictoDeRuta` y no quien la lee.
|
|
280
|
+
*/
|
|
281
|
+
export interface EscrituraPropuesta {
|
|
282
|
+
ruta: unknown;
|
|
283
|
+
lineas: LineaDeDiff[];
|
|
284
|
+
}
|
|
285
|
+
export type VeredictoDeEscrituras = {
|
|
286
|
+
admitidas: true;
|
|
287
|
+
escrituras: EscrituraExternaPedida[];
|
|
288
|
+
} | {
|
|
289
|
+
admitidas: false;
|
|
290
|
+
motivo: string;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Las guardas de ruta sobre una tanda de escrituras propuestas, sea cual sea el motor.
|
|
294
|
+
*
|
|
295
|
+
* **Vive aquí, en UN sitio, y los dos motores externos que escriben por petición la llaman.**
|
|
296
|
+
* Cada uno traduce lo suyo —Codex sus `changes` con `kind` y `diff`, OpenCode el `toolCall`
|
|
297
|
+
* de ACP con su `oldText`/`newText`— y a partir de ahí el camino es el mismo. Escribir este
|
|
298
|
+
* bucle una vez por motor sería un segundo (y un tercer) sitio donde el fail-closed puede
|
|
299
|
+
* dejar de estarlo, que es la única forma en la que estas guardas se han roto nunca.
|
|
300
|
+
*
|
|
301
|
+
* **Una sola ruta mala tumba la tanda entera.** Es la dirección conservadora, y además la
|
|
302
|
+
* única que los dos protocolos saben expresar: los dos contestan una petición con UNA
|
|
303
|
+
* decisión, así que «las que pasen sí» no se puede decir.
|
|
304
|
+
*/
|
|
305
|
+
export declare function veredictoDeEscriturasExternas(opciones: {
|
|
306
|
+
cwd: string;
|
|
307
|
+
agente: string;
|
|
308
|
+
propuestas: readonly EscrituraPropuesta[];
|
|
309
|
+
ficheros: ReadonlySet<string>;
|
|
310
|
+
real?: (ruta: string) => string;
|
|
311
|
+
}): VeredictoDeEscrituras;
|
|
312
|
+
/**
|
|
313
|
+
* La decisión entera de una tanda: guardas de ruta y DESPUÉS la política.
|
|
314
|
+
*
|
|
315
|
+
* **Vive extraída y no en el cierre de cada adaptador**, que es donde este repo ha visto
|
|
316
|
+
* fallar esta arquitectura nueve veces: una composición de producción dentro de algo que
|
|
317
|
+
* todos los tests doblan. Con los adaptadores externos sería literal, porque los tests no
|
|
318
|
+
* lanzan sus binarios.
|
|
319
|
+
*
|
|
320
|
+
* Fail-closed en los cuatro caminos: sin política, con una ruta rechazada, si la política
|
|
321
|
+
* revienta, o si contesta que no. Y el orden importa: preguntar por algo cuyo único final
|
|
322
|
+
* posible es un rechazo es sacar un modal inútil — la misma regla que el `when` de
|
|
323
|
+
* `seDetieneEn` en `agent/grafo/perfiles.ts`.
|
|
324
|
+
*/
|
|
325
|
+
export declare function decisionDeEscrituraExterna(opciones: {
|
|
326
|
+
cwd: string;
|
|
327
|
+
agente: string;
|
|
328
|
+
propuestas: readonly EscrituraPropuesta[];
|
|
329
|
+
ficheros: ReadonlySet<string>;
|
|
330
|
+
real?: (ruta: string) => string;
|
|
331
|
+
/** Ausente = nadie autoriza en esta sesión, y «nadie a quien preguntar» nunca es «sí». */
|
|
332
|
+
aprobar?: PoliticaDeEscrituraExterna;
|
|
333
|
+
}): Promise<{
|
|
334
|
+
concedida: boolean;
|
|
335
|
+
motivo?: string;
|
|
336
|
+
}>;
|
|
337
|
+
/**
|
|
338
|
+
* El diff de una escritura del hijo, con la MISMA función que compone el de una aprobación
|
|
339
|
+
* del grafo (`interrupts.ts#cambioDe`).
|
|
340
|
+
*
|
|
341
|
+
* La traducción es solo el NOMBRE de la tool: las claves de los argumentos coinciden —
|
|
342
|
+
* medido en `sdk-tools.d.ts`—, así que `Write` es un `write_file` y `Edit` un `edit_file`.
|
|
343
|
+
* Compartir la función en vez de escribir un segundo diff es lo que impide que la ventana de
|
|
344
|
+
* aprobación de un agente externo enseñe algo distinto de la de siempre.
|
|
345
|
+
*
|
|
346
|
+
* Un matiz declarado: `Edit` sin `replace_all` cambia UNA aparición y falla si hay varias,
|
|
347
|
+
* mientras que `cambioDe` pinta el reemplazo de todas. Cuando la edición es válida para el
|
|
348
|
+
* hijo hay exactamente una, así que coinciden; cuando no lo es, el diff enseña de más y la
|
|
349
|
+
* escritura no llega a ocurrir.
|
|
350
|
+
*/
|
|
351
|
+
export declare function diffDeEscrituraExterna(tool: string, entrada: Record<string, unknown>, rutaVirtual: string, leer?: (ruta: string) => string): LineaDeDiff[];
|
|
352
|
+
/**
|
|
353
|
+
* La política de la SESIÓN, derivada de su `pedirAprobacion`. **Extraída y exportada a
|
|
354
|
+
* propósito**: es el cableado, y el cableado es donde este repo lleva SIETE reglas que se
|
|
355
|
+
* quedaron sin montar con todo en verde. Vive fuera del cierre de `abrirSesionReal` para
|
|
356
|
+
* poder probarla contra lo real en vez de contra un doble.
|
|
357
|
+
*
|
|
358
|
+
* Ausente es «no hay a quién preguntar», y entonces no hay política — o sea que el hijo no
|
|
359
|
+
* escribe. Es el caso de `xonecode run` en CI y de cualquier sesión montada sin aprobación:
|
|
360
|
+
* el mismo camino por el que hoy el turno dice «piden aprobación y no hay quién apruebe».
|
|
361
|
+
*/
|
|
362
|
+
export declare function politicaExternaDeSesion(pedirAprobacion: ((pendientes: PendienteDeAprobacion[], ficheros: Map<string, string>, diffs: Map<string, LineaDeDiff[]>) => Promise<Map<string, Decision>>) | undefined, modo?: ModoDeLaSesion): PoliticaDeEscrituraExterna | undefined;
|
|
363
|
+
export declare function eventoDeToolExterna(nombre: string, entrada: Record<string, unknown>, cwd: string, real?: (ruta: string) => string): {
|
|
364
|
+
nombre: string;
|
|
365
|
+
detalle?: string;
|
|
366
|
+
};
|
|
367
|
+
/**
|
|
368
|
+
* Todo lo que un agente externo necesita de la SESIÓN, en un solo sitio y exportado.
|
|
369
|
+
*
|
|
370
|
+
* **Está extraída del cierre de `abrirSesionReal` a propósito**, y no por gusto: son cuatro
|
|
371
|
+
* campos opcionales que se componen dentro de algo que todos sus tests doblan, o sea el
|
|
372
|
+
* patrón de fallo que este repo lleva medido siete veces — una regla que deja de estar
|
|
373
|
+
* montada CON TODO EN VERDE. Aquí los tres que importan se pueden comprobar contra lo real:
|
|
374
|
+
* que sin `pedirAprobacion` no hay política (y por tanto no hay escritura), que la actividad
|
|
375
|
+
* del hijo acaba en la cola de eventos, y que la lista de ficheros es una FUNCIÓN y no una
|
|
376
|
+
* foto congelada al abrir la sesión.
|
|
377
|
+
*/
|
|
378
|
+
export declare function opcionesDeSubagenteExterno(opciones: {
|
|
379
|
+
pedirAprobacion?: (pendientes: PendienteDeAprobacion[], ficheros: Map<string, string>, diffs: Map<string, LineaDeDiff[]>) => Promise<Map<string, Decision>>;
|
|
380
|
+
ficherosDelProyecto: () => ReadonlySet<string>;
|
|
381
|
+
eventos: ColaDeEventos;
|
|
382
|
+
/** Lo que el hijo consumió, para la cuenta de la sesión. Ausente = no se lleva la cuenta. */
|
|
383
|
+
alConsumir?: (consumo: ConsumoExterno) => void;
|
|
384
|
+
/**
|
|
385
|
+
* El modo de escritura de la sesión. Ausente = supervisado, o sea que cada escritura del
|
|
386
|
+
* hijo se pregunta, que es lo que hacía antes de que el modo existiera.
|
|
387
|
+
*/
|
|
388
|
+
modo?: ModoDeLaSesion;
|
|
389
|
+
}): {
|
|
390
|
+
aprobarEscritura?: PoliticaDeEscrituraExterna;
|
|
391
|
+
ficherosDelProyecto: () => ReadonlySet<string>;
|
|
392
|
+
alUsarTool: (tool: ToolDeUnHijo) => void;
|
|
393
|
+
alRazonar: (texto: string) => void;
|
|
394
|
+
alConsumir?: (consumo: ConsumoExterno) => void;
|
|
395
|
+
};
|
|
396
|
+
/** Cuántos ficheros se le enumeran. Por encima, se dice cuántos quedan fuera. */
|
|
397
|
+
export declare const TOPE_DE_INVENTARIO = 400;
|
|
398
|
+
/**
|
|
399
|
+
* El inventario del proyecto, para un agente EXTERNO.
|
|
400
|
+
*
|
|
401
|
+
* **Existe porque un hijo de Claude Code no puede enumerar la carpeta, y eso está medido**
|
|
402
|
+
* (11-09-2026, espiando el hook en una ejecución real). Intentó `Bash ls`, `Bash find` —
|
|
403
|
+
* denegadas—, pidió `ToolSearch {"query":"select:Glob,Grep"}` y **no las encontró**: ese
|
|
404
|
+
* hijo no trae ninguna herramienta de listado. Después probó las tools MCP del usuario
|
|
405
|
+
* (denegadas también) y acabó leyendo a ciegas nombres inventados —`README.md`,
|
|
406
|
+
* `CLAUDE.md`, `app.ini`, `main.xml`…, ninguno existía— para concluir que «el proyecto está
|
|
407
|
+
* prácticamente vacío para mí, porque no puedo listarlo».
|
|
408
|
+
*
|
|
409
|
+
* La salida fácil habría sido concederle `Bash`, y es justo la que no se puede tomar: con
|
|
410
|
+
* `Bash` escribe el proyecto entero saltándose la política, el diff y las guardas de ruta.
|
|
411
|
+
* La buena es que el harness YA sabe qué ficheros hay —es la misma lista con la que
|
|
412
|
+
* reconoce una vista aplanada— así que se le DICE. Es el patrón de `core/adjuntos.ts`:
|
|
413
|
+
* montar no basta, hay que decir que están.
|
|
414
|
+
*
|
|
415
|
+
* Dos cosas que hereda de las reglas de siempre: las rutas van VIRTUALES (desde la raíz del
|
|
416
|
+
* proyecto, nunca las de la máquina) y la lista va ACOTADA con el total al lado, que es lo
|
|
417
|
+
* que impide leer los que caben como si fueran todos.
|
|
418
|
+
*/
|
|
419
|
+
export declare function inventarioDelProyecto(ficheros: ReadonlySet<string>, tope?: number): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las skills de xonecode, servidas a un hijo de **Claude Code** como un PLUGIN LOCAL.
|
|
3
|
+
*
|
|
4
|
+
* **La palanca es `plugins`, y eso se midió — `additionalDirectories` NO vale.** El primer
|
|
5
|
+
* intento fue montar una carpeta con la disposición `<dir>/.claude/skills/` y pasarla por
|
|
6
|
+
* `additionalDirectories`, porque su documentación dice que añadir un directorio recarga
|
|
7
|
+
* «CLAUDE.md, skills, and plugins». Probado contra un hijo de verdad, preguntándole qué
|
|
8
|
+
* skills tenía: listó las del usuario y las de sus plugins, y **ninguna de las dos del
|
|
9
|
+
* montaje**. Con `plugins: [{type:"local", path}]` y un `plugin.json` que apunta su `skills`
|
|
10
|
+
* a una carpeta, las mismas dos aparecen como `xonecode:xone-review` y
|
|
11
|
+
* `xonecode:xone-debugging`. Esa diferencia es todo el motivo de este fichero.
|
|
12
|
+
*
|
|
13
|
+
* **Y por eso no se escribe nada dentro del proyecto.** La otra forma de que Claude Code las
|
|
14
|
+
* encuentre sería un `.claude/skills/` en la carpeta del proyecto, y ahí no se puede: el
|
|
15
|
+
* proyecto es la app del cliente, se sincroniza con CloudStudio y entra en el commit de cada
|
|
16
|
+
* turno, así que nuestro andamiaje acabaría subido a Studio. Esta carpeta es NUESTRA
|
|
17
|
+
* (`~/.xonecode/motores/claude`) y el hijo la recibe por argumento.
|
|
18
|
+
*
|
|
19
|
+
* **Enlaces y no copias**: las de serie pesan megas —una sola son 77 ficheros— y esto se
|
|
20
|
+
* monta en cada arranque de un subagente externo.
|
|
21
|
+
*
|
|
22
|
+
* **Y el hijo puede LEER la carpeta entera de cada skill montada, no solo su `SKILL.md`**
|
|
23
|
+
* (`carpetasDeLecturaDeSkills`, sumadas a las lecturas de `veredictoDeLectura`). Antes se negaba, a
|
|
24
|
+
* propósito, y el precio resultó demasiado alto: medido en una tarea de Maset (15-10-2026), el
|
|
25
|
+
* developer y el consultor en Claude Code no pudieron leer `references/xml-ui/…` y escribieron
|
|
26
|
+
* atributos de XOne a ciegas —`img=` en un `type="IMG"`, donde la documentación dice `path=`—; el
|
|
27
|
+
* consultor lo dijo: «mi sandbox bloquea Read fuera del proyecto… No puedo confirmar si es `img` o
|
|
28
|
+
* `path`». No se abre «una carpeta de fuera por comodidad»: se abren SOLO las carpetas de las skills
|
|
29
|
+
* que este mismo montaje sirve, una a una, en LECTURA, comprobadas por texto y por camino real
|
|
30
|
+
* (`dentroDeUnaLectura`). La casa, `.xonecode/` y el resto de la máquina siguen cerrados.
|
|
31
|
+
*
|
|
32
|
+
* **Segundo límite**: el nombre le llega PREFIJADO (`xonecode:<nombre>`), que es como Claude
|
|
33
|
+
* Code nombra lo que viene de un plugin, mientras que el `.md` de un subagente y
|
|
34
|
+
* `promptDeAgente` lo nombran a secas. No se reescribe el prompt para igualarlo: el prefijo
|
|
35
|
+
* lo pone el motor y adivinarlo aquí sería atarse a su formato.
|
|
36
|
+
*/
|
|
37
|
+
/** El nombre del plugin. Sale en el nombre de cada skill (`xonecode:<nombre>`), así que
|
|
38
|
+
* vive en una constante: es dato del producto, no una cadena suelta. */
|
|
39
|
+
export declare const NOMBRE_DEL_PLUGIN = "xonecode";
|
|
40
|
+
/** La carpeta que gobernamos para este motor. Fuera del proyecto, a propósito. */
|
|
41
|
+
export declare function carpetaDelPluginDeSkills(casa?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* El manifiesto, PURO y por eso comprobable sin disco.
|
|
44
|
+
*
|
|
45
|
+
* `skills` apunta a una subcarpeta relativa y no a la raíz del paquete: la carpeta de
|
|
46
|
+
* montaje FUNDE las tres raíces (serie, global y proyecto) con la precedencia de
|
|
47
|
+
* `cargarSkills`, y una ruta suelta solo podría apuntar a una de ellas.
|
|
48
|
+
*/
|
|
49
|
+
export declare function manifiestoDelPluginDeSkills(): string;
|
|
50
|
+
/**
|
|
51
|
+
* Deja la carpeta del plugin lista y devuelve su ruta — o AUSENTE si no hay ninguna skill
|
|
52
|
+
* que servir, o si no se pudo montar.
|
|
53
|
+
*
|
|
54
|
+
* **Ausente no tumba el turno.** Esto cuelga del arranque de un subagente: un fallo al
|
|
55
|
+
* escribir en la casa del usuario no puede llevarse por delante el trabajo, así que el hijo
|
|
56
|
+
* arranca sin plugin y con las suyas, que es como estaba antes.
|
|
57
|
+
*
|
|
58
|
+
* **La carpeta de skills se RECREA entera** en cada montaje. Dentro solo hay enlaces que
|
|
59
|
+
* pusimos nosotros, así que borrarla es seguro; y sin borrarla, una skill que el usuario
|
|
60
|
+
* quitó del disco seguiría anunciada por un enlace roto — el ajuste viejo que sobrevive a su
|
|
61
|
+
* dueño, que es el fallo que este repo persigue en todas partes.
|
|
62
|
+
*/
|
|
63
|
+
export declare function montarPluginDeSkills(opciones?: {
|
|
64
|
+
casa?: string;
|
|
65
|
+
raiz?: string;
|
|
66
|
+
}): string | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Las skills que el hijo de Claude Code puede VER y usar (la opción `skills` del SDK): las de su `.md`, con el nombre que
|
|
69
|
+
* les da el plugin (`xonecode:<nombre>`). Sin plugin montado, ninguna. Omitir la opción «no es skills off» (su propia
|
|
70
|
+
* documentación): el hijo veía TODAS las que descubre, también las del usuario en `~/.claude` y las de sus plugins.
|
|
71
|
+
* Es un filtro de contexto, no un candado: los ficheros de las demás siguen en el disco, y leerlos lo niega
|
|
72
|
+
* `veredictoDeLectura` (fuera del proyecto y de las carpetas de las skills montadas).
|
|
73
|
+
*/
|
|
74
|
+
export declare function skillsVisiblesDelHijo(skills: readonly string[] | undefined, conPlugin: boolean): string[];
|
|
75
|
+
/**
|
|
76
|
+
* Las carpetas que un hijo de Claude Code puede LEER de las skills montadas: de cada una, su enlace dentro del plugin
|
|
77
|
+
* (`<plugin>/skills/<nombre>`, que es la ruta que el motor le enseña) y su carpeta REAL. Las dos hacen falta:
|
|
78
|
+
* `dentroDeUnaLectura` compara el texto de la ruta Y su camino real, y el plugin usa ENLACES, así que una lectura por el
|
|
79
|
+
* enlace tiene el texto bajo el plugin y el camino real bajo la skill. Solo las que están en disco.
|
|
80
|
+
*/
|
|
81
|
+
export declare function carpetasDeLecturaDeSkills(opciones?: {
|
|
82
|
+
casa?: string;
|
|
83
|
+
raiz?: string;
|
|
84
|
+
}): string[];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex como subagente: un turno contra `codex app-server --stdio`.
|
|
3
|
+
*
|
|
4
|
+
* **Todo lo que hay aquí está MEDIDO contra el binario real (0.152.1), no deducido de una
|
|
5
|
+
* documentación.** El encuadre es JSON por línea sin campo `jsonrpc`; `initialize` contesta
|
|
6
|
+
* con el `userAgent` y el `codexHome`; `thread/start` acepta `{cwd, ephemeral, approvalPolicy,
|
|
7
|
+
* sandbox}` y devuelve `{thread:{id}}`; `turn/start` toma
|
|
8
|
+
* `{threadId, input:[{type:"text", text, text_elements:[]}]}`; y la respuesta final llega en
|
|
9
|
+
* un `item/completed` cuyo `item.type` es `agentMessage` con `phase: "final_answer"`. Los
|
|
10
|
+
* valores de sandbox son exactamente tres, y los enumeró el propio servidor al rechazar uno
|
|
11
|
+
* mal escrito: `read-only`, `workspace-write` y `danger-full-access`.
|
|
12
|
+
*
|
|
13
|
+
* **Se usa el `codex` del PATH, no un paquete npm.** El harness de deepseek se trae
|
|
14
|
+
* `@openai/codex` para no depender del PATH; aquí se prefiere el que el usuario ya tiene
|
|
15
|
+
* instalado y autenticado, porque ese paquete son ~100 MB de binario por plataforma y
|
|
16
|
+
* traerlo obligaría a todo el mundo a bajarlo para una capacidad opcional. `CODEX_BIN`
|
|
17
|
+
* permite apuntar a otro.
|
|
18
|
+
*
|
|
19
|
+
* **El sandbox es `read-only` SIEMPRE, y lo que abre la escritura es el `approvalPolicy`.**
|
|
20
|
+
* Esa es la decisión central y está medida (11-09-2026, tres ejecuciones): con
|
|
21
|
+
* `sandbox: "workspace-write"` las escrituras dentro del cwd ocurren solas y no vuelven a
|
|
22
|
+
* xonecode, o sea que ninguna de sus guardas de ruta las vería. Con `read-only` la caja del
|
|
23
|
+
* sistema operativo sigue siendo la denegación —no depende de que el modelo colabore— y
|
|
24
|
+
* `approvalPolicy: "on-request"` convierte cada escritura en una PETICIÓN que contestamos
|
|
25
|
+
* nosotros: el mismo papel que el `ask` del hook `PreToolUse` en Claude Code. Medido:
|
|
26
|
+
* contestando `accept` el fichero se escribe, y contestando `decline` no queda fichero, el
|
|
27
|
+
* item queda `declined` y el turno SIGUE, así que el agente puede contarlo. Sin escritura
|
|
28
|
+
* concedida se manda `never`, que evita que el hijo se quede esperando a alguien.
|
|
29
|
+
*
|
|
30
|
+
* **Lo que se decide y lo que se pregunta llegan en mensajes DISTINTOS.** La petición
|
|
31
|
+
* (`item/fileChange/requestApproval`) trae solo un `itemId`; los ficheros vinieron antes, en
|
|
32
|
+
* el `item/started` de ese id. De ahí el registro de items de aquí abajo: sin él no hay diff
|
|
33
|
+
* que enseñar, y sin diff no hay decisión que tomar. La traducción de esos cambios a lo que
|
|
34
|
+
* las pieles pintan, y las guardas de ruta reaplicadas, viven en `escrituraDeCodex.ts`.
|
|
35
|
+
*
|
|
36
|
+
* **Lo que no se sabe decir que no, se ABORTA.** Se contestan las peticiones cuyo «no» está
|
|
37
|
+
* en su esquema (`{decision:"decline"}` para fichero, comando y permisos;
|
|
38
|
+
* `{action:"decline"}` para una elicitación de MCP). `item/tool/requestUserInput` no tiene
|
|
39
|
+
* «no» —su respuesta es `{answers:{…}}` y nada más—, así que ahí se aborta, igual que ante
|
|
40
|
+
* cualquier petición que no esté nombrada. Lo que NUNCA se puede hacer es dejarla sin
|
|
41
|
+
* contestar: eso deja a codex bloqueado hasta que el tope lo mate.
|
|
42
|
+
*
|
|
43
|
+
* Y una consecuencia que hay que saber: el hijo es el Codex DEL USUARIO, con su
|
|
44
|
+
* configuración —sus MCP, sus plugins, sus hooks y sus skills—. Medido: al abrir el hilo
|
|
45
|
+
* arrancan los servidores MCP que tenga puestos. xonecode no los filtra ni los toca.
|
|
46
|
+
*/
|
|
47
|
+
import type { PeticionExterna, PoliticaDeEscrituraExterna, ToolDeUnHijo } from "../../core/ports.js";
|
|
48
|
+
/**
|
|
49
|
+
* El binario. `CODEX_BIN` gana, para poder apuntar a una versión concreta o a un envoltorio. En
|
|
50
|
+
* Windows, el `codex.exe` nativo que lanzaría el `codex.js` del shim de npm
|
|
51
|
+
* (`ejecutableParaLanzar`): ni el `.cmd` ni `node` se pueden matar con el nieto dentro.
|
|
52
|
+
*/
|
|
53
|
+
export declare function binarioDeCodex(): string;
|
|
54
|
+
/** ¿Está el binario? Se pregunta lanzándolo, que es la única respuesta que no miente. */
|
|
55
|
+
export declare function codexDisponible(): Promise<boolean>;
|
|
56
|
+
export declare function correrCodex(peticion: PeticionExterna, opciones?: {
|
|
57
|
+
/** Lo que el hilo lleva consumido. Se avisa al terminar, con el último total visto. */
|
|
58
|
+
alConsumir?: (consumo: {
|
|
59
|
+
entrada: number;
|
|
60
|
+
salida: number;
|
|
61
|
+
cache: number;
|
|
62
|
+
}) => void;
|
|
63
|
+
/** Quién autoriza cada escritura. Ausente = no se escribe ninguna, y se dice por qué. */
|
|
64
|
+
aprobar?: PoliticaDeEscrituraExterna;
|
|
65
|
+
/**
|
|
66
|
+
* Los del proyecto AHORA, para reconocer una vista aplanada. Es una FUNCIÓN y no una
|
|
67
|
+
* lista por lo mismo que en `crearSubagenteExterno`: el hijo escribe durante el turno.
|
|
68
|
+
*/
|
|
69
|
+
ficheros?: () => ReadonlySet<string>;
|
|
70
|
+
/** El `realpath`, inyectado para poder probar la guarda sin tocar disco. */
|
|
71
|
+
real?: (ruta: string) => string;
|
|
72
|
+
/** Lo que hace MIENTRAS trabaja, como línea de actividad (`actividadDeCodex.ts`). */
|
|
73
|
+
alUsarTool?: (tool: ToolDeUnHijo) => void;
|
|
74
|
+
/** Lo que va CONTANDO: sus mensajes de fase `commentary`. */
|
|
75
|
+
alRazonar?: (texto: string) => void;
|
|
76
|
+
}): Promise<string>;
|