xonecode 0.38.44 → 0.39.4
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/apps/web/dist/assets/{EditorDeFichero-BeWDctgN.js → EditorDeFichero-4HFwLke_.js} +1 -1
- package/apps/web/dist/assets/index-C57A_ylS.css +1 -0
- package/apps/web/dist/assets/index-CYZEmLsX.js +506 -0
- package/apps/web/dist/assets/{php-D3QdOnb8.js → php-CdQiFsq1.js} +1 -1
- package/apps/web/dist/assets/{ruby-DDAcW-Z2.js → ruby-3JrCXo0h.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- 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 +148 -0
- package/dist/agent/tareas/tareasEnDisco.js +17 -0
- package/dist/agent/tareas/tareasEnDisco.js.map +1 -1
- 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/arranque.js +39 -0
- package/dist/web/servidor/arranque.js.map +1 -1
- 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
- package/apps/web/dist/assets/index-B-6cDRAV.js +0 -506
- package/apps/web/dist/assets/index-BQdHnRbo.css +0 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El corredor: coge tareas de la cola, las corre y escribe sus transiciones.
|
|
3
|
+
*
|
|
4
|
+
* **Un solo corredor por máquina**, con cerrojo de pid: dos consolas abiertas serían dos
|
|
5
|
+
* ejecutores sobre la misma cola, y con ellos dos turnos del mismo proyecto a la vez. El
|
|
6
|
+
* segundo proceso sirve el dashboard y NO ejecuta, y lo dice (`corriendoAqui()`): un kanban
|
|
7
|
+
* que se ve igual en dos ventanas pero solo avanza en una tiene que decir en cuál.
|
|
8
|
+
*
|
|
9
|
+
* **Y el cerrojo solo no basta.** Su recogida cuando el dueño parece muerto no se puede
|
|
10
|
+
* hacer atómica con primitivas de sistema de ficheros —«está muerto» es la observación de
|
|
11
|
+
* un instante— y deja un residuo declarado en `agent/tareas/tareasEnDisco.ts#recoger` en el que
|
|
12
|
+
* dos procesos pueden creerse dueños. Lo que hace verdad «un solo corredor» son las DOS
|
|
13
|
+
* comprobaciones de aquí, y hacen falta las dos:
|
|
14
|
+
* - `sigoSiendoDueño()` **antes de despachar cada tarea**, no solo al arrancar: es lo que
|
|
15
|
+
* hace que el que perdió el cerrojo se entere ANTES de abrir una consola.
|
|
16
|
+
* - y la ESCRITURA final condicionada a que la tarea siga siendo la nuestra (ver
|
|
17
|
+
* `escribirSiSigueSiendoNuestra`): la comprobación del despacho no cubre el momento de
|
|
18
|
+
* escribir el resultado, que llega minutos después.
|
|
19
|
+
*
|
|
20
|
+
* La política de QUÉ arranca no está aquí: es `core/tareas.ts#siguientesAEjecutar`, pura y
|
|
21
|
+
* con sus tests. Aquí está el lazo, que es lo que no se puede probar sin dobles.
|
|
22
|
+
*/
|
|
23
|
+
import { type Tarea } from "../../core/tareas.js";
|
|
24
|
+
import { type ResultadoDeTurno } from "../../core/entrega.js";
|
|
25
|
+
import type { JuezDeTareaPort } from "../../core/ports.js";
|
|
26
|
+
import type { PantallaElegida } from "../../core/tareas.js";
|
|
27
|
+
import type { ConsolaDeProyecto } from "./vestibulo.js";
|
|
28
|
+
import type { Sumidero } from "./transporte.js";
|
|
29
|
+
import type { Acto } from "../../core/actos.js";
|
|
30
|
+
import type { TareasEnDisco } from "../../agent/tareas/tareasEnDisco.js";
|
|
31
|
+
/**
|
|
32
|
+
* Lo que git sabe de una sesión, y que la puerta de la entrega necesita entero.
|
|
33
|
+
*
|
|
34
|
+
* Las dos cosas salen de UNA pregunta (`cambiosDeSesion`): si hay «antes» con que comparar,
|
|
35
|
+
* y si la sesión cambió algo. `escribio` solo se puede afirmar con marca — sin ella no es
|
|
36
|
+
* que no escribiera, es que no hay con qué mirarlo (ver `MedidaDeEntrega.escribio`).
|
|
37
|
+
*/
|
|
38
|
+
export interface RevisionDeSesion {
|
|
39
|
+
revisable: boolean;
|
|
40
|
+
escribio?: boolean;
|
|
41
|
+
/** QUÉ cambió, con la ruta RELATIVA que da git. Sale de la MISMA medida que `escribio`
|
|
42
|
+
* —una sola llamada, las dos derivadas en la misma expresión, así que no pueden
|
|
43
|
+
* discrepar—, y de aquí sale el hecho que se le cuenta al juez. Ausente cuando no hay
|
|
44
|
+
* marca; `[]` cuando git dice que no cambió nada. */
|
|
45
|
+
cambiados?: readonly string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* La `revisable` de PRODUCCIÓN, sobre `cambiosDeSesion`.
|
|
49
|
+
*
|
|
50
|
+
* Vive aquí y no en un cierre de `arrancarConsolaWeb` por la razón de siempre en este repo:
|
|
51
|
+
* ahí dentro no se puede llamar, y todos los tests de esa función doblan lo que la rodea —
|
|
52
|
+
* así que esta derivación podía quedarse mal con todo en verde. Medido: una mutación que
|
|
53
|
+
* hacía `escribio: true` a fuego sobrevivió a las 25 mutaciones de la tanda anterior.
|
|
54
|
+
*
|
|
55
|
+
* **`revisable` es «alguien puede mirar esto», y eso vale con las DOS medidas**: la
|
|
56
|
+
* atribución por commit (`via: "git"`) y el respaldo contra la foto de apertura
|
|
57
|
+
* (`desde-apertura`, el único posible en un proyecto donde no se commitea — offline, o la
|
|
58
|
+
* carpeta que abrió una persona). Exigir solo la primera habría dejado sin entregar TODA
|
|
59
|
+
* tarea de un proyecto fuera del workspace, que es donde `commitearTurno` no commitea a
|
|
60
|
+
* propósito. `sin-marca` sigue siendo la única que no se puede revisar.
|
|
61
|
+
*
|
|
62
|
+
* **Lo que sí distingue las dos es `cambiados`**: se quitan los ficheros que nadie ha
|
|
63
|
+
* commiteado, porque no consta de quién son. Para una tarea eso no esconde nada suyo —
|
|
64
|
+
* `commitDeTurno` corre en el `finally` del turno y se ESPERA, así que cuando la puerta de
|
|
65
|
+
* entrega pregunta, lo que la tarea escribió ya está commiteado— y en cambio evita
|
|
66
|
+
* atribuirle lo que estuviera suelto de antes. En el respaldo no hay ninguna fila marcada,
|
|
67
|
+
* así que ahí la lista es exactamente la de siempre: todo lo que cambió desde la apertura,
|
|
68
|
+
* de quien sea.
|
|
69
|
+
*
|
|
70
|
+
* Las tres respuestas posibles, y la del medio es la que sostiene todo:
|
|
71
|
+
* - con ficheros → hay «antes» con que comparar y la sesión cambió algo.
|
|
72
|
+
* - sin ficheros → hay «antes» y la sesión NO cambió nada. Es lo único que permite
|
|
73
|
+
* entregar una tarea de solo lectura, y viene de git y nunca de `autorizadas`, que es la
|
|
74
|
+
* intención del agente y no el hecho.
|
|
75
|
+
* - `sin-marca` → no hay con qué mirarlo, así que **no se afirma nada** sobre si escribió:
|
|
76
|
+
* el campo se queda ausente y la condición del verificador se exige como siempre.
|
|
77
|
+
*/
|
|
78
|
+
export declare function revisionConGit(cambiosDeSesion: (raiz: string, sesion: string) => Promise<{
|
|
79
|
+
via: string;
|
|
80
|
+
ficheros: readonly {
|
|
81
|
+
ruta: string;
|
|
82
|
+
sinCommitear?: true;
|
|
83
|
+
}[];
|
|
84
|
+
}>): (raiz: string, sesion: string) => Promise<RevisionDeSesion>;
|
|
85
|
+
/**
|
|
86
|
+
* Lo que le pasa a una tarea cuya consola se cierra debajo: al parar el proceso, y al
|
|
87
|
+
* encontrarla «en proceso» sin nadie detrás en el arranque siguiente.
|
|
88
|
+
*
|
|
89
|
+
* Es UNA situación —el turno se cortó a mitad y no hay resultado— pero **tiene dos finales
|
|
90
|
+
* distintos, y de eso depende lo que reintentar signifique**. `volcar()` corre en el
|
|
91
|
+
* `finally` del turno, así que un corte a mitad no deja transcript ni entrada en el índice
|
|
92
|
+
* de sesiones; el hilo del checkpointer, en cambio, puede sobrevivir o no:
|
|
93
|
+
* - **Si sobrevive** —hay conversación volcada, así que `sesionAbrible` dice que sí—, el
|
|
94
|
+
* agente recuerda el hilo y reintentar CONTINÚA lo que llevaba hecho. Es el texto de
|
|
95
|
+
* siempre, y sigue siendo verdad en ese caso.
|
|
96
|
+
* - **Si no** —el corte antes de volcar nada—, `olvidarSiNoSePuedeAbrir` acaba de BORRAR
|
|
97
|
+
* el checkpoint: un id que no lleva a ninguna parte son además decenas de megas que
|
|
98
|
+
* nadie puede alcanzar. Ahí reintentar arranca un hilo nuevo con el encargo entero
|
|
99
|
+
* (`AVISO_SIN_HILO_REANUDABLE`), y decir que el agente lo recuerda miente dos veces:
|
|
100
|
+
* sobre lo que pasó y sobre lo que va a pasar.
|
|
101
|
+
*
|
|
102
|
+
* **De dónde sale que sean dos y no uno.** El texto único se escribió cuando el hilo SÍ
|
|
103
|
+
* quedaba escrito siempre, y un commit posterior introdujo `olvidarSiNoSePuedeAbrir`, que
|
|
104
|
+
* lo borra en ese mismo caso. Los dos cambios eran correctos contra su propio encargo; la
|
|
105
|
+
* contradicción solo se veía leyéndolos juntos. Por eso el motivo se compone DESPUÉS de
|
|
106
|
+
* saber si el hilo se olvidó, y no antes: quien lo escribe es el único que lo sabe.
|
|
107
|
+
*/
|
|
108
|
+
export declare const MOTIVO_CORTADA_POR_CIERRE: string;
|
|
109
|
+
/**
|
|
110
|
+
* Por qué está aparcada una tarea que PARÓ la persona (IXCODE-50, `Corredor.cortar(id, {pausa})`).
|
|
111
|
+
* Dice quién la paró y cómo seguir, en las dos versiones de siempre: con el hilo vivo, «Continuar»
|
|
112
|
+
* lo retoma; sin él, solo queda empezar de cero.
|
|
113
|
+
*/
|
|
114
|
+
export declare const motivoDePausa: (hiloOlvidado: boolean) => string;
|
|
115
|
+
/** El mismo corte, con el hilo ya olvidado. Ver arriba. */
|
|
116
|
+
export declare const MOTIVO_CORTADA_SIN_HILO: string;
|
|
117
|
+
/** Cuál de los dos, según lo que la regla de `sesion` acabara de decidir. */
|
|
118
|
+
export declare const motivoDeCorteAMitad: (hiloOlvidado: boolean) => string;
|
|
119
|
+
/**
|
|
120
|
+
* Cuando llega un feedback pero el hilo anterior YA NO se puede reanudar —`Tarea.sesion`
|
|
121
|
+
* está ausente porque la regla de `sesion` ya lo limpió al no haber nada abrible—, el turno
|
|
122
|
+
* arranca un hilo NUEVO sin memoria de nada. Mandarle solo el feedback a ese hilo en blanco
|
|
123
|
+
* sería una frase sin sujeto: «sí, con histórico» no dice nada sin el encargo delante. Así
|
|
124
|
+
* que se dice la verdad —esto no continúa nada— y se manda el encargo entero al lado. Es
|
|
125
|
+
* la mitad de «no se finge que continúa» que le toca a esta capa: la otra mitad, que
|
|
126
|
+
* `sesion` sobreviva siempre que haya algo que abrir, ya está en la regla de `sesion`.
|
|
127
|
+
*/
|
|
128
|
+
export declare const AVISO_SIN_HILO_REANUDABLE: string;
|
|
129
|
+
/**
|
|
130
|
+
* La petición que se le manda al turno cuando la tarea trae un feedback pendiente.
|
|
131
|
+
*
|
|
132
|
+
* **Reanudando, el feedback SOLO** — el mismo patrón que los hallazgos del verificador
|
|
133
|
+
* (`agent/turno/turnoReal.ts#conVerificacion`): entra como un mensaje de USUARIO más en el hilo
|
|
134
|
+
* que ya sabe el encargo, lo que se intentó y por qué se aparcó. Repetir el encargo ahí
|
|
135
|
+
* sería ruido: el modelo ya lo tiene.
|
|
136
|
+
*
|
|
137
|
+
* **Sin hilo que reanudar, el encargo entero, con el aviso delante.** Ver
|
|
138
|
+
* `AVISO_SIN_HILO_REANUDABLE`.
|
|
139
|
+
*/
|
|
140
|
+
export declare const peticionDeFeedback: (encargo: string, texto: string, reanudando: boolean) => string;
|
|
141
|
+
/**
|
|
142
|
+
* Lo que se espera como mucho a que un turno cortado devuelva, al parar el proceso.
|
|
143
|
+
*
|
|
144
|
+
* Generoso pero FINITO: un Ctrl-C que se cuelga para siempre es lo peor que puede hacer este
|
|
145
|
+
* camino, y el repo ya trata esta clase con tope (el `TOPE_MS` de Codex, los `TOPES_MS` de
|
|
146
|
+
* los dispositivos). Al agotarse no se miente diciendo que se paró: la tarea se queda «en
|
|
147
|
+
* proceso» y la reconciliación del siguiente arranque la aparca, que es justo para lo que
|
|
148
|
+
* existe.
|
|
149
|
+
*/
|
|
150
|
+
export declare const TOPE_DE_PARADA_MS = 30000;
|
|
151
|
+
/**
|
|
152
|
+
* Lo que se espera, como MUCHO, a que el juez de QA conteste.
|
|
153
|
+
*
|
|
154
|
+
* Es la regla de siempre en este repo —«cada proceso lleva tope», y «un cuelgue se dice
|
|
155
|
+
* como *no respondió*, nunca se queda el panel en *consultando…*»— aplicada a una llamada
|
|
156
|
+
* de modelo: los SDK traen plazos por omisión del orden de diez minutos, y durante todo ese
|
|
157
|
+
* rato la tarea diría «en proceso» ocupando el hueco y el proyecto sin que nadie pueda
|
|
158
|
+
* saber por qué. Dos minutos es de sobra para un veredicto de dos frases sobre una lista de
|
|
159
|
+
* nombres.
|
|
160
|
+
*
|
|
161
|
+
* Al agotarse NO se entrega: la consulta se abandona (la llamada sigue viva en segundo
|
|
162
|
+
* plano, no hay con qué abortarla desde aquí) y la tarea queda esperando feedback con el
|
|
163
|
+
* motivo — que es lo mismo que hace `parar()` cuando su plazo se agota: no mentir.
|
|
164
|
+
*/
|
|
165
|
+
export declare const TOPE_DEL_JUEZ_MS = 120000;
|
|
166
|
+
/** Lo que el corredor necesita de una consola de proyecto abierta para una tarea. */
|
|
167
|
+
export interface ConsolaParaTarea {
|
|
168
|
+
raiz: string;
|
|
169
|
+
idDeHilo: string;
|
|
170
|
+
/**
|
|
171
|
+
* Corre el encargo.
|
|
172
|
+
*
|
|
173
|
+
* `aparcar` es lo que la consola de tarea llama al toparse con algo que necesita a una
|
|
174
|
+
* persona; `autorizado` es lo que llama al AUTORIZAR escrituras sin aprobación, con las
|
|
175
|
+
* rutas relativas. Los dos son callbacks y no un valor de retorno porque el turno puede
|
|
176
|
+
* LANZAR después de haber autorizado —eso es justo lo que hace `preguntar`—, y un retorno
|
|
177
|
+
* se perdería con la excepción. `autorizado` puede llamarse varias veces: un turno
|
|
178
|
+
* autoriza en varias rondas de aprobación.
|
|
179
|
+
*/
|
|
180
|
+
correrTarea(encargo: string, aparcar: (motivo: string) => void, autorizado?: (ficheros: readonly string[]) => void): Promise<ResultadoDeTurno | void>;
|
|
181
|
+
cerrar(): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Espera a que la marca de git de la sesión esté escrita.
|
|
184
|
+
*
|
|
185
|
+
* Opcional porque los dobles de test no la tienen, y su ausencia es inofensiva: lo único
|
|
186
|
+
* que pasa es que la medida de «revisable» puede llegar antes que la ref. En producción
|
|
187
|
+
* la aporta `consolaParaTarea`, y es lo que cierra una carrera MEDIDA — sin ella
|
|
188
|
+
* `cambiosDeSesion` decía `sin-marca` y TODA tarea se aparcaba diciendo que nadie podía
|
|
189
|
+
* revisarla. La espera vive aquí y no en `cerrar()` para no cobrársela a quien cierra un
|
|
190
|
+
* proyecto estando sentado delante.
|
|
191
|
+
*/
|
|
192
|
+
esperarMarca?(): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Engancha a alguien que MIRA en vivo lo que hace este turno, y devuelve el transcript de
|
|
195
|
+
* ese instante. Opcional porque los dobles de test no lo tienen; su ausencia solo
|
|
196
|
+
* significa que esa consola no se puede mirar.
|
|
197
|
+
*
|
|
198
|
+
* **Lo que se mira son los actos de SU sesión, no un registro nuevo.** Son los mismos que
|
|
199
|
+
* `volcar()` escribe en el `.jsonl`, así que la vista en vivo y el transcript que se lee
|
|
200
|
+
* al abrir la sesión después son lo MISMO — la misma regla que la lista de artefactos,
|
|
201
|
+
* que sale de los actos y nunca del disco.
|
|
202
|
+
*
|
|
203
|
+
* En producción esto reenvía a `ConsolaWeb.mirar` y **no** a `conectar`: con `conectar`,
|
|
204
|
+
* el `eof()` de esa consola pasaría a decir que hay un humano al que preguntar (medido), y
|
|
205
|
+
* la consola de una tarea es justo la que no tiene a nadie.
|
|
206
|
+
*/
|
|
207
|
+
mirar?(enviar: Sumidero): readonly Acto[];
|
|
208
|
+
/** Se va UN mirón. Los demás siguen: dos personas pueden mirar la misma tarea. */
|
|
209
|
+
dejarDeMirar?(enviar: Sumidero): void;
|
|
210
|
+
}
|
|
211
|
+
export interface Corredor {
|
|
212
|
+
arrancar(): Promise<void>;
|
|
213
|
+
/** Corta lo que esté en vuelo —un turno tarda minutos— y suelta el cerrojo si es nuestro. */
|
|
214
|
+
parar(): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* Corta el turno de ESA tarea si corre AQUÍ, sin tocar las demás — es `parar()` acotado a
|
|
217
|
+
* una sola entrada. Task 14: `descartar` lo llama ANTES de borrar, porque sin esto el
|
|
218
|
+
* turno seguía corriendo (y escribiendo en el proyecto) después de que la tarea
|
|
219
|
+
* desapareciera del kanban, sin que ninguna pantalla lo dijera.
|
|
220
|
+
*
|
|
221
|
+
* **Devuelve si se puede seguir** — `true` también cuando no había NADA que cortar (la
|
|
222
|
+
* tarea no corre en este proceso: no está en `enVuelo`, así que borrarla es seguro sin
|
|
223
|
+
* esperar nada). `false` solo cuando SÍ corría aquí y no soltó el proyecto dentro del
|
|
224
|
+
* plazo (`TOPE_DE_PARADA_MS`, el mismo de `parar()`): quien llama tiene que leerlo como
|
|
225
|
+
* «no está seguro borrar todavía», nunca como «bórrala igual» — un turno que sigue
|
|
226
|
+
* escribiendo no puede perder también su carpeta de adjuntos por debajo.
|
|
227
|
+
*
|
|
228
|
+
* Espera a `EnVuelo.trabajo` entero, no solo a que `cortar()` dispare el abort: son dos
|
|
229
|
+
* cosas distintas y solo la segunda dice que la consola SOLTÓ su montaje de `/adjuntos/`
|
|
230
|
+
* — antes de eso, borrar esa carpeta es quitarle el suelo a un turno vivo.
|
|
231
|
+
*/
|
|
232
|
+
cortar(id: string, opciones?: {
|
|
233
|
+
pausa?: boolean;
|
|
234
|
+
}): Promise<boolean>;
|
|
235
|
+
/**
|
|
236
|
+
* Engancha a quien quiere MIRAR en vivo lo que hace una tarea, y devuelve su transcript
|
|
237
|
+
* hasta ese instante.
|
|
238
|
+
*
|
|
239
|
+
* `undefined` = esa tarea no corre en este proceso (ya acabó, o la ejecuta el otro
|
|
240
|
+
* corredor, que este no puede alcanzar). **No es `[]`**: una lista vacía significaría
|
|
241
|
+
* «corre y todavía no ha pintado nada», y confundirlas dejaría una pantalla esperando
|
|
242
|
+
* para siempre los actos de un turno que no existe.
|
|
243
|
+
*
|
|
244
|
+
* Es de SOLO lectura por construcción: por aquí no entra nada hacia el turno, solo sale
|
|
245
|
+
* lo que ya se está guardando en el transcript de su sesión.
|
|
246
|
+
*/
|
|
247
|
+
mirar(id: string, enviar: Sumidero): readonly Acto[] | undefined;
|
|
248
|
+
/** Se va UN mirón de esa tarea. Los demás siguen mirándola. */
|
|
249
|
+
dejarDeMirar(id: string, enviar: Sumidero): void;
|
|
250
|
+
/** ¿Ejecuta ESTE proceso? Falso si el cerrojo lo tiene otro, o si lo hemos perdido. */
|
|
251
|
+
corriendoAqui(): boolean;
|
|
252
|
+
/**
|
|
253
|
+
* ¿Lo ejecuta OTRO proceso? `undefined` = no se ha podido mirar.
|
|
254
|
+
*
|
|
255
|
+
* Es la otra mitad de `corriendoAqui`, y sin ella la interfaz no puede distinguir dos
|
|
256
|
+
* cosas que significan lo contrario: **«no soy yo» manda a esperar y «no hay nadie» dice
|
|
257
|
+
* que no va a pasar nada** hasta que alguna consola tome el relevo. Un aviso que manda a
|
|
258
|
+
* esperar a un proceso que no existe es peor que uno mudo.
|
|
259
|
+
*
|
|
260
|
+
* Los tres valores salen de lo MEDIDO en `tomarCerrojo`, y ninguno se deduce: `true` si
|
|
261
|
+
* el cerrojo lo tenía otro (o si lo hemos perdido en marcha), `false` si lo tomamos
|
|
262
|
+
* nosotros —aunque después lo hayamos soltado, que es cómo «nadie» es alcanzable de
|
|
263
|
+
* verdad: el arranque revienta tras tomarlo— y `undefined` si ni se pudo consultar (un
|
|
264
|
+
* `~/.xonecode/tareas` que no se puede escribir). **El pid NO sale de aquí**: es un dato
|
|
265
|
+
* de la máquina, no le dice nada a quien lo lee, y este valor viaja por el cable.
|
|
266
|
+
*/
|
|
267
|
+
ejecutaOtroProceso(): boolean | undefined;
|
|
268
|
+
/** Vuelve a mirar la cola: se llama al crear una tarea, al terminar una, y al abrir o
|
|
269
|
+
* cerrar un proyecto (que es lo que bloquea y desbloquea su raíz). */
|
|
270
|
+
revisar(): void;
|
|
271
|
+
/** Para los tests: espera a que se asiente lo que el lazo tenga lanzado. */
|
|
272
|
+
asentar(): Promise<void>;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Del `ConsolaDeProyecto` que abre el vestíbulo al `ConsolaParaTarea` que el corredor pide.
|
|
276
|
+
*
|
|
277
|
+
* Aquí se junta todo: la segunda puerta (que no mueve el cable), la consola que APARCA en
|
|
278
|
+
* vez de contestar por nadie, y el ejecutor de siempre — el mismo que corre un turno de una
|
|
279
|
+
* persona, con las mismas barreras.
|
|
280
|
+
*
|
|
281
|
+
* **Vive aquí y no en el cierre de `arranque.ts`** —donde el plan la puso— por una razón
|
|
282
|
+
* medible: desde ahí no se puede llamar, y la propiedad que sostiene (que la sesión de la
|
|
283
|
+
* tarea se GUARDE) es justo la que se rompe en silencio. El `MEDIDO:` de `vestibulo.test.ts`
|
|
284
|
+
* no la vigila: el agujero está en qué piel se le pasa, así que ese test se queda verde
|
|
285
|
+
* tanto con el arreglo como sin él.
|
|
286
|
+
*
|
|
287
|
+
* **La PIEL es la que hace que el turno se guarde**, y es el único motivo de que esta
|
|
288
|
+
* función sea algo más que tres campos reenviados. `volcar()` (`vestibulo.ts`) lee los actos
|
|
289
|
+
* de la consola de PROYECTO, así que un turno corrido con una `Consola` ajena no vuelca
|
|
290
|
+
* nada: la conversación se pinta en un objeto que nadie lee y la tarea acaba con su sesión
|
|
291
|
+
* vacía. Pasándole `consola.consola.consola.piel` —la misma que usa una persona— el turno
|
|
292
|
+
* escribe actos de asistente, de razonamiento y las tarjetas de artefacto en el transcript
|
|
293
|
+
* de SU sesión, que es lo que hace que atender la tarea sea abrir su conversación.
|
|
294
|
+
*/
|
|
295
|
+
export declare function consolaParaTarea(consola: ConsolaDeProyecto): ConsolaParaTarea;
|
|
296
|
+
export declare function crearCorredorDeTareas(opciones: {
|
|
297
|
+
disco: TareasEnDisco;
|
|
298
|
+
/**
|
|
299
|
+
* Trae la pantalla de Stitch ELEGIDA para la tarea (`Tarea.pantallaDeStitch`) a la carpeta de artefactos de su sesión,
|
|
300
|
+
* ANTES del primer turno, y devuelve la línea para el encargo (`core/stitch.ts#textoDePantallaElegida`). Nunca lanza.
|
|
301
|
+
* Ausente = esta ejecución no tiene conectores: el encargo dice con qué `name` traerla.
|
|
302
|
+
*/
|
|
303
|
+
prepararDiseno?: (raiz: string, sesion: string, pantalla: PantallaElegida) => Promise<string>;
|
|
304
|
+
/**
|
|
305
|
+
* Abre el proyecto para una tarea — y con `sesion`, lo REABRE con esa exacta, que es lo
|
|
306
|
+
* que hace que reanudar (un reintento, o un feedback) siga la MISMA conversación en vez
|
|
307
|
+
* de abrir una en blanco.
|
|
308
|
+
*
|
|
309
|
+
* `construirConsolaDeProyecto` (`vestibulo.ts`) ya hace lo que hace falta con `sesion`
|
|
310
|
+
* pasada — reabre el índice de la sesión, decide `idSesion = sesion` en vez de un
|
|
311
|
+
* `randomUUID()`, y el `thread_id` del checkpointer sale de ahí—, así que esto solo tiene
|
|
312
|
+
* que REENVIAR lo que la tarea ya sepa. `undefined` en la primera ejecución sigue dando
|
|
313
|
+
* una sesión nueva, igual que siempre.
|
|
314
|
+
*/
|
|
315
|
+
abrirParaTarea: (raiz: string, sesion?: string, adjuntos?: string, tarea?: string) => Promise<ConsolaParaTarea>;
|
|
316
|
+
/** Se lee en cada pasada: cambiar el tope en Ajustes tiene que notarse sin reiniciar. */
|
|
317
|
+
concurrencia: () => number;
|
|
318
|
+
/**
|
|
319
|
+
* SIEMBRA la marca de tarea en el índice de sesiones de un proyecto
|
|
320
|
+
* (`sesiones.ts#marcarTareaDeSesion`). Se llama al arrancar, una vez por tarea que ya
|
|
321
|
+
* tenga sesión, y existe solo por las sesiones anteriores a esa marca: sin ella, la
|
|
322
|
+
* primera sesión de tarea de cada proyecto se queda pintada como una conversación para
|
|
323
|
+
* siempre. Ausente = esta ejecución no siembra nada, y las viejas se quedan sin marcar,
|
|
324
|
+
* que es el lado conservador.
|
|
325
|
+
*/
|
|
326
|
+
marcarSesionDeTarea?: (raiz: string, sesion: string, tarea: string) => void;
|
|
327
|
+
/**
|
|
328
|
+
* Las raíces donde NO se puede arrancar nada ahora mismo: hoy, la del proyecto que tiene
|
|
329
|
+
* abierto una persona. Se lee en cada pasada por lo mismo que la concurrencia — abrir y
|
|
330
|
+
* cerrar un proyecto no reinicia nada. Ver `siguientesAEjecutar#bloqueados` para el por
|
|
331
|
+
* qué («gana la persona»).
|
|
332
|
+
*/
|
|
333
|
+
bloqueados?: () => readonly string[];
|
|
334
|
+
/**
|
|
335
|
+
* ¿Hay algo que una persona pueda ABRIR con ese id de sesión? O sea: ¿está en el índice
|
|
336
|
+
* de sesiones del proyecto, con su transcript volcado?
|
|
337
|
+
*
|
|
338
|
+
* Ausente = **no se sabe**, y entonces no se toca nada: quitar la `sesion` y olvidar un
|
|
339
|
+
* hilo son destructivos, así que sin nadie que pueda afirmar que no hay nada abrible se
|
|
340
|
+
* conserva — la misma dirección conservadora que `historica` cuando no se le puede
|
|
341
|
+
* preguntar al checkpointer. Ver `conSesionSoloSiSePuedeAbrir`.
|
|
342
|
+
*/
|
|
343
|
+
sesionAbrible?: (raiz: string, sesion: string) => boolean;
|
|
344
|
+
/** Olvida el hilo del agente de una sesión que no nombra nada abrible
|
|
345
|
+
* (`agent/sesiones/checkpointer.ts#olvidarHilo`). Ver `conSesionSoloSiSePuedeAbrir`. */
|
|
346
|
+
olvidarHilo?: (raiz: string, sesion: string) => Promise<void>;
|
|
347
|
+
/**
|
|
348
|
+
* Cuánto se espera, como MUCHO, a que los turnos cortados devuelvan en `parar()`. Entra
|
|
349
|
+
* por parámetro como el `msDeEspera` de la consola web y por lo mismo: `npm test` no puede
|
|
350
|
+
* esperar un tope de verdad. Ver `TOPE_DE_PARADA_MS`.
|
|
351
|
+
*/
|
|
352
|
+
esperaAlParar?: number;
|
|
353
|
+
/** Cuánto se espera al juez. Por parámetro por lo mismo que `esperaAlParar`: `npm test`
|
|
354
|
+
* no puede esperar un tope de verdad. Ver `TOPE_DEL_JUEZ_MS`. */
|
|
355
|
+
esperaDelJuez?: number;
|
|
356
|
+
pid?: number;
|
|
357
|
+
/** Se llama en cada cambio, para que el cable emita la cola nueva. */
|
|
358
|
+
alCambiar?: (tareas: readonly Tarea[]) => void;
|
|
359
|
+
/**
|
|
360
|
+
* A dónde van los avisos SOBRE ESTE PROCESO —«las tareas las ejecuta otro»—, y solo
|
|
361
|
+
* esos. Lo que le pasa a una TAREA no sale por aquí: `informar` escribe un acto de
|
|
362
|
+
* sistema en la pantalla de una persona, y el sitio de un fallo de tarea es el registro
|
|
363
|
+
* de la tarea (su `motivo`, y su transcript). Un aviso sobre la tarea de otro proyecto
|
|
364
|
+
* en medio de la conversación de alguien es ruido que además no es accionable ahí.
|
|
365
|
+
*/
|
|
366
|
+
informar?: (texto: string) => void;
|
|
367
|
+
/**
|
|
368
|
+
* El juez de QA que decide si el trabajo hace lo que se pedía.
|
|
369
|
+
*
|
|
370
|
+
* **Es OBLIGATORIO, fail-closed por TIPO**, igual que `PoliticaDeAprobacion` en
|
|
371
|
+
* `core/cloudstudio.ts`: «no se puede invocar sin decir quién autoriza». Un puerto
|
|
372
|
+
* opcional con omisión conservadora compilaría sin el cableado de producción, y entonces
|
|
373
|
+
* la pieza estaría sin montar con todo en verde — que es exactamente el agujero que
|
|
374
|
+
* `construirCorredorDeTareasCableado` y `backendDeAgente` existen para cerrar.
|
|
375
|
+
*/
|
|
376
|
+
juez: JuezDeTareaPort;
|
|
377
|
+
/**
|
|
378
|
+
* ¿Se puede REVISAR lo que la tarea escribió en esa sesión?
|
|
379
|
+
*
|
|
380
|
+
* En producción es `cambiosDeSesion(raiz, sesion).via === "git"` — la MISMA función que
|
|
381
|
+
* pinta la pestaña Revisión, no una parecida, así que «revisable» significa literalmente
|
|
382
|
+
* «Revisión lo enseña». Entra por parámetro porque es git y `npm test` no puede
|
|
383
|
+
* necesitarlo en cada caso.
|
|
384
|
+
*
|
|
385
|
+
* **No es «el árbol está limpio», y eso está medido**: una tarea que escribe un fichero
|
|
386
|
+
* deja el árbol sucio por definición (`git status --porcelain` → `?? Clientes.xne`), así
|
|
387
|
+
* que con esa condición ninguna tarea se entregaría nunca. Ver `core/entrega.ts`.
|
|
388
|
+
*
|
|
389
|
+
* Devuelve DOS cosas y no una porque las dos salen de la misma pregunta a git: si hay
|
|
390
|
+
* «antes» con que comparar, y **cuántos ficheros cambió la sesión** — de lo segundo
|
|
391
|
+
* depende que una tarea de solo lectura se pueda entregar, y tiene que salir de git y no
|
|
392
|
+
* de `autorizadas` (ver `MedidaDeEntrega.escribio`).
|
|
393
|
+
*/
|
|
394
|
+
revisable: (raiz: string, sesion: string) => Promise<RevisionDeSesion>;
|
|
395
|
+
}): Corredor;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DatosDeCierre } from "../../core/gestorDeTareas.js";
|
|
2
|
+
/** Compone `DatosDeCierre` desde el disco real del proyecto: git para lo que cambió, el
|
|
3
|
+
* `.jsonl` de la sesión para el veredicto y la última respuesta. */
|
|
4
|
+
export declare function datosDeCierre(raiz: string, id: string): Promise<DatosDeCierre>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Esperar a que alguien pare la consola web, y que pararla sea un cierre ORDENADO.
|
|
3
|
+
*
|
|
4
|
+
* El cierre ordenado ya existía (`arrancarConsolaWeb`: corredor, vestíbulo, servidor): aborta
|
|
5
|
+
* cada turno en vuelo, su `finally` escribe la foto de memoria y la consola vuelca el chat al
|
|
6
|
+
* `.jsonl`. Lo frágil era la ESPERA: con `process.once`, una segunda señal no tenía oyente y
|
|
7
|
+
* node aplicaba su acción por omisión —matar en seco a mitad del cierre—.
|
|
8
|
+
*
|
|
9
|
+
* Cuándo llega esa segunda señal, medido: cuando un `npm run <script>` cuyo comando es `tsx …`
|
|
10
|
+
* A SECAS recibe un Ctrl-C, node recibe dos SIGINT —el del grupo del terminal y el que reenvía
|
|
11
|
+
* npm unos 30 ms después—, y un cierre más largo que eso moría con 130. Con el `npm run web` de
|
|
12
|
+
* hoy (`npm run build:web && tsx …`) NO pasa: el `sh` que el `&&` deja en medio se queda el
|
|
13
|
+
* reenvío, y un cierre de 3 s sobrevive; tampoco con `./bin/xonecode` (`exec tsx`). Es una
|
|
14
|
+
* guarda contra quitar ese `&&`, y lo que añade de verdad es el aviso y la salida forzada.
|
|
15
|
+
*
|
|
16
|
+
* Tres reglas:
|
|
17
|
+
* - La PRIMERA señal empieza el cierre y lo DICE, con la salida forzada al lado.
|
|
18
|
+
* - Una señal dentro de `VENTANA_DE_SENAL_REPETIDA_MS` es el reenvío: se ignora.
|
|
19
|
+
* - Una posterior es alguien que insiste: un cierre colgado tiene que tener salida, y se
|
|
20
|
+
* FUERZA con el código de la señal (130 SIGINT, 143 SIGTERM).
|
|
21
|
+
*
|
|
22
|
+
* Los oyentes se quedan puestos a propósito hasta que el proceso sale: quitarlos devolvería
|
|
23
|
+
* a node la acción por omisión justo cuando más falta hace no tenerla.
|
|
24
|
+
*/
|
|
25
|
+
/** Cuánto después de la primera señal una igual se toma por el reenvío de npm (medido: ~30 ms). */
|
|
26
|
+
export declare const VENTANA_DE_SENAL_REPETIDA_MS = 1000;
|
|
27
|
+
type Senal = "SIGINT" | "SIGTERM";
|
|
28
|
+
export interface OpcionesDeInterrupcion {
|
|
29
|
+
/** De dónde llegan las señales. Por omisión, `process`. */
|
|
30
|
+
fuente?: {
|
|
31
|
+
on(senal: Senal, oyente: () => void): unknown;
|
|
32
|
+
};
|
|
33
|
+
ahora?: () => number;
|
|
34
|
+
/** Salir YA. Por omisión, `process.exit`. */
|
|
35
|
+
forzar?: (codigo: number) => void;
|
|
36
|
+
avisar?: (texto: string) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function esperarInterrupcion(opciones?: OpcionesDeInterrupcion): Promise<void>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Piel } from "../../core/turno.js";
|
|
2
|
+
import type { Acto } from "../../core/actos.js";
|
|
3
|
+
import type { ConsumoDeTurno } from "../../core/actos.js";
|
|
4
|
+
export interface PielWeb {
|
|
5
|
+
piel: Piel;
|
|
6
|
+
/** La lista de actos, para el transporte y para la persistencia. */
|
|
7
|
+
actos: () => readonly Acto[];
|
|
8
|
+
/**
|
|
9
|
+
* Se llama con cada acto nuevo: es por donde el transporte lo emite. También se
|
|
10
|
+
* llama cuando el último acto es un `herramientas` que se ACTUALIZA en vez de crecer
|
|
11
|
+
* —el cierre de una racha sustituyendo su apertura, la misma regla de `conLineaDeTool`—:
|
|
12
|
+
* sin ese aviso, un transporte que solo escuchara altas mostraría para siempre la línea
|
|
13
|
+
* de apertura de la racha. Un consumidor que reciba dos `herramientas` seguidos
|
|
14
|
+
* sustituye el último por el nuevo; cualquier otro tipo se añade.
|
|
15
|
+
*/
|
|
16
|
+
alActo: (escucha: (acto: Acto) => void) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function crearPielWeb(ahora?: () => number,
|
|
19
|
+
/**
|
|
20
|
+
* Lo consumido ACUMULADO por la sesión, si consta. Es el mismo cierre que la consola ya
|
|
21
|
+
* tiene (`ConsolaDeProyecto.consumo`, que pregunta a la sesión real), y entra aquí para
|
|
22
|
+
* que el `fin` pueda llevar el DELTA del turno sin que `core/turno.ts` sepa nada de
|
|
23
|
+
* consumo: la piel lo consulta al cerrar, no el motor al llamarla.
|
|
24
|
+
*
|
|
25
|
+
* Va inyectado y no leído de un cierre propio porque la sesión real llega TARDE —nace
|
|
26
|
+
* dentro del primer turno—, así que lo que se guarda es la PREGUNTA, no la respuesta.
|
|
27
|
+
*
|
|
28
|
+
* Ausente = esta piel no persiste consumo, y entonces el `fin` sale sin `consumo`, que es
|
|
29
|
+
* «no consta». Las otras dos pieles ni lo reciben: por eso `Piel.fin(ms)` no cambia de
|
|
30
|
+
* firma y stdio y la TUI siguen byte-idénticas.
|
|
31
|
+
*/
|
|
32
|
+
consumoAcumulado?: () => ConsumoDeTurno | undefined): PielWeb;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* La sesión remota: cada MÓVIL conectado por el puente es un sumidero más del cable, enganchado
|
|
3
|
+
* por la MISMA puerta que una pestaña SSE (`engancharCliente`/`soltarCliente`). Así recibe la
|
|
4
|
+
* misma ráfaga al entrar, sigue a la consola en foco cuando se muda y cuenta como «hay alguien
|
|
5
|
+
* delante» igual que una pestaña. Lo que sale pasa `filtrarSalida`; lo que entra,
|
|
6
|
+
* `validarEntradaDelMovil`, y se despacha por las mismas funciones que `POST /accion`.
|
|
7
|
+
*
|
|
8
|
+
* **Por la vía ngrok, el puente va a la dirección de un TÚNEL** (`tunel`), que se abre al
|
|
9
|
+
* encender y se cierra en todo final —apagar, un canal que se cierra solo, la caída del propio
|
|
10
|
+
* túnel—, salvo al REVOCAR: la sala y el secreto son nuevos y la dirección pública la misma, y
|
|
11
|
+
* un segundo ngrok de la misma cuenta lo rechazaría el propio ngrok. Su caída se escucha por
|
|
12
|
+
* IDENTIDAD del túnel y no por generación, porque sobrevive a la generación que lo abrió.
|
|
13
|
+
*/
|
|
14
|
+
import type { PuenteRemotoPort, TunelAbierto } from "../../core/ports.js";
|
|
15
|
+
import type { Panorama } from "../../core/panorama.js";
|
|
16
|
+
import { type EntradaDelMovil, type MensajeDeArtefactoAlMovil } from "../../core/remoto.js";
|
|
17
|
+
import type { Sumidero } from "./transporte.js";
|
|
18
|
+
export type EstadoDeSesionRemota = {
|
|
19
|
+
estado: "apagada";
|
|
20
|
+
} | {
|
|
21
|
+
estado: "abriendo";
|
|
22
|
+
} | {
|
|
23
|
+
estado: "activa";
|
|
24
|
+
url: string;
|
|
25
|
+
moviles: number;
|
|
26
|
+
}
|
|
27
|
+
/** Sin `url`: el relé no contestó nunca (inalcanzable) y se sigue intentando. Se puede apagar. */
|
|
28
|
+
| {
|
|
29
|
+
estado: "reconectando";
|
|
30
|
+
url?: string;
|
|
31
|
+
moviles: number;
|
|
32
|
+
} | {
|
|
33
|
+
estado: "error";
|
|
34
|
+
motivo: string;
|
|
35
|
+
};
|
|
36
|
+
export interface OpcionesDeSesionRemota {
|
|
37
|
+
/** `undefined` = el paquete no está instalado. Solo se llama al encender. */
|
|
38
|
+
puerto: () => Promise<PuenteRemotoPort | undefined>;
|
|
39
|
+
servidor: () => string;
|
|
40
|
+
/**
|
|
41
|
+
* El túnel de ESTE encendido, preguntado en cada `encender`: `undefined` = vía servidor
|
|
42
|
+
* (`servidor()`), y con valor el puente va a `TunelAbierto.servidor`. Un fallo suyo cruza solo
|
|
43
|
+
* si su texto es de `MOTIVOS_DEL_TUNEL`.
|
|
44
|
+
*/
|
|
45
|
+
tunel?: () => {
|
|
46
|
+
abrir(): Promise<TunelAbierto>;
|
|
47
|
+
} | undefined;
|
|
48
|
+
engancharCliente(sumidero: Sumidero): void;
|
|
49
|
+
soltarCliente(sumidero: Sumidero): void;
|
|
50
|
+
despachar(mensaje: EntradaDelMovil): void;
|
|
51
|
+
/**
|
|
52
|
+
* Un móvil acaba de entrar (ya enganchado): `enviar` le escribe SOLO a él, por el mismo filtro y
|
|
53
|
+
* tope que su sumidero. Es por donde le llega su primer `panorama`, que no va a las pestañas.
|
|
54
|
+
*/
|
|
55
|
+
alEntrarMovil?(enviar: (mensaje: Panorama) => void): void;
|
|
56
|
+
informar(texto: string): void;
|
|
57
|
+
alCambiar(estado: EstadoDeSesionRemota): void;
|
|
58
|
+
/** Solo para los tests, que no quieren fabricar 700 kB: por omisión `TOPE_DE_SALIDA_BYTES`. */
|
|
59
|
+
topeDeSalida?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface SesionRemota {
|
|
62
|
+
encender(): Promise<void>;
|
|
63
|
+
revocar(): Promise<void>;
|
|
64
|
+
/** Resuelve cuando el túnel, si lo había, está cerrado: el cierre de la consola lo espera. */
|
|
65
|
+
apagar(): Promise<void>;
|
|
66
|
+
estado(): EstadoDeSesionRemota;
|
|
67
|
+
/** ¿Hay algún móvil dentro? Para no componer un `panorama` que no leería nadie. */
|
|
68
|
+
hayMoviles(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* A TODOS los móviles y a nadie más: el `panorama` y los trozos de un artefacto pedido desde el
|
|
71
|
+
* móvil no son de las pestañas, así que no pasan por `clientes` sino por los móviles de esta
|
|
72
|
+
* sesión, con el filtro y el tope de siempre.
|
|
73
|
+
*/
|
|
74
|
+
difundir(mensaje: Panorama | MensajeDeArtefactoAlMovil): void;
|
|
75
|
+
}
|
|
76
|
+
export declare const MOTIVO_NO_ABRIO = "no se pudo abrir la sesi\u00F3n remota";
|
|
77
|
+
export declare const SIN_PAQUETE = "la sesi\u00F3n remota no est\u00E1 disponible en esta instalaci\u00F3n";
|
|
78
|
+
/** Lo que ngrok o el sistema digan no cruza: solo un texto nuestro, o el genérico. */
|
|
79
|
+
export declare const motivoFijoDelTunel: (texto: unknown) => string;
|
|
80
|
+
export declare function crearSesionRemota(o: OpcionesDeSesionRemota): SesionRemota;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El servidor de la consola web: `node:http`, loopback, sin framework.
|
|
3
|
+
*
|
|
4
|
+
* Tres cosas son de seguridad y no de estilo:
|
|
5
|
+
* - **Loopback y nada más.** No hay bandera para `0.0.0.0`: un servidor local que abre
|
|
6
|
+
* la red expone el proyecto entero del usuario y su `auth.json` está a un bug de
|
|
7
|
+
* distancia.
|
|
8
|
+
* - **`Host` y `Origin` en TODA petición.** El ataque real a un servidor local no es que
|
|
9
|
+
* alguien escanee el puerto: es DNS rebinding, donde una web cualquiera resuelve su
|
|
10
|
+
* dominio a 127.0.0.1 y le habla a este proceso desde el navegador de la víctima. Un
|
|
11
|
+
* `Host` que no sea loopback, o un `Origin` que no sea el nuestro, es 403.
|
|
12
|
+
* - **`.xonecode` no se sirve NUNCA.** Ni el del proyecto ni el del home. Va antes que
|
|
13
|
+
* la comprobación de existencia, para que un 403 y un 404 no cuenten cosas distintas.
|
|
14
|
+
*/
|
|
15
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
16
|
+
export type ManejadorRuta = (peticion: IncomingMessage, respuesta: ServerResponse) => void | Promise<void>;
|
|
17
|
+
export interface ServidorWeb {
|
|
18
|
+
readonly puerto: number;
|
|
19
|
+
/** La dirección de bind REAL (`servidorHttp.address().address`), no una construida. */
|
|
20
|
+
readonly direccion: string;
|
|
21
|
+
readonly token: string;
|
|
22
|
+
readonly url: string;
|
|
23
|
+
/** Registra un manejador propio para `MÉTODO ruta` — usado por tareas futuras (SSE, acciones). */
|
|
24
|
+
registrarRuta(metodo: string, ruta: string, manejador: ManejadorRuta): void;
|
|
25
|
+
/**
|
|
26
|
+
* Registra un manejador para `MÉTODO ruta` que se atiende SIN cookie ni `?t=`: solo tras
|
|
27
|
+
* las comprobaciones de `Host` y `Origin`, que siguen delante igual que para cualquier
|
|
28
|
+
* otra ruta. Es para el callback OAuth de un conector: la cookie es `SameSite=Strict`, así
|
|
29
|
+
* que una redirección que llega desde el proveedor viene SIN ella y se quedaría en un 401
|
|
30
|
+
* antes de que el propio callback pudiera decidir nada. La autenticación de una ruta
|
|
31
|
+
* pública la pone su manejador (un `state` de un solo uso), nunca esta función.
|
|
32
|
+
*/
|
|
33
|
+
registrarRutaPublica(metodo: string, ruta: string, manejador: ManejadorRuta): void;
|
|
34
|
+
cerrar(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
interface OpcionesServidor {
|
|
37
|
+
puerto: number;
|
|
38
|
+
raizEstaticos: string;
|
|
39
|
+
/**
|
|
40
|
+
* Un anfitrión EXTRA que se acepta además del loopback, para un túnel (ngrok, Tailscale)
|
|
41
|
+
* que apunte a este proceso. Es una lista de uno y sin comodines a propósito: el
|
|
42
|
+
* comprobante de `Host` es la única defensa contra el DNS rebinding, y «lo que acabe en
|
|
43
|
+
* .ngrok-free.app» la deja abierta a cualquiera que se registre en ngrok.
|
|
44
|
+
*
|
|
45
|
+
* El puerto NO se le añade: un túnel HTTPS llega con `Host: algo.ngrok-free.app`, sin
|
|
46
|
+
* puerto, mientras que el loopback llega con el suyo. Se compara tal cual.
|
|
47
|
+
*
|
|
48
|
+
* Ausente = solo loopback, que es como debe estar salvo que alguien lo pida a propósito.
|
|
49
|
+
*/
|
|
50
|
+
anfitrion?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function arrancarServidor(opciones: OpcionesServidor): Promise<ServidorWeb>;
|
|
53
|
+
export {};
|