<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Blog — Tom Girou</title><description>Notas das trincheiras sobre PHP, Symfony, PrestaShop, CI/CD e colocar software em produção — por Tom Girou, Senior Lead Dev.</description><link>https://tom-girou.dev/</link><language>pt</language><item><title>Três strings e dois fallbacks: integrando a share sheet nativa ao Forgemage.net</title><link>https://tom-girou.dev/pt/blog/forgemage-native-share-sheet/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/forgemage-native-share-sheet/</guid><description>O botão de compartilhar na página de detalhe de pedido do Forgemage.net abre a share sheet do sistema onde quer que o sistema operacional tenha uma — Android, iOS, Windows, macOS —, copia o link onde não tem, e fica quieto quando você simplesmente muda de ideia. Aqui está a implementação inteira: navigator.share com três strings, uma guarda de AbortError que deixa cair em vez de capturar, um fallback de clipboard com um fallback de execCommand por baixo, e o detalhe de uma letra no Symfony que decide se o link compartilhado funciona ou não.</description><pubDate>Thu, 27 Aug 2026 00:00:00 GMT</pubDate><category>JavaScript</category><category>Web Share API</category><category>Symfony</category><category>Twig</category><category>Progressive Enhancement</category></item><item><title>Cada novo forjamago deixava a busca mais lenta: matando o N+1 por trás do Forgemage.net</title><link>https://tom-girou.dev/pt/blog/forgemage-search-n1-queries/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/forgemage-search-n1-queries/</guid><description>O diretório de forjamagos do Forgemage.net rodava umas sete queries por card — reviews, tempo de resposta, status online, três relações lazy — além de contadores de facetas recalculados a cada mudança de filtro. Veja como levei uma página de 24 cards de ~168 queries para um punhado, com um cache em batch escopado à request e uma passada paginate-then-hydrate, sem mexer nas páginas de perfil individuais.</description><pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate><category>Symfony</category><category>Doctrine</category><category>PHP</category><category>Performance</category><category>N+1</category></item><item><title>Markdown for Agents, self-hosted: um subscriber Symfony no lugar de um plano da Cloudflare</title><link>https://tom-girou.dev/pt/blog/markdown-for-agents/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/markdown-for-agents/</guid><description>A Cloudflare converte páginas em markdown para agentes de IA via Accept: text/markdown — nos planos pagos. O mesmo contrato HTTP cabe num event subscriber Symfony de 144 linhas. Minha homepage foi de 59 KB de HTML para 7,7 KB de markdown, na mesma URL.</description><pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate><category>Symfony</category><category>PHP</category><category>AI Agents</category><category>HTTP</category><category>SEO</category></item><item><title>Claude Code pelo celular: Tailscale, Termius e a máquina inteira no bolso</title><link>https://tom-girou.dev/pt/blog/claude-code-from-my-phone/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/claude-code-from-my-phone/</guid><description>O /remote-control do Claude Code espelha uma sessão no seu celular. SSH via Tailscale te entrega a workstation inteira: retomar sessões, abrir novas em qualquer repo, acompanhar logs, reiniciar containers — sem nada exposto à internet.</description><pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate><category>Claude Code</category><category>Tailscale</category><category>SSH</category><category>Android</category><category>Workflow</category></item><item><title>RepoWrapped: um Spotify Wrapped para um repo do GitHub, e a API que brigou comigo</title><link>https://tom-girou.dev/pt/blog/repo-wrapped/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/repo-wrapped/</guid><description>Uma ideia de fim de semana — uma página de stats compartilhável e um badge de README para qualquer repo e contributor do GitHub — virou uma briga com a API de stats do GitHub: 202 que nunca se resolvem, um muro no top 100 e um lookup do primeiro commit que você precisa arrancar de um header.</description><pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate><category>Laravel</category><category>PHP</category><category>GitHub API</category><category>Caching</category><category>Side Project</category></item><item><title>Deixando PMs não técnicos consultarem a codebase em linguagem natural</title><link>https://tom-girou.dev/pt/blog/ai-codebase-portal-for-pms/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/ai-codebase-portal-for-pms/</guid><description>Por que construí um analista de IA somente leitura que permite a gerentes de projeto fazer perguntas sobre uma codebase e ter um ticket no Jira criado automaticamente — e por que a coisa toda só funciona porque a IA pode ler, mas nunca escrever.</description><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><category>Claude</category><category>Agent SDK</category><category>Developer Tools</category><category>Jira</category><category>PrestaShop</category></item><item><title>Adicionando code review por IA a um GitLab self-hosted — sem entregar as chaves</title><link>https://tom-girou.dev/pt/blog/claude-gitlab-ai-review/</link><guid isPermaLink="true">https://tom-girou.dev/pt/blog/claude-gitlab-ai-review/</guid><description>Como integrei o Claude ao pipeline de merge requests de um GitLab self-hosted antigo, e por que todo o design depende de nunca deixar a IA ler um diff não confiável e ter um token ao mesmo tempo.</description><pubDate>Wed, 24 Jun 2026 00:00:00 GMT</pubDate><category>CI/CD</category><category>GitLab</category><category>Claude</category><category>Code Review</category><category>Security</category></item></channel></rss>