Parte 4 de 4
Reglas de opencode para Windows y desarrollo
Creamos dos archivos de reglas que guían a opencode: uno para PowerShell/Windows y otro para el entorno de desarrollo portátil en J:, con encoding UTF-8, módulos y flujo Git adaptado a solitario.
Con las partes 1-3 tenía opencode portable corriendo en el SSD con OmniRoute y OpenRouter. Pero el asistente no conocía mi entorno: dónde está Python, que estoy en PowerShell, qué herramientas usa cada proyecto. La solución fue escribir dos archivos de reglas que opencode carga al arrancar y sigue automáticamente.
1. Dónde viven las reglas en opencode
En la instalación portable, la config vive en J:\opencode\xdg\config\opencode\. Opencode carga automáticamente los archivos .md de la carpeta rules:
New-Item -ItemType Directory -Path "J:\opencode\xdg\config\opencode\rules" -Force
Dividí el comportamiento en dos archivos con responsabilidades distintas:
J:\opencode\xdg\config\opencode\rules\
├── windows_rules.md ← entorno y terminal (PowerShell, rutas, encoding)
└── development_rules.md ← ecosistemas dev (Node, Python, Git, env vars)
Descarga las reglas
Te dejo el paquete con ambos archivos listos para copiar a J:\opencode\xdg\config\opencode\rules\:
2. Windows rules: la base
El primer archivo arrancó con lo esencial: estoy en Windows nativo con PowerShell y nunca debo usar comandos Unix. La tabla de traducción Unix → PowerShell fue la pieza central:
| ❌ MAL (Unix) | ✅ BIEN (PowerShell) |
|---|---|
ls -la o ll |
Get-ChildItem -Force |
touch archivo.txt |
New-Item -ItemType File -Name archivo.txt |
mkdir -p dir/subdir |
New-Item -ItemType Directory -Force -Path dir\subdir |
rm -rf carpeta |
Remove-Item -Recurse -Force carpeta |
grep "texto" archivo.txt |
Select-String -Pattern "texto" -Path archivo.txt |
comando1 && comando2 |
comando1 ; comando2 |
Regla de encadenamiento: en PowerShell 5.1
&&y||daban error de sintaxis; el punto y coma era la única opción portable. Esto cambió con PowerShell 7 (lo vemos en la sección 6).
Además dejé fijadas las reglas de eficiencia: respuestas cortas, agrupar comandos en una sola petición, lectura selectiva (nunca leer un archivo entero de más de 300 líneas) y no devolver archivos completos cuando solo cambian unas líneas.
3. Ampliar con PowerShell específico
La base no bastaba. Añadí diez subsecciones con el PowerShell útil para el día a día:
- 3.1 Rutas:
\nativo y comillas dobles si hay espacios ("C:\Program Files\app") - 3.2 Variables de entorno:
$env:NOMBRE(no$NOMBREni%NOMBRE%) - 3.3 Encoding: default UTF-16; forzar UTF-8 (ver lección en sección 5)
- 3.4 Errores:
$?,$LASTEXITCODE,try/catch,-ErrorAction Stop - 3.5 Pipeline: objetos .NET,
Where-Object,Select-Object,ForEach-Object - 3.6 Alias:
gci,ni,ri,cp,mv,cat,ps,kill - 3.7 Directorio de trabajo:
Set-Location,Push-Location/Pop-Location - 3.8 Comillas: dobles expanden
$(...), simples son literales - 3.9 Comparadores:
-eq,-like,-match,-contains,-incon sufijos c/i - 3.10 Background:
Start-Process,Start-Job,Start-ThreadJob
4. Reestructurar para localizar rápido
Con 13 subsecciones, navegar a pelo era lento. Reestructuré el archivo con una tabla de contenidos con anclas al principio:
## Tabla de contenidos
1. [Principios Generales](#1-principios-generales)
2. [Comandos Básicos (Unix → PowerShell)](#2-comandos-básicos-unix--powershell)
3. [PowerShell Específico](#3-powershell-específico)
- 3.1 [Rutas y Separadores](#31-rutas-y-separadores)
- ...
Cada sección ahora tiene su número y su ancla: el asistente localiza “encoding” o “background jobs” con un vistazo, sin leer el archivo entero.
5. Añadir ayuda y módulos (lo esencial de verdad)
Revisando el archivo, faltaban dos cosas que uso a diario aunque parezcan avanzadas:
- 3.11 Sistema de ayuda:
Get-Help comando -Full,-Examples,-Online,Update-Help - 3.12 Módulos:
Get-Module -ListAvailable,Import-Module,Install-Module,Find-Module
Lección: en PowerShell 5.1
-Encoding utf8crea BOM
Set-ContentyOut-File -Encoding utf8escriben UTF-8 con BOM, y herramientas modernas (Vite, Astro, Svelte) fallan con esos archivos. La solución portable: usar el método de .NET[IO.File]::WriteAllText("archivo", "texto"), que genera UTF-8 sin BOM por defecto. Otra corrección del mismo repaso: al lanzar servidores de desarrollo en background hay que redirigir la salida a un log (o a$null) para que la terminal no se quede bloqueada. Con PowerShell 7 esto dejó de ser un problema de BOM (lo vemos ahora).
6. Migración a PowerShell 7
Instalé PowerShell 7 y el escenario cambió a mejor:
- Encoding 3.3: ahora
Set-Content/Out-File -Encoding utf8generan UTF-8 sin BOM por defecto — el workaround de[IO.File]::WriteAllTextdejó de ser necesario - Encadenamiento:
&&y||funcionan de forma nativa en PS7+;;queda como opción de máxima compatibilidad - 3.13 novedades: pipeline chain operators, ternary
cond ? a : b, null coalescing??,$PSVersionTable.PSEdition = "Core", cross-platform, mejor rendimiento (.NET 6+)
Actualicé la sección 2 y el 3.3 para reflejar el nuevo entorno, manteniendo nota de 5.1 para no perder compatibilidad si un día tenemos que tocar una máquina antigua.
7. Development rules: el entorno de desarrollo
El segundo archivo ataca el mismo problema pero para código: qué tooling esperar en cada tecnología y cómo trabajar sin saturar la terminal.
Node.js y frontend:
- Instalaciones silenciosas siempre:
npm install paquete --no-fund --no-audit --loglevel=error - Binarios con
npx(nunca-gsalvo que se pida):npx astro add tailwind,npx svelte-check - Servidores de desarrollo (
npm run dev) bloquean la terminal → técnica background delwindows_rules.mdo avisar al usuario
Calidad y testing (secciones 2.4 y 2.5): detectar qué usa el proyecto (lint, format, typecheck), ejecutarlos obligatoriamente tras tocar código, y si un test falla, corregir el código real — nunca retocar un test para hacerlo pasar.
Python (entorno portátil J:): llamar siempre al ejecutable directo, sin activar venvs:
| Contexto | Comando/Ruta |
|---|---|
| Global | J:\Python\python.exe script.py |
| Venv local | .\venv\Scripts\python.exe script.py |
| Instalar (quiet) | .\venv\Scripts\python.exe -m pip install -q paquete |
Con instalación de entornos, requirements.txt, pyproject.toml + pip-tools y pip freeze > requirements.txt.
Variables de entorno: .env local no commiteado, .env.example versionado con claves dummy, carga con dotenv o node --env-file=.env (Node 20.6+), y nunca hardcodear secretos.
8. Git adaptado a un desarrollador solitario
La primera versión aplicaba un flujo de equipo (rama protegida, PRs obligatorios, squash). Para mi trabajo en solitario era demasiado restrictivo. Lo adapté:
- 4.1 Flujo ágil / solo dev: commits y pushes directos a
mainpara iteraciones rápidas; ramas separadas solo para features grandes que puedan romper la app; integración congit merge(idealmente--ff-onlyo con rebase previo) para historial lineal - 4.2 Hooks: si el
pre-commit(lint + format + typecheck) o elcommit-msgfallan, nunca usar--no-verify— leer el error, corregir y reintentar el commit limpio
Problemas y lecciones
Lección: las reglas evolucionan con el entorno
El BOM en UTF-8 solo era un problema en PowerShell 5.1. Al migrar a PS7, la regla (y el workaround recomendado) dejaron de tener sentido. Los archivos de reglas no son estáticos: se revisan cada vez que cambia la herramienta, no al revés.
Lección: separar responsabilidades entre reglas
windows_rules.mdhabla de cómo se ejecuta (PowerShell, rutas, encoding);development_rules.mdde qué se ejecuta (npm, Python, Git). Mantenerlos separados hace que cada archivo sea plano, corto y de una sola idea.
Lección: lo “avanzado” es lo cotidiano
Get-HelpyImport-Moduleparecían de manual avanzado, pero son los dos comandos que uso prácticamente a diario. Priorizamos reglas por frecuencia de uso, no por nivel de complejidad.
Cierre
Con estos dos archivos, opencode sabe en qué entorno vive y cómo trabajar eficientemente: comandos PowerShell correctos, encoding UTF-8 fiable, tooling del proyecto detectado antes de ejecutar nada, y un flujo Git pensado para desarrollo en solitario. Y como buen ciudadano del SSD: todo vive en J:\opencode\xdg\config\opencode\rules\, listo para moverse de PC sin arrastrar configuración del host.
La serie sigue viva: el asistente ya conoce el sistema operativo y el ecosistema de desarrollo. En la siguiente parte, cualquier ajuste específico que vaya surgiendo sobre el camino lo documentaremos igual.