Saltar al contenido
Aula en la nube
Guía del curso · OpenCode

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.

OpenCode 1.18.35
la versión de clase
Modelos del centro
nada sale del instituto
Tú decides
permisos y diffs
Todo el curso
del proyecto 2 en adelante

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

no: otra vueltasímuchasvueltastú: sí / noTú pides«añade la orden listar»Planificaqué mirar, qué cambiarUsa una herramientaread · grep · edit · bashVe el resultadocontenido, diff, salida¿Ha terminado?compara con lo pedidoTe pide permisosi la regla es askTermina y te avisatú revisas y decides

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.

HerramientaQué haceDicho de otra forma
readLee un fichero (o un trozo).Como abrirlo en el editor para mirarlo.
globBusca ficheros por nombre o patrón: src/**/*.py.Como el buscador de ficheros.
grepBusca texto dentro de los ficheros.Como Ctrl+Shift+F en VS Code.
editCambia unas líneas concretas de un fichero que ya existe.Te enseña el diff antes de aplicarlo (si está en ask).
writeCrea un fichero nuevo o lo reescribe entero.Lo controla el mismo permiso que edit.
bashEjecuta una orden en la terminal: uv run, git status, ls…La más potente y la más peligrosa: por eso pregunta.
webfetchDescarga una página web y la lee.En el proyecto, siempre pregunta antes.
taskLanza un subagente (general, explore o uno tuyo) para una subtarea.Trabaja en una sesión hija y te devuelve un resumen.
todowriteMantiene una lista de pasos pendientes y hechos.Verás la lista tachándose mientras trabaja.
skillCarga una skill (conocimiento extra) cuando la necesita.Solo carga la que le sirve, no todas.
questionTe hace una pregunta con opciones cuando duda.Respóndela: es mejor que dejarle adivinar.
Qué cambia para ti. Ya no escribes cada línea, pero sigues siendo quien decide qué se hace, quien revisa cada diff y cada orden antes de aceptarla, y quien responde de lo que entrega. Si el agente mete un fallo y tú lo aceptas, el fallo es tuyo. Lo que no sabes explicar, no lo entregas.

Por qué OpenCode (y por qué modelos del centro)

Open source

Código abierto: puedes ver cómo funciona y no depende de una suscripción.

En la terminal

Funciona igual en Linux, Windows y macOS, y dentro de la terminal integrada de VS Code.

Cualquier proveedor

Se conecta a decenas de proveedores… y a un servidor propio como el del centro.

Agentes y permisos a tu medida

Defines qué puede hacer solo, qué te pregunta y qué nunca hará.

El mismo concepto que la industria

Claude Code, Codex o el modo agente de Copilot funcionan igual: lo que aprendes aquí, lo usas allí.

Configuración en ficheros

AGENTS.md, comandos, skills y agentes viven en tu repo y viajan con él.

Modelos locales

Privacidad

Tu código, tus ficheros y tus prompts se quedan en el servidor del instituto. No alimentan a ninguna empresa.

Modelos locales

Sin cuentas de pago

No necesitas tarjeta ni suscripción. Te basta la clave que te da el profesor.

Modelos locales

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.

Ojo con la versión. En clase usamos OpenCode 1.18.35 (la línea OpenCode 1). Existe ya OpenCode 2, que cambia la configuración: usa claves en plural (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.

Terminal
curl -fsSL https://opencode.ai/install | bash -s -- --version 1.18.35

Windows nativo

  1. Instala Git for Windows (OpenCode usa Git Bash para ejecutar órdenes).
  2. Instala Node.js LTS (trae npm).
  3. En una terminal nueva de PowerShell:
PowerShell
npm install -g opencode-ai@1.18.35

Windows 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:

Terminal de WSL
curl -fsSL https://opencode.ai/install | bash -s -- --version 1.18.35

Ojo: en WSL las variables de entorno y la config van en el ~ de Linux, no en el de Windows.

Comprueba que está bien

Terminal
opencode --version # debe decir 1.18.35
opencode debug paths # dónde guarda config, datos y logs

Si 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. 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 / zsh
    mkdir -p ~/.config/opencode
    code ~/.config/opencode/opencode.json # o nano
    PowerShell
    New-Item -ItemType Directory -Force "$env:USERPROFILE\.config\opencode"
    notepad "$env:USERPROFILE\.config\opencode\opencode.json"
  2. 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 en model.
    • @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.
    • model y small_model: el modelo de trabajo y el de tareas ligeras (títulos de sesión…). Aquí, el mismo.
  3. 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. 4

    Comprueba la conexión

    Terminal
    opencode models centro # debe salir centro/qwen3.8-flash-next
    opencode debug config # config final; la clave sale enmascarada
    opencode run "Responde solo: hola" # prueba real con el modelo

    Si opencode run se 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.

¿Por qué variables y no la clave escrita en el fichero? Porque así la clave no está en ningún fichero, y por tanto no puede acabar por accidente en un commit, en una captura o en un repo público. Es la misma regla que en tu proyecto: ninguna clave en el repo ni en su historial (es un mínimo del proyecto 2). En la semana 3, tu propia CLI leerá las mismas variables desde Python.
Semipresencial: puedes usar OpenCode en casa, también dentro de la terminal integrada de VS Code. Cómo conectarte desde casa a los modelos del centro lo explica el profesor en la tutoría colectiva de arranque.

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:

Terminal
cd ~/cli-tareas
opencode
  1. 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.
  2. 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.
  3. 3Caja de entrada. Escribes la petición. Intro envía; para un salto de línea, shift+enter o ctrl+j.
  4. 4Barra inferior. Agente activo (Build o Plan) y modelo. Míralo antes de escribir: ¿estás en el agente que quieres?
  5. Esquema simplificado: colores y textos exactos cambian según el tema y la versión.

Lo que puedes escribir en la caja

texto normal

Tu petición, en español. Concreta: qué fichero, qué orden, qué criterio de «terminado».

@fichero

Adjunta un fichero (con búsqueda difusa): @src/tareas/cli.py. También invoca subagentes: @explore ….

!orden

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).

