OpenCode: tu agente de programación
A partir del proyecto 2 programas de forma agéntica: con OpenCode, un agente que vive en tu terminal, lee tu proyecto, propone cambios y ejecuta órdenes — siempre con tu permiso. Está conectado a los modelos de IA locales del centro: tu código y tus datos no salen del instituto. El chat queda para consultas; el código se construye con el agente.
Esta guía es tu referencia para todo el curso, en presencial y en semipresencial. Vuelve a ella cada vez que aparezca algo nuevo. Y fíjate en el detalle: la herramienta con la que vas a programar tu CLI… es una CLI.
Chat vs agente
Hasta ahora usabas la IA como un chat: preguntas, te contesta con texto, y tú copias el código y lo pegas. Un agente es el mismo tipo de modelo, pero con herramientas: puede abrir tus ficheros, buscar, editarlos y ejecutar órdenes. Ve el resultado de cada paso y decide el siguiente, en bucle, hasta terminar.
Chat
- No ve tu proyecto: solo lo que le pegas.
- Responde una vez; tú haces el trabajo de copiar, pegar y probar.
- Ideal para preguntar: «¿qué es un decorador?», «¿por qué falla esto?».
Agente (OpenCode)
- Lee el proyecto entero por su cuenta (lo que necesite).
- Edita ficheros y ejecuta órdenes, pidiéndote permiso según tus reglas.
- Comprueba su propio trabajo (ejecuta, ve el error, corrige) antes de darte el turno.
El bucle del agente
Un chat da una respuesta. Un agente da muchas vueltas a este bucle hasta acabar la tarea.
Las herramientas del agente
Son las que tiene el agente build en la versión de clase. Los permisos (más abajo) deciden cuáles usa solo, cuáles te pregunta y cuáles tiene prohibidas.
| Herramienta | Qué hace | Dicho de otra forma |
|---|---|---|
| read | Lee un fichero (o un trozo). | Como abrirlo en el editor para mirarlo. |
| glob | Busca ficheros por nombre o patrón: src/**/*.py. | Como el buscador de ficheros. |
| grep | Busca texto dentro de los ficheros. | Como Ctrl+Shift+F en VS Code. |
| edit | Cambia unas líneas concretas de un fichero que ya existe. | Te enseña el diff antes de aplicarlo (si está en ask). |
| write | Crea un fichero nuevo o lo reescribe entero. | Lo controla el mismo permiso que edit. |
| bash | Ejecuta una orden en la terminal: uv run, git status, ls… | La más potente y la más peligrosa: por eso pregunta. |
| webfetch | Descarga una página web y la lee. | En el proyecto, siempre pregunta antes. |
| task | Lanza un subagente (general, explore o uno tuyo) para una subtarea. | Trabaja en una sesión hija y te devuelve un resumen. |
| todowrite | Mantiene una lista de pasos pendientes y hechos. | Verás la lista tachándose mientras trabaja. |
| skill | Carga una skill (conocimiento extra) cuando la necesita. | Solo carga la que le sirve, no todas. |
| question | Te hace una pregunta con opciones cuando duda. | Respóndela: es mejor que dejarle adivinar. |
Por qué OpenCode (y por qué modelos del centro)
Código abierto: puedes ver cómo funciona y no depende de una suscripción.
Funciona igual en Linux, Windows y macOS, y dentro de la terminal integrada de VS Code.
Se conecta a decenas de proveedores… y a un servidor propio como el del centro.
Defines qué puede hacer solo, qué te pregunta y qué nunca hará.
Claude Code, Codex o el modo agente de Copilot funcionan igual: lo que aprendes aquí, lo usas allí.
AGENTS.md, comandos, skills y agentes viven en tu repo y viajan con él.
Privacidad
Tu código, tus ficheros y tus prompts se quedan en el servidor del instituto. No alimentan a ninguna empresa.
Sin cuentas de pago
No necesitas tarjeta ni suscripción. Te basta la clave que te da el profesor.
Igual para todos
Todo el grupo usa el mismo modelo con las mismas condiciones: la nota depende de tu trabajo, no de quién paga más.
permissions, agents, providers) que la 1.18 no entiende. Si un tutorial habla de permissions o agents en plural, es OpenCode 2: aquí van en singular (permission, agent, provider, command, mcp). Y no instales con brew install opencode ni con pacman -S opencode: esos traen la V2. Si tu editor marca las claves en singular como deprecated, ignóralo: el esquema publicado ya es el de la V2.Instalación paso a paso
En los equipos del aula ya lo tienes preparado o lo instalas en la primera sesión. En casa (semipresencial), elige tu sistema:
Linux y macOS
El script oficial, fijando la versión. Instala en ~/.opencode/bin y lo añade al PATH. Después, abre una terminal nueva.
curl -fsSL https://opencode.ai/install | bash -s -- --version 1.18.35Windows nativo
- Instala Git for Windows (OpenCode usa Git Bash para ejecutar órdenes).
- Instala Node.js LTS (trae npm).
- En una terminal nueva de PowerShell:
npm install -g opencode-ai@1.18.35Windows con WSL
La alternativa que recomienda la documentación: un Linux dentro de Windows. Si ya usas WSL (Ubuntu), dentro de su terminal usa el script de Linux:
curl -fsSL https://opencode.ai/install | bash -s -- --version 1.18.35Ojo: en WSL las variables de entorno y la config van en el ~ de Linux, no en el de Windows.
Comprueba que está bien
opencode --version # debe decir 1.18.35opencode debug paths # dónde guarda config, datos y logsSi sale command not found (o no se reconoce en Windows), cierra la terminal y abre otra: las terminales abiertas antes de instalar no conocen el PATH nuevo. Si la versión no es la 1.18.35, revisa cómo lo instalaste (mira Errores típicos). En Linux, para copiar y pegar dentro de OpenCode hace falta xclip, xsel o wl-clipboard.
Conectarlo a los modelos del centro
OpenCode necesita saber a qué servidor hablar y con qué clave. Eso va en tu configuración global (de tu usuario, en tu equipo), nunca en el repositorio. La URL del servidor y la clave te las da el profesor (en clase o en el aula virtual).
- 1
Crea el fichero de configuración global
Ruta:
~/.config/opencode/opencode.json(en Windows,%USERPROFILE%\.config\opencode\opencode.json). Crea la carpeta y ábrelo con tu editor:bash / zshmkdir -p ~/.config/opencodecode ~/.config/opencode/opencode.json # o nanoPowerShellNew-Item -ItemType Directory -Force "$env:USERPROFILE\.config\opencode"notepad "$env:USERPROFILE\.config\opencode\opencode.json" - 2
Pega esta configuración tal cual
No hay ninguna dirección ni clave escrita:
{env:CENTRO_IA_URL}y{env:CENTRO_IA_KEY}le dicen a OpenCode que las lea de dos variables de entorno.~/.config/opencode/opencode.json{"$schema": "https://opencode.ai/config.json","autoupdate": false,"provider": {"centro": {"npm": "@ai-sdk/openai-compatible","name": "IA del centro","options": {"baseURL": "{env:CENTRO_IA_URL}","apiKey": "{env:CENTRO_IA_KEY}"},"models": {"qwen3.8-flash-next": {"name": "Qwen 3.8 Flash-Next (centro)","limit": { "context": 524288, "output": 65536 },"tool_call": true}}}},"model": "centro/qwen3.8-flash-next","small_model": "centro/qwen3.8-flash-next"}autoupdate: false: que no se actualice solo (seguimos en 1.18.35).centro: el nombre que le damos al proveedor; es lo que va antes de la barra enmodel.@ai-sdk/openai-compatible: el servidor del centro habla el mismo «idioma» que la API de OpenAI.limit: cuánto contexto y salida admite el modelo. Sin esto OpenCode no sabe cuándo resumir la conversación.tool_call: true: el modelo sabe usar herramientas. Sin eso no hay agente, solo chat.modelysmall_model: el modelo de trabajo y el de tareas ligeras (títulos de sesión…). Aquí, el mismo.
- 3
Define las variables de entorno
Sustituye los
…por lo que te dé el profesor (la URL termina en/v1).Linux / macOS / WSL# Añade al final de ~/.bashrc (o ~/.zshrc en macOS)export CENTRO_IA_URL="…"export CENTRO_IA_KEY="…"Windows (PowerShell)setx CENTRO_IA_URL "…"setx CENTRO_IA_KEY "…"Y después, abre una terminal nueva: las variables solo existen en las terminales que se abren después.
- 4
Comprueba la conexión
Terminalopencode models centro # debe salir centro/qwen3.8-flash-nextopencode debug config # config final; la clave sale enmascaradaopencode run "Responde solo: hola" # prueba real con el modeloSi
opencode runse queda esperando sin fin, el servidor no responde: OpenCode reintenta para siempre. Sal con Ctrl+C y revisa la URL y que estás en la red del centro.
Primeros pasos en la TUI
TUI (Text User Interface) es una interfaz completa dentro de la terminal. Se abre entrando en la carpeta del proyecto y escribiendo opencode:
cd ~/cli-tareasopencode- 1Conversación. Tus mensajes, las respuestas y cada herramienta que usa (qué fichero lee, qué orden ejecuta). Léelo: es el «razonamiento en voz alta» del agente.
- 2Petición de permiso. Cuando una regla está en ask, se para y te enseña el diff o la orden. Nada se aplica hasta que respondes.
- 3Caja de entrada. Escribes la petición. Intro envía; para un salto de línea, shift+enter o ctrl+j.
- 4Barra inferior. Agente activo (Build o Plan) y modelo. Míralo antes de escribir: ¿estás en el agente que quieres?
- Esquema simplificado: colores y textos exactos cambian según el tema y la versión.
Lo que puedes escribir en la caja
Tu petición, en español. Concreta: qué fichero, qué orden, qué criterio de «terminado».
Adjunta un fichero (con búsqueda difusa): @src/tareas/cli.py. También invoca subagentes: @explore ….
Ejecuta una orden tú mismo y el agente ve la salida: !uv run tareas --help. Escribir / abre la lista de comandos.
Un ejemplo de primera petición en el agente plan:
Lee @AGENTS.md y @src/tareas/cli.py. Quiero añadir la orden «version» que muestre la versión de __init__.py. No cambies nada todavía: explícame en 5 líneas qué ficheros tocarías y cómo comprobaré que funciona.
Atajos y comandos de barra
La tecla líder es ctrl+x: la pulsas, sueltas y pulsas la letra (por ejemplo ctrl+x y luego u = deshacer).
| Atajo | Comando | Para qué |
|---|---|---|
| Tab / Shift+Tab | — | Cambia de agente primario: build ↔ plan |
| Esc | — | Interrumpe la respuesta en curso |
| ctrl+p | — | Paleta con todos los comandos |
| ctrl+x n | /new | Sesión nueva (una por tarea) |
| ctrl+x l | /sessions | Lista de sesiones para retomar una |
| ctrl+x m | /models | Elegir modelo |
| ctrl+x c | /compact | Resume la conversación para liberar contexto |
| ctrl+x u | /undo | Deshace tu último mensaje, sus respuestas y sus cambios en ficheros |
| ctrl+x r | /redo | Rehace lo deshecho |
| ctrl+x x | /export | Exporta la conversación a Markdown |
| — | /init | Crea o mejora el AGENTS.md del proyecto |
| — | /review | Revisa los cambios sin commit (o un commit o rama) |
| — | /skills | Explora las skills que ve el agente |
| — | /mcps | Servidores MCP; espacio los activa o desactiva |
| — | /help | Ayuda |
| ctrl+c | /exit | Salir |
Sesiones
Cada conversación es una sesión y se guarda. Abre una nueva para cada tarea (/new), recupera una anterior con /sessions, o continúa la última desde la terminal:
opencode -c # continúa la última sesiónopencode session list # lista de sesiones/undo y /redo
/undo borra tu último mensaje, sus respuestas y revierte los cambios en ficheros; /redo lo restaura. Funciona con instantáneas internas que OpenCode guarda aparte: no hace commits en tu repo. Pero necesita que el proyecto sea un repositorio git con al menos un commit. Y no deshace efectos externos: un paquete instalado, una orden que movió ficheros fuera, un git push…
/compact
Resume la conversación para liberar contexto. OpenCode lo hace solo cuando se llena, pero hacerlo tú al cambiar de fase (o abrir /new) da mejores resultados: un modelo con menos ruido se equivoca menos.
/export
Exporta la conversación a Markdown y la abre en tu editor. Útil para guardar el prompt clave y lo que respondió en docs/prompts.md, que forma parte de tu proceso evaluable.
Agentes: build, plan y subagentes
Un agente es una configuración del modelo: un prompt, unas herramientas y unos permisos. OpenCode trae varios, y puedes crear los tuyos.
| Agente | Tipo | Qué puede hacer | Cuándo |
|---|---|---|---|
| build | primario (por defecto) | Todas las herramientas, con los permisos de tu config. | Para hacer: editar, crear, ejecutar. |
| plan | primario | No puede editar ficheros (salvo sus propios planes). Ojo: de fábrica bash NO está restringido. | Para pensar: analizar, proponer, revisar un plan. |
| general | subagente | Investigación y tareas de varios pasos. Puede modificar ficheros. | Una subtarea que no quieres que ensucie tu conversación. |
| explore | subagente | Solo lectura: busca y lee (no edita), aunque puede ejecutar órdenes. | «¿Dónde se valida el JSON?», «¿qué usa a motor.py?» |
"edit": "ask", esa regla le alcanza también a plan. Por eso el opencode.json del proyecto le pone "edit": "deny" y deja que las órdenes sigan tus reglas de bash (las peligrosas siguen en deny). Ojo: si le pusieras "bash": "ask", anularías esos deny y rm pasaría a «preguntar». Compruébalo con opencode debug agent plan.Cambiar e invocar
- Tab alterna entre build y plan (mira la barra inferior).
- Un subagente se invoca con
@:@explore busca dónde se lee acciones.json. - El agente principal también puede lanzarlos solo (herramienta
task), eligiéndolos por su descripción. - Los subagentes trabajan en una sesión hija: su exploración no llena tu contexto.
opencode agent list # agentes cargadosopencode debug agent plan # reglas efectivas de unoCrea los tuyos
Un fichero Markdown en .opencode/agents/: el nombre del fichero es el nombre del agente, el frontmatter su configuración (description es obligatoria; mode: subagent, temperature, permission…) y el cuerpo, su prompt. Es el revisor de la semana 2:
---description: Revisa el código de la CLI tareas sin modificar nada y señala errores, casos feos y problemas multiplataformamode: subagenttemperature: 0.1permission: edit: deny webfetch: deny bash: "*": deny "git diff *": allow "git log *": allow "git status *": allow---Eres el revisor de código del proyecto (1º DAM). Revisa lo que te indiquen y responde en español con:1. Errores seguros (con fichero y línea).2. Casos feos sin cubrir: ruta inexistente, carpeta vacía, nombres con tildes o espacios, JSON roto, destino que ya existe.3. Problemas en Windows/macOS (rutas, encoding, shell).4. Una pregunta que el alumno debería saber responder sobre ese código.No reescribas el código: señala y explica.Se usa así: @revisor revisa src/tareas/motor.py. No puede editar ni navegar por la web; solo mirar diffs e historial sin preguntar. Como es un fichero del repo, el revisor viaja con tu proyecto.
Permisos: lo que puede hacer sin preguntarte
De fábrica, OpenCode tiene casi todo en allow: edita y ejecuta órdenes sin preguntar. En el curso eso no vale. Cada herramienta (y cada orden de bash) acaba en una de tres respuestas:
Lo hace sin preguntar.
Se para, te enseña qué va a hacer y espera.
Bloqueado. Ni lo intenta.
Cuando pregunta, respondes once (solo esta vez), always (lo mismo durante el resto de la sesión) o reject (no). Las órdenes que te pregunta, léelas antes de aceptar.
La regla de oro: gana la última que coincide
Las reglas se leen de arriba abajo y, si varias coinciden, manda la última. Por eso "*" va primero (lo general) y las excepciones después, con los deny al final. El * significa «cualquier cosa»: git diff * vale para git diff y para git diff src/.
- "*": askcoincide
- "git diff *": allowgana ✓
- "rm *": denyno coincide
Resultado: allow
- "*": askcoincide
- "git diff *": allowno coincide
- "rm *": denygana ✓
Resultado: deny
El opencode.json del proyecto
Va en la raíz de tu repo (cli-tareas/opencode.json) y se sube a git: no lleva claves, solo reglas. Se fusiona con tu config global.
{ "$schema": "https://opencode.ai/config.json", "permission": { "edit": "ask", "webfetch": "ask", "external_directory": "ask", "read": { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" }, "bash": { "*": "ask", "ls *": "allow", "pwd": "allow", "cat *": "allow", "git status *": "allow", "git diff *": "allow", "git log *": "allow", "uv run tareas --help": "allow", "uv run tareas validar *": "allow", "uv run pytest *": "allow", "git commit *": "ask", "git push *": "deny", "git reset *": "deny", "rm *": "deny", "sudo *": "deny" } }, "agent": { "plan": { "permission": { "edit": "deny" } } }}| Regla | Qué significa |
|---|---|
| "edit": "ask" | Cada edición o fichero nuevo te enseña el diff y espera tu sí. En la semana 1 es obligatorio: lees todo lo que entra en tu repo. |
| "webfetch": "ask" | Si quiere leer una web, pregunta. Así sabes de dónde saca la información. |
| "external_directory": "ask" | Nada fuera de la carpeta del proyecto sin preguntar (tu carpeta personal, otras prácticas…). |
| "read": { "*": "allow", … } | Puede leer cualquier fichero del proyecto sin preguntar… |
| "*.env": "deny", "*.env.*": "deny" | …salvo los .env con claves: esos ni los ve. Va DESPUÉS del "*" porque gana la última que coincide. |
| "*.env.example": "allow" | La plantilla sin claves sí puede leerla (va al final para volver a permitirla). |
| "bash": { "*": "ask", … } | Regla general: cualquier orden pregunta. Es la primera para que las demás la puedan matizar. |
| "ls *", "pwd", "cat *" | Mirar carpetas y ficheros no rompe nada: allow. |
| "git status *", "git diff *", "git log *" | Consultar git tampoco: allow. El agente puede ver qué ha cambiado. |
| "uv run tareas --help", "uv run tareas validar *" | Probar la ayuda y validar acciones.json es inofensivo: allow. |
| "uv run pytest *" | Pasar las pruebas (semana 4): allow. |
| "git commit *": "ask" | Los commits los haces tú; si te lo propone, te pregunta (y normalmente dirás que no). |
| "git push *", "git reset *": "deny" | Subir o reescribir historia: nunca el agente. |
| "rm *", "sudo *": "deny" | Borrar ficheros o usar permisos de administrador: prohibido. Al final del bloque, para que nada los pise. |
| "agent": { "plan": … } | Al agente plan le quita editar y le pone bash en ask (explicado en Agentes). |
uv run tareas ejecutar …? Porque esa orden mueve, renombra o borra ficheros de verdad. Si el agente se equivoca de carpeta, los daños son reales y /undo no los deshace. Esa orden siempre te pregunta, y tú la pruebas en ~/pruebas-tareas con --simular. Y git push lo haces tú.La trampa al fusionar configuraciones
Las configuraciones (global, proyecto, agente) se fusionan, no se sustituyen. Si la global dice "rm *": "deny" y otra posterior dice "*": "allow", el resultado queda en ese orden… y como gana la última, rm queda permitido. Solución: repite los deny importantes después del "*" en el mismo bloque (como hace el fichero de arriba) y compruébalo con opencode debug agent build.
--auto. opencode --auto (o el «auto-approve» de la paleta) aprueba solo todo lo que está en ask. Es decir: desactiva tu revisión. Un modelo que entiende mal una petición puede borrar, sobrescribir o ejecutar lo que no debe, y tú ni lo verás. En el curso está prohibido; en tu carpeta personal, también.AGENTS.md: la memoria del proyecto
El modelo no recuerda nada entre sesiones. AGENTS.md es un fichero Markdown en la raíz del proyecto que OpenCode carga al empezar cada sesión: qué es el proyecto, cómo se ejecuta, qué normas hay que respetar. Es un estándar: lo leen también otros agentes.
Créalo con /init
/init analiza el repo, puede hacerte alguna pregunta y crea (o mejora) el AGENTS.md. Después lo editas tú: quita lo que sobra, añade tus normas. Corto y concreto: se carga siempre y ocupa contexto.
Global vs proyecto
- Proyecto:
AGENTS.mden la raíz. Se sube a git: cualquiera (o cualquier agente) que abra tu repo hereda las normas. - Global:
~/.config/opencode/AGENTS.md. Tus preferencias personales para todos los proyectos («respóndeme en español»).
# tareas · CLI de tareas con ficheros (proyecto de 1º DAM)## Stack y órdenes- Python 3.12 + Typer + Rich, gestionado con uv (src layout, paquete src/tareas).- Ejecutar: `uv run tareas --help` · Validar config: `uv run tareas validar` · Pruebas (semana 4): `uv run pytest`.## Normas- Mensajes y comentarios en español; código claro antes que listo.- pathlib siempre, encoding="utf-8", nada de os.system ni shell=True: tiene que funcionar en Linux, Windows y macOS.- Nunca ejecutes acciones sobre carpetas reales: solo en ~/pruebas-tareas y con --simular.- No toques .env ni escribas claves en ningún fichero. No hagas git push ni commits: los hace el alumno.- Antes de cambiar un fichero, explica en 2-3 líneas qué vas a hacer.Cada vez que el agente repita un error («otra vez ha usado os.system»), la solución no es repetírselo en cada sesión: es añadir una línea a AGENTS.md y hacer commit. Los cambios en AGENTS.md cuentan tu proceso.
Comandos personalizados
Si escribes el mismo tipo de prompt muchas veces, conviértelo en un comando: un fichero .opencode/commands/<nombre>.md que se lanza con /nombre.
Piezas
- Frontmatter:
description(lo que ves en la lista),agent(con qué agente se ejecuta) y, si quieres,modelosubtask: true(como subtarea, sin ensuciar tu conversación). $ARGUMENTS: todo lo que escribes detrás del comando.$1,$2…: cada argumento por separado (entre comillas si lleva espacios).!`orden`: ejecuta la orden al lanzar el comando y mete su salida en el prompt.@fichero: adjunta un fichero.
---description: Añade una acción nueva a acciones.json y, si hace falta, el código que la soportaagent: build---Quiero añadir la acción: $ARGUMENTS1. Carga la skill acciones-json.2. Propón primero la entrada JSON y espera mi visto bueno.3. Si el tipo ya existe, solo edita acciones.json. Si no, añade la clase en src/tareas/acciones.py siguiendo el patrón de las demás.4. Termina ejecutando `uv run tareas validar` y dime qué orden con --simular debo probar yo.Estado actual del repo:!`git status --short`Se usa así (semana 2):
/nueva-accion renombrar-capturas "Renombra las capturas de pantalla con su fecha y un contador"
Skills: conocimiento bajo demanda
Una skill es un paquete de conocimiento que el agente carga solo cuando lo necesita. El agente ve una lista con el nombre y la descripción de cada skill; si una le sirve para lo que está haciendo, la carga con la herramienta skill y lee el contenido completo. Así no gasta contexto en lo que no toca.
Dónde y cómo
- Una carpeta por skill:
.opencode/skills/<nombre>/SKILL.md. name: minúsculas, números y guiones, y igual que el nombre de la carpeta.description: obligatoria. Di qué hace y cuándo usarla: es lo único que el agente lee para decidir.- Compruébalo con
/skillsen la TUI (oopencode debug skill).
---name: acciones-jsondescription: Reglas del fichero acciones.json de la CLI tareas (campos, tipos, filtros, plantillas y validación). Úsala siempre que crees o cambies acciones o el código que las lee (config.py, acciones.py, motor.py).---# Esquema de acciones.json- Raíz: {"version": 1, "acciones": [...]}. Cada acción: nombre (único, minúsculas-con-guiones), descripcion, tipo.- Tipos: mover y copiar (requieren destino), renombrar (requiere plantilla), borrar (siempre pide confirmación salvo --si).- filtro opcional: extensiones (lista, en minúsculas), patron (regex válida), mas_antiguo_que_dias, mayor_que_mb.- plantilla: huecos {fecha:%Y-%m-%d}, {n:03}, {ext}, {nombre}.## Reglas al programar- Valida el JSON en config.py ANTES de ejecutar; errores con AccionNoValida(accion, campo, motivo).- pathlib y shutil; encoding="utf-8"; nunca shell=True; nunca sobrescribir (destino_libre).- Toda acción admite --simular y devuelve list[Resultado].- Si añades un campo o un tipo nuevo, documéntalo en el README y en esta skill.¿AGENTS.md, skill o comando?
| AGENTS.md | Skill | Comando | |
|---|---|---|---|
| Qué es | Normas fijas del proyecto | Conocimiento especializado | Un prompt que repites |
| Cuándo se carga | Siempre, al empezar cada sesión | Solo cuando el agente decide que le sirve | Cuando tú escribes /nombre |
| Quién lo dispara | Nadie: está siempre | El agente (herramienta skill) | Tú |
| Gasta contexto | Siempre: tenlo corto | Solo nombre y descripción hasta que se usa | Solo al usarlo |
| Ejemplo del curso | Stack, órdenes, «no hagas push» | Reglas del esquema de acciones.json | /nueva-accion renombrar-capturas |
| Dónde | AGENTS.md (raíz) | .opencode/skills/<nombre>/SKILL.md | .opencode/commands/<nombre>.md |
Regla rápida: lo que debe saber siempre → AGENTS.md; lo que debe saber a veces → skill; lo que tú pides a menudo → comando. Y los tres se suben a git.
MCP: enchufes para herramientas externas
El Model Context Protocol (MCP) es un estándar para conectar un agente con herramientas de fuera: documentación actualizada de librerías, un navegador, una base de datos… Cada servidor MCP es un enchufe que añade herramientas nuevas (se llaman servidor_herramienta). OpenCode es el cliente; tú decides qué enchufas.
{ "$schema": "https://opencode.ai/config.json", "mcp": { "context7": { "type": "remote", "url": "https://mcp.context7.com/mcp", "enabled": false }, "apuntes": { "type": "local", "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "./docs"], "enabled": false } }}Dos tipos
- remote: un servidor en Internet; lleva
url(y si hace falta,headers). - local: un programa que se arranca en tu equipo;
commandes un array (["npx", "-y", …]), nunca una cadena: si no, OpenCode no arranca. enabled: false: definido pero apagado. Lo enciendes cuando lo necesitas.
opencode mcp list # estado de cada servidorEn la TUI, /mcps los lista y la barra espaciadora los enciende o apaga.
enabled: false y se activa solo cuando hace falta (semana 3)."headers": { "CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}" }.Detalle: opencode mcp add escribe en tu config global, aunque estés dentro del proyecto. Si quieres el MCP en el proyecto, edita su opencode.json a mano.
El flujo de trabajo del curso
El mismo en todas las sesiones. Si te saltas un paso, lo notarás (y se notará en tus commits).
- 01Tú
Escribe la intención
Spec, entrada de acciones.json o criterio de aceptación. Qué quieres y cómo sabrás que está bien.
docs/spec.md - 02Plan
Pide un plan
Tab a plan: «explícame cómo lo harías y qué ficheros tocarías». Lo lees y lo corriges.
Tab → plan - 03Build
Que lo haga
Tab a build: «hazlo». Apruebas cada edición y cada orden leyendo el diff.
Tab → build - 04Tú
Audita
Lee el código y prueba en ~/pruebas-tareas con --simular y casos feos. Si sale mal: /undo o le explicas el fallo.
!uv run tareas … - 05Tú
Commit pequeño
git add + git commit con un mensaje que cuenta el paso. Guarda el prompt clave en docs/prompts.md (o /export).
git commit - 06Tú
Sesión nueva
Una sesión por tarea (/new) y /compact si la conversación se alarga.
/new
Buenas prácticas con modelos locales
- Tareas pequeñas: una orden, una función, un error. Nunca «hazme la CLI entera».
- Una sesión por tarea (
/new): menos ruido, menos errores. - Plan antes de build: corregir un plan cuesta segundos; corregir código, horas.
- Lee cada diff antes de aceptarlo. Si no lo entiendes, pregunta antes de aceptar.
- Adjunta solo los ficheros necesarios con
@, no «lee todo el proyecto». /compactcuando la conversación se alargue.- Commits pequeños hechos por ti, con mensajes que cuentan el paso.
- Guarda tus prompts clave en
docs/prompts.md(o/export).
Seguridad
- Secretos: las claves solo en variables de entorno. Nunca en el código, en
opencode.jsonni en el chat. .enven el.gitignoreantes del primer commit; el agente tiene prohibido leerlo.- Permisos del proyecto siempre activos:
edit: ask, bash en ask,rm/sudo/git pushen deny. - Nunca
--auto. - Nunca en carpetas reales: las acciones de tu CLI se prueban en
~/pruebas-tareasy con--simular. - No abras OpenCode en tu carpeta personal (
~): ábrelo dentro del proyecto.
Tu ruta con OpenCode en el curso
No se aprende todo el primer día. Cada semana del proyecto 2 añade una pieza. En semipresencial, las semanas 1 y 2 son la quincena 3 y las semanas 3 y 4, la quincena 4.
| Semana | Qué aprendes de OpenCode |
|---|---|
Semana 1 26-30 oct Sesión 1 · Arranque → |
|
Semana 2 2-6 nov Sesión 2 · acciones.json y el motor → |
|
Semana 3 avance |
|
Semana 4 avance |
|
Más adelante en el curso
Código JavaScript/TypeScript que reacciona a lo que hace el agente: por ejemplo, impedir que lea ciertos ficheros.
Le das al agente herramientas nuevas escritas por ti en .opencode/tools/.
Sin interfaz: un script o la CI le pasa una tarea. Siempre con permisos exactos (nunca --auto) y con un tiempo máximo, porque si el servidor no responde reintenta sin fin.
El agente responde a comentarios en issues y PR de GitHub. Ojo: los servidores de GitHub no llegan a la red del centro.
Errores típicos y soluciones
Antes de pedir ayuda, busca aquí el síntoma. Para diagnosticar casi todo: opencode debug config.
| Síntoma | Causa probable | Solución |
|---|---|---|
| opencode: command not found (o «no se reconoce» en Windows) | La terminal se abrió antes de instalar y no tiene el PATH nuevo; o la instalación de npm no está en el PATH. | Cierra y abre la terminal. Linux/macOS: el script instala en ~/.opencode/bin. Windows: comprueba npm install -g y abre una terminal nueva. |
| opencode --version no dice 1.18.35 | Lo instalaste con brew, pacman u otro gestor que trae OpenCode 2, o se actualizó. | Desinstala esa versión e instala con el script o npm fijando 1.18.35; deja "autoupdate": false. |
| opencode models centro no muestra nada | La config no está en ~/.config/opencode/opencode.json, el JSON tiene un error o el id del proveedor no es centro. | opencode debug config para ver qué config lee; revisa la ruta y el nombre. |
| opencode run se queda reintentando sin fin | El servidor no responde: URL mal escrita, falta /v1, no estás en la red del centro o el servidor está caído. | Ctrl+C. Revisa CENTRO_IA_URL (termina en /v1) y que estás en la red del aula; si sigue, avisa al profesor. |
| Error 401/403 o «clave no válida» | La variable no existe en esa terminal: {env:VAR} se sustituye por una cadena vacía. Falta export, o la terminal es anterior al setx. | echo $CENTRO_IA_KEY (bash) o echo $env:CENTRO_IA_KEY (PowerShell). Si sale vacío: export en ~/.bashrc o setx, y terminal NUEVA. |
| Expected array, got "npx …" mcp.x.command y no arranca | El command de un MCP local está escrito como cadena. | "command": ["npx", "-y", "paquete"]: siempre un array. |
| bad file reference: "{file:…}" … does not exist | Usas {file:…} apuntando a un fichero que no existe: OpenCode se niega a arrancar. | Crea el fichero o corrige la ruta. En el curso usamos {env:…}, no {file:…}. |
| V2 permissions are not supported by OpenCode V1 | Has copiado configuración de OpenCode 2 ("permissions" en plural). | Claves en singular: permission, agent, provider, command, mcp. |
| Mis agentes o proveedores no aparecen | Están bajo "agents" o "providers" (claves V2): la 1.18 las ignora sin avisar. | Renómbralas a agent y provider. |
| /undo no revierte los ficheros | El proyecto no es un repositorio git (o no tiene commits). | git init, git add y un primer commit antes de abrir OpenCode. |
| He cambiado la config y no hace caso | La configuración no se recarga en caliente. | Sal de OpenCode y vuelve a abrirlo. |
| Se ejecutó algo que creía prohibido | Una regla "*": "allow" posterior (otra config o el agente) gana a tu deny. | Pon los deny al final del bloque; compruébalo con opencode debug agent build. |
| Una skill no aparece en /skills | name distinto de la carpeta, sin description, o frontmatter mal escrito. | opencode debug skill y revisa el frontmatter. |
| Pregunta permiso para todo | bash con "*": "ask" y pocas excepciones. | Es lo esperado al principio. Añade allow solo para órdenes seguras, o responde always en la sesión. |
| Respuestas cortadas o «context length exceeded» | Conversación muy larga o demasiados MCP y skills cargados. | /compact o /new; desactiva los MCP que no uses. |
| En Linux no puedo copiar ni pegar | Falta la utilidad de portapapeles. | xclip o xsel (X11), wl-clipboard (Wayland). |
opencode debug config # config final fusionada (claves enmascaradas)opencode debug agent build # permisos efectivos de un agenteopencode debug skill # skills que encuentraopencode mcp list # estado de los MCPEnlaces
Documentación oficial: opencode.ai/docs. Ya describe la versión 1.19, pero lo esencial coincide con la 1.18.35 de clase. No sigas la documentación de OpenCode 2 (/v2/docs) ni los tutoriales con claves en plural.
