<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Granda | Ideas &amp; Code</title><link>https://granda.org/es/</link><description>Recent content on Granda | Ideas &amp; Code</description><generator>Hugo</generator><language>es</language><lastBuildDate>Fri, 13 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://granda.org/es/index.xml" rel="self" type="application/rss+xml"/><item><title>Tu Tesla Aparcado Es un Centro de Datos</title><link>https://granda.org/es/2026/03/13/tu-tesla-aparcado-es-un-centro-de-datos/</link><pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/03/13/tu-tesla-aparcado-es-un-centro-de-datos/</guid><description>&lt;p&gt;Tu coche está aparcado el 95% del tiempo. Dentro hay un chip capaz de 300-500 billones de operaciones por segundo, conectado a refrigeración, conversión de energía y una radio celular. No hace nada.&lt;/p&gt;
&lt;p&gt;Tesla y xAI quieren cambiar eso. El 11 de marzo, Elon Musk &lt;a href="https://www.cnbc.com/2026/03/11/musk-unveils-joint-tesla-xai-project-macrohard.html"&gt;presentó &amp;ldquo;Macrohard&amp;rdquo;&lt;/a&gt; — llamado internamente Digital Optimus — un proyecto conjunto que convierte los Tesla aparcados en agentes de IA personales. No chatbots. Agentes que observan tu pantalla, controlan tu ratón y teclado, y realizan trabajo real.&lt;/p&gt;</description></item><item><title>QA Visual como Etapa del Pipeline de CI</title><link>https://granda.org/es/2026/02/06/qa-visual-como-etapa-del-pipeline-de-ci/</link><pubDate>Fri, 06 Feb 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/02/06/qa-visual-como-etapa-del-pipeline-de-ci/</guid><description>&lt;p&gt;Fusioné un PR el mes pasado. La revisión de código se veía bien. Los tests pasaron. Luego abrí el sitio en mi teléfono y la barra lateral estaba completamente rota.&lt;/p&gt;
&lt;p&gt;La solución fue trivial—faltaba una media query. El bug era obvio una vez que realmente mirabas la vista móvil. Nadie lo hizo.&lt;/p&gt;
&lt;p&gt;Así que añadí una etapa del pipeline que mira.&lt;/p&gt;
&lt;p&gt;Abro un issue de GitHub que dice:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Implementar la opción de Entrada Manual para añadir clientes. Al hacer clic, abre un drawer deslizante ancho con un formulario para crear un nuevo cliente.&lt;/p&gt;</description></item><item><title>¿Para Quién Es Agent Trace?</title><link>https://granda.org/es/2026/01/30/para-qui%C3%A9n-es-agent-trace/</link><pubDate>Fri, 30 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/01/30/para-qui%C3%A9n-es-agent-trace/</guid><description>&lt;p&gt;Cursor lanzó &lt;a href="https://github.com/cursor/agent-trace"&gt;Agent Trace&lt;/a&gt;, una especificación abierta para rastrear qué código en un repositorio fue escrito por un LLM. Registra el modelo, la herramienta, la conversación y los rangos de línea exactos, todo añadido a un archivo JSONL en tu proyecto.&lt;/p&gt;
&lt;p&gt;La propuesta: &amp;ldquo;A medida que los agentes escriben más código, es importante entender qué provino de la IA versus los humanos.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Pasé tiempo leyendo la especificación y la implementación de referencia. La ingeniería es sólida: esquema limpio, extensibilidad bien pensada, buena lista de socios (Amp, Amplitude, Cloudflare, Cognition, Google, Vercel). Pero seguía volviendo a una pregunta: ¿qué &lt;em&gt;haces&lt;/em&gt; con estos datos?&lt;/p&gt;</description></item><item><title>Darse de baja</title><link>https://granda.org/es/unsubscribe/</link><pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/unsubscribe/</guid><description>&lt;p id="unsubscribe-message"&gt;Procesando...&lt;/p&gt;
&lt;script&gt;
(function() {
 const params = new URLSearchParams(window.location.search);
 const msg = document.getElementById('unsubscribe-message');

 if (params.get('success') === 'true') {
 msg.textContent = 'Te has dado de baja del boletín informativo.';
 } else if (params.get('error') === 'missing') {
 msg.textContent = 'Error: No se proporcionó el token de baja.';
 } else if (params.get('error') === 'invalid') {
 msg.textContent = 'Error: Enlace de baja no válido.';
 } else {
 msg.textContent = 'Error: Ocurrió un error desconocido.';
 }
})();
&lt;/script&gt;</description></item><item><title>Enlaces Enriquecidos para Desarrolladores Perezosos</title><link>https://granda.org/es/2026/01/10/enlaces-enriquecidos-para-desarrolladores-perezosos/</link><pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/01/10/enlaces-enriquecidos-para-desarrolladores-perezosos/</guid><description>&lt;p&gt;Cuando comparto un enlace de mi blog en Twitter o Slack, aparece como texto plano. Sin imagen de vista previa. Solo una URL como &lt;a href="https://granda.org/en/2026/01/02/claude-code-on-the-go/"&gt;granda.org/en/2026/01/02/claude-code-on-the-go/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Necesitaba imágenes Open Graph. El enfoque estándar: crear manualmente una imagen de 1200x630 para cada entrada. Eso es tedioso. Le pedí a Claude que lo automatizara.&lt;/p&gt;
&lt;div class="desktop-only"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart LR
 Push[git push] --&amp;gt; GHA[GitHub Actions]
 GHA --&amp;gt; Hugo[Hugo Server]
 GHA --&amp;gt; PW[Playwright]
 PW --&amp;gt;|screenshot| Hugo
 PW --&amp;gt; IMG[OG Image]
 IMG --&amp;gt; Commit[git commit]
 Commit --&amp;gt; Deploy[Deploy]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="mobile-only"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart TB
 Push[git push] --&amp;gt; GHA[GitHub Actions]
 GHA --&amp;gt; Hugo[Hugo Server]
 GHA --&amp;gt; PW[Playwright]
 PW --&amp;gt;|screenshot| Hugo
 PW --&amp;gt; IMG[OG Image]
 IMG --&amp;gt; Commit[git commit]
 Commit --&amp;gt; Deploy[Deploy]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="la-configuración"&gt;La Configuración&lt;/h2&gt;
