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,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CloudStudioPort` sobre el MCP real.
|
|
3
|
+
*
|
|
4
|
+
* La costura es una función `invocar`, no el `Client` del SDK: así los tests prueban el
|
|
5
|
+
* comportamiento —reapertura, desenvoltura, argumentos— sin red ni SDK. La sesión viva
|
|
6
|
+
* que produce ese `invocar` la construye `sesionCloudStudio` (`agent/cloudstudio/cloudstudioMcp.ts`);
|
|
7
|
+
* este módulo no abre nada por su cuenta.
|
|
8
|
+
*/
|
|
9
|
+
import type { CloudStudioPort } from "../../core/ports.js";
|
|
10
|
+
export interface LlamadaMcp {
|
|
11
|
+
nombre: string;
|
|
12
|
+
argumentos: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export type Invocar = (nombre: string, argumentos: Record<string, unknown>) => Promise<unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Las pausas antes de cada reapertura cuando CloudStudio dice que no hay proyecto abierto:
|
|
17
|
+
* la primera inmediata y las siguientes, crecientes. Tres intentos en total, y ni uno más.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PAUSAS_DE_REAPERTURA_MS: readonly [0, 1000, 3000];
|
|
20
|
+
/**
|
|
21
|
+
* @param nombreDeProyecto El NOMBRE del proyecto, nunca su id. El servidor abre por nombre y
|
|
22
|
+
* rechaza el identificador («not found for user», medido), y este valor es el que usa la
|
|
23
|
+
* reapertura automática de `conSesion`. Pasarle el id daba un bucle sordo: se reabría con
|
|
24
|
+
* algo que el servidor no encuentra, la tool volvía a decir «no project is open», y el
|
|
25
|
+
* error hablaba de la tool y no del argumento equivocado.
|
|
26
|
+
*/
|
|
27
|
+
export declare function clienteCloudStudio(invocar: Invocar, nombreDeProyecto: string,
|
|
28
|
+
/** La pausa entre reaperturas. Por parámetro para que los tests no esperen de verdad. */
|
|
29
|
+
esperar?: (ms: number) => Promise<void>): CloudStudioPort;
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conexión MCP de CloudStudio.
|
|
3
|
+
*
|
|
4
|
+
* El endpoint protege sus tools con OAuth del IDS. Este adaptador realiza el flujo
|
|
5
|
+
* Authorization Code + PKCE que espera MCP Streamable HTTP: abre el navegador, recibe
|
|
6
|
+
* el callback en loopback y guarda el resultado SOLO en ~/.xonecode, nunca en el repo.
|
|
7
|
+
*/
|
|
8
|
+
import { type OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
9
|
+
import type { OAuthClientInformationMixed, OAuthClientMetadata, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
10
|
+
import type { Entorno } from "../../core/settings.js";
|
|
11
|
+
/**
|
|
12
|
+
* Debe ser estable: el IDS registra el redirect_uri del cliente OAuth.
|
|
13
|
+
*
|
|
14
|
+
* Se exporta porque `cli/main.ts` necesita el mismo número para rechazar `--puerto 7634`
|
|
15
|
+
* en el servidor web (el callback de OAuth y la web no pueden compartir puerto). Antes
|
|
16
|
+
* había una copia literal en `main.ts` porque este valor era privado; una sola fuente
|
|
17
|
+
* evita que las dos constantes diverjan si el puerto cambia algún día.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PUERTO_CALLBACK = 7634;
|
|
20
|
+
/**
|
|
21
|
+
* El CloudStudio oficial. Vive aquí y no en `cli/consola.ts` (de donde se movió) porque
|
|
22
|
+
* es la dirección de un SERVIDOR, no un detalle de la piel de consola, y
|
|
23
|
+
* `adoptarLegadoSiProcede` —de este mismo fichero— la necesita para decidir si el fichero
|
|
24
|
+
* plano de antes de los entornos pertenece al oficial: `agent/` no puede importar de
|
|
25
|
+
* `cli/` (convención documentada en `agent/turno/turnoReal.ts`), así que si esto se hubiera
|
|
26
|
+
* quedado en `consola.ts` la migración habría tenido que duplicar el literal.
|
|
27
|
+
*/
|
|
28
|
+
export declare const URL_CLOUDSTUDIO_POR_OMISION = "https://mcp.xonewebstudio.com/mcp";
|
|
29
|
+
/** Permisos mínimos para descubrir el catálogo MCP; no otorgan escritura ni ejecución. */
|
|
30
|
+
export declare const SCOPES_CLOUDSTUDIO: readonly ["openid", "profile", "email", "offline_access", "mcp.read"];
|
|
31
|
+
export declare const SCOPES_CLOUDSTUDIO_ESCRITURA: readonly ["openid", "profile", "email", "offline_access", "mcp.read", "mcp.write"];
|
|
32
|
+
/** Un único consentimiento para el trabajo normal del agente; jamás incluye mcp.admin. */
|
|
33
|
+
export declare const SCOPES_CLOUDSTUDIO_AGENTE: readonly ["openid", "profile", "email", "offline_access", "xonewebstudioapi", "mcp.read", "mcp.write", "mcp.execute", "mcp.branch"];
|
|
34
|
+
/** El juego de credenciales de UN entorno. Es el `EstadoOAuth` plano de antes de que
|
|
35
|
+
* hubiera más de un CloudStudio. */
|
|
36
|
+
export type EstadoDeEntorno = {
|
|
37
|
+
clientInformation?: OAuthClientInformationMixed;
|
|
38
|
+
tokens?: OAuthTokens;
|
|
39
|
+
codeVerifier?: string;
|
|
40
|
+
/** Permisos concedidos junto al token; evita reautorizar si el servidor omite `scope`. */
|
|
41
|
+
scopes?: string[];
|
|
42
|
+
};
|
|
43
|
+
/** El id reservado para el fichero plano de antes de los entornos: ver `leerEstado`. */
|
|
44
|
+
export declare const CLAVE_LEGADO = "legado";
|
|
45
|
+
/**
|
|
46
|
+
* El fichero entero: un juego POR ENTORNO.
|
|
47
|
+
*
|
|
48
|
+
* Antes era un solo juego plano en la raíz del fichero, porque solo existía un
|
|
49
|
+
* CloudStudio. Con entornos registrables —los dos oficiales y el on-premise de un
|
|
50
|
+
* cliente— hace falta indexar: cerrar sesión en uno no puede tocar los tokens de los
|
|
51
|
+
* demás, así que cada entorno vive en su propia clave y una escritura solo toca la suya.
|
|
52
|
+
*
|
|
53
|
+
* La clave `legado` es el fichero plano de antes, ya envuelto. No se puede adivinar a
|
|
54
|
+
* qué entorno pertenecía —el formato viejo no guardaba la URL—, así que se conserva
|
|
55
|
+
* intacto hasta que `adoptarLegadoSiProcede` lo adopta al registrar el entorno de
|
|
56
|
+
* `URL_CLOUDSTUDIO_POR_OMISION`, la única URL que ese fichero pudo haber usado por
|
|
57
|
+
* omisión (si el usuario tecleó otra URL en el paso de alta, la migración automática no
|
|
58
|
+
* la alcanza y el fichero se queda en `legado` para siempre: no hay forma de saberlo).
|
|
59
|
+
*/
|
|
60
|
+
export type EstadoOAuth = {
|
|
61
|
+
version: 2;
|
|
62
|
+
porEntorno: Record<string, EstadoDeEntorno>;
|
|
63
|
+
};
|
|
64
|
+
/** Resultado reducido: los esquemas completos de tools no deben entrar en el transcript. */
|
|
65
|
+
export interface ConexionCloudStudio {
|
|
66
|
+
url: string;
|
|
67
|
+
scopes: readonly string[];
|
|
68
|
+
herramientas: Array<{
|
|
69
|
+
nombre: string;
|
|
70
|
+
descripcion: string;
|
|
71
|
+
}>;
|
|
72
|
+
proyectos: Array<{
|
|
73
|
+
id: string;
|
|
74
|
+
nombre: string;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Cómo se llama a sí mismo el servidor MCP (el `serverInfo` del `initialize`). Ausente
|
|
78
|
+
* cuando no publica ninguno legible: entonces no se afirma nada — quien registra el
|
|
79
|
+
* entorno se queda con el nombre que dedujo de la URL.
|
|
80
|
+
*/
|
|
81
|
+
servidor?: {
|
|
82
|
+
nombre: string;
|
|
83
|
+
version?: string;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface OpcionesCloudStudio {
|
|
87
|
+
/** Costura para tests y para no acoplar el agente a un navegador concreto. */
|
|
88
|
+
abrirNavegador?: (url: URL) => void;
|
|
89
|
+
/** Se muestra antes de abrir el navegador; útil también en sesiones SSH. */
|
|
90
|
+
informar?: (texto: string) => void;
|
|
91
|
+
/** Tope de espera de la vuelta del usuario desde el IDS. */
|
|
92
|
+
timeoutMs?: number;
|
|
93
|
+
rutaAuth?: string;
|
|
94
|
+
/** Scope elegido conscientemente por el comando o por una futura tool permitida. */
|
|
95
|
+
scopes?: readonly string[];
|
|
96
|
+
/**
|
|
97
|
+
* Qué entorno guarda/lee sus credenciales, dentro del fichero único indexado por
|
|
98
|
+
* entorno. Se cae a `legado` cuando no se indica: es el mismo juego que usaba el
|
|
99
|
+
* fichero plano de antes de que existieran entornos registrables, así que un
|
|
100
|
+
* llamador que todavía no conoce su id de entorno (el flujo de terminal de hoy;
|
|
101
|
+
* `cli/main.ts` no lo pasa) sigue leyendo y escribiendo exactamente donde lo hacía.
|
|
102
|
+
*/
|
|
103
|
+
entornoId?: string;
|
|
104
|
+
/**
|
|
105
|
+
* A dónde mandar el navegador cuando la autorización SALE BIEN.
|
|
106
|
+
*
|
|
107
|
+
* La página del callback termina diciendo «Ya puedes volver a xonecode», que en la
|
|
108
|
+
* consola de terminal es cierto y en la web es una instrucción falsa: quien autorizó
|
|
109
|
+
* desde el navegador ya está donde tiene que estar, y lo que le hace falta es volver a
|
|
110
|
+
* SU pestaña. Con esta opción el callback responde un 302 a la URL de la web.
|
|
111
|
+
*
|
|
112
|
+
* El puerto del callback (7634) no se mueve: el IDS registra ese `redirect_uri`. Lo que
|
|
113
|
+
* cambia es lo que se contesta DESPUÉS de recibir el código, que el IDS no mira.
|
|
114
|
+
*
|
|
115
|
+
* El fallo NO redirige, a propósito: la web todavía no sabe nada del error —se entera
|
|
116
|
+
* por la promesa rechazada, y lo cuenta por su propio canal— así que mandarla allí
|
|
117
|
+
* enseñaría un vestíbulo en blanco en lugar del motivo. La página de error se queda, con
|
|
118
|
+
* un texto que no presupone terminal.
|
|
119
|
+
*/
|
|
120
|
+
redirigirA?: string;
|
|
121
|
+
}
|
|
122
|
+
type DefinicionDeTool = {
|
|
123
|
+
name: string;
|
|
124
|
+
description?: string;
|
|
125
|
+
inputSchema?: unknown;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Qué tool lista los proyectos. Primero los nombres conocidos, en orden; si ninguno está,
|
|
129
|
+
* una heurística conservadora: tiene que hablar de listar Y de proyectos, y no pedir
|
|
130
|
+
* argumentos. `studio_open_project` o `studio_download_project` no la superan a propósito
|
|
131
|
+
* — abrir el proyecto equivocado en el arranque es peor que no encontrar la tool.
|
|
132
|
+
*/
|
|
133
|
+
export declare function herramientaDeProyectos(tools: readonly DefinicionDeTool[]): DefinicionDeTool | undefined;
|
|
134
|
+
/** Extrae solo una identidad visible; el resultado íntegro nunca va al transcript. */
|
|
135
|
+
/**
|
|
136
|
+
* Un proyecto del listado remoto, con lo ÚNICO que se conserva de él.
|
|
137
|
+
*
|
|
138
|
+
* La respuesta de `studio_list_projects` trae bastante más —permisos (`rights`), el correo
|
|
139
|
+
* del propietario (`suser`), una tabla de `studiopermissions`— y nada de eso sale de aquí:
|
|
140
|
+
* esta función es el punto de estrangulamiento, y hay un test que compara las claves
|
|
141
|
+
* EXACTAS de lo que devuelve para que un «ya que estamos, llevemos también el correo» no
|
|
142
|
+
* cuele el de un compañero de camino.
|
|
143
|
+
*
|
|
144
|
+
* `compartido` y `ultimoAcceso` son las DOS excepciones que se añadieron a la mínima de
|
|
145
|
+
* siempre (`id`, `nombre`), y las dos por el mismo motivo: son datos del PROYECTO, no de una
|
|
146
|
+
* PERSONA. `compartido` es un booleano y no el correo de quien compartió; `ultimoAcceso` es
|
|
147
|
+
* la fecha (`last`) y no trae más contexto que ella. Las dos son opcionales a propósito:
|
|
148
|
+
* ausente significa «CloudStudio no lo dijo», que no es lo mismo que «no» / «nunca abierto».
|
|
149
|
+
*/
|
|
150
|
+
export interface ProyectoRemoto {
|
|
151
|
+
id: string;
|
|
152
|
+
nombre: string;
|
|
153
|
+
/** Compartido CONTIGO por otra persona. Ausente = el servidor no lo dijo. */
|
|
154
|
+
compartido?: boolean;
|
|
155
|
+
/** Fecha ISO del último acceso (`last`). Ausente = no consta — el fixture medido contra
|
|
156
|
+
* el servidor real trae un proyecto sin este campo. */
|
|
157
|
+
ultimoAcceso?: string;
|
|
158
|
+
}
|
|
159
|
+
export declare function proyectosDeResultado(valor: unknown): ProyectoRemoto[];
|
|
160
|
+
/** Dónde vive el estado OAuth cuando nadie inyecta otra ruta. Exportada porque
|
|
161
|
+
* `web/servidor/vestibulo.ts` la necesita para `adoptarLegadoSiProcede`: una segunda copia
|
|
162
|
+
* del literal es cómo divergen las rutas el día que una se corrige y la otra no. */
|
|
163
|
+
export declare function rutaAuthPorDefecto(): string;
|
|
164
|
+
/**
|
|
165
|
+
* Lee el fichero entero. Un formato SIN `version` es el plano de antes de los entornos:
|
|
166
|
+
* se envuelve como `{ version: 2, porEntorno: { legado: <plano> } }` **solo en memoria**
|
|
167
|
+
* — un arranque de solo lectura (`xonecode config`, `describe`) no puede reescribir el
|
|
168
|
+
* disco del usuario, así que la migración se materializa recién en la primera escritura
|
|
169
|
+
* (`guardarEstadoDeEntorno`, `adoptarLegadoSiProcede`), nunca aquí.
|
|
170
|
+
*/
|
|
171
|
+
export declare function leerEstado(ruta: string): EstadoOAuth;
|
|
172
|
+
/**
|
|
173
|
+
* Un fichero de una versión futura y desconocida no se puede sobrescribir a ciegas: este
|
|
174
|
+
* código no sabe qué juegos de credenciales lleva dentro, y `leerEstado` lo trata como
|
|
175
|
+
* vacío para no tumbar un arranque de solo lectura. Escribir SOBRE ese vacío destruiría
|
|
176
|
+
* lo que hubiera. Un JSON corrupto (parse roto) es harina de otro costal —ya se
|
|
177
|
+
* sobrescribía así antes de que existieran los entornos, es el comportamiento actual que
|
|
178
|
+
* el enunciado pide no tocar— así que solo se bloquea la versión reconocible pero
|
|
179
|
+
* distinta de 2, nunca el texto irrecuperable.
|
|
180
|
+
*/
|
|
181
|
+
export declare class EstadoOAuthVersionIncompatible extends Error {
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Sustituye el juego de credenciales de UN entorno y deja los demás tal cual estaban:
|
|
185
|
+
* lee el fichero entero, reemplaza solo `porEntorno[id]` y reescribe con la misma
|
|
186
|
+
* mecánica de temporal + `rename` de `guardarEstado` — es la que asegura 0600/0700 y que
|
|
187
|
+
* un fallo a mitad de escritura no deja el fichero truncado.
|
|
188
|
+
*/
|
|
189
|
+
export declare function guardarEstadoDeEntorno(ruta: string, id: string, datos: EstadoDeEntorno): void;
|
|
190
|
+
/**
|
|
191
|
+
* Cierra sesión en UN entorno. Si no tenía nada guardado no hay nada que tocar: escribir
|
|
192
|
+
* de todos modos reescribiría el fichero entero (y su mtime) sin que haya cambiado nada
|
|
193
|
+
* observable.
|
|
194
|
+
*/
|
|
195
|
+
export declare function olvidarEntorno(ruta: string, id: string): void;
|
|
196
|
+
/**
|
|
197
|
+
* Adopta `legado` como el juego del entorno recién registrado, y SOLO si su URL es la
|
|
198
|
+
* oficial por omisión — es la única URL que el fichero plano pudo haber usado sin que el
|
|
199
|
+
* usuario tecleara una distinta a mano (ver el comentario de `EstadoOAuth`). Si `legado`
|
|
200
|
+
* no existe, o ya hay algo guardado bajo `entorno.id`, no hace nada: no hay nada que
|
|
201
|
+
* migrar en el primer caso, y pisar un juego ya autenticado sería peor que dejar el
|
|
202
|
+
* plano huérfano en el segundo.
|
|
203
|
+
*/
|
|
204
|
+
export declare function adoptarLegadoSiProcede(ruta: string, entorno: Pick<Entorno, "id" | "url">): void;
|
|
205
|
+
/**
|
|
206
|
+
* Abre una URL en el navegador del sistema. Exportada porque la consola web hace lo mismo
|
|
207
|
+
* al arrancar (`web/servidor/arranque.ts`) y tres `spawn` con la misma tabla de comandos
|
|
208
|
+
* en dos ficheros es cómo divergen.
|
|
209
|
+
*
|
|
210
|
+
* El `on("error")` no es decorativo: `spawn` de un comando que no existe —un contenedor
|
|
211
|
+
* sin `xdg-open`, un SSH sin escritorio— no lanza, EMITE `error`, y sin escucha eso es una
|
|
212
|
+
* excepción no capturada que se lleva el proceso por delante. Aquí abrir el navegador es
|
|
213
|
+
* siempre lo ACCESORIO: la URL ya está impresa, y el servidor tiene que seguir en pie.
|
|
214
|
+
*/
|
|
215
|
+
/**
|
|
216
|
+
* Con qué comando se abre una URL en cada sistema. PURA, y separada por eso mismo: el caso
|
|
217
|
+
* que se rompió no se podía probar desde un Mac sin sacarlo de aquí.
|
|
218
|
+
*
|
|
219
|
+
* **En Windows NO se usa `cmd /c start`, y ese era el fallo.** MEDIDO: en Windows el login
|
|
220
|
+
* de OAuth fallaba SIEMPRE con `invalid_request · The mandatory 'client_id' parameter is
|
|
221
|
+
* missing` (OpenIddict ID2029), y el navegador abría
|
|
222
|
+
* `…/connect/authorize?response_type=code` — cortado justo en el primer `&`.
|
|
223
|
+
*
|
|
224
|
+
* La causa es la combinación de dos reglas, ninguna de las dos nuestra: Node solo
|
|
225
|
+
* entrecomilla un argumento si lleva espacios, tabuladores o comillas, y la URL de
|
|
226
|
+
* autorización no lleva ninguno; y `cmd.exe` trata `&` como SEPARADOR DE COMANDOS. Así que
|
|
227
|
+
* la línea llegaba partida y `start` solo recibía hasta el primer `&` — se perdían
|
|
228
|
+
* `client_id`, `redirect_uri`, `code_challenge`, `scope` y `resource`, y el resto se
|
|
229
|
+
* intentaba ejecutar como comandos sueltos. En silencio, porque el `spawn` va con
|
|
230
|
+
* `stdio: "ignore"` y el `on("error")` se lo traga. El SDK pone `response_type` primero y
|
|
231
|
+
* `client_id` justo después (`client/auth.js`), que es por qué lo que sobrevivía era
|
|
232
|
+
* exactamente ese primer parámetro.
|
|
233
|
+
*
|
|
234
|
+
* `rundll32 url.dll,FileProtocolHandler` recibe la URL como **un solo argumento** y no pasa
|
|
235
|
+
* por ningún intérprete de comandos, así que la clase entera de fallo desaparece: ni `&`,
|
|
236
|
+
* ni `%VAR%`, ni comillas. La alternativa era seguir con `cmd` entrecomillando a mano y
|
|
237
|
+
* `windowsVerbatimArguments`, que arregla el `&` pero deja la URL a merced del resto de la
|
|
238
|
+
* sintaxis de `cmd` — se prefirió quitar el intérprete a aprender a escaparlo.
|
|
239
|
+
*
|
|
240
|
+
* macOS y Linux nunca lo tuvieron: `open` y `xdg-open` reciben la URL como argumento único
|
|
241
|
+
* y no hay shell de por medio.
|
|
242
|
+
*/
|
|
243
|
+
export declare function comandoParaAbrir(plataforma: NodeJS.Platform, url: URL): {
|
|
244
|
+
comando: string;
|
|
245
|
+
args: string[];
|
|
246
|
+
};
|
|
247
|
+
export declare function abrirEnSistema(url: URL): void;
|
|
248
|
+
export declare const AVISO_DE_URL_DE_MCP = "la URL del MCP debe ser HTTPS \u2014solo se admite http:// en 127.0.0.1 o localhost, para un on-premise en desarrollo\u2014 y no puede incluir credenciales";
|
|
249
|
+
/**
|
|
250
|
+
* La ÚNICA regla de qué URL de MCP vale, y por eso vive aquí y no en cada gate.
|
|
251
|
+
*
|
|
252
|
+
* Había tres puertas con dos criterios: el wizard del navegador aceptaba loopback,
|
|
253
|
+
* `vestibulo.ts#urlDeEntornoValida` exigía HTTPS y lo rechazaba, y esta función —la última,
|
|
254
|
+
* la que de verdad conecta— también. Registrar un entorno on-premise de desarrollo era
|
|
255
|
+
* imposible por la segunda, y aflojar solo la segunda habría dejado registrar uno que
|
|
256
|
+
* después fallaba al primer `conectarCloudStudio`: un alta que se puede escribir y no se
|
|
257
|
+
* puede usar es peor que el rechazo claro de hoy.
|
|
258
|
+
*
|
|
259
|
+
* Se resuelve por el lado PERMISIVO porque el caso existe —un CloudStudio on-premise
|
|
260
|
+
* levantado en local durante el desarrollo— y porque en loopback el texto plano no cruza
|
|
261
|
+
* ninguna red: es el mismo trato que ya se da al `redirect_uri` del callback de OAuth
|
|
262
|
+
* (`http://127.0.0.1:7634`) y a la propia consola web. Fuera de loopback, HTTPS y nada más.
|
|
263
|
+
* La copia del cliente (`apps/web/src/componentes/Wizard.tsx#urlDeEntornoAceptable`) dice
|
|
264
|
+
* lo mismo y no puede importar esta: lo prohíbe `src/web/frontera.test.ts`.
|
|
265
|
+
*/
|
|
266
|
+
export declare function urlDeMcpAceptable(valor: string): boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Qué se le contesta al navegador que vuelve del IDS.
|
|
269
|
+
*
|
|
270
|
+
* Sale del servidor y se prueba aparte porque montarlo exige el puerto 7634 —fijo, porque
|
|
271
|
+
* el IDS registra ese `redirect_uri`— y ahí no se puede escoger uno efímero: un test que
|
|
272
|
+
* atara el puerto real fallaría en cuanto alguien tuviera una autorización en curso.
|
|
273
|
+
*/
|
|
274
|
+
export declare function respuestaDeCallback(codigo: string | null, error: string | null, redirigirA?: string): {
|
|
275
|
+
estado: number;
|
|
276
|
+
cabeceras: Record<string, string>;
|
|
277
|
+
cuerpo: string;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Arranca el servidor HTTP local que recibe el `code` de la redirección, con su
|
|
281
|
+
* temporizador de espera. Se llama solo cuando `auth()` YA dijo `REDIRECT` —antes se
|
|
282
|
+
* llamaba SIEMPRE, incluso con un token guardado y válido que no iba a redirigir nunca—:
|
|
283
|
+
* MEDIDO, eso ocupaba el puerto 7634 fijo y armaba un temporizador de cinco minutos en
|
|
284
|
+
* cada llamada a `abrirCliente`, y dos llamadas seguidas o solapadas (dos conexiones del
|
|
285
|
+
* vestíbulo listando proyectos del mismo entorno, por ejemplo) chocaban por el mismo
|
|
286
|
+
* puerto sin que hiciera falta ningún login de verdad.
|
|
287
|
+
*
|
|
288
|
+
* **Un login nuevo SE QUEDA con el puerto, y ése es el arreglo.** El puerto es FIJO —el IDS
|
|
289
|
+
* registra el `redirect_uri`, así que no se puede esquivar eligiendo otro— y el plazo de
|
|
290
|
+
* espera es de cinco minutos. O sea que un login que no se completa (se cierra la pestaña,
|
|
291
|
+
* se cancela, falla) dejaba el 7634 cogido POR NOSOTROS todo ese rato, y cada reintento
|
|
292
|
+
* moría con `EADDRINUSE 127.0.0.1:7634` mientras el código caducaba al otro lado. MEDIDO en
|
|
293
|
+
* la consola web: el mismo proceso tenía a la vez su puerto y el 7634, y lo soltaba justo al
|
|
294
|
+
* cumplirse el plazo — de ahí que «se curara solo al rato», que es lo que lo disfrazaba de
|
|
295
|
+
* carrera entre procesos.
|
|
296
|
+
*
|
|
297
|
+
* Quien llega después gana porque es quien tiene a alguien delante: el pendiente es, por
|
|
298
|
+
* definición, el que nadie está mirando. Su promesa se RECHAZA con el motivo en vez de
|
|
299
|
+
* dejarse colgada, o el flujo viejo se quedaría esperando un código que ya no va a llegar.
|
|
300
|
+
*
|
|
301
|
+
* Lo que esto NO puede arreglar es que el puerto lo tenga OTRO proceso, y entonces se dice
|
|
302
|
+
* con esas palabras: un `EADDRINUSE` crudo manda a buscar un choque de puertos cuando lo
|
|
303
|
+
* que hay es otra consola autenticando.
|
|
304
|
+
*/
|
|
305
|
+
export declare function escucharCallback(timeoutMs: number, redirigirA?: string,
|
|
306
|
+
/** Solo para las pruebas: el real es fijo y lo impone el `redirect_uri` del IDS. */
|
|
307
|
+
puerto?: number): Promise<{
|
|
308
|
+
codigo: Promise<string>;
|
|
309
|
+
cerrar: () => void;
|
|
310
|
+
}>;
|
|
311
|
+
/** Provider OAuth persistente, deliberadamente pequeño y compatible con el SDK MCP. */
|
|
312
|
+
/**
|
|
313
|
+
* Exportada SOLO para poder probar `invalidateCredentials` —el gancho del que depende que
|
|
314
|
+
* el SDK sepa recuperarse de un token muerto— sin red ni navegador. Nadie fuera de este
|
|
315
|
+
* módulo la construye para usarla: quien abre sesión llama a `sesionCloudStudio` o a
|
|
316
|
+
* `conectarCloudStudio`, que la montan por dentro.
|
|
317
|
+
*/
|
|
318
|
+
export declare class ProviderCloudStudio implements OAuthClientProvider {
|
|
319
|
+
private readonly ruta;
|
|
320
|
+
/** El entorno cuyo juego de credenciales lee y escribe este provider: opera SOLO
|
|
321
|
+
* sobre `porEntorno[entornoId]`, nunca sobre el fichero entero, para que abrir
|
|
322
|
+
* sesión en un entorno no pueda pisar el juego de otro. */
|
|
323
|
+
private readonly entornoId;
|
|
324
|
+
private readonly alRedirigir;
|
|
325
|
+
private readonly scopes;
|
|
326
|
+
private estado;
|
|
327
|
+
private readonly metadata;
|
|
328
|
+
constructor(ruta: string,
|
|
329
|
+
/** El entorno cuyo juego de credenciales lee y escribe este provider: opera SOLO
|
|
330
|
+
* sobre `porEntorno[entornoId]`, nunca sobre el fichero entero, para que abrir
|
|
331
|
+
* sesión en un entorno no pueda pisar el juego de otro. */
|
|
332
|
+
entornoId: string, redirectUrl: string, alRedirigir: (url: URL) => void, scopes: readonly string[]);
|
|
333
|
+
/** Solo esta clave se toca en el fichero, nunca `porEntorno` entero: es lo que hace
|
|
334
|
+
* que abrir sesión en un entorno deje intactos los tokens de los demás. */
|
|
335
|
+
private guardar;
|
|
336
|
+
get redirectUrl(): string;
|
|
337
|
+
get clientMetadata(): OAuthClientMetadata;
|
|
338
|
+
clientInformation(): OAuthClientInformationMixed | undefined;
|
|
339
|
+
saveClientInformation(info: OAuthClientInformationMixed): void;
|
|
340
|
+
tokens(): OAuthTokens | undefined;
|
|
341
|
+
saveTokens(tokens: OAuthTokens): void;
|
|
342
|
+
redirectToAuthorization(url: URL): void;
|
|
343
|
+
/**
|
|
344
|
+
* El gancho de recuperación del SDK, y no un extra: `auth()` (`client/auth.js`) atrapa
|
|
345
|
+
* `InvalidGrantError` —el refresh token muerto— e `InvalidClientError`, llama a esto y
|
|
346
|
+
* REINTENTA el flujo entero. Sin implementarlo, esa llamada es un no-op: el SDK reintenta
|
|
347
|
+
* con las mismas credenciales podridas, vuelve a fallar y lanza. O sea que un token
|
|
348
|
+
* caducado sin refresco válido era un fallo duro —«hay que borrar el fichero a mano»—
|
|
349
|
+
* cuando el propio SDK sabía volver a autenticar solo.
|
|
350
|
+
*
|
|
351
|
+
* Cada alcance borra LO SUYO y nada más, y se escribe en el acto: lo que se está
|
|
352
|
+
* arreglando es justo un estado a medias, y dejarlo en memoria sin guardar significaría
|
|
353
|
+
* que el siguiente arranque lo vuelve a leer del fichero.
|
|
354
|
+
*/
|
|
355
|
+
invalidateCredentials(alcance: "all" | "client" | "tokens" | "verifier" | "discovery"): void;
|
|
356
|
+
saveCodeVerifier(verifier: string): void;
|
|
357
|
+
codeVerifier(): string;
|
|
358
|
+
}
|
|
359
|
+
/** El `invocar` que consume `clienteCloudStudio` (`agent/cloudstudio/cloudstudioClient.ts`).
|
|
360
|
+
* Se define aquí por estructura, no por import, para no crear un ciclo entre los dos
|
|
361
|
+
* módulos: ambos son adaptadores del mismo servidor pero no dependen entre sí. */
|
|
362
|
+
export type InvocarMcp = (nombre: string, argumentos: Record<string, unknown>) => Promise<unknown>;
|
|
363
|
+
/** Sesión MCP viva: `invocar` llama tools, `cerrar` libera el transporte. */
|
|
364
|
+
export interface SesionCloudStudio {
|
|
365
|
+
invocar: InvocarMcp;
|
|
366
|
+
cerrar: () => Promise<void>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Envuelve un `callTool` crudo del SDK en la función `invocar` que espera
|
|
370
|
+
* `clienteCloudStudio`. Separada de `sesionCloudStudio` para poder probar la conversión
|
|
371
|
+
* `isError → excepción` con un `callTool` falso, sin tocar OAuth ni el transporte: es la
|
|
372
|
+
* pieza de la que depende toda la reapertura de sesión en `agent/cloudstudio/cloudstudioClient.ts`,
|
|
373
|
+
* y una implementación que se limitara a `return callTool(...)` pasaría los tests de
|
|
374
|
+
* `clienteCloudStudio` igual de mal que los de aquí bien, si esto no se probara aparte.
|
|
375
|
+
*/
|
|
376
|
+
export declare function invocarSobre(callTool: (peticion: {
|
|
377
|
+
name: string;
|
|
378
|
+
arguments: Record<string, unknown>;
|
|
379
|
+
}) => Promise<unknown>): InvocarMcp;
|
|
380
|
+
/**
|
|
381
|
+
* Sesión MCP viva contra CloudStudio, para `clienteCloudStudio`
|
|
382
|
+
* (`agent/cloudstudio/cloudstudioClient.ts`): descarga, escribe y cambia de rama necesitan una
|
|
383
|
+
* conexión que sobreviva a más de una llamada, cosa que `conectarCloudStudio` no ofrece
|
|
384
|
+
* porque cierra el transporte en cuanto termina de mirar el catálogo.
|
|
385
|
+
*/
|
|
386
|
+
export declare function sesionCloudStudio(urlTexto: string, opciones?: OpcionesCloudStudio): Promise<SesionCloudStudio>;
|
|
387
|
+
/**
|
|
388
|
+
* El nombre del servidor MCP, saneado, o `undefined` si no publica ninguno usable.
|
|
389
|
+
*
|
|
390
|
+
* Es texto que llega de fuera y acaba en `settings.json` y en la barra lateral, así que
|
|
391
|
+
* pasa por la misma disciplina que cualquier otro dato remoto de este fichero: se quita lo
|
|
392
|
+
* que no es imprimible (un `\n` o un `\r` en un nombre parte la línea de un log y disfraza
|
|
393
|
+
* lo que venga detrás), se colapsan los espacios y se acota. Lo que NUNCA sale de aquí es
|
|
394
|
+
* un identificador: el id del entorno se deduce del host y no de esto, porque el id es un
|
|
395
|
+
* segmento de ruta y el servidor no puede elegir carpetas en el disco de nadie.
|
|
396
|
+
*
|
|
397
|
+
* `title` antes que `name` porque es la convención de MCP: `title` es el nombre para leer y
|
|
398
|
+
* `name` el programático (`xone-cloudstudio`). Si no hay `title`, `name` es mejor que nada.
|
|
399
|
+
*/
|
|
400
|
+
export declare function servidorDeImplementacion(info: {
|
|
401
|
+
name?: unknown;
|
|
402
|
+
title?: unknown;
|
|
403
|
+
version?: unknown;
|
|
404
|
+
} | undefined): {
|
|
405
|
+
nombre: string;
|
|
406
|
+
version?: string;
|
|
407
|
+
} | undefined;
|
|
408
|
+
/**
|
|
409
|
+
* Inicia (o reutiliza) OAuth, completa initialize y lista las tools disponibles.
|
|
410
|
+
* La conexión de tools al grafo vendrá después: esta función prueba la conexión sin
|
|
411
|
+
* incorporar los esquemas de todas las tools al prompt del agente.
|
|
412
|
+
*/
|
|
413
|
+
export declare function conectarCloudStudio(urlTexto: string, opciones?: OpcionesCloudStudio): Promise<ConexionCloudStudio>;
|
|
414
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
2
|
+
import { type InvocarMcp, type ProyectoRemoto } from "./cloudstudioMcp.js";
|
|
3
|
+
/** Lo que se usa de un cliente MCP: lo justo para poder doblarlo en los tests. */
|
|
4
|
+
export interface ClienteMcpMinimo {
|
|
5
|
+
listTools(): Promise<{
|
|
6
|
+
tools: {
|
|
7
|
+
name: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
inputSchema?: unknown;
|
|
10
|
+
}[];
|
|
11
|
+
}>;
|
|
12
|
+
callTool(peticion: {
|
|
13
|
+
name: string;
|
|
14
|
+
arguments?: Record<string, unknown>;
|
|
15
|
+
}): Promise<unknown>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export interface ConexionDeServidor {
|
|
19
|
+
invocar: InvocarMcp;
|
|
20
|
+
/** Los proyectos que ve el cliente de máquina. Se pregunta cada vez: no se cachea. */
|
|
21
|
+
proyectos(): Promise<ProyectoRemoto[]>;
|
|
22
|
+
cerrar(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface OpcionesDeConexionDeServidor {
|
|
25
|
+
url: string;
|
|
26
|
+
authProvider: OAuthClientProvider;
|
|
27
|
+
scopes?: readonly string[];
|
|
28
|
+
/** Costura de test: por omisión, `auth` del SDK. */
|
|
29
|
+
autorizar?: (provider: OAuthClientProvider, opciones: {
|
|
30
|
+
serverUrl: URL;
|
|
31
|
+
resourceMetadataUrl: URL;
|
|
32
|
+
scope: string;
|
|
33
|
+
}) => Promise<"AUTHORIZED" | "REDIRECT">;
|
|
34
|
+
/** Costura de test: por omisión, `Client` + `StreamableHTTPClientTransport` del SDK. */
|
|
35
|
+
conectar?: (url: URL, provider: OAuthClientProvider) => Promise<ClienteMcpMinimo>;
|
|
36
|
+
}
|
|
37
|
+
export declare function conectarStudioDeServidor(opciones: OpcionesDeConexionDeServidor): Promise<ConexionDeServidor>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/agent/cloudstudio/conexionDeServidor.ts
|
|
2
|
+
/**
|
|
3
|
+
* Conexión a CloudStudio para un SERVIDOR: sin navegador, sin callback y sin fichero de estado.
|
|
4
|
+
*
|
|
5
|
+
* `sesionCloudStudio` (`cloudstudioMcp.ts`) está hecha para una persona delante: autoriza con
|
|
6
|
+
* código + PKCE, escucha un callback en un puerto fijo y guarda los tokens en
|
|
7
|
+
* `~/.xonecode/cloudstudio-oauth.json`. En un servidor no hay nadie que abra el navegador, y
|
|
8
|
+
* el IDS admite *client credentials* para un cliente de máquina. Esto es la otra puerta, y es
|
|
9
|
+
* un fichero APARTE a propósito: la de las personas no cambia ni una línea.
|
|
10
|
+
*
|
|
11
|
+
* El proveedor llega HECHO (`ClientCredentialsProvider` del SDK, o el que sea): aquí no se
|
|
12
|
+
* decide cómo se autentica nadie, solo se usa. Si aun así el proveedor pide redirigir, es que
|
|
13
|
+
* no es de máquina, y se dice en vez de quedarse esperando un callback que no llegará.
|
|
14
|
+
*/
|
|
15
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
16
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
17
|
+
import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
18
|
+
import { AVISO_DE_URL_DE_MCP, SCOPES_CLOUDSTUDIO_AGENTE, herramientaDeProyectos, invocarSobre, proyectosDeResultado, urlDeMcpAceptable, } from "./cloudstudioMcp.js";
|
|
19
|
+
async function conectarDeVerdad(url, provider) {
|
|
20
|
+
const cliente = new Client({ name: "xonecode-servidor", version: "1" });
|
|
21
|
+
const transporte = new StreamableHTTPClientTransport(url, { authProvider: provider });
|
|
22
|
+
try {
|
|
23
|
+
await cliente.connect(transporte);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
await transporte.close();
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
listTools: () => cliente.listTools(),
|
|
31
|
+
callTool: (p) => cliente.callTool(p),
|
|
32
|
+
close: () => transporte.close(),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export async function conectarStudioDeServidor(opciones) {
|
|
36
|
+
if (!urlDeMcpAceptable(opciones.url))
|
|
37
|
+
throw new Error(AVISO_DE_URL_DE_MCP);
|
|
38
|
+
const url = new URL(opciones.url);
|
|
39
|
+
const scopes = opciones.scopes ?? SCOPES_CLOUDSTUDIO_AGENTE;
|
|
40
|
+
const autorizar = opciones.autorizar ?? auth;
|
|
41
|
+
const resultado = await autorizar(opciones.authProvider, {
|
|
42
|
+
serverUrl: url,
|
|
43
|
+
resourceMetadataUrl: new URL("/.well-known/oauth-protected-resource", url.origin),
|
|
44
|
+
scope: scopes.join(" "),
|
|
45
|
+
});
|
|
46
|
+
if (resultado !== "AUTHORIZED") {
|
|
47
|
+
throw new Error("el proveedor pidió autorización interactiva: en un servidor hace falta un cliente de máquina (client credentials)");
|
|
48
|
+
}
|
|
49
|
+
const cliente = await (opciones.conectar ?? conectarDeVerdad)(url, opciones.authProvider);
|
|
50
|
+
return {
|
|
51
|
+
invocar: invocarSobre((peticion) => cliente.callTool(peticion)),
|
|
52
|
+
proyectos: async () => {
|
|
53
|
+
const listado = await cliente.listTools();
|
|
54
|
+
const definicion = herramientaDeProyectos(listado.tools);
|
|
55
|
+
if (definicion === undefined) {
|
|
56
|
+
throw new Error("CloudStudio no publicó ninguna herramienta de listado de proyectos");
|
|
57
|
+
}
|
|
58
|
+
return proyectosDeResultado(await cliente.callTool({ name: definicion.name, arguments: {} }));
|
|
59
|
+
},
|
|
60
|
+
cerrar: () => cliente.close(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=conexionDeServidor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conexionDeServidor.js","sourceRoot":"","sources":["../../../src/agent/cloudstudio/conexionDeServidor.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,IAAI,EAA4B,MAAM,0CAA0C,CAAC;AAC1F,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GAGlB,MAAM,qBAAqB,CAAC;AA6B7B,KAAK,UAAU,gBAAgB,CAAC,GAAQ,EAAE,QAA6B;IACrE,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,IAAI,6BAA6B,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE;QACpC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpC,KAAK,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,QAAsC;IACnF,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,yBAAyB,CAAC;IAC5D,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE;QACvD,SAAS,EAAE,GAAG;QACd,mBAAmB,EAAE,IAAI,GAAG,CAAC,uCAAuC,EAAE,GAAG,CAAC,MAAM,CAAC;QACjF,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACxB,CAAC,CAAC;IACH,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,gBAAgB,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC1F,OAAO;QACL,OAAO,EAAE,YAAY,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU,CAAC;QACxE,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1C,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACxF,CAAC;YACD,OAAO,oBAAoB,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAChG,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;KAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crear una rama en Studio a partir de otra.
|
|
3
|
+
*
|
|
4
|
+
* `CloudStudioPort` no lo tiene a propósito: la consola sube a la MISMA rama de la que bajó, y
|
|
5
|
+
* nada de lo que hay hoy crea ramas. Quien trabaja de servidor (xonecode-copilot) sí lo
|
|
6
|
+
* necesita: hace la tarea en una rama de destino que puede no existir todavía. Va aparte y no
|
|
7
|
+
* en el puerto para que el puerto —y sus dobles— no cambien.
|
|
8
|
+
*
|
|
9
|
+
* Se reabre el proyecto al final por lo mismo que `cambiarRama`: una operación de ramas puede
|
|
10
|
+
* cerrar el proyecto en el servidor, y la siguiente llamada fallaría con «No project is open».
|
|
11
|
+
*/
|
|
12
|
+
import type { CloudStudioPort } from "../../core/ports.js";
|
|
13
|
+
import type { InvocarMcp } from "./cloudstudioMcp.js";
|
|
14
|
+
/** Devuelve `true` si la creó y `false` si ya existía. */
|
|
15
|
+
export declare function crearRama(invocar: InvocarMcp, puerto: Pick<CloudStudioPort, "abrir" | "ramas">, proyecto: string, nueva: string, desde: string): Promise<boolean>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Devuelve `true` si la creó y `false` si ya existía. */
|
|
2
|
+
export async function crearRama(invocar, puerto, proyecto, nueva, desde) {
|
|
3
|
+
await puerto.abrir(proyecto);
|
|
4
|
+
const antes = await puerto.ramas();
|
|
5
|
+
if (antes.includes(nueva))
|
|
6
|
+
return false;
|
|
7
|
+
if (!antes.includes(desde))
|
|
8
|
+
throw new Error(`la rama origen «${desde}» no existe`);
|
|
9
|
+
await invocar("studio_manage_branches", { operation: "create", branchName: nueva, targetBranch: desde });
|
|
10
|
+
await puerto.abrir(proyecto);
|
|
11
|
+
if (!(await puerto.ramas()).includes(nueva)) {
|
|
12
|
+
throw new Error(`Studio no creó la rama «${nueva}» (desde «${desde}»)`);
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=crearRama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crearRama.js","sourceRoot":"","sources":["../../../src/agent/cloudstudio/crearRama.ts"],"names":[],"mappings":"AAeA,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAmB,EACnB,MAAgD,EAChD,QAAgB,EAChB,KAAa,EACb,KAAa;IAEb,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,aAAa,CAAC,CAAC;IACnF,MAAM,OAAO,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IACzG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,aAAa,KAAK,IAAI,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CloudStudioPort } from "../../core/ports.js";
|
|
2
|
+
import type { EstadoDeSync } from "../../core/cloudstudio.js";
|
|
3
|
+
/** Bastante para que la espera de red se solape; poco para no parecer un ataque. */
|
|
4
|
+
export declare const CONCURRENCIA = 6;
|
|
5
|
+
export interface OpcionesDeDescarga {
|
|
6
|
+
puerto: CloudStudioPort;
|
|
7
|
+
raiz: string;
|
|
8
|
+
proyecto: {
|
|
9
|
+
id: string;
|
|
10
|
+
nombre: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* La rama ORIGEN: de la que se baja. Sin fijarla aquí, `descargarProyecto` trae lo que
|
|
14
|
+
* sea que esté ACTIVO en la sesión de Studio —que no tiene por qué ser esta—, y una
|
|
15
|
+
* subida posterior firmaría ese contenido como si fuera de `ramaOrigen`, en silencio.
|
|
16
|
+
*/
|
|
17
|
+
ramaOrigen: string;
|
|
18
|
+
informar?: (texto: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Dejar la copia vacía ANTES de escribir la bajada (`gitSync.ts#vaciarCopia`). Se llama
|
|
21
|
+
* **solo con el zip ya en la mano**: si la descarga falla, la copia tiene que seguir como
|
|
22
|
+
* estaba, y vaciar primero la dejaría sin nada. Y **la vía fichero a fichero NO vacía**:
|
|
23
|
+
* trae solo los de texto, así que media bajada sobre una carpeta vacía sería perder los
|
|
24
|
+
* binarios — ahí se escribe encima, como siempre, y se dice.
|
|
25
|
+
*/
|
|
26
|
+
vaciarAntes?: () => void;
|
|
27
|
+
}
|
|
28
|
+
export declare function rutaSyncJson(raiz: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Borra del disco las vistas aplanadas y las quita de la lista de descargados.
|
|
31
|
+
*
|
|
32
|
+
* De colecciones solo se trabaja con el `.xne` y con `app.xml`: el `X.xml` lo REGENERA
|
|
33
|
+
* Studio. Hasta ahora solo se le ocultaba al agente con un Proxy; borrarlo de verdad hace
|
|
34
|
+
* que la regla valga también para el usuario, su editor y su `grep`.
|
|
35
|
+
*
|
|
36
|
+
* **El momento es lo que importa**: esto corre tras extraer y ANTES del commit de baseline
|
|
37
|
+
* (`prepararRepo`). Al revés, git vería esos `.xml` como borrados y —al haberse descargado,
|
|
38
|
+
* el candado no los frenaría— la primera subida los borraría EN STUDIO.
|
|
39
|
+
*
|
|
40
|
+
* Que no entren en `descargados` es el segundo cierre: aunque algún día alguien reordene
|
|
41
|
+
* las guardas de `planDeSubida`, el candado sigue impidiendo su borrado remoto.
|
|
42
|
+
*/
|
|
43
|
+
export declare function retirarVistasAplanadas(raiz: string, rutas: string[]): string[];
|
|
44
|
+
export declare function descargarProyecto(opciones: OpcionesDeDescarga): Promise<EstadoDeSync>;
|