# Formas de subir el código

> Las cuatro vías por las que tu código llega a Dilohost (git push, tu propio repositorio, zip por el agente y enlace de subida) y cuándo usar cada una.

Tu agente elige solo la mejor vía según lo que pueda hacer: si tiene terminal, si el proyecto ya está en GitHub o si solo puede hablar contigo en el navegador. Todas acaban igual: una versión nueva de tu app, con su historial.

## Resumen

| # | Vía | Para quién | Cómo |
|---|---|---|---|
| 1 | **Git de Dilohost** (recomendada) | Agentes con terminal: Claude Code, Codex, OpenCode, Gemini CLI, Cursor… | `deploy.git_remote` y `git push` |
| 2 | **Tu propio repositorio** | Proyectos que ya están en GitHub, GitLab, Bitbucket, Codeberg u otro git | `deploy.connect_repo` y `deploy.sync` |
| 3 | **Zip que sube el agente** | Agentes que pueden hacer peticiones HTTP pero no usar git | `upload` con `mode="agent"` |
| 4 | **Enlace de subida para ti** | Chats en el navegador, como claude.ai o ChatGPT | `upload` con `mode="page"` |
| — | Ficheros sueltos o repositorio público | Webs pequeñas y cambios puntuales | `deploy.publish` con `files` o `git_url` |

## 1. Git de Dilohost

Cada app tiene su propio repositorio privado en Dilohost. El agente pide una credencial y empuja la rama `main`:

<p class="prompt">Publica este proyecto en Dilohost como la app «web» del proyecto «tienda».</p>

```bash
git -c http.extraHeader="Authorization: …" push https://git.dilohost.es/tenants/… HEAD:main
```

- La dirección, la credencial y el comando exacto los da `deploy.git_remote`. La credencial vale **una hora**, solo para el repositorio de **esa** app, y va en una cabecera: nunca se guarda en la dirección del remoto ni en `.git/config`.
- Con la misma credencial se puede clonar lo publicado (útil para retomar un proyecto desde otro equipo).
- **Cada push a `main` publica** una versión nueva. Solo se publica `main`: otras ramas o etiquetas no se guardan.
- Sube solo lo que cambia, admite ficheros binarios y cualquier tamaño razonable (un repositorio de más de 1 GB ya no admite más pushes).
- Para anular las credenciales que hayas dado, `deploy.git_revoke`.

Es la vía más rápida y la que el agente usa por defecto si tiene terminal.

## 2. Tu propio repositorio

Si tu proyecto ya vive en GitHub, GitLab, Bitbucket o Codeberg, Dilohost lo lee de ahí:

<p class="prompt">Conecta mi repositorio github.com/miempresa/tienda a la app web de la tienda y publícalo.</p>

1. El agente pide la conexión (`deploy.connect_repo`, con confirmación) y te da una **clave de despliegue de solo lectura**.
2. La añades en tu repositorio (en GitHub: **Settings → Deploy keys**). Dilohost nunca puede escribir en él.
3. Opcionalmente, añades el **webhook** que te da el agente: así cada push a la rama conectada publica solo.
4. El agente publica con `deploy.sync`.

Detalles:

- Se publica **una rama** (por defecto `main`; puedes elegir otra al conectar).
- El secreto del webhook se muestra **una sola vez**, al conectar. `deploy.repo` enseña la conexión, pero no lo repite.
- Para otros servidores git se usa un token de acceso de **solo lectura** en lugar de la clave (`access_token`).
- Una app conectada a tu repositorio **solo** se publica desde él, para que no haya dos versiones del código. Para volver a las otras vías, `deploy.disconnect_repo` (con confirmación).

## 3. Zip que sube el agente

Para agentes que pueden hacer peticiones HTTP pero no usar git:

1. `upload.begin` con `mode="agent"` devuelve un formulario firmado y el comando `curl` ya preparado.
2. El agente sube el zip.
3. `upload.commit` cierra la subida y empieza la publicación. `upload.status` dice cómo va.

## 4. Enlace de subida para ti

Desde claude.ai o ChatGPT el agente no puede subir ficheros, así que te da un enlace:

<p class="prompt">Quiero publicar mi proyecto, lo tengo en un zip en el ordenador.</p>

1. El agente llama a `upload.begin` con `mode="page"` y te pasa un enlace de dilohost.es.
2. Lo abres (con tu sesión iniciada), arrastras el zip y se publica solo.
3. El agente sigue el progreso con `upload.status`.

## Reglas del zip

Valen para las vías 3 y 4:

| Regla | Valor |
|---|---|
| Tamaño del zip | hasta 200 MB |
| Tamaño descomprimido | hasta 1 GB |
| Número de ficheros | hasta 20.000 |
| Tamaño de cada fichero | hasta 100 MB |
| Validez del enlace | 15 minutos y una sola subida |
| Subidas abiertas a la vez | 3 por cuenta |

- El zip **sustituye** el código anterior de la app. El historial se conserva y puedes volver atrás.
- Se respeta el `.gitignore`. No incluyas `node_modules`, `vendor` ni carpetas de build.
- Si todo va dentro de una carpeta raíz, se quita esa carpeta.
- Se descartan `.git`, `__MACOSX` y los ficheros `.env` con secretos (se conservan `.env.example`, `.env.sample` y `.env.dist`). Los secretos van en [variables](/docs/publicar/variables).
- Se rechazan rutas absolutas, rutas con `..` y enlaces simbólicos.

## Ficheros sueltos y repositorios públicos

Para una web pequeña o un cambio de texto, el agente puede mandar los ficheros directamente:

<p class="prompt">Cambia el horario en index.html de la web de la peluquería.</p>

- `deploy.publish` con `files`: un objeto `{"ruta": "contenido"}`, solo texto, hasta 400 ficheros y 8 MB por publicación. Los ficheros que no mandes se quedan como estaban, salvo que use `replace_all`; para borrar alguno, `delete`.
- `deploy.publish` con `git_url`: la dirección `https://` de un **repositorio público** (y su rama con `git_ref`). Se publica una copia; para publicar en cada push, usa la vía 2.

## Relacionado

- [Apps con servidor](/docs/publicar/apps)
- [Webs estáticas](/docs/publicar/webs-estaticas)
- [Versiones y vuelta atrás](/docs/publicar/versiones)
- [Límites](/docs/referencia/limites)
