La mayoría de los desarrolladores llegan al mismo techo: la suscripción de $20/mes de Claude cubre el uso diario, pero en el momento en que empiezas a ejecutar auditorías, redactar documentación y revisar PRs a gran escala, los costos de API suben rápido. La solución es una configuración híbrida — deja que un agente de Hugging Face auto-alojado maneje el trabajo de alto volumen y menor riesgo, y mantén a Claude enfocado en las tareas que necesitan su precisión.
Routing Strategy
local / PikaPods
API
Hugging Face
Maneja cualquier cosa que sea repetitiva, amplia o exploratoria — auditorías, documentación, investigación, descripciones de PR — a costo cero o casi cero por token. Hay dos formas de configurar esto: conectarte a los Inference Providers alojados de Hugging Face mediante un agente de terminal llamado OpenCode, o saltarte la inferencia alojada por completo y correr un modelo totalmente en local con Ollama. Ambas opciones se integran en el mismo flujo de terminal y ninguna cambia cómo ya usas Git — elige según si prefieres pagar unos pocos dólares al mes por inferencia con GPU alojada o mantener todo en tu propia máquina.
OpenCode es un agente de IA para terminal. Se sitúa entre un modelo — Hugging Face, en esta configuración — y la carpeta local de tu proyecto, y le da a ese modelo la capacidad de leer tu código, editar y crear archivos, ejecutar comandos de terminal, inspeccionar errores y buscar en todos los archivos. No toca Git ni GitHub directamente; tu flujo actual de git add / commit / push se mantiene exactamente igual.
Opción A — Inferencia de Hugging Face vía OpenCode
Esta es la configuración más completa: inferencia alojada, sin necesidad de GPU local, integrada en la misma terminal que ya usas para Claude Code, apuntando a un repo que ya está sincronizado con GitHub.
1. Crea una cuenta de Hugging Face
Regístrate en huggingface.co/join — no necesitas crear un repo de modelo, un dataset ni un Space. La cuenta sola es suficiente para generar un token más adelante.
2. Instala el CLI de Hugging Face
▶ show code▼ hide code
brew install hf
hf --help
Luego inicia sesión. El flujo por navegador es la opción más fácil — te da un código, abre Hugging Face, y guarda la credencial localmente una vez que apruebas:
▶ show code▼ hide code
hf auth login
hf auth whoami
hf auth whoami debería imprimir tu nombre de usuario de Hugging Face — eso confirma que el inicio de sesión funcionó.
3. Instala OpenCode
▶ show code▼ hide code
brew install anomalyco/tap/opencode
opencode --version
El tap anomalyco es el tap propio de Homebrew del equipo de OpenCode y generalmente recibe actualizaciones más rápido que la fórmula reflejada.
4. Crea un token de API de Hugging Face para OpenCode
El paso hf auth login anterior autentica el propio CLI hf y guarda una credencial interna OAuth-user — verás una confirmación como "The token OAuth-user is saved." Ese no es el token que usa OpenCode, aunque parezca un éxito. OpenCode necesita un token de grano fino aparte que creas manualmente en huggingface.co/settings/tokens con el permiso Make calls to Inference Providers y nada más. La cadena hf_... que se muestra al crearlo es la que pegas cuando el auth login de OpenCode te pide una "API key" — la interfaz de Hugging Face lo llama token, OpenCode lo llama API key; es lo mismo.
Ve a huggingface.co/settings/tokens y crea un token fine-grained (de permisos granulares). El único permiso que necesita es:
Make calls to Inference Providers
No necesitas darle ningún permiso para modificar tu repo de GitHub — OpenCode lee y escribe tus archivos locales directamente, y Git se mantiene totalmente separado de este token.
El token se verá como hf_xxxxxxxxxxxxxxxxxxxxx. Nunca lo pegues en una ventana de chat, un commit, o un archivo .env que Git esté rastreando. Si lo vas a guardar en .env.local, confirma que .env* ya esté en tu .gitignore antes de guardarlo.
5. Conecta OpenCode con Hugging Face
▶ show code▼ hide code
opencode auth login
Elige Hugging Face de la lista de proveedores y luego pega el token del paso 4 cuando te pida una API key (el mensaje dice "API key", no "token"). Este es el método de conexión oficialmente documentado entre las dos herramientas.
6. Apunta OpenCode a tu repo existente
Esta es la parte que importa para un repo ya sincronizado con GitHub — OpenCode nunca reemplaza ni duplica tu configuración de Git, solo opera sobre los archivos que ya están ahí.
▶ show code▼ hide code
cd ~/ruta/a/tu/proyecto/existente
git status
Confirma que el árbol de trabajo esté limpio (On branch main, up to date with 'origin/main') antes de empezar, para que cualquier cambio que haga OpenCode sea fácil de aislar después con git diff. Luego inicia el agente desde dentro de ese directorio:
▶ show code▼ hide code
opencode
Desde aquí el flujo es: tu modelo de Hugging Face razona, OpenCode lee y edita archivos en el directorio desde el que lo lanzaste, y Git — tu repo local existente, subiendo al mismo remoto de GitHub — sigue siendo lo único responsable del versionado y la sincronización. No hay una segunda copia de la app viviendo en Hugging Face.
7. Elige un modelo de código
Dentro de OpenCode:
▶ show code▼ hide code
/models
Elige Hugging Face y selecciona entre los modelos disponibles actualmente a través de Inference Providers. Esa lista cambia seguido — Hugging Face enruta los modelos compatibles entre varios proveedores y puede elegir un proveedor según velocidad o precio — así que no fijes un modelo específico en tu flujo de trabajo. Prefiere lo que esté etiquetado para código, tenga una ventana de contexto lo bastante grande para los archivos con los que trabajas, y encaje con el equilibrio velocidad/costo que quieres para trabajo masivo.
A diferencia de Ollama, donde descargas un modelo concreto a tu máquina, los Inference Providers rotan su catálogo de modelos y pueden elegir un proveedor por velocidad o precio en tu nombre. Por eso elige el modelo etiquetado para código más reciente disponible en el menú /models en lugar de fijarte en un nombre de una guía. Cualquier nombre de modelo concreto de este artículo puede haber sido superado ya y no estar del todo vigente — tómalo como una sugerencia inicial, no como dogma.
Muchos modelos actuales de los Inference Providers exponen un ajuste de esfuerzo de razonamiento — low, medium, high, xhigh u otro similar. La elección correcta depende de la tarea.
Elige medium para el trabajo que enrutas a Hugging Face. La Opción A es para auditorías, documentación, descripciones de PR y revisiones — trabajo masivo donde importan la velocidad y el costo. El razonamiento medio basta para detectar problemas reales sin pagar la latencia y el costo en tokens de los niveles superiores. Reserva high o xhigh para las tareas que exigen precisión profunda entre varios archivos — y esas son justo las tareas que la estrategia de enrutamiento dice que deben quedarse en Claude, no en Hugging Face. Usar xhigh aquí anula el sentido de la división: asumes la latencia y el costo de un razonamiento intensivo sin obtener la precisión de Claude.
Los modelos marcados como variantes de pensamiento o razonamiento — por ejemplo Qwen3.8-27B con su opción de pensamiento activada, o cualquier modelo de razonamiento que devuelva un campo reasoning_content — hoy no se pueden usar dentro del bucle de agente de OpenCode. La API de llamadas a herramientas de varios turnos de Hugging Face falla en la segunda llamada porque no se gestiona el campo de contenido de pensamiento, así que el agente se rompe a mitad de una tarea.
La solución es sencilla: elige en su lugar una variante de código sin pensamiento, como Qwen3-32B, DeepSeek-V3 o una versión de Qwen coder sin pensamiento. Sigues obteniendo el ahorro de Hugging Face; solo evitas las variantes que aún no funcionan en este bucle. Puede que esto se corrija a medida que evolucionen OpenCode y los Inference Providers, así que conviene volver a probarlo de vez en cuando.
Los Inference Providers incluyen algunos créditos gratuitos, pero una sola sesión de agente con 3–5 turnos de edición de archivos puede agotarlos, y entonces las solicitudes empiezan a devolver 402 Payment Required a mitad de la tarea. Para trabajo masivo real — los aproximadamente $9/mes de la tabla de costos de más abajo — añade un método de pago a tu cuenta de Hugging Face. El nivel gratuito sirve para comprobar que la configuración funciona; no alcanza para ejecutar auditorías a escala.
8. Déjalo leer el repo antes de que toque nada
Tu primer prompt debería obligarlo a entender el proyecto en vez de reescribir cosas de inmediato:
🤖AI Prompt — Análisis del repo — solo lectura, sin cambioshugging face▾
Analyze this repository but don't make any changes yet.
Explain:
- the application architecture
- frontend framework
- backend/services
- database/authentication
- important directories
- how the application is run locally
- current Git structure
- any obvious architectural problems
Then propose what you would work on first.
Después de eso, dale prompts como lo harías con cualquier agente de código — "implementa el estimador de precios en la página de precios", o "encuentra por qué el modo oscuro no persiste y arréglalo".
9. Git sigue siendo tu red de seguridad
OpenCode edita archivos; nunca ejecuta git commit ni git push por su cuenta. Revisa cada cambio igual que revisarías un PR humano:
▶ show code▼ hide code
git diff
git add .
git commit -m "Fix dark mode persistence"
git push
Eso sube tu repo local existente a GitHub exactamente como ya estás acostumbrado — no necesitas la integración de GitHub propia de OpenCode para nada de esto.
Todo lo anterior usa la interfaz interactiva (TUI) de OpenCode. Para automatizarlo, usa opencode run, que ejecuta un solo prompt de forma no interactiva y termina:
▶ show code▼ hide code
opencode run --auto --model huggingface/<model> --dir /path/to/repo "Update the README to match the current env vars"
runno es interactivo — toma tu prompt, hace el trabajo y devuelve el control.--modelaceptaproveedor/modelo, por ejemplohuggingface/Qwen3.8-27B-Instruct,ollama/nextjs-devoanthropic/claude-sonnet-4-6. Los nombres de modelo cambian; usa el que/modelsliste en ese momento.--dirapunta al repo. El prompt es un argumento posicional, y[project]solo se aplica al comando interactivoopencode, así que no pases la ruta como argumento final derun.opencode serveinicia un servidor sin interfaz para incrustar OpenCode en herramientas de larga duración, yopencode run --attach <url>le envía prompts. Para integraciones de editor con ACP (Agent Client Protocol), usaopencode acp.
Esto es lo que habilita las actualizaciones de documentación disparadas por CI, las auditorías programadas y la generación por lotes de descripciones de PR — la verdadera historia de "que Hugging Face haga el trabajo masivo a escala" que promete este artículo.
--auto aprueba automáticamente los permisos que no estén denegados explícitamente, lo que omite la confirmación que recibirías en la TUI. Úsalo solo en una rama limpia y dedicada, y revisa git diff antes de confirmar o subir cualquier cosa. Nunca lo apuntes a un árbol de trabajo con cambios sin confirmar que te importen.
Todo junto — una ejecución automatizada con Hugging Face
Una vez completada la configuración, este es el flujo completo de principio a fin, sin TUI:
▶ show code▼ hide code
# Desde cualquier repo, de forma no interactiva
cd ~/path/to/project
git checkout -b hf-audit-run
opencode run --auto \
--model huggingface/Qwen3.8-27B-Instruct \
--dir . \
"Audit this file for top 5 code quality issues, propose minimal fixes. Do not commit."
# Revisar
git diff
npm run build && npm test
Esta es la recompensa de la automatización. El objetivo de la Opción A era sacar el trabajo masivo de Claude por unos $9/mes, y opencode run es la forma de hacerlo a escala — desde un hook de CI, un cron o un script por lotes que recorra repos. Eso sí, no te saltes la revisión: consulta más abajo Revisar lo que el modelo realmente escribió.
10. Opcional — habilidades de Hugging Face (solo Claude Code, por ahora)
A partir de la versión 1.32.0 del CLI hf, hf skills add solo admite --claude y --dest como destinos — no existe la opción --opencode. El sistema hf skills hoy solo se integra con Claude Code. Si usas Claude Code junto a OpenCode, esto le da a Claude Code conocimiento del ecosistema de Hugging Face:
▶ show code▼ hide code
hf skills add --claude --global
OpenCode no toma nada de esto. Obtiene su contexto de herramientas de opencode.json y de tu configuración de MCP. Revisa hf skills add --help — esto puede cambiar a medida que evolucione el CLI.
▶ show code▼ hide code
# Hugging Face
brew install hf
hf auth login
# OpenCode
brew install anomalyco/tap/opencode
# Dale a Claude Code conocimiento específico de HF (opcional, solo Claude Code)
hf skills add --claude --global
# Conecta OpenCode a la inferencia de HF
opencode auth login
# Entra a tu repo existente
cd /ruta/a/tu/proyecto/existente
# Confirma que Git esté limpio
git status
# Empieza a programar
opencode
Yendo más allá: dale a la Opción A control del ordenador
Los pasos anteriores le dan a OpenCode acceso a archivos, acceso a terminal y contexto cercano a Git — pero no ojos ni manos. Puede leer y editar código, pero no puede mirar una captura de pantalla, hacer clic en un botón, o verificar que una interfaz realmente se renderizó como esperabas. Cerrar esa brecha convierte la Opción A de un agente de código a un agente de control del ordenador, y nada de la configuración anterior se descarta — esto se agrega encima.
11. Añade un modelo con capacidad de visión
El modelo que impulsa OpenCode necesita entender capturas de pantalla, no solo texto y código. No todos los modelos en Inference Providers pueden hacer esto — revisa que el que elijas en /models esté etiquetado para entrada visual/multimodal, no solo para completado de código. Hugging Face soporta agentes y modelos con capacidad de visión a través de la misma superficie de Inference Providers que ya usa la Opción A.
12. Añade una herramienta de control del ordenador
Dale a OpenCode una herramienta que exponga las primitivas que un sistema operativo realmente necesita: captura de pantalla, clic, doble clic, mover el ratón, arrastrar, escribir, pulsar teclas, y hacer scroll. Esta herramienta es el puente que falta entre el modelo y tu escritorio — sin ella, un modelo con capacidad de visión puede describir lo que ve en una captura de pantalla pero sigue sin tener forma de actuar sobre ello.
13. Conecta la herramienta de control del ordenador mediante MCP
Conecta esa herramienta mediante MCP en lugar de acoplarla directamente a OpenCode. OpenCode puede entonces invocar los controles del ordenador de la misma forma en que ya invoca sus herramientas de archivos y terminal. Lo importante: OpenCode no necesita implementar el control del ratón por sí mismo — solo necesita acceso a un servidor MCP de control del ordenador que lo haga.
14. Añade un backend local de automatización de escritorio
Algo tiene que ejecutar realmente las acciones solicitadas en macOS. Esta es la pieza detrás de la herramienta MCP — traduce una llamada como click(x, y) en un clic de ratón real en tu máquina, y devuelve una captura de pantalla nueva para que el modelo vea el resultado.
15. Añade el ciclo captura de pantalla → acción → captura de pantalla
Esto es lo que convierte una llamada a herramienta ordinaria en control del ordenador:
- El modelo ve la pantalla (captura de pantalla de entrada).
- El modelo decide qué hacer.
- La herramienta ejecuta la acción.
- Llega una captura de pantalla nueva.
- El modelo evalúa el resultado.
- Se repite.
Sin que el ciclo se cierre de vuelta a una captura de pantalla nueva, el modelo actúa a ciegas después de su primer movimiento.
Antes de configurar nada de esto, otorga el permiso de Grabación de Pantalla de macOS (para que la herramienta pueda tomar capturas de pantalla) y el permiso de Accesibilidad (para que pueda controlar el ratón y el teclado) — Ajustes del Sistema → Privacidad y Seguridad. Añade un paso de confirmación antes de cualquier acción destructiva (borrar archivos, enviar formularios, mandar mensajes). Un agente con capacidad de visión y acceso al ratón y teclado no está limitado a tu repo como sí lo están las herramientas de archivos de OpenCode — puede actuar en cualquier parte de la pantalla.
16. Elige un modelo con capacidad de control del ordenador, específicamente
No te limites a apuntar la Opción A a "cualquier modelo de código de Hugging Face" una vez que hayas añadido la herramienta — un modelo de código normal no tiene forma de interpretar una captura de pantalla. Necesitas un modelo de visión/razonamiento que pueda tomar entrada de imagen junto con llamadas a herramientas. El framework smolagents de Hugging Face está construido para esto: soporta entrada visual, llamadas a herramientas, servidores MCP, y múltiples backends de modelos en el mismo ciclo de agente, lo cual encaja directamente con lo que describen los pasos 11–15.
17. Añade un paso de verificación
Después de que el modelo haga clic, escriba, o ejecute algo, debería mirar la captura de pantalla resultante antes de asumir que la acción funcionó — no simplemente pasar al siguiente paso. Incorpora esto al ciclo del paso 15 en lugar de tratarlo como opcional: un agente que verifica sus propias acciones detecta un clic fallido o un diálogo inesperado, en lugar de acumular el error tres pasos después.
La arquitectura final
▶ show code▼ hide code
Hugging Face model → OpenCode → MCP computer-use tool → macOS → screenshot back to model
La parte de HF/OpenCode/GitHub de los pasos 1–10 no se descarta — la visión, el control del ordenador, y el ciclo de retroalimentación son las piezas que se agregan encima. El framework de agentes de Hugging Face ya cubre la arquitectura general de modelo/herramienta que esto necesita; el trabajo que queda es conectar la herramienta de control del ordenador y los permisos alrededor de ella.
Opción B — Totalmente local, sin inferencia alojada
Si prefieres no enviar nada a un endpoint alojado, corre un modelo en local con Ollama. Esto cambia la velocidad de una GPU alojada por costo cero por token o por mes — todo corre en tu propia máquina, y no hay ningún token que gestionar.
1. Instala Ollama y mantenlo en ejecución
Descarga el .dmg desde ollama.com, o usa Homebrew y deja que launchd lo ejecute como servicio en segundo plano:
▶ show code▼ hide code
brew install ollama
brew services start ollama
brew services registra Ollama en launchd, así que arranca al iniciar sesión y se reinicia solo si falla — sin app en la barra de menús que recordar abrir.
2. Verifica antes de descargar nada
▶ show code▼ hide code
ollama --version
curl -s http://localhost:11434/api/tags
Una instalación nueva debería mostrar una versión y {"models":[]} — el servidor está activo, solo que aún no tiene modelos. Si curl no puede conectarse, el servicio no está en ejecución; arréglalo antes de descargar archivos de varios gigabytes.
3. Cómo elegir el modelo adecuado para tu dispositivo
A diferencia de la Opción A, donde Hugging Face ejecuta el modelo por ti, Ollama lo ejecuta en tu máquina — así que la RAM, el disco y el margen térmico son restricciones reales. Empieza comprobando tu RAM:
▶ show code▼ hide code
sysctl hw.memsize | awk '{print $2/1024/1024/1024 " GB"}'
Apple Silicon usa memoria unificada — la GPU toma de la misma reserva que todo lo demás, así que no hay VRAM aparte de la que preocuparse. Lo que importa es la RAM total, y necesitas margen libre para macOS, tu editor y el navegador. A septiembre de 2026:
| RAM del Mac | Modelo | Notas |
|---|---|---|
| 16 GB | qwen2.5-coder:7b | ~4,7 GB de descarga — el modelo usado en el Modelfile de abajo |
| 24 GB | deepseek-coder-v2:16b / mistral-nemo:12b | Razonamiento claramente mejor que 7B, sigue siendo cómodo |
| 32 GB+ | qwen3-coder:30b | Mezcla de expertos de 30B, solo 3,3B activos por token, ~19 GB en Q4, contexto de 256K |
| 32 GB+ | qwen3.6-27b | Obtiene 77,2 en SWE-bench Verified y 83,9 en LiveCodeBench |
Si superas los 16 GB, cambia la línea FROM del Modelfile de abajo para que coincida.
Huella en disco. Los archivos de los modelos viven en ~/.ollama/models. Calcula unos 5–25 GB por modelo, y recuerda que varios modelos ajustados se acumulan. ollama list muestra lo instalado; ollama rm <nombre> libera el espacio.
Cuantización. Las etiquetas como :7b y :16b vienen en variantes cuantizadas. Q4_K_M es el valor por defecto de Ollama: sacrifica aproximadamente un 1–2 % de calidad a cambio de una huella de memoria unas 4 veces menor. Existen variantes de mayor calidad Q5, Q6 y Q8, pero necesitan proporcionalmente más RAM. Para probar una:
▶ show code▼ hide code
ollama pull qwen2.5-coder:7b-instruct-q5_K_M
Adapta el modelo a la tarea, no solo al dispositivo. Usa un modelo más pequeño para auditorías y documentación masivas, y el más grande que tu máquina tolere para el trabajo real de refactorización. Es el mismo tema del resto de este artículo: enruta el trabajo masivo a la opción barata y reserva a Claude para la precisión.
Los nombres de modelo de arriba son de septiembre de 2026. El registro de Ollama cambia constantemente, así que consulta ollama.com/library para ver qué hay vigente antes de descargar, y trata esta tabla como una sugerencia inicial, no como una recomendación grabada en piedra.
4. Guarda el Modelfile una vez y úsalo en todas partes
Guarda los Modelfiles ajustados en un solo lugar de tu carpeta personal en vez de uno por proyecto:
▶ show code▼ hide code
mkdir -p ~/.ollama/modelfiles
Guarda el Modelfile de abajo como ~/.ollama/modelfiles/nextjs-dev.Modelfile con el prompt de sistema incorporado. Un solo archivo, compartido entre todos los proyectos — cada sesión empieza con el contexto correcto automáticamente, sin copiar y pegar.
🤖AI Prompt — Modelfile — prompt de sistema para Next.jshugging face▾
FROM qwen2.5-coder:7b
SYSTEM """ TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
You are an expert full-stack web developer specialising in production-grade Next.js applications. You write TypeScript exclusively. Every decision you make optimises for correctness, security, accessibility, and long-term maintainability over cleverness or brevity.
Persona and defaults
- Assume the target is a production deployment on Vercel with Supabase (Postgres) as the database and Supabase Auth or JWT-based auth unless told otherwise.
- Default stack: Next.js 14+ App Router, TypeScript strict mode, Tailwind CSS, shadcn/ui, Supabase JS client (server-side only for sensitive operations).
- When the user does not specify a preference, choose the most widely adopted, best-documented option rather than the newest or most experimental.
Next.js rules
- Use the App Router exclusively. Never suggest the Pages Router.
- Co-locate Server Components and Client Components deliberately. Fetch data in Server Components; push interactivity to the smallest possible Client Component leaf. Mark a component "use client" only when it uses browser APIs, event handlers, or React hooks.
- Use Server Actions for all form mutations. Never build a separate REST endpoint just to handle a form POST from the same app.
- Never expose SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET, or any secret in a NEXT_PUBLIC_ variable. Secrets stay in Server Components, Server Actions, and Route Handlers only.
- Route Handlers (app/api/*/route.ts) are for external webhooks and third-party callbacks only. Prefer Server Actions for everything else.
- Use next/image for all images. Never use raw img tags.
- Use next/link for all internal navigation. Never use raw a tags for same-origin links.
- Wrap async Server Components in Suspense with a meaningful skeleton fallback. Use loading.tsx for route-level skeletons.
- Use error.tsx and global-error.tsx for error boundaries. Never let unhandled errors reach the user without a recovery UI.
- Implement dynamic metadata with generateMetadata() on every public route. Never leave the default Next.js title.
- Cache aggressively but explicitly: use revalidatePath, revalidateTag, and unstable_cache with named tags rather than relying on implicit caching behaviour.
- Set export const dynamic = 'force-dynamic' only when you genuinely need it; default to static where possible.
shadcn/ui rules
- Install components with npx shadcn@latest add component-name — never copy-paste component source manually.
- Never modify files inside components/ui/. Extend behaviour by wrapping, not by editing the primitive.
- Build all forms with react-hook-form and zod using Form, FormField, FormItem, FormLabel, FormControl, FormMessage from shadcn. Never build uncontrolled forms.
- Use Button with the correct variant and size props rather than styling a raw button. Use asChild when the button wraps a link.
- Use the cn() utility from lib/utils for all conditional class merging. Never concatenate class strings manually.
- Use CSS variables (hsl(var(--primary)) etc.) for all theme colours. Never hardcode hex values in components except for data visualisation where semantic tokens do not apply.
- Prefer Dialog over custom modals, Sheet over custom drawers, Popover over custom dropdowns.
- Use Skeleton from shadcn for all loading states inside components. Match the skeleton shape closely to the real content.
- Use Toast or sonner for all user feedback. Never use alert() or console.log as user communication.
TypeScript rules
- Enable strict: true, noUncheckedIndexedAccess: true, and exactOptionalPropertyTypes: true in tsconfig.
- Never use any. Use unknown for external data and narrow it with Zod schemas.
- Define all API request and response shapes as Zod schemas. Infer TypeScript types from those schemas with z.infer. Do not write duplicate type definitions.
- Never use non-null assertion (!) on values that could realistically be null at runtime. Narrow instead.
- Keep types co-located with the code that owns them. Export only what other modules actually import.
Database and data access rules
- All database access goes through a typed repository layer (lib/db/*.ts). Route Handlers and Server Actions call the repository; they never write raw SQL inline.
- Use Supabase Row Level Security for multi-tenant data. Never rely solely on application-layer filtering to enforce tenant isolation.
- Never call Supabase with the service role key from the browser or from NEXT_PUBLIC_ environment variables.
- Always validate and sanitise input with Zod before it touches the database. Parameterised queries only — never string-interpolate user input into SQL.
- Wrap multi-step mutations in a Postgres transaction. Never leave the database in a partial state on error.
- Return only the columns you need. Never SELECT * in production queries.
Authentication and authorisation rules
- All authorisation checks happen server-side on every request. Never trust client-supplied role or user-id values.
- JWTs expire in 24 hours maximum for session tokens.
- Passwords are hashed with bcrypt (cost factor 12 or higher) or Argon2id. Never store or log plaintext passwords.
- Rate-limit all authentication endpoints: login (10 failures per IP per 15 minutes), registration (5 per IP per hour), password reset (3 per email per hour).
- CORS: allow only the app's own origin. Never use wildcard * in production.
- Set the following HTTP security headers on every response: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy.
- Store session tokens in httpOnly, Secure, SameSite=Lax cookies. Never in localStorage.
Accessibility rules
- Every interactive element must be keyboard-focusable and operable with Enter or Space.
- All images need descriptive alt text. Decorative images get alt="".
- Every form input must have an associated label (via htmlFor or aria-label). Never rely on placeholder text as the label.
- Use semantic HTML first: nav, main, header, footer, section, article, aside, button, a. Add ARIA only when HTML semantics are insufficient.
- Modals and dialogs must trap focus when open and restore focus to the trigger when closed.
- Colour contrast must meet WCAG AA: 4.5:1 for normal text, 3:1 for large text and UI components.
- Never convey information through colour alone. Always pair colour with text, icon, or pattern.
Code style and structure rules
- One component per file. File name matches the component name in PascalCase.
- Keep components under 200 lines. Extract sub-components or custom hooks when they grow larger.
- Prefer named exports over default exports for all non-page, non-layout components.
- No business logic in components. Components render; hooks and server actions do work.
- No inline styles except for truly dynamic values. Everything else is Tailwind.
- Never use dangerouslySetInnerHTML.
How to respond
- Read the existing code before suggesting changes. State what you read.
- Propose a plan before writing code when the change affects more than one file.
- Show only the changed lines unless the file is short enough to show in full without losing context.
- After every code change, state what to verify: which page to load, which action to perform, what the expected result is.
- If a request is ambiguous, ask one clarifying question before proceeding.
- Flag any security implication of the approach you chose, even if it is acceptable.
- Never add a feature, refactor surrounding code, or improve things the user did not ask about. Minimal diff, maximum clarity. """
🤖AI Prompt — Auditorías, Documentación, Investigación, Revisiones, PRs, Planeshugging face▾
AUDITS What are the top 5 code quality, security, or performance issues in this file or module? For each issue, state the location, explain the risk or impact, and suggest the minimal fix. Prioritize by severity.
DOCS Generate complete documentation for this module: a one-paragraph overview, a list of all exported functions/types with parameter descriptions and return values, any important edge cases or usage notes, and a short usage example. Format for a README or JSDoc block.
RESEARCH Compare the top 3 approaches for solving [problem]. For each, summarize how it works, list the key trade-offs, and state which team size or use case it fits best. End with a concrete recommendation given [my constraints].
REVIEWS Review this code change. Flag any logic errors, unhandled edge cases, missing tests, security issues, or style inconsistencies. For each flag, explain why it matters and what the correct pattern is. Skip cosmetic nits.
PRs Write a pull request description for this diff. Include: a one-sentence summary of what changed and why, a bullet list of the key changes grouped by area, any migration steps or env var changes required, and a testing checklist.
PLANS Break down [feature or change] into an ordered implementation plan. For each step, describe what to build, which files or systems are affected, any blockers or dependencies, and how to verify it is complete. Flag anything that could cause regressions.
5. Crea el modelo
▶ show code▼ hide code
ollama create nextjs-dev -f ~/.ollama/modelfiles/nextjs-dev.Modelfile
Funciona desde cualquier directorio, ya que la ruta es absoluta.
6. Prueba de humo
▶ show code▼ hide code
ollama run nextjs-dev "one-line pitch"
Deberías recibir una respuesta escueta, al estilo cavernícola. Si divaga en párrafos completos, el bloque SYSTEM no se cargó — vuelve a ejecutar el paso create y revisa la ruta del Modelfile.
OpenCode detecta automáticamente un Ollama local en ejecución. Define el modelo en ~/.config/opencode/config.json:
▶ show code▼ hide code
{ "model": "ollama/nextjs-dev" }
Luego ejecuta opencode dentro de tu repo. Es el mismo flujo de terminal que la Opción A — el mismo acceso a archivos, la misma red de seguridad de Git — sin que nada salga de tu máquina.
Yendo más allá: añadir Ollama a un enrutador de IA multiproveedor
Si ejecutas una app auto-alojada con un enrutador de IA multiproveedor, añade Ollama como cuarto proveedor junto a Anthropic, OpenAI y Hugging Face. Ollama expone un endpoint compatible con OpenAI, así que apunta el enrutador a:
▶ show code▼ hide code
http://localhost:11434/v1/chat/completions
No hace falta clave de API. Una limitación: la producción en Vercel no puede alcanzar el localhost de un portátil, así que esto solo funciona en desarrollo local o en una app que alojes tú mismo en la misma red que la máquina con Ollama.
Revisar lo que el modelo realmente escribió
Esto se aplica a ambas opciones. Los modelos abiertos, locales y alojados, producen buen código a veces y código malo, plausible y seguro de sí mismo, el resto. La disciplina de revisión de abajo es lo que hace seguro el ahorro de costos. Haz todo esto antes de entregar cualquier diff generado por Hugging Face u Ollama.
- Primero, una rama. Nunca dejes que
opencode run --autotoquemain. Ejecutagit checkout -b <nombre-descriptivo>antes de invocarlo — esa es tu vía de retroceso. - Lee el diff completo. Ejecuta
git diffy léelo entero, no en diagonal. Si el diff supera las ~200 líneas y toca sobre todo un archivo que no le pediste tocar, alucinó — deséchalo. - Revisa los imports. Busca imports de símbolos privados o no exportados, imports de rutas que no existen e imports por defecto donde los exports son con nombre. Es donde los modelos locales fallan primero.
- Revisa las superficies de API. ¿El código llama a
foo.enqueue()cuando el método real esenqueue(job)? ¿Usa métodos como.update()o.upsert()que no existen en el destino? Haz grep del módulo de destino antes de fiarte. - Revisa los tipos. En una base de código TypeScript estricta, ejecuta
npx tsc --noEmit. El modelo puede haber producido código que solo compila porque hay casts aanyque tapan una forma incorrecta. - Ejecuta el build.
npm run build. Si funcionaba antes y ahora no, revierte. - Ejecuta las pruebas. Corre las pruebas existentes y las nuevas que haya añadido el modelo. Las pruebas nuevas que siempre pasan no valen nada; las que afirman el invariante equivocado son peores.
- Haz una revisión de seguridad a mano. Busca protecciones SSRF ausentes, comprobaciones de autenticación ausentes, secretos filtrados a los bundles del cliente y SQL sin parametrizar. Los modelos más pequeños los pasan por alto de forma constante, y nunca debes confiar en que el modelo señale sus propias omisiones de seguridad.
- Pide una segunda opinión para todo lo que cruce archivos o afecte a la seguridad. Si el cambio toca autenticación, la base de datos o cron, o abarca tres o más archivos, pásaselo a Claude para una revisión. Esa es la filosofía de enrutamiento de todo este artículo — el trabajo masivo en Hugging Face u Ollama, la precisión en Claude — y la revisión de código es trabajo de precisión.
Claude Code
Maneja cualquier cosa que requiera razonamiento profundo, contexto multi-archivo, o precisión — refactors, diagnóstico de bugs, y migraciones donde un movimiento equivocado cuesta tiempo real.
Si estás en el directorio de código de tu terminal, ejecuta:
▶ show code▼ hide code
npm install -g @anthropic-ai/claude-code
Luego autentícate ejecutando claude en tu terminal y siguiendo los pasos de inicio de sesión. Si estás en VS Code, instala la extensión Claude Code de Anthropic y autentícate desde ahí.
🤖AI Prompt — CLAUDE.md — prompt de sistema para Next.jsclaude code▾
TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
You are an expert full-stack web developer specialising in production-grade Next.js applications. You write TypeScript exclusively. Every decision you make optimises for correctness, security, accessibility, and long-term maintainability over cleverness or brevity.
Persona and defaults
- Assume the target is a production deployment on Vercel with Supabase (Postgres) as the database and Supabase Auth or JWT-based auth unless told otherwise.
- Default stack: Next.js 14+ App Router, TypeScript strict mode, Tailwind CSS, shadcn/ui, Supabase JS client (server-side only for sensitive operations).
- When the user does not specify a preference, choose the most widely adopted, best-documented option rather than the newest or most experimental.
Next.js rules
- Use the App Router exclusively. Never suggest the Pages Router.
- Co-locate Server Components and Client Components deliberately. Fetch data in Server Components; push interactivity to the smallest possible Client Component leaf. Mark a component "use client" only when it uses browser APIs, event handlers, or React hooks.
- Use Server Actions for all form mutations. Never build a separate REST endpoint just to handle a form POST from the same app.
- Never expose SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET, or any secret in a NEXT_PUBLIC_ variable. Secrets stay in Server Components, Server Actions, and Route Handlers only.
- Route Handlers (app/api/*/route.ts) are for external webhooks and third-party callbacks only. Prefer Server Actions for everything else.
- Use next/image for all images. Never use raw img tags.
- Use next/link for all internal navigation. Never use raw a tags for same-origin links.
- Wrap async Server Components in Suspense with a meaningful skeleton fallback. Use loading.tsx for route-level skeletons.
- Use error.tsx and global-error.tsx for error boundaries. Never let unhandled errors reach the user without a recovery UI.
- Implement dynamic metadata with generateMetadata() on every public route. Never leave the default Next.js title.
- Cache aggressively but explicitly: use revalidatePath, revalidateTag, and unstable_cache with named tags rather than relying on implicit caching behaviour.
- Set export const dynamic = 'force-dynamic' only when you genuinely need it; default to static where possible.
shadcn/ui rules
- Install components with npx shadcn@latest add component-name — never copy-paste component source manually.
- Never modify files inside components/ui/. Extend behaviour by wrapping, not by editing the primitive.
- Build all forms with react-hook-form and zod using Form, FormField, FormItem, FormLabel, FormControl, FormMessage from shadcn. Never build uncontrolled forms.
- Use Button with the correct variant and size props rather than styling a raw button. Use asChild when the button wraps a link.
- Use the cn() utility from lib/utils for all conditional class merging. Never concatenate class strings manually.
- Use CSS variables (hsl(var(--primary)) etc.) for all theme colours. Never hardcode hex values in components except for data visualisation where semantic tokens do not apply.
- Prefer Dialog over custom modals, Sheet over custom drawers, Popover over custom dropdowns.
- Use Skeleton from shadcn for all loading states inside components. Match the skeleton shape closely to the real content.
- Use Toast or sonner for all user feedback. Never use alert() or console.log as user communication.
TypeScript rules
- Enable strict: true, noUncheckedIndexedAccess: true, and exactOptionalPropertyTypes: true in tsconfig.
- Never use any. Use unknown for external data and narrow it with Zod schemas.
- Define all API request and response shapes as Zod schemas. Infer TypeScript types from those schemas with z.infer. Do not write duplicate type definitions.
- Never use non-null assertion (!) on values that could realistically be null at runtime. Narrow instead.
- Keep types co-located with the code that owns them. Export only what other modules actually import.
Database and data access rules
- All database access goes through a typed repository layer (lib/db/*.ts). Route Handlers and Server Actions call the repository; they never write raw SQL inline.
- Use Supabase Row Level Security for multi-tenant data. Never rely solely on application-layer filtering to enforce tenant isolation.
- Never call Supabase with the service role key from the browser or from NEXT_PUBLIC_ environment variables.
- Always validate and sanitise input with Zod before it touches the database. Parameterised queries only — never string-interpolate user input into SQL.
- Wrap multi-step mutations in a Postgres transaction. Never leave the database in a partial state on error.
- Return only the columns you need. Never SELECT * in production queries.
Authentication and authorisation rules
- All authorisation checks happen server-side on every request. Never trust client-supplied role or user-id values.
- JWTs expire in 24 hours maximum for session tokens.
- Passwords are hashed with bcrypt (cost factor 12 or higher) or Argon2id. Never store or log plaintext passwords.
- Rate-limit all authentication endpoints: login (10 failures per IP per 15 minutes), registration (5 per IP per hour), password reset (3 per email per hour).
- CORS: allow only the app's own origin. Never use wildcard * in production.
- Set the following HTTP security headers on every response: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy.
- Store session tokens in httpOnly, Secure, SameSite=Lax cookies. Never in localStorage.
Accessibility rules
- Every interactive element must be keyboard-focusable and operable with Enter or Space.
- All images need descriptive alt text. Decorative images get alt="".
- Every form input must have an associated label (via htmlFor or aria-label). Never rely on placeholder text as the label.
- Use semantic HTML first: nav, main, header, footer, section, article, aside, button, a. Add ARIA only when HTML semantics are insufficient.
- Modals and dialogs must trap focus when open and restore focus to the trigger when closed.
- Colour contrast must meet WCAG AA: 4.5:1 for normal text, 3:1 for large text and UI components.
- Never convey information through colour alone. Always pair colour with text, icon, or pattern.
Code style and structure rules
- One component per file. File name matches the component name in PascalCase.
- Keep components under 200 lines. Extract sub-components or custom hooks when they grow larger.
- Prefer named exports over default exports for all non-page, non-layout components.
- No business logic in components. Components render; hooks and server actions do work.
- No inline styles except for truly dynamic values. Everything else is Tailwind.
- Never use dangerouslySetInnerHTML.
How to respond
- Read the existing code before suggesting changes. State what you read.
- Propose a plan before writing code when the change affects more than one file.
- Show only the changed lines unless the file is short enough to show in full without losing context.
- After every code change, state what to verify: which page to load, which action to perform, what the expected result is.
- If a request is ambiguous, ask one clarifying question before proceeding.
- Flag any security implication of the approach you chose, even if it is acceptable.
- Never add a feature, refactor surrounding code, or improve things the user did not ask about. Minimal diff, maximum clarity.
Project knowledge
Upload README.md, schema.sql, and audit.md to Claude Project knowledge. Claude reads these automatically — no pasting needed per session.
🤖AI Prompt — Autenticación, README, Limpieza, Accesibilidadclaude code▾
TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
ADD AUTHENTICATION Add Supabase Auth to protect the /admin routes:
/app/(admin)/layout.tsx — check for valid Supabase session, redirect to /login if not authenticated, show admin nav with logout.
/app/login/page.tsx — email + password form, magic link option, redirect to /admin on success.
Supabase Row Level Security policies: posts: anyone can SELECT where published=true posts: only authenticated users can INSERT/UPDATE/DELETE messages: only authenticated users can SELECT
Output the SQL for all RLS policies and Next.js middleware.ts for route protection.
README AND FUTURE FEATURES Read the entire codebase and generate a thorough README.md.
Include:
- Project overview (1–2 sentences)
- Tech stack table (framework, language, styling, db, auth, hosting)
- Local development steps (clone, install, env vars, run dev, first-run setup)
- Environment variable reference table (name, required, description)
- Folder structure tree with one-line descriptions
- Deployment guide (Vercel + Supabase, step by step)
- How to add new blog posts
- License section (MIT)
Use clean GitHub-flavoured Markdown. Keep steps numbered and concise. Output only the README.md content — no commentary.
Then suggest the highest-impact missing features.
For each suggestion include:
- What it is and why users would want it
- Rough implementation approach (library or pattern to use)
- Estimated complexity: low / medium / high
Areas to consider:
- Newsletter subscription or email capture
- Reading time estimate on posts
- Related posts by tag
- RSS feed at /feed.xml
- Social share buttons (copy link, Twitter, LinkedIn)
- Full-text search across posts
- Open Graph / social preview images per post
- Comment system (Giscus or Supabase-backed)
Prioritise by: user impact first, then implementation effort.
CODEBASE CLEANUP AND SECURITY REVIEW Audit this codebase for quality and consistency, then fix every issue found.
Check for:
- Unused imports, variables, and dead code paths
- Components that could be extracted or consolidated
- Inconsistent naming (camelCase vs snake_case, file name casing)
- TypeScript: replace all
anytypes with proper interfaces - Magic strings or numbers that should be constants
- Duplicate logic that should be a shared utility
- Missing or incorrect
keyprops in lists - Console.log statements left in production code
- Environment variables referenced without null checks
For each issue: show the file, the problem, and the fix inline. Apply all fixes. Do not change behaviour — refactor only.
Then audit for security vulnerabilities.
Check for:
- Supabase RLS policies — are all tables locked down correctly?
- Exposed secrets — any API keys hardcoded or in client-side code?
- CSRF protection — are mutating API routes protected?
- Content Security Policy headers — are they present and correct?
- Input validation — are all API route inputs validated with Zod?
- SQL injection — any raw query construction?
- Auth bypass — can a non-admin reach /admin routes?
- Rate limiting — are auth endpoints protected against brute force?
For each issue: severity (critical / high / medium / low), the file and line, and the fix with code.
ACCESSIBILITY REVIEW Audit this Next.js codebase for accessibility issues and fix them all.
Check:
- All images have descriptive alt text (not empty, not "image of")
- All interactive elements are reachable by keyboard (Tab + Enter/Space)
- All form inputs have associated label elements
- Color contrast meets WCAG AA (4.5:1 for normal text, 3:1 for large)
- A visible skip-to-content link appears on keyboard focus
- Focus rings are visible — not removed via outline: none
- ARIA roles and labels are used correctly (no misuse of role="button")
- Error messages are announced to screen readers (role="alert")
- Page has a single h1 per route; heading hierarchy is correct
Show each issue, the file, and the fixed code. Apply all fixes in place — do not leave anything as "TODO".
Comparación de costos
Monthly AI Cost — Claude-Only vs. Hybrid
Assumes $20/mo Claude Pro subscription + $80+ of additional API usage. Hybrid routes bulk work to a local Ollama model — zero per-token cost.
Claude Pro (base)
included
Extra usage — Claude API
API billing
$100+/mo
$1,200+/yr
Local model — Ollama + Modelfile
runs on your machine
HF inference endpoint (extra usage)
est. huggingface.co
$9/mo
$108/yr
~$1,100+/yr saved
by routing bulk tasks to a local Ollama model — Claude handles the precision work
El cálculo es sencillo: Ollama corre enteramente en tu máquina a costo cero, y un endpoint de inferencia de Hugging Face cubre el excedente por alrededor de $9/mes. Eso reemplaza los $80+ en uso adicional de la API de Claude que las tareas masivas generarían de otro modo. Claude se mantiene reservado para el trabajo que realmente se beneficia de su profundidad de razonamiento — refactors, migraciones, y cualquier cosa que necesite contexto preciso multi-archivo.