# Gitea 1.24 — endpoint cheat sheet Base URL: `https://gitea.nucleoriofrio.com/api/v1` (la skill prefija `/api/v1` si el path no empieza con `/api/`). Auth: `Authorization: token `. Todas las queries pasan por `scripts/query.sh` salvo que digamos lo contrario. ## Health | Endpoint | Notas | |---|---| | `GET /version` | Health check. Devuelve `{"version":"1.24.7"}` | | `GET /user` | El usuario detrás del PAT actual | ## Repos | Endpoint | Notas | |---|---| | `POST /user/repos` | Crear repo bajo el user autenticado (claudeCode0). Body: ver schema abajo. La skill bloquea `private:true` acá (regla dura) | | `POST /orgs/{org}/repos` | Crear repo bajo una org (NucleOS). Mismo body | | `GET /users/{user}/repos` | Listar repos públicos de un user | | `GET /orgs/{org}/repos` | Listar repos de una org | | `GET /repos/{o}/{r}` | Detalle de un repo | | `DELETE /repos/{o}/{r}` | Borrar repo (requiere PAT con `delete_repo` o admin) | ### Schema de creación (POST body) ```json { "name": "skill-foo", // required "description": "...", // opcional "private": false, // default false "auto_init": true, // crear con README inicial "default_branch": "main", "license": "MIT", // opcional, template name "gitignores": "Node", // opcional, template name (case-sensitive) "readme": "Default", // opcional, README template "template": false // marcar como template repo } ``` Listas de templates válidos: ver `https://gitea.nucleoriofrio.com/api/v1/repos/issue/templates` no aplica; los template names son los mismos que GitHub usa para gitignore (Node, Python, Go, etc.) y para licenses (MIT, Apache-2.0, GPL-3.0). Para gitignores no comunes (ej. "Bash"), Gitea responde 400 silencioso — omitir el campo y crear un .gitignore manualmente después. ## Pull Requests | Endpoint | Filtros / body | |---|---| | `GET /repos/{o}/{r}/pulls` | `?state=open\|closed\|all`, `?limit=N`, `?page=N`, `?sort=...` | | `GET /repos/{o}/{r}/pulls/{number}` | Detalle completo | | `POST /repos/{o}/{r}/pulls` | Body: `{title, body, head, base}`. `head` = `branch` (mismo repo) o `user:branch` (fork) | | `GET /repos/{o}/{r}/issues/{n}/comments` | PRs son issues; este es el endpoint de comments. Requiere PAT con `read:issue` | | `POST /repos/{o}/{r}/issues/{n}/comments` | Crear comment (out of scope en MVP) | | `POST /repos/{o}/{r}/pulls/{n}/merge` | Mergear (out of scope — disruptive) | ### Schema mínimo PR create (POST body) ```json { "title": "fix(scope): short imperative", "body": "## Context\n...", "head": "feature-branch", "base": "main" } ``` ## Gitea Actions ### Discovery / metadata | Endpoint | Notas | |---|---| | `GET /repos/{o}/{r}/actions/workflows` | Lista workflows. `id` = filename (ej. `deploy-infra.yml`) | | `GET /repos/{o}/{r}/actions/workflows/{wf_id}` | Single workflow | | `GET /repos/{o}/{r}/actions/workflows/{wf_id}/timing` | Tiempos del workflow | ### Runs (Gitea los llama "tasks") | Endpoint | Notas | |---|---| | `GET /repos/{o}/{r}/actions/tasks` | **Lista todos los runs** (filtros server-side: solo `page`+`limit`). Devuelve `{workflow_runs: [{id, run_number, status, event, head_branch, head_sha, workflow_id, display_title, created_at, updated_at, run_started_at, url, name}], total_count}` | | `GET /repos/{o}/{r}/actions/runs/{run}/artifacts` | Artifacts de un run | **No existen** estos endpoints en Gitea 1.24 (sí en GitHub): - `GET /actions/runs` (sin scope a workflow) - `GET /actions/runs/{id}` (single run plano) - `GET /actions/runs/{id}/jobs` - `GET /actions/runs/{id}/logs` plano (existe pero devuelve zip — no usable) ### Jobs | Endpoint | Notas | |---|---| | `GET /repos/{o}/{r}/actions/jobs/{job_id}/logs` | **Texto plano** del log de un job. Único path para leer logs desde la skill | **No existe** `GET /actions/jobs/{job_id}` (single job detail). Para saber qué `job_id` corresponde a un `task_id`, la skill hace probe (rango `task_id ± 10`, match por primera línea `received task `). ### Artifacts | Endpoint | Notas | |---|---| | `GET /repos/{o}/{r}/actions/artifacts` | Lista artifacts del repo | | `GET /repos/{o}/{r}/actions/artifacts/{id}` | Single artifact metadata | | `GET /repos/{o}/{r}/actions/artifacts/{id}/zip` | Download artifact | ### Bloqueado por la skill (admin guard) Estos endpoints requieren PAT admin del org. La skill aborta con exit 3 si los llamás (override: `export GITEA_USER_PAT=`): | Endpoint | Verbo | |---|---| | `/admin/*` | cualquiera | | `/orgs/{org}/actions/secrets/*` | GET/PUT/DELETE | | `/orgs/{org}/actions/variables/*` | GET/POST/PUT/DELETE | | `/repos/{o}/{r}/actions/secrets/*` | GET/PUT/DELETE | | `/repos/{o}/{r}/actions/variables/*` | GET/POST/PUT/DELETE | ## Códigos de error comunes | HTTP | Causa | Qué hacer | |---|---|---| | 401 | PAT inválido / revocado | Re-correr `setup.sh` (puede haber agarrado el duplicado equivocado en bitwarden) | | 403 | Scope insuficiente del PAT (típico: `read:issue` faltante) | Regenerar PAT con scopes correctos, re-correr `setup.sh`, o pedir PAT admin temporal | | 404 | Repo/PR/run no existe (o no tenés acceso) | Verificar el path y los args | | 422 | Body POST inválido (ej. PR sin head/base) | Revisar schema | | `404 page not found` (texto crudo) | Endpoint no existe en Gitea 1.24 (ej. `/actions/runs/{id}/jobs`) | Usar el endpoint alternativo (`/actions/tasks`, probe de job_id) | ## Querystring params típicos - **Paginación**: `?page=N&limit=N`. Default `page=1, limit=10` (varía por endpoint). - **Sort** (en algunos endpoints): `?sort=newest|oldest|...` - **State**: `?state=open|closed|all` (PRs, issues) ## Referencias - Spec oficial: https://docs.gitea.com/api/1.24/ - Swagger JSON de la instancia: `https://gitea.nucleoriofrio.com/swagger.v1.json` (descargá con curl + python para inspeccionar paths nuevos) - Cuenta del bot: https://gitea.nucleoriofrio.com/claudecode0 - Org NucleOS: https://gitea.nucleoriofrio.com/NucleOS