26 KiB
Tool index — catálogo canónico de herramientas
Este es el índice único de todo lo ejecutable del repo. Si buscas "qué script
uso para X", empieza aquí y no en los TOOLS.md de cada skill (esos son guías de
uso; este es el catálogo).
Verificado contra el host real el 2026-08-07. Las firmas de parámetros se extrajeron del AST de PowerShell, no a mano.
0. Cómo leer este índice
- R/W —
RO= solo lectura, se puede ejecutar sin preguntar.W= muta estado, exige confirmación explícita del usuario antes de ejecutar.RO/W= depende de los parámetros (columna "notas" lo aclara). - Env — variables que deben estar cargadas (
. .\.env.local.ps1). Si faltan, el script lanza excepción, no falla silenciosamente. - Todo se ejecuta desde la raíz del repo, en PowerShell.
1. Los 6 gotchas que producen resultados silenciosamente incorrectos
Léelos antes de invocar nada. No son teóricos: los cuatro primeros se verificaron el 2026-08-07 y el quinto el 2026-08-23. Cada uno rompe una tarea de forma que parece haber funcionado.
1.1 -Raw significa lo OPUESTO en dos familias de wrappers
Hay dos convenciones incompatibles. Elegir mal no da error: da un resultado vacío.
| Wrapper | Sin -Raw (default) |
Con -Raw |
|---|---|---|
coolify_skill\scripts\Invoke-CoolifyApi.ps1 |
string JSON | objetos PowerShell |
scripts\Invoke-CloudflareApi.ps1 |
string JSON | objetos PowerShell |
deploy_skill\scripts\Invoke-GitHubApi.ps1 |
objetos PowerShell | {Status, Headers, Body} |
gitea_skill\scripts\Invoke-GiteaApi.ps1 |
objetos PowerShell | {Status, Headers, Body} |
Consecuencia práctica: en Coolify y Cloudflare, si vas a filtrar o proyectar el
resultado necesitas -Raw. Sin él recibes un System.String y
# MAL: devuelve una fila vacía, sin error. El resultado es un string.
.\coolify_skill\scripts\Invoke-CoolifyApi.ps1 -Path "/resources" |
Select-Object name, uuid
# BIEN
.\coolify_skill\scripts\Invoke-CoolifyApi.ps1 -Path "/resources" -Raw |
Select-Object name, uuid
Usa el default (string JSON) solo cuando vas a mostrar la respuesta tal cual.
1.2 Invoke-ProxmoxSsh.ps1 corrompe las comillas anidadas
Invoke-ProxmoxSshCommand pasa $Command como un único argumento a ssh, y
PowerShell 5.1 destroza las comillas embebidas al invocar un ejecutable nativo.
Cualquier comando con quoting anidado —típicamente docker exec ... bash -lc '... psql -c "SELECT ..."'— llega mutilado al host:
bash: line 1: -c: command not found
psql: option requires an argument -- 'F'
Solución verificada: codifica el comando remoto en base64. Es el patrón a usar para cualquier cosa con más de un nivel de comillas:
$remote = @'
pct exec 102 -- docker exec -i postgres-c11xzy2tx2cdapm32f5b89vy bash -lc 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -At -c "SELECT name FROM public.installation_configs"'
'@
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($remote))
.\scripts\Invoke-ProxmoxSsh.ps1 -Command "echo $b64 | base64 -d | bash 2>&1"
El here-string @'...'@ (comillas simples) es obligatorio: evita que PowerShell
expanda $POSTGRES_PASSWORD del lado de Windows.
Para comandos de un solo nivel de comillas (pct list, docker ps --format '{{.Names}}') el wrapper directo funciona bien.
1.3 Los nombres de contenedor NO se pueden adivinar
Coolify nombra cada contenedor <servicio>-<uuid> (y a veces le añade un sufijo
numérico de build). No existe un contenedor llamado chatwoot ni nextcloud:
chatwoot-c11xzy2tx2cdapm32f5b89vy
nextcloud-db-hdcdpkm0jko3qqvn5683ercc
web-instademo0portal0insta0demo1-060825532589
Siempre resuelve el nombre real antes de usarlo. Dos caminos:
# a) desde Docker, por patrón
.\scripts\Invoke-ProxmoxSsh.ps1 -Command "pct exec 102 -- docker ps --format '{{.Names}}' | grep -i chatwoot"
# b) desde Coolify, para obtener el uuid del recurso (y de ahí el sufijo)
.\coolify_skill\scripts\Invoke-CoolifyApi.ps1 -Path "/resources" -Raw |
Where-Object { $_.name -match 'chatwoot' } | Select-Object name, uuid, fqdn
Corolario: un redeploy puede recrear el contenedor con otro sufijo, y cualquier script o cron que tenga el nombre hardcodeado empieza a fallar. Es exactamente lo que le pasó al guard de Chatwoot (ver runbooks/chatwoot-update.md).
1.4 /applications/* da 404 — por Cloudflare, no por Coolify (corregido 2026-08-29)
Re-verificado a fondo el 2026-08-29 sobre v4.3.14 y el diagnóstico anterior cambió: el 404 NO lo produce Coolify. Es un bloqueo del edge de Cloudflare en el hostname público. Mismo token, misma ruta:
| Llamada | Resultado |
|---|---|
https://coolify.urieljareth.org/api/v1/applications (vía Cloudflare) |
404 |
http://192.168.0.117:8000/api/v1/applications (origen, LXC 102) |
200 |
/github-apps |
igual: 404 vía CF, 200 vía origen |
/version, /resources, /services, /databases, /projects, /servers, /teams, /deployments, /security/keys |
OK por ambas vías |
La API del origen está completa: el openapi.yaml del contenedor
(/var/www/html/openapi.yaml) declara todo el namespace de /applications/*,
notificaciones, proveedores cloud y MCP, y responde. Para esos endpoints,
apunta la llamada al origen ($env:COOLIFY_API_URL_ORIGIN) o corrige la regla
de Cloudflare en el dashboard. Además, desde v4.2 los endpoints de estado
exigen POST (GET /deploy → 405; ver notas §10.1).
Esto re-habilita (previa verificación en el próximo deploy) herramientas que estaban marcadas rotas — ver §4.
Nota (2026-08-24): POST /services sí funciona para stacks compose
propios, con tres condiciones que la API no perdona: no enviar type junto a
docker_compose_raw, mandar el compose en base64, y enviar el body como
bytes UTF-8. Las tres estaban mal en el toolkit y ya están corregidas; el
detalle está en
docs/casos/firecrawl-stack-minimo.md §4.
Test-PreDeployChecklist.ps1 sigue sin leer docker-compose.coolify.yml
(solo mira docker-compose.yml|yaml y compose.yml|yaml), así que puede dar
todo PASS sobre un archivo que no abrió.
1.5 "Verde en Coolify" NO significa "enrutado en Traefik"
Verificado el 2026-08-23. Es la causa de que un servicio recién creado desde la
librería de Coolify devuelva 503 no available server estando en verde.
Son dos señales distintas y la UI solo muestra una:
| Señal | Quién la usa | Qué significa |
|---|---|---|
State.Status = running |
La UI de Coolify (el punto verde) | El contenedor existe y no ha muerto |
State.Health.Status = healthy |
Traefik | El contenedor entra al balanceador |
Traefik solo enruta contenedores que Docker reporta healthy. Un contenedor
running + unhealthy no tiene ruta, la petición cae al catch-all de
Coolify (default_redirect_503.yaml: priority: -1000, servicio noop con
servers: { }) y de ahí sale el string no available server.
En este host el primer boot de un servicio tarda minutos (rootfs ext4 sobre
loopback sobre HDD, ~39 ms por escritura), pero 12 de los 14 servicios no
tienen start_period en su healthcheck. Se les declara unhealthy mucho antes
de que la app llegue a escuchar.
Distingue el código HTTP antes de tocar nada:
502 Bad Gateway→ Traefik tiene la ruta, el backend rechaza. Problema de la app o del puerto.503 no available server→ Traefik no tiene la ruta. Casi siempre es un contenedor que todavía está arrancando. Espera, no redeployes: un redeploy reinicia el entrypoint desde cero y reinicia el arranque lento.
# El diagnóstico correcto, en un comando (solo lectura):
.\coolify_skill\scripts\Test-CoolifyServiceReady.ps1 -Uuid <uuid> -WaitSeconds 600
Detalle completo, evidencia e hipótesis descartadas: docs/casos/coolify-servicio-nuevo-503-no-available-server.md.
1.6 Si la imagen no expone el puerto donde sirve, el FQDN necesita :puerto
Verificado el 2026-08-24 diagnosticando grimmory, que devolvía 502.
Coolify deriva el label traefik.http.services.*.loadbalancer.server.port del
puerto que lleve el FQDN guardado en service_applications.fqdn. Si el FQDN
no lleva puerto, Coolify no emite el label, y Traefik cae al único puerto que
declare la imagen (Config.ExposedPorts).
Eso funciona por accidente cuando app e imagen coinciden, y falla en silencio cuando no:
| Servicio | FQDN guardado | Sirve en | Imagen expone | Resultado |
|---|---|---|---|---|
nextcloud |
sin puerto | 80 | 80 | OK por coincidencia |
n8n |
…:5678 |
5678 | 5678 | OK explícito |
qdrant |
…:6333 |
6333 | 6333 | OK explícito |
grimmory |
sin puerto | 80 | 6060 | 502 |
grimmory corría healthy (su healthcheck prueba http://127.0.0.1/health, o
sea el 80, y pasaba), Traefik lo enrutaba, y llegaba al 6060 donde no hay nada:
connection refused → 502.
Ojo con la confusión: tener SERVICE_URL_GRIMMORY_80 en el compose no basta.
Lo que manda es el puerto en el FQDN almacenado.
Cómo distinguirlo de otros fallos:
502→ hay ruta, el backend rechaza. Compara el puerto donde escucha la app con el que busca Traefik. Casi siempre es esto.503 no available server→ no hay ruta (§1.5).
# Puertos donde escucha de verdad (en hex; 0050 = 80, 1F90 = 8080):
.\scripts\Invoke-ProxmoxSsh.ps1 -Command "pct exec 102 -- docker exec <cont> sh -c 'cat /proc/net/tcp'"
# Puerto que busca Traefik (si no sale nada, cae al ExposedPorts de la imagen):
.\scripts\Invoke-ProxmoxSsh.ps1 -Command "pct exec 102 -- docker inspect <cont> --format '{{json .Config.Labels}}'"
Arreglo: poner el puerto en el FQDN (https://x.urieljareth.org:80) y
redeployar el servicio — los labels solo se regeneran al recrear el
contenedor.
2. Infraestructura: host Proxmox, red, apps del host
Todo llega al host por un solo camino:
PowerShell → Invoke-ProxmoxSshCommand → ssh [email protected]
→ pct exec 102 -- docker ... (para cualquier cosa de Docker)
| Script | R/W | Env | Parámetros | Qué hace |
|---|---|---|---|---|
| scripts/ProxmoxAgent.ps1 | librería | — | — | Dot-source obligatorio (. .\scripts\ProxmoxAgent.ps1). Expone Get-ProxmoxConfig, Assert-ProxmoxConfig, Invoke-ProxmoxSshCommand, Invoke-ProxmoxApi. Todos los demás scripts lo consumen; no reimplementes la conexión. |
| scripts/Test-ProxmoxConnection.ps1 | RO | opcional PROXMOX_API_TOKEN_* |
— | Smoke test: config + SSH + muestra de Docker + auth de API. Sale 1 si algo falla. Ejecútalo antes de trabajo operativo. |
| scripts/Get-ProxmoxInventory.ps1 | RO | — | — | Snapshot completo: host, LXC, QEMU, Docker en LXC 102. |
| scripts/Invoke-ProxmoxSsh.ps1 | RO/W | — | -Command <string> |
Comando arbitrario por SSH. El R/W lo determina el comando: pct list es RO, pct stop es W. Ver gotcha §1.2 para comillas anidadas. |
| scripts/Invoke-CloudflareApi.ps1 | RO/W | CLOUDFLARE_API_TOKEN |
-Method -Path -BodyJson -Raw |
API de Cloudflare (túnel + DNS). GET es RO; el resto W. -Raw → objetos (§1.1). |
| scripts/Install-CoolifyAutostart.ps1 | W (RO con -VerifyOnly) |
— | -VerifyOnly -SkipOnboot -RunNow -Uninstall |
Instala el auto-arranque del stack tras corte de luz (LXC 102 + túnel). Usa -VerifyOnly para auditar sin tocar nada. |
API REST de Proxmox (distinta de la de Coolify): requiere
PROXMOX_API_TOKEN_ID + PROXMOX_API_TOKEN_SECRET. Invoke-ProxmoxApi lanza
excepción si faltan.
⚠️ Estado actual (2026-08-07):
.env.local.ps1no definePROXMOX_API_TOKEN_ID/_SECRET,CLOUDFLARE_API_TOKENniCOOLIFY_EMAIL/COOLIFY_PASSWORD. Las tres rutas que dependen de ellas (API de Proxmox, API de Cloudflare, flujo UI de Coolify) fallan hoy. Lo que sí está cargado:PROXMOX_HOST/NODE/USER/SSH_KEY/COOLIFY_LXC,COOLIFY_API_URL,COOLIFY_TOKEN,GITHUB_TOKEN,GITHUB_OWNER,GITEA_URL/USER/TOKEN.
2.1 Chatwoot — parche enterprise
Contexto completo en runbooks/chatwoot-update.md.
| Script | R/W | Parámetros | Qué hace |
|---|---|---|---|
| scripts/Get-ChatwootLicenseStatus.ps1 | RO | -ServiceUuid -AppContainer -DbContainer -Deep |
Estado de la licencia. -Deep verifica además los feature flags por cuenta (accounts.feature_flags). Usa esto para diagnosticar; nunca el parche. |
| scripts/Apply-ChatwootEnterprisePatch.ps1 | W | -DryRun -ReenableAccountFeatures -ServiceUuid -Container -AppContainer -LxcId -ProxmoxHost -SshKey |
Reaplica el parche. El SQL de 3 filas no basta: pasa siempre -ReenableAccountFeatures. Usa -DryRun primero. |
| scripts/chatwoot-enterprise-guard.sh | — | — | Copia versionada del guard que corre en el host. No se ejecuta desde Windows. Instalado en /root/scripts/chatwoot-enterprise-guard.sh, agendado por /etc/cron.d/chatwoot-enterprise-guard cada 5 min. Log: /var/log/chatwoot-enterprise-guard.log (solo escribe cuando actúa). |
2.2 Artefactos que viven en el host (no se invocan desde Windows)
| Archivo | Qué es |
|---|---|
| scripts/host/coolify-autostart.sh | Script de arranque; lo despliega Install-CoolifyAutostart.ps1. |
| scripts/host/coolify-autostart.service | Unit de systemd correspondiente. |
| scripts/fix-nextcloud-config.php | Fragmento puntual del fix HTTPS de Nextcloud. Ver runbooks/nextcloud.md. |
| scripts/Set-ProxmoxEnv.example.ps1 | Plantilla de entorno. El template completo es .env.example. |
2.3 Scripts de deploy específicos de una app
scripts/apps/ guarda scripts one-off con uuid y dominio hardcodeados. Son
mutantes y están atados a un recurso concreto: lee la cabecera antes de
ejecutar uno, y verifica que el uuid siga siendo el correcto (§1.3).
| Script | R/W | Env | Qué hace |
|---|---|---|---|
| scripts/apps/Deploy-SoloLeveling.ps1 | W | COOLIFY_*, PROXMOX_*, GITHUB_TOKEN (scope repo) |
Re-deploy de "El Sistema (Solo Leveling)" sin depender del pull de GHCR (el registry es privado y el token no tiene read:packages). Construye la imagen en el servidor (clone del repo privado + docker build), la taguea con el nombre que espera el compose generado por Coolify, y levanta el servicio. Params: -ServiceUuid -Domain -Repo -Image -NoBuild. Requiere que el service ya esté registrado en Coolify. |
| scripts/apps/Deploy-OhDaddy.ps1 | W | COOLIFY_*, PROXMOX_* |
Redeploy de oh-daddy (stack app+db+Inngest self-hosted, servicio rzittzudkunwx8gilonn7tqe). Clone del repo público + stacks/oh-daddy/Dockerfile inyectado, build de oh-daddy-app:local en el server, compose up -d, schema idempotente y re-registro de funciones Inngest (PUT /api/inngest). Params: -ServiceUuid -Fqdn -Repo -Image -NoBuild. Detalle: casos/oh-daddy-deploy.md. |
3. Coolify — operación
| Script | R/W | Env | Parámetros | Qué hace |
|---|---|---|---|---|
| coolify_skill/scripts/Get-CoolifyDockerStatus.ps1 | RO | — | -Filter <regex> -All |
Estado de contenedores vía LXC 102. -All lista todo; -Filter acota por regex. Primera parada para "¿está corriendo X?". |
| coolify_skill/scripts/Test-CoolifyServiceReady.ps1 | RO | — | -Uuid <uuid> -Fqdn <url> -WaitSeconds <n> |
Contrasta running vs healthy por contenedor (la discrepancia que la UI esconde), avisa de start_period insuficiente, detecta setup en curso (chown/apt) y prueba el dominio distinguiendo 503 de 502. Primera parada para un 503 no available server — ver §1.5. |
| coolify_skill/scripts/Set-CoolifyHealthcheckGrace.ps1 | RO/W | — | -Uuid <uuid> -StartPeriodSeconds 300 -MinIntervalSeconds 10 -ShowResult -Apply |
Inserta start_period en los healthcheck que no lo tienen y sube intervalos demasiado cortos, editando services.docker_compose_raw. Dry-run sin -Apply. Con -Apply guarda copia de rollback en backups/ y verifica leyendo de vuelta. No redeploya — el healthcheck solo aplica al recrear el contenedor. Ver §1.5. |
| coolify_skill/scripts/Invoke-CoolifyApi.ps1 | RO/W | COOLIFY_TOKEN |
-Method -Path -BodyJson -Raw |
API de Coolify. GET RO; POST/PUT/PATCH/DELETE W → confirmación. Ver §1.1 (-Raw) y §1.4 (endpoints que dan 404). |
coolify_skill/scripts/coolify.sh |
RO/W | COOLIFY_TOKEN |
— | Helper Bash legacy para sesiones Linux/WSL. En este repo se prefieren los wrappers PowerShell. |
Referencia de la API: no cargues el árbol completo. Busca y abre un solo archivo:
rg -n "deploy|database|environment" .\coolify_skill\references
Get-Content .\coolify_skill\references\ops\deploy-by-tag-or-uuid.md
4. Deploy de proyectos nuevos a Coolify
⚠️ Lee esto antes de usar cualquier cosa de esta sección. El pipeline "una sola línea" fallaba porque
/applications/*daba 404 (§1.4). Desde el 2026-08-29 sabemos que ese 404 es de Cloudflare, no de Coolify: apuntandoCOOLIFY_API_URLal origen (http://192.168.0.117:8000/api/v1) el namespace completo responde. Scripts marcados ❌ abajo deben funcionar así — pendiente de verificar en el próximo deploy; el flujo UI y la vía DB siguen como fallback.
| Script | R/W | Env | Estado en esta instancia |
|---|---|---|---|
| Publish-ProjectToCoolify.ps1 | W | GITHUB_TOKEN, COOLIFY_TOKEN |
⚠️ Su paso 5 invoca New-CoolifyApplication.ps1 → probar contra el origen. |
| New-CoolifyApplication.ps1 | W | COOLIFY_TOKEN |
⚠️ Usa POST /applications/public y PATCH /applications/{uuid} → funcionan vía origen (404 solo vía Cloudflare). |
| Invoke-CoolifyRollback.ps1 | W | COOLIFY_TOKEN |
⚠️ Usa PATCH /applications/{uuid} → funciona vía origen. |
| New-CoolifyService.ps1 | W | COOLIFY_TOKEN |
✅ Funciona. Usa POST /services. Es la vía válida para stacks multi-contenedor. |
| New-CoolifyAppViaDB.ps1 | W (INSERT directo en la DB) | — | ⚠️ Último recurso. Escribe la fila en applications de la DB de Coolify saltándose API y UI. Sin validación ni rollback. Requiere -EnvironmentId y -GithubRepoId reales. |
coolify-ui/coolify-login.mjs + Configure-CoolifyComposeApp.mjs |
W (vía navegador) | COOLIFY_EMAIL, COOLIFY_PASSWORD |
✅ Fallback soportado para apps git build-from-source. Credenciales probables ya en .env.local.ps1 (sin verificar). |
Vías, en orden de preferencia:
- Stack multi-contenedor con
docker-compose.coolify.yml→New-CoolifyService.ps1(API). - App git build-from-source → API contra el origen; si falla, flujo UI con Playwright (
coolify-ui/). - Último recurso →
New-CoolifyAppViaDB.ps1.
Detalle completo del flujo v4.1.2 y sus trampas (BOM UTF-8 rompe el parser YAML de Coolify; "Reload Compose File" es obligatorio; fijar dominios por servicio o sale 503; no encolar deploys concurrentes) en deploy_skill/references/coolify-4.1.2-notes.md.
4.1 Scripts de deploy que funcionan sin depender de /applications
| Script | R/W | Env | Parámetros | Qué hace |
|---|---|---|---|---|
| Initialize-CoolifyProject.ps1 | W (solo local) | — | -Path -Stack {node|python|compose|static} -AppPort -Force |
Genera Dockerfile/compose/.dockerignore compatibles. Idempotente: no sobreescribe sin -Force. |
| Test-PreDeployChecklist.ps1 | RO | — | -Path -ExpectedPort -Strict |
Valida el proyecto contra las reglas duras de AGENTS-coolify-apps.md. Gate obligatorio antes de cualquier push. |
| New-GitHubRepo.ps1 | W (remoto) | GITHUB_TOKEN |
-Name -Description -Private -Owner |
Crea el repo en GitHub. Idempotente: avisa si ya existe. |
| Invoke-GitHubApi.ps1 | RO/W | GITHUB_TOKEN |
-Method -Path -BodyJson -Raw |
API de GitHub. Default → objetos (§1.1). |
| Test-PostDeploy.ps1 | RO | COOLIFY_TOKEN (opcional) |
-Fqdn -ContainerName -SiblingService -ApplicationUuid |
Verifica el estado en Coolify: contenedores, logs del proxy, DNS entre hermanos. -ApplicationUuid consulta /applications/* → vía pública da 404 (Cloudflare), vía origen funciona. |
| Test-ServiceOnline.ps1 | RO | — | -Fqdn -Path -ExpectedStatusCode -ExpectTitle -Screenshot -SkipBrowser -TimeoutMs -Retries |
La "definición de done". Dos capas: HTTP 200 vía curl + render real en Chromium (Playwright). Detecta 502 de Traefik, TLS a medias y crashes de JS del cliente. Sin Node/Playwright la capa de navegador se omite con warning, no falla. |
deploy_skill/scripts/verify-online.mjs |
RO | — | (invocado por el script de arriba) | Capa de navegador de Test-ServiceOnline.ps1: navegación real con Playwright, captura pageerror y requests fallidos del main frame. No lo invoques directo. Requiere npm install en la raíz del repo. |
git push usa Windows Credential Manager (wincred), no el PAT. Verificado
para la cuenta urieljarethbusiness-cpu.
Plantillas: deploy_skill/references/templates/ —
Dockerfile.node, Dockerfile.python, docker-compose.app-db.yml,
env.local.template.ps1.
5. Gitea — hosting git self-hosted
Distinto de deploy_skill: esto administra la capa de hosting git, no Coolify. El propio repo Manager vive aquí.
| Script | R/W | Env | Parámetros | Qué hace |
|---|---|---|---|---|
| Test-GiteaConnection.ps1 | RO | GITEA_URL, GITEA_TOKEN |
— | Smoke test: /version, /user, /settings/api, /repos/search. Sale 1 si algo falla. |
| Get-GiteaRepo.ps1 | RO | GITEA_URL, GITEA_TOKEN |
-Owner -Name -Search -List |
Lee, lista o busca repos. -Owner default = usuario del token. |
| Invoke-GiteaApi.ps1 | RO/W | GITEA_URL, GITEA_TOKEN |
-Method -Path -BodyJson -Raw |
API de Gitea. Usa curl.exe --data-binary con UTF-8 sin BOM (el parser de Gitea se rompe con BOM). Default → objetos (§1.1). |
| New-GiteaRepo.ps1 | W | GITEA_URL, GITEA_TOKEN |
-Name -Description -Private -Owner -NoAutoInit |
Crea repo (idempotente). -NoAutoInit evita el README del lado servidor para poder empujar historia local sin conflicto. |
| Sync-GiteaRemote.ps1 | W | GITEA_URL, GITEA_TOKEN |
-AppPath -Name -Owner -RemoteName -Branch -CreateIfMissing -Private -Force |
Cablea el remoto y hace push headless. El token nunca toca el disco: va en un http.extraHeader de un solo uso, no en .git/config. -RemoteName gitea (default) convive con un origin de GitHub. |
6. Reglas de seguridad (no negociables)
- Read-only primero. El default es diagnosticar: list, status, logs, inspect, health checks.
- Confirmación explícita antes de cualquier cambio de estado. Aplica a:
pct/qmstart/stop/reboot/destroy;dockerrestart/stop/rm/compose up-down; deploys de Coolify y cualquierPOST/PUT/PATCH/DELETE; escritura de variables de entorno; y todo cambio de firewall, red, storage, volumen, clave o token. Antes de una acción riesgosa: captura el estado actual y enuncia el camino de rollback. - Nunca escribas secretos en el repo. Ni tokens, ni passwords, ni claves
privadas, ni cookies, ni secretos de token PVE — no en Markdown, no en
scripts, no en logs. Viven solo en
.env.local.ps1(gitignored) o en el almacén de secretos del SO. Al depurar bases de datos, verifica conectividad sin imprimir credenciales. - Prefiere los scripts del repo antes que cadenas de comandos manuales largas, y no construyas comandos destructivos amplios a partir de strings generados.
-Forceexiste en varios scripts para saltarse los prompts. Úsalo solo después de que el usuario haya aprobado el plan concreto.
7. Dónde está el resto del contexto
| Qué necesitas | Dónde |
|---|---|
| Arquitectura + router de intención | CLAUDE.md |
| Topología verificada (fuente de verdad del estado) | proxmox-inventory.md |
| Procedimientos concretos | runbooks/ |
| Casos resueltos paso a paso | casos/ |
| Incidentes archivados | incidentes/ |
| Contrato para construir una app deployable | AGENTS-coolify-apps.md |
| Reglas operativas por dominio | agent/SKILL.md, coolify_skill/SKILL.md, deploy_skill/SKILL.md, gitea_skill/SKILL.md |
| Guías de uso por dominio (ejemplos ejecutables) | los TOOLS.md de cada carpeta *_skill/ |