AtajoComandoPara 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/newSesión nueva (una por tarea)
ctrl+x l/sessionsLista de sesiones para retomar una
ctrl+x m/modelsElegir modelo
ctrl+x c/compactResume la conversación para liberar contexto
ctrl+x u/undoDeshace tu último mensaje, sus respuestas y sus cambios en ficheros
ctrl+x r/redoRehace lo deshecho
ctrl+x x/exportExporta la conversación a Markdown
—/initCrea o mejora el AGENTS.md del proyecto
—/reviewRevisa los cambios sin commit (o un commit o rama)
—/skillsExplora las skills que ve el agente
—/mcpsServidores MCP; espacio los activa o desactiva
—/helpAyuda
ctrl+c/exitSalir

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:

Terminal
opencode -c # continúa la última sesión
opencode 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.

AgenteTipoQué puede hacerCuándo
buildprimario (por defecto)Todas las herramientas, con los permisos de tu config.Para hacer: editar, crear, ejecutar.
planprimarioNo puede editar ficheros (salvo sus propios planes). Ojo: de fábrica bash NO está restringido.Para pensar: analizar, proponer, revisar un plan.
generalsubagenteInvestigación y tareas de varios pasos. Puede modificar ficheros.Una subtarea que no quieres que ensucie tu conversación.
exploresubagenteSolo lectura: busca y lee (no edita), aunque puede ejecutar órdenes.«¿Dónde se valida el JSON?», «¿qué usa a motor.py?»
Plan solo bloquea ediciones. El agente plan de fábrica no puede escribir ficheros, pero sí ejecutar órdenes con tus permisos generales. Y si tu configuración dice "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.
Terminal
opencode agent list # agentes cargados
opencode debug agent plan # reglas efectivas de uno

Crea 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:

.opencode/agents/revisor.md
---
description: Revisa el código de la CLI tareas sin modificar nada y señala errores, casos feos y problemas multiplataforma
mode: subagent
temperature: 0.1
permission:
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:

allow

Lo hace sin preguntar.

ask

Se para, te enseña qué va a hacer y espera.

deny

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/.

orden: git diff src/tareas/cli.py
  • "*": askcoincide
  • "git diff *": allowgana ✓
  • "rm *": denyno coincide

Resultado: allow

orden: rm -r build
  • "*": 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.

cli-tareas/opencode.json
{
"$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" } }
}
}
ReglaQué 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).
¿Por qué no está permitido 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.

Nunca uses --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.md en 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»).
cli-tareas/AGENTS.md
# 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, model o subtask: 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.
.opencode/commands/nueva-accion.md
---
description: Añade una acción nueva a acciones.json y, si hace falta, el código que la soporta
agent: build
---
Quiero añadir la acción: $ARGUMENTS
1. 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 /skills en la TUI (o opencode debug skill).
.opencode/skills/acciones-json/SKILL.md
---
name: acciones-json
description: 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.mdSkillComando
Qué esNormas fijas del proyectoConocimiento especializadoUn prompt que repites
Cuándo se cargaSiempre, al empezar cada sesiónSolo cuando el agente decide que le sirveCuando tú escribes /nombre
Quién lo disparaNadie: está siempreEl agente (herramienta skill)Tú
Gasta contextoSiempre: tenlo cortoSolo nombre y descripción hasta que se usaSolo al usarlo
Ejemplo del cursoStack, órdenes, «no hagas push»Reglas del esquema de acciones.json/nueva-accion renombrar-capturas
DóndeAGENTS.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.