&lt;p&gt;Le expliqué el problema a Claude: las entradas necesitan imágenes de vista previa social, pero no quiero crearlas manualmente. Captura el contenido del artículo, guárdalo como imagen OG, actualiza el frontmatter automáticamente.&lt;/p&gt;</description></item><item><title>Mi Ingeniero de QA es un LLM</title><link>https://granda.org/es/2026/01/09/mi-ingeniero-de-qa-es-un-llm/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/01/09/mi-ingeniero-de-qa-es-un-llm/</guid><description>&lt;p&gt;Claude puede hacer clic en botones.&lt;/p&gt;
&lt;p&gt;Suena trivial, pero cambia cómo construyo interfaces de usuario. Con Playwright MCP, Claude no solo escribe código—abre un navegador, navega a localhost y verifica que las cosas realmente funcionen. Detecta errores que pasaría por alto en revisiones de código.&lt;/p&gt;
&lt;h2 id="la-configuración"&gt;La Configuración&lt;/h2&gt;
&lt;p&gt;Playwright MCP le da a Claude automatización de navegador. Lo ejecuto con Chromium sin interfaz gráfica:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;playwright&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;npx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;@anthropic-ai/mcp-server-playwright&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--headless&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ahora Claude puede navegar, hacer clic, escribir y tomar capturas de pantalla. Ve lo que los usuarios ven.&lt;/p&gt;</description></item><item><title>Creando Mi Propio Boletín con Claude</title><link>https://granda.org/es/2026/01/07/creando-mi-propio-bolet%C3%ADn-con-claude/</link><pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/01/07/creando-mi-propio-bolet%C3%ADn-con-claude/</guid><description>&lt;p&gt;Segundo día del pico de tráfico de Hacker News. Cuarenta mil visitantes, sin forma de contactarlos nuevamente. Necesitaba un formulario de suscripción para el boletín.&lt;/p&gt;
&lt;p&gt;Revisé Buttondown, Beehiiv, Substack, ConvertKit. Todo era excesivo. Solo necesitaba recopilar correos electrónicos. No necesitaba campañas, análisis ni gestión de suscriptores. Y quería ser dueño de mis datos.&lt;/p&gt;
&lt;p&gt;Así que le pedí a Claude que lo construyera.&lt;/p&gt;
&lt;div class="desktop-only"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart LR
 User([User]) --&amp;gt; Form[Newsletter Form]
 Form --&amp;gt;|POST /api/subscribe| Worker[Cloudflare Worker]
 Worker --&amp;gt; KV[(Cloudflare KV)]
 KV -.-&amp;gt;|Daily sync| GHA[GitHub Actions]
 GHA -.-&amp;gt; Repo[(subscribers.jsonl)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="mobile-only"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart TB
 User([User]) --&amp;gt; Form[Newsletter Form]
 Form --&amp;gt;|POST /api/subscribe| Worker[Cloudflare Worker]
 Worker --&amp;gt; KV[(Cloudflare KV)]
 KV -.-&amp;gt;|Daily sync| GHA[GitHub Actions]
 GHA -.-&amp;gt; Repo[(subscribers.jsonl)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="la-configuración"&gt;La Configuración&lt;/h2&gt;
&lt;p&gt;Le di a Claude un token de API de Cloudflare a través de una variable de entorno y describí lo que quería: un formulario que recopile correos electrónicos y los almacene en un lugar que yo controlo.&lt;/p&gt;</description></item><item><title>Claude Code en Movimiento</title><link>https://granda.org/es/2026/01/02/claude-code-en-movimiento/</link><pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate><guid>https://granda.org/es/2026/01/02/claude-code-en-movimiento/</guid><description>&lt;p&gt;Ejecuto seis agentes de Claude Code en paralelo desde mi teléfono. Sin portátil, sin ordenador de escritorio—solo Termius en iOS y una VM en la nube.&lt;/p&gt;
&lt;h2 id="la-configuración"&gt;La Configuración&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart LR
 A[Phone] --&amp;gt;|Termius + mosh| B[Tailscale VPN]
 B --&amp;gt; C[Vultr VM]
 C --&amp;gt; D[Claude Code]
 D --&amp;gt;|PreToolUse hook| E[Poke webhook]
 E --&amp;gt;|Push notification| A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El ciclo es: iniciar una tarea, guardar el teléfono, recibir notificación cuando Claude necesite información. Desarrollo asíncrono desde cualquier lugar.&lt;/p&gt;</description></item><item><title>Dejando que la IA lo Haga</title><link>https://granda.org/es/2025/12/28/dejando-que-la-ia-lo-haga/</link><pubDate>Sun, 28 Dec 2025 00:00:00 +0000</pubDate><guid>https://granda.org/es/2025/12/28/dejando-que-la-ia-lo-haga/</guid><description>&lt;p&gt;Necesitaba un servidor de desarrollo: VM con acceso SSH y herramientas de desarrollo instaladas. Le describí lo que quería a Claude Code y dejé que se encargara de la configuración.&lt;/p&gt;
&lt;h2 id="el-prompt"&gt;El Prompt&lt;/h2&gt;
&lt;p&gt;Pedí una VM de Vultr con 8 núcleos y 32GB de RAM, accesible solo a través de Tailscale, con sesiones persistentes que sobrevivan caídas de red.&lt;/p&gt;
&lt;h2 id="lo-que-claude-code-construyó"&gt;Lo que Claude Code Construyó&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. Provisionó la VM a través de la API de Vultr&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Traducciones Automáticas del Blog con Claude y GitHub Actions</title><link>https://granda.org/es/2025/12/23/traducciones-autom%C3%A1ticas-del-blog-con-claude-y-github-actions/</link><pubDate>Tue, 23 Dec 2025 00:00:00 +0000</pubDate><guid>https://granda.org/es/2025/12/23/traducciones-autom%C3%A1ticas-del-blog-con-claude-y-github-actions/</guid><description>&lt;p&gt;Cada publicación que escribo se traduce automáticamente. Claude maneja la traducción, confirma los resultados en main, y las versiones traducidas se despliegan junto con la original.&lt;/p&gt;
&lt;h2 id="el-flujo"&gt;El Flujo&lt;/h2&gt;
&lt;p&gt;El flujo de trabajo de traducción se ejecuta en GitHub Actions cuando el contenido en inglés se fusiona a main:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;main]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s1"&gt;&amp;#39;content/**/*.en.md&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-mermaid" data-lang="mermaid"&gt;flowchart LR
 B[Fusionar a main] --&amp;gt; C[Traducciones generadas]
 C --&amp;gt; D[Confirmado en main]
 D --&amp;gt; E[Despliegue a producción con todos los idiomas]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="el-prompt"&gt;El Prompt&lt;/h2&gt;
&lt;p&gt;El flujo de trabajo usa &lt;a href="https://github.com/anthropics/claude-code-action"&gt;claude-code-action&lt;/a&gt;:&lt;/p&gt;</description></item><item><title>Acerca de</title><link>https://granda.org/es/about/</link><pubDate>Mon, 22 Dec 2025 00:00:00 +0000</pubDate><guid>https://granda.org/es/about/</guid><description>&lt;h2 id="resumen"&gt;Resumen&lt;/h2&gt;
&lt;p&gt;Este documento proporciona información general sobre el autor de este blog.&lt;/p&gt;
&lt;h2 id="1-antecedentes"&gt;1. Antecedentes&lt;/h2&gt;
&lt;p&gt;Ingeniero de software con 15 años de experiencia, 10 de ellos trabajando en el campo.
Las áreas de enfoque incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sistemas distribuidos&lt;/li&gt;
&lt;li&gt;Desarrollo backend e infraestructura&lt;/li&gt;
&lt;li&gt;Desarrollo full-stack y de producto de extremo a extremo&lt;/li&gt;
&lt;li&gt;Diseño de interfaz de usuario&lt;/li&gt;
&lt;li&gt;Construcción de sistemas seguros y confiables&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-contacto"&gt;2. Contacto&lt;/h2&gt;
&lt;p&gt;Siempre feliz de conectar con otros en la industria:
&lt;a href="https://x.com/mtt"&gt;@mtt&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Acerca de</title><link>https://granda.org/es/authorship/</link><pubDate>Mon, 22 Dec 2025 00:00:00 +0000</pubDate><guid>https://granda.org/es/authorship/</guid><description>&lt;h2 id="resumen"&gt;Resumen&lt;/h2&gt;
&lt;p&gt;Este documento describe la metodología de autoría empleada en este blog.&lt;/p&gt;
&lt;h2 id="1-introducción"&gt;1. Introducción&lt;/h2&gt;
&lt;p&gt;Este blog se genera en gran medida con la asistencia de Modelos de Lenguaje de Gran Escala (LLMs). El autor proporciona dirección, edición y control de calidad; la máquina proporciona borradores iniciales y traducciones.&lt;/p&gt;
&lt;h2 id="2-justificación"&gt;2. Justificación&lt;/h2&gt;
&lt;p&gt;El autor cree en la transparencia con respecto a la creación de contenido asistida por AI. En lugar de ocultar las herramientas utilizadas, esta divulgación tiene como objetivo:&lt;/p&gt;</description></item><item><title>Hola Mundo</title><link>https://granda.org/es/2025/12/20/hola-mundo/</link><pubDate>Sat, 20 Dec 2025 00:00:00 +0000</pubDate><guid>https://granda.org/es/2025/12/20/hola-mundo/</guid><description>&lt;p&gt;¡Bienvenidos a mi blog! Esta es mi primera publicación.&lt;/p&gt;
&lt;p&gt;Aquí compartiré ideas, notas y cosas que me parecen interesantes.&lt;/p&gt;</description></item></channel></rss>