opencode.json (bloque mcp)
{
"$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; command es un array (["npx", "-y", …]), nunca una cadena: si no, OpenCode no arranca.
  • enabled: false: definido pero apagado. Lo enciendes cuando lo necesitas.
Terminal
opencode mcp list # estado de cada servidor

En la TUI, /mcps los lista y la barra espaciadora los enciende o apaga.

Gastan contexto. Cada servidor encendido añade la descripción de todas sus herramientas a cada petición. Dos o tres MCP pueden comerse buena parte del contexto y hacer que el agente use peor sus herramientas. Por eso context7 va con enabled: false y se activa solo cuando hace falta (semana 3).
Riesgos. Un MCP local ejecuta código con tus permisos; uno remoto recibe lo que el agente le envía. Solo servidores conocidos y de confianza, y si piden token, nunca en claro: "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).

  1. 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
  2. 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
  3. 03Build

    Que lo haga

    Tab a build: «hazlo». Apruebas cada edición y cada orden leyendo el diff.

    Tab → build
  4. 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 …
  5. 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
  6. 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».
  • /compact cuando 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.json ni en el chat.
  • .env en el .gitignore antes del primer commit; el agente tiene prohibido leerlo.
  • Permisos del proyecto siempre activos: edit: ask, bash en ask, rm/sudo/git push en deny.
  • Nunca --auto.
  • Nunca en carpetas reales: las acciones de tu CLI se prueban en ~/pruebas-tareas y 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.

SemanaQué aprendes de OpenCode
Semana 1
26-30 oct
Sesión 1 · Arranque →
  • Instalar la 1.18.35 y conectarla con los modelos del centro.
  • Antes de abrir OpenCode, a mano: uv init, .gitignore y primer commit (sin git no hay /undo).
  • opencode.json de permisos del proyecto.
  • /init → AGENTS.md, que luego editas tú.
  • plan → build para crear cli.py (version + listar), aprobando diffs; /undo; commits tuyos.
Semana 2
2-6 nov
Sesión 2 · acciones.json y el motor →
  • Tu acciones.json, escrito por ti sin IA.
  • Skill del proyecto acciones-json (compruébala con /skills).
  • Comando personalizado /nueva-accion.
  • Subagente revisor (@revisor) y /review antes de cada commit.
Semana 3
avance
  • MCP: context7 para documentación de librerías, desactivado por defecto y activado solo cuando hace falta.
  • La capa IA de TU CLI llamando desde Python a los mismos modelos del centro (CENTRO_IA_URL / CENTRO_IA_KEY, modo sin red).
Semana 4
avance
  • El agente escribe pruebas que tú auditas.
  • opencode run no interactivo (por ejemplo, en scripts).
  • Release v1.0.

Más adelante en el curso

Plugins

Código JavaScript/TypeScript que reacciona a lo que hace el agente: por ejemplo, impedir que lea ciertos ficheros.

Herramientas propias

Le das al agente herramientas nuevas escritas por ti en .opencode/tools/.

opencode run en scripts

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.

opencode github

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íntomaCausa probableSolució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.35Lo 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 nadaLa 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 finEl 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 arrancaEl command de un MCP local está escrito como cadena."command": ["npx", "-y", "paquete"]: siempre un array.
bad file reference: "{file:…}" … does not existUsas {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 V1Has copiado configuración de OpenCode 2 ("permissions" en plural).Claves en singular: permission, agent, provider, command, mcp.
Mis agentes o proveedores no aparecenEstán bajo "agents" o "providers" (claves V2): la 1.18 las ignora sin avisar.Renómbralas a agent y provider.
/undo no revierte los ficherosEl 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 casoLa configuración no se recarga en caliente.Sal de OpenCode y vuelve a abrirlo.
Se ejecutó algo que creía prohibidoUna 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 /skillsname distinto de la carpeta, sin description, o frontmatter mal escrito.opencode debug skill y revisa el frontmatter.
Pregunta permiso para todobash 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 pegarFalta la utilidad de portapapeles.xclip o xsel (X11), wl-clipboard (Wayland).
Diagnóstico
opencode debug config # config final fusionada (claves enmascaradas)
opencode debug agent build # permisos efectivos de un agente
opencode debug skill # skills que encuentra
opencode mcp list # estado de los MCP

Enlaces

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.