<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>TabNews</title>
        <link>https://www.tabnews.com.br/recentes/rss</link>
        <description>Conteúdos para quem trabalha com Programação e Tecnologia</description>
        <lastBuildDate>Wed, 08 Apr 2026 19:27:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>pt</language>
        <image>
            <title>TabNews</title>
            <url>https://www.tabnews.com.br/favicon-mobile.png</url>
            <link>https://www.tabnews.com.br/recentes/rss</link>
        </image>
        <item>
            <title><![CDATA[Amazon impedirá que Kindles mais antigos comprem e baixem livros da Kindle Store]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/amazon-impedira-que-kindles-mais-antigos-comprem-e-baixem-livros-da-kindle-store</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/amazon-impedira-que-kindles-mais-antigos-comprem-e-baixem-livros-da-kindle-store</guid>
            <pubDate>Wed, 08 Apr 2026 19:27:58 GMT</pubDate>
            <description><![CDATA[A Amazon anunciou que, a partir de 20 de maio, dispositivos Kindle mais antigos deixarão de permitir a compra e o download de livros diretamente pela Kindle Store. A mudança afeta todos o...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A Amazon anunciou que, a partir de 20 de maio, dispositivos Kindle mais antigos deixarão de permitir a compra e o download de livros diretamente pela Kindle Store. A mudança afeta todos os modelos lançados e vendidos até 2012.</p><p>Os usuários ainda poderão acessar e ler os livros que já estiverem armazenados nesses dispositivos, porém não será mais possível baixar novos conteúdos. Além disso, caso o aparelho seja restaurado para as configurações de fábrica, não será mais possível realizar login em uma conta da Amazon.</p><p>Esta é a primeira vez que a empresa descontinua completamente o suporte a modelos antigos da linha Kindle. Entre os dispositivos impactados estão:</p><ul><li>Kindle de 1ª e 2ª geração</li><li>Kindle DX e DX Graphite</li><li>Kindle Keyboard</li><li>Kindle 4</li><li>Kindle Touch</li><li>Kindle 5</li><li>Kindle Paperwhite de 1ª geração</li><li>Tablets Kindle Fire das gerações de 2011 e 2012</li></ul></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Campainha de bicicleta consegue enganar algoritmos de fones de ouvido com cancelamento ativo de ruído]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/campainha-de-bicicleta-consegue-enganar-algoritmos-de-fones-de-ouvido-com-cancelamento-ativo-de-ruido</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/campainha-de-bicicleta-consegue-enganar-algoritmos-de-fones-de-ouvido-com-cancelamento-ativo-de-ruido</guid>
            <pubDate>Wed, 08 Apr 2026 19:08:59 GMT</pubDate>
            <description><![CDATA[A empresa automobilística Škoda apresentou uma campainha de bicicleta capaz de enganar algoritmos de fones de ouvido com cancelamento ativo de ruído. Esses fones funcionam captando sons e...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A empresa automobilística Škoda apresentou uma campainha de bicicleta capaz de enganar algoritmos de fones de ouvido com cancelamento ativo de ruído.</p><p>Esses fones funcionam captando sons externos por meio de microfones e gerando ondas sonoras inversas para anulá-los, o que reduz a percepção do ambiente ao redor. Como consequência, pedestres podem deixar de ouvir alertas importantes, incluindo campainhas tradicionais de bicicleta, o que aumenta o risco de acidentes.</p><p>Para contornar essa limitação, a Škoda desenvolveu a campainha DuoBell, uma solução totalmente analógica e mecânica que emite som em uma faixa entre 750 e 780 Hz, capaz de atravessar os filtros desses fones. O dispositivo também conta com um ressonador adicional ajustado para uma frequência mais alta, ampliando a eficácia do sinal sonoro. Além disso, um mecanismo de martelo produz batidas rápidas e irregulares, gerando ondas sonoras que os algoritmos de cancelamento não conseguem processar com rapidez suficiente para suprimir.</p><p>Em testes, pedestres utilizando fones com cancelamento ativo ganharam até 22 metros adicionais de distância e 5 segundos extras de tempo de reação quando a DuoBell foi acionada.</p><p>Inicialmente, a tecnologia está disponível apenas em Londres, no Reino Unido, mas a Škoda planeja expandi-la globalmente.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Por que é tão difícil gerar um QR Code simples hoje em dia?]]></title>
            <link>https://www.tabnews.com.br/jeancarlodev/por-que-e-tao-dificil-gerar-um-qr-code-simples-hoje-em-dia</link>
            <guid>https://www.tabnews.com.br/jeancarlodev/por-que-e-tao-dificil-gerar-um-qr-code-simples-hoje-em-dia</guid>
            <pubDate>Wed, 08 Apr 2026 18:59:38 GMT</pubDate>
            <description><![CDATA[Como qualquer pessoa normal, quando eu precisava gerar um QR Code, eu fazia o óbvio: abria o Google e digitava: gerador de qrcode. Eu só queria resolver meu problema em 5 minutos. Rápido....]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Como qualquer pessoa normal, quando eu precisava gerar um QR Code, eu fazia o óbvio:</p><p>abria o Google e digitava: gerador de qrcode.</p><p>Eu só queria resolver meu problema em 5 minutos. Rápido. Simples. Sem dor.</p><p>Mas aí começa o inferno:</p><ul><li>Site lento</li><li>“Crie sua conta para continuar”</li><li>“Teste grátis por 7 dias”</li><li>Marca d’água no QR</li><li>Pede cartão pra baixar um PNG</li></ul><p>Tudo isso… pra gerar um quadradinho preto.</p><p>Passei tanta raiva que desisti e fui direto no ChatGPT. Em segundos, resolvido.</p><p>Dias depois, me caiu a ficha:<br>isso não deveria ser difícil assim.</p><p>Então eu fiz o meu próprio gerador.</p><p>Foi exatamente essa frustração que me motivou a criar algo do jeito que deveria ser desde o início.</p><p>Um gerador de QR Code que:</p><ul><li>não pede login</li><li>não pede cadastro</li><li>não pede e-mail</li><li>não tem marca d’água</li><li>gera na hora</li><li>baixa direto</li></ul><p>Simples. Rápido. Funcional.</p><p>Do jeito que sempre deveria ter sido.</p><p>Se você já passou por essa mesma raiva, isso aqui é pra você:<br><a href="https://quickeasy.tools/pt/tools/qr-code-generator" rel="nofollow">https://quickeasy.tools/pt/tools/qr-code-generator</a></p><p>Quero muito o seu feedback.<br>O formulário de feedback do site está com problema por enquanto, então se puder, me escreva por aqui mesmo caso sinta falta de alguma funcionalidade ou encontre algum bug.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Estudei Engenharia de Sistemas no Japão: O que a Universidade de Wakayama me ensinou sobre a base da tecnologia]]></title>
            <link>https://www.tabnews.com.br/Yoshijp/estudei-engenharia-de-sistemas-no-japao-o-que-a-universidade-de-wakayama-me-ensinou-sobre-a-base-da-tecnologia</link>
            <guid>https://www.tabnews.com.br/Yoshijp/estudei-engenharia-de-sistemas-no-japao-o-que-a-universidade-de-wakayama-me-ensinou-sobre-a-base-da-tecnologia</guid>
            <pubDate>Wed, 08 Apr 2026 16:27:17 GMT</pubDate>
            <description><![CDATA[Olá, pessoal do TabNews. Me chamo Yan e sou estudante do 6º ano de Engenharia de Computação na UFGD (Universidade Federal da Grande Dourados). Em janeiro deste ano, retornei ao Brasil apó...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Olá, pessoal do TabNews.</p><p>Me chamo Yan e sou estudante do 6º ano de Engenharia de Computação na UFGD (Universidade Federal da Grande Dourados). Em janeiro deste ano, retornei ao Brasil após um período de intercâmbio no departamento de Engenharia de Sistemas da Universidade de Wakayama, no Japão.</p><p>Essa experiência de vivenciar dois mundos acadêmicos e tecnológicos tão distintos me trouxe reflexões profundas. Hoje, quero compartilhar com vocês as principais diferenças que observei entre a educação de engenharia no Brasil e no Japão, e o que podemos aprender com o estilo japonês.</p><h3 id="yoshijp-content-1-a-cultura-do-kenkyushitsu-laboratório-de-pesquisa">1. A Cultura do "Kenkyushitsu" (Laboratório de Pesquisa)</h3><p>No Brasil, é comum termos matérias até o final do curso e, paralelamente, fazermos um TCC ou uma Iniciação Científica. No Japão, o sistema é diferente.</p><p>Lá, existe a cultura do <strong>Kenkyushitsu (研究室)</strong>. Nos últimos anos da graduação, o aluno é "adotado" por um laboratório e passa a viver aquele ambiente. Você ganha sua própria mesa no laboratório e sua rotina passa a ser quase inteiramente dedicada à pesquisa, lado a lado com mestrandos e doutorandos. Essa imersão cria um foco absurdo e um senso de comunidade e responsabilidade com o projeto muito forte. Foi nesse ambiente, por exemplo, que pude me aprofundar no conceito de "Natureza Digital" (Digital Nature), que hoje é o tema do meu TCC no Brasil.</p><h3 id="yoshijp-content-2-o-foco-extremo-na-base-e-no-hardware">2. O Foco Extremo na Base e no Hardware</h3><p>No Brasil, vejo muitos estudantes (eu incluso, em vários momentos) com pressa para aprender o framework do momento para entrar logo no mercado de trabalho.</p><p>No Japão, a abordagem é muito mais voltada para a fundação. Mesmo em cursos focados em software, há uma carga pesadíssima em eletrônica, arquitetura de computadores, linguagens de baixo nível e matemática. A filosofia é: <em>se você entende perfeitamente como o hardware se comporta (do Arduino aos processadores complexos), você consegue aprender qualquer framework de software rapidamente e com muito mais qualidade.</em></p><h3 id="yoshijp-content-3-monozukuri-a-arte-de-fazer-bem-feito">3. "Monozukuri": A Arte de Fazer Bem Feito</h3><p>Existe um termo japonês chamado <strong>Monozukuri (ものづくり)</strong>, que pode ser traduzido como a "arte de fabricar coisas". Isso se reflete diretamente no código e nos projetos.</p><p>Enquanto no Brasil temos o famoso "jogo de cintura" para resolver problemas rápidos (o que é uma grande qualidade nossa), no Japão o foco está no processo, na documentação minuciosa e em testes exaustivos antes de qualquer implementação. A tolerância a falhas na etapa de planejamento é baixíssima. É um processo mais lento no início, mas que gera sistemas extremamente robustos no longo prazo.</p><h3 id="yoshijp-content-conclusão-unindo-o-melhor-dos-dois-mundos">Conclusão: Unindo o Melhor dos Dois Mundos</h3><p>Acredito que o engenheiro de computação brasileiro tem uma criatividade e uma capacidade de adaptação que são raras no mundo. No entanto, se conseguirmos aliar essa nossa agilidade com o rigor técnico, o foco na base e o respeito ao processo que os japoneses têm, nos tornaremos profissionais imbatíveis.</p><p>Gostaria de saber de vocês: como enxergam a nossa formação aqui no Brasil em relação a esses pontos? Alguém aqui já teve experiências trabalhando com equipes japonesas ou asiáticas?</p><p>Vou adorar ler os comentários e trocar ideias com vocês!</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[O blog que eu gostaria de ter encontrado quando comecei a programar]]></title>
            <link>https://www.tabnews.com.br/wesleydmscn/o-blog-que-eu-gostaria-de-ter-encontrado-quando-comecei-a-programar</link>
            <guid>https://www.tabnews.com.br/wesleydmscn/o-blog-que-eu-gostaria-de-ter-encontrado-quando-comecei-a-programar</guid>
            <pubDate>Wed, 08 Apr 2026 16:13:47 GMT</pubDate>
            <description><![CDATA[Quando eu era criança, eu já queria entender como a tecnologia funcionava de verdade. Não era só usar — era abrir, fuçar, testar, quebrar e descobrir como as coisas eram feitas. Hoje, olh...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Quando eu era criança, eu já queria entender como a tecnologia funcionava de verdade.</p><p>Não era só usar — era abrir, fuçar, testar, quebrar e descobrir como as coisas eram feitas.</p><p>Hoje, olhando pra trás, percebo que estou me tornando exatamente aquilo que eu imaginava naquela época: alguém que entende (ou pelo menos tenta entender) como tudo funciona por baixo dos panos.</p><p>E foi daí que nasceu meu blog.</p><p>👉 <a href="https://wesleydmscn.com/" rel="nofollow">https://wesleydmscn.com/</a></p><p>Ele não é um curso.<br>Não é uma documentação.<br>E definitivamente não é conteúdo genérico.</p><p>É mais como um caderno aberto.</p><p>Um lugar onde eu registro o que estou aprendendo — sobre programação, tecnologia, ciência da computação… e até retrogaming.</p><p>Sim, retrogaming também 🎮</p><p>Porque pra mim, entender tecnologia também passa por entender jogos clássicos, como eles funcionavam e o que tinha por trás daquilo tudo.</p><p>Alguns exemplos do que você vai encontrar lá:</p><ul><li>criar uma API estilo Bit.ly com Node.js puro</li><li>conceitos mais profundos de TypeScript (Effective TS)</li><li>React na prática</li><li>programação de jogos</li><li>e até coisas como mecânicas de jogos do PS1 (tipo Resident Evil)</li></ul><p>Tudo sem a pretensão de ser perfeito — só útil.</p><p>Se você curte aprender entendendo de verdade (e não só copiando código), talvez faça sentido pra você.</p><p>🚀 <a href="https://wesleydmscn.com/" rel="nofollow">https://wesleydmscn.com/</a></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Moradores de prédio]]></title>
            <link>https://www.tabnews.com.br/elmineiro/moradores-de-predio</link>
            <guid>https://www.tabnews.com.br/elmineiro/moradores-de-predio</guid>
            <pubDate>Wed, 08 Apr 2026 14:41:40 GMT</pubDate>
            <description><![CDATA[Quais informações vocês não conseguem encontrar fácil sobre seu condomínio? Quais sao as maiores dores que voce passa hoje no codnominio e na gestao ao ter contato com sindico? Estou faze...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Quais informações vocês não conseguem encontrar fácil sobre seu condomínio? Quais sao as maiores dores que voce passa hoje no codnominio e na gestao ao ter contato com sindico?</p><p>Estou fazendo essas perguntas pois estou criando uma aplicacao para condominios e nada melhor que perguntar pra pessoas reais.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[PITCH] ABRINDO A CAIXA PRETA DA IA/LLM]]></title>
            <link>https://www.tabnews.com.br/Oletros/pitch-abrindo-a-caixa-preta-da-ia-llm</link>
            <guid>https://www.tabnews.com.br/Oletros/pitch-abrindo-a-caixa-preta-da-ia-llm</guid>
            <pubDate>Wed, 08 Apr 2026 14:10:11 GMT</pubDate>
            <description><![CDATA[Meus 2 cents, Conhecer por dentro a "caixa preta" ajuda bastante a planejar como usar melhor uma IA/LLM, entendendo como ela chega a certos resultados. Fiz um vídeo para mostrar alguns po...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Meus 2 cents,</p><p>Conhecer por dentro a <strong>"caixa preta"</strong> ajuda bastante a planejar como usar melhor uma IA/LLM, entendendo como ela chega a certos resultados.</p><p>Fiz um vídeo para mostrar alguns pontos de como as coisas por debaixo do capô, e outras questões sobre o seu funcionamento.</p><ul><li><a href="https://www.youtube.com/watch?v=zyoztn7VsWg" rel="nofollow">CAPÍTULO 2: ABRINDO A CAIXA PRETA</a></li></ul><p>Abro com um exemplo de <strong>"teste de turing"</strong> bastante simples mas didático (ainda que polêmico), perguntando a 2 LLMs comerciais (chatGPT e Gemini):</p><blockquote><p>"Preciso lavar meu carro, e o lava-jato fica a 50 metros da minha casa. É melhor ir a pé ou de carro ?"</p></blockquote><p>O chatGPT analisou a questão como um dilema filosófico ou de estilo de vida, ignorando a premissa física óbvia:</p><blockquote><p>Para lavar o carro, o objeto "carro" precisa ser levado fisicamente até lá.</p></blockquote><p>O Gemini demonstrou um entendimento superior, mas ainda assim tratou a questão trivial com uma complexidade desnecessária e gastando uma linha de raciocínio imensa.</p><p>O argumento a <strong>favor</strong> da <strong>IA/LLM</strong> é que ela <strong>"chegou ao resultado certo"</strong> nos dois testes.</p><p><strong>Porém</strong>, o que importa <strong>não é apenas o resultado</strong>, mas o que ele <strong>significa</strong> no mundo físico (e quais as <strong>premissas</strong> que foram assumidas para este significado).</p><blockquote><p><strong>NOTA</strong>: Por serem longas para um post, as respostas completas dos chatbots estão no capítulo 2 do livro.</p></blockquote><p>Uma <strong>resposta humana</strong> coerente seria curta:</p><blockquote><p><em>"Para lavar o carro, você precisa levá-lo até lá. Se não quiser dirigir, verifique se eles têm serviço de leva-e-traz"</em>.</p></blockquote><p>A <strong>diferença é sutil</strong>, mas <strong>vital</strong>: o humano entende que o <strong>carro é o foco obrigatório da missão</strong>; a <strong>IA/LLM</strong> entende apenas que <strong>"carro"</strong>, <strong>"pé"</strong> e <strong>"50 metros"</strong> são <strong>tokens</strong> que precisam ser avaliados quanto ao seu peso estatístico e relação com outros <strong>tokens</strong> para gerar uma resposta fluida (mas destituída de relação com o mundo físico).</p><p><strong>LEMBRANDO:</strong> A <strong>IA/LLM</strong> não é <strong>"pior"</strong> que o humano; ela possui um raciocínio <strong>diferente</strong>, baseado em ângulos estatísticos e probabilidades de <strong>tokens</strong>.</p><h2 id="oletros-content-conclusão">Conclusão</h2><p>Por isso, seja usando uma IA/LLM como ferramenta em questão da nossa vida cotidiana (p.ex. atendendo uma fila de Suporte/ URA/ Whatsapp/ etc), ou no planejamento e construção de um aplicativo é importante lembrar que a IA/LLM <strong>NÃO SABE</strong> a implicação das decisões no mundo real:</p><ul><li>Cabe a você, o desenvolvedor, fornecer este <strong>"ancoramento"</strong> na realidade que a IA/LLM não possui.</li></ul><p>Saúde e Sucesso !</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agência Central de Inteligência dos EUA utiliza tecnologia inédita para localizar aviador abatido]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/agencia-central-de-inteligencia-dos-eua-utiliza-tecnologia-inedita-para-localizar-aviador-abatido</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/agencia-central-de-inteligencia-dos-eua-utiliza-tecnologia-inedita-para-localizar-aviador-abatido</guid>
            <pubDate>Wed, 08 Apr 2026 13:10:45 GMT</pubDate>
            <description><![CDATA[A CIA utilizou uma tecnologia inédita chamada “Ghost Murmur” para localizar e resgatar um aviador americano abatido no sul do Irã. O nome “Murmur” faz referência ao termo clínico usado pa...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A CIA utilizou uma tecnologia inédita chamada “Ghost Murmur” para localizar e resgatar um aviador americano abatido no sul do Irã.</p><p>O nome “Murmur” faz referência ao termo clínico usado para descrever o ritmo cardíaco, enquanto “Ghost” remete à ideia de localizar alguém desaparecido.</p><p>A ferramenta emprega magnetometria quântica de longo alcance para identificar a “impressão eletromagnética” de um batimento cardíaco humano, conseguindo isolar esse sinal em meio ao ruído de fundo. O sistema conseguiu detectar os sinais vitais do aviador, especialmente no momento em que ele deixou um esconderijo para transmitir um sinal.</p><p>Esta foi a primeira vez que a tecnologia foi utilizada em uma operação real. Sua capacidade é comparada a “ouvir uma voz em um estádio”, e apresenta melhor desempenho em ambientes com baixa interferência eletromagnética, como regiões desérticas.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[PITCH] Criei um SaaS que permite configurar agentes PicoClaw com apenas um clique]]></title>
            <link>https://www.tabnews.com.br/danisaints/pitch-criei-um-saas-que-permite-configurar-agentes-picoclaw-com-apenas-um-clique</link>
            <guid>https://www.tabnews.com.br/danisaints/pitch-criei-um-saas-que-permite-configurar-agentes-picoclaw-com-apenas-um-clique</guid>
            <pubDate>Wed, 08 Apr 2026 12:50:33 GMT</pubDate>
            <description><![CDATA[Criei um SaaS que permite configurar agentes PicoClaw com apenas um clique, facilitando a vida de quem tem dificuldade em mexer com terminais ou VPS. O PicoClaw é uma variante do OpenClaw...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Criei um SaaS que permite configurar agentes PicoClaw com apenas um clique, facilitando a vida de quem tem dificuldade em mexer com terminais ou VPS.<br>O PicoClaw é uma variante do OpenClaw escrita em Go, o que o torna extremamente leve, sendo capaz de rodar em dispositivos com apenas 10 MB de RAM.</p><p>No meu painel, o processo é muito simples: o usuário faz o login, escolhe um plano, define o nome do bot e insere sua chave de API do Google.</p><p>O sistema então se comunica com a minha VPS, faz o deploy via Docker e gera um acesso seguro através de um IP e um token.</p><p>Apesar de leve, ele mantém as funções do OpenClaw, permitindo conexões com Telegram, Discord e até sugestões de integração com WhatsApp.</p><p>O maior desafio técnico foi fazer a plataforma Base 44 conversar com a VPS de forma consistente para clonar as imagens sem erros.</p><p>Atualmente, cada nó da minha VPS suporta até 10 agentes, mas pretendo expandir anexando novos nós no futuro.</p><p><a href="https://picoclawone.com" rel="nofollow">https://picoclawone.com</a></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deep Links no iOS com Swift: Info.plist, AppDelegate e Universal Links — sem pacote (Parte 3)]]></title>
            <link>https://www.tabnews.com.br/crdornelles/deep-links-no-ios-com-swift-info-plist-appdelegate-e-universal-links-sem-pacote-parte-3</link>
            <guid>https://www.tabnews.com.br/crdornelles/deep-links-no-ios-com-swift-info-plist-appdelegate-e-universal-links-sem-pacote-parte-3</guid>
            <pubDate>Wed, 08 Apr 2026 12:40:05 GMT</pubDate>
            <description><![CDATA[Seguindo a série sobre deep links em Flutter sem pacote. Desta vez: iOS nativo. A lógica é a mesma do Android. As APIs são completamente diferentes. No Post 3 implementei: Info.plist com...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Seguindo a série sobre deep links em Flutter sem pacote. Desta vez: iOS nativo.</p><p>A lógica é a mesma do Android. As APIs são completamente diferentes.</p><hr><p>No Post 3 implementei:</p><ul><li><code>Info.plist</code> com <code>CFBundleURLTypes</code> para registrar o custom scheme (<code>fitconnect://</code>)</li><li><code>Runner.entitlements</code> com Associated Domains para Universal Links</li><li><code>AppDelegate.swift</code> com:<ul><li><code>FlutterMethodChannel</code> → link no cold start</li><li><code>FlutterEventChannel</code> → stream com app aberto</li><li><code>open url</code> → custom scheme</li><li><code>continue userActivity</code> → Universal Links</li></ul></li></ul><pre><code class="hljs language-swift"><span class="hljs-comment">// Custom scheme</span><span class="hljs-keyword">override</span> <span class="hljs-keyword">func</span> <span class="hljs-title function_">application</span>(<span class="hljs-keyword">_</span> <span class="hljs-params">app</span>: <span class="hljs-type">UIApplication</span>,    <span class="hljs-params">open</span> <span class="hljs-params">url</span>: <span class="hljs-type">URL</span>,    <span class="hljs-params">options</span>: [<span class="hljs-type">UIApplication</span>.<span class="hljs-params">OpenURLOptionsKey</span>: <span class="hljs-keyword">Any</span>] <span class="hljs-operator">=</span> [:]) -> <span class="hljs-type">Bool</span> {    handleDeepLink(url: url, isInitial: <span class="hljs-literal">false</span>)    <span class="hljs-keyword">return</span> <span class="hljs-keyword">super</span>.application(app, open: url, options: options)}<span class="hljs-comment">// Universal Links</span><span class="hljs-keyword">override</span> <span class="hljs-keyword">func</span> <span class="hljs-title function_">application</span>(<span class="hljs-keyword">_</span> <span class="hljs-params">application</span>: <span class="hljs-type">UIApplication</span>,    <span class="hljs-params">continue</span> <span class="hljs-params">userActivity</span>: <span class="hljs-type">NSUserActivity</span>,    <span class="hljs-params">restorationHandler</span>: <span class="hljs-keyword">@escaping</span> ([<span class="hljs-type">UIUserActivityRestoring</span>]<span class="hljs-operator">?</span>) -> <span class="hljs-type">Void</span>) -> <span class="hljs-type">Bool</span> {    <span class="hljs-keyword">guard</span> userActivity.activityType <span class="hljs-operator">==</span> <span class="hljs-type">NSUserActivityTypeBrowsingWeb</span>,          <span class="hljs-keyword">let</span> url <span class="hljs-operator">=</span> userActivity.webpageURL <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> }    handleDeepLink(url: url, isInitial: <span class="hljs-literal">false</span>)    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>}</code></pre><hr><h2 id="crdornelles-content-coisas-que-quebram-fácil">Coisas que quebram fácil</h2><ul><li>testar Universal Links colando no Safari (não funciona — use iMessage ou Mail)</li><li>esquecer o prefixo <code>applinks:</code> no Associated Domains</li><li><code>apple-app-site-association</code> não configurado no servidor (Post 5)</li><li>link chegando duas vezes no cold start — <code>lastProcessedLink</code> resolve</li></ul><hr><h2 id="crdornelles-content-fonte-post-completo-no-medium">Fonte (post completo no Medium)</h2><p><a href="https://medium.com/@crdornelles/deep-links-no-ios-implementa%C3%A7%C3%A3o-nativa-com-swift-flutter-parte-3-d37569fd0a15" rel="nofollow">https://medium.com/@crdornelles/deep-links-no-ios-implementa%C3%A7%C3%A3o-nativa-com-swift-flutter-parte-3-d37569fd0a15</a></p><hr><p>Se alguém já teve Universal Link abrindo no Safari em vez do app mesmo com tudo configurado — conta como resolveu. Esse é o problema mais comum nessa etapa.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[5 Lacunas Críticas que Todo Dev JavaScript Ignora em APIs, npm e Open Source]]></title>
            <link>https://www.tabnews.com.br/mrmsoares/5-lacunas-criticas-que-todo-dev-javascript-ignora-em-apis-npm-e-open-source</link>
            <guid>https://www.tabnews.com.br/mrmsoares/5-lacunas-criticas-que-todo-dev-javascript-ignora-em-apis-npm-e-open-source</guid>
            <pubDate>Wed, 08 Apr 2026 12:02:30 GMT</pubDate>
            <description><![CDATA[O problema que ninguém admite Você instala pacotes npm sem pensar. Expõe APIs sem versionamento. Valida dados só no frontend. Contribui com open source sem entender a governança do projet...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><pre><code class="hljs language-mdx">## O problema que ninguém admiteVocê instala pacotes npm sem pensar. Expõe APIs sem versionamento. Valida dados só no frontend. Contribui com open source sem entender a governança do projeto.São lacunas silenciosas. Não quebram nada hoje. Mas amanhã, destroem produção.Este post cobre cinco lacunas reais que encontro repetidamente em projetos JavaScript profissionais. Cada uma com diagnóstico, ferramenta e código funcional.Vamos direto.## Lacuna 1: Segurança de dependências npmA maioria dos devs roda `npm install` e nunca mais olha para o que entrou no `node_modules`. Isso é um convite para supply chain attacks.O incidente do `event-stream` em 2018 provou isso. Um pacote com milhões de downloads semanais foi comprometido. O atacante injetou código malicioso que roubava bitcoins.### Diagnóstico rápidoRode isso agora no seu projeto:```bashnpm audit</code></pre><p>Provavelmente você verá vulnerabilidades. Mas <code>npm audit</code> sozinho não basta. Ele só checa o registry público. Não detecta typosquatting, pacotes abandonados ou maintainers comprometidos.</p><h3 id="mrmsoares-content-ferramentas-que-realmente-cobrem-a-lacuna">Ferramentas que realmente cobrem a lacuna</h3><p>Instale o <code>socket.dev</code> CLI para análise profunda:</p><pre><code class="hljs language-bash">npm install -g @socketsecurity/cli</code></pre><p>Agora rode a análise no seu projeto:</p><pre><code class="hljs language-bash">socket scan ./package.json</code></pre><p>Para automatizar no CI, adicione ao seu <code>package.json</code>:</p><pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>  <span class="hljs-attr">"scripts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>    <span class="hljs-attr">"security:audit"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"npm audit --audit-level=high"</span><span class="hljs-punctuation">,</span>    <span class="hljs-attr">"security:scan"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"socket scan ./package.json"</span><span class="hljs-punctuation">,</span>    <span class="hljs-attr">"security:check"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"npm run security:audit &#x26;&#x26; npm run security:scan"</span>  <span class="hljs-punctuation">}</span><span class="hljs-punctuation">}</span></code></pre><h3 id="mrmsoares-content-lockfile--sua-primeira-linha-de-defesa">Lockfile — sua primeira linha de defesa</h3><p>Nunca ignore o <code>package-lock.json</code>. Ele garante builds reproduzíveis. Em CI, use sempre:</p><pre><code class="hljs language-bash">npm ci</code></pre><p>O <code>npm ci</code> respeita o lockfile literalmente. O <code>npm install</code> pode alterá-lo. Essa diferença sutil já causou bugs em produção que levaram dias para diagnosticar.</p><h3 id="mrmsoares-content-política-de-dependências-com-npmrc">Política de dependências com <code>.npmrc</code></h3><p>Crie um <code>.npmrc</code> na raiz do projeto:</p><pre><code class="hljs language-ini"><span class="hljs-attr">audit</span>=<span class="hljs-literal">true</span><span class="hljs-attr">fund</span>=<span class="hljs-literal">false</span><span class="hljs-attr">save-exact</span>=<span class="hljs-literal">true</span><span class="hljs-attr">engine-strict</span>=<span class="hljs-literal">true</span></code></pre><p>O <code>save-exact=true</code> é crucial. Ele trava a versão exata no <code>package.json</code>, eliminando surpresas de minor/patch updates automáticos.</p><h2 id="mrmsoares-content-lacuna-2-apis-sem-versionamento-nem-contrato">Lacuna 2: APIs sem versionamento nem contrato</h2><p>Você cria uma rota <code>/api/users</code>, deploya, e três meses depois precisa mudar o formato de resposta. Quebra todos os clientes. Clássico.</p><h3 id="mrmsoares-content-versionamento-por-url--o-jeito-pragmático">Versionamento por URL — o jeito pragmático</h3><pre><code class="hljs language-javascript"><span class="hljs-comment">// server.js</span><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;<span class="hljs-keyword">const</span> app = <span class="hljs-title function_">express</span>();<span class="hljs-comment">// v1 — contrato original</span>app.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/api/v1/users'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {  res.<span class="hljs-title function_">json</span>({    <span class="hljs-attr">users</span>: [      { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Ana'</span>, <span class="hljs-attr">email</span>: <span class="hljs-string">'ana@email.com'</span> }    ]  });});<span class="hljs-comment">// v2 — novo formato com paginação</span>app.<span class="hljs-title function_">get</span>(<span class="hljs-string">'/api/v2/users'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {  res.<span class="hljs-title function_">json</span>({    <span class="hljs-attr">data</span>: [      { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">fullName</span>: <span class="hljs-string">'Ana Silva'</span>, <span class="hljs-attr">contact</span>: { <span class="hljs-attr">email</span>: <span class="hljs-string">'ana@email.com'</span> } }    ],    <span class="hljs-attr">meta</span>: { <span class="hljs-attr">page</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">total</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">perPage</span>: <span class="hljs-number">20</span> }  });});app.<span class="hljs-title function_">listen</span>(<span class="hljs-number">3000</span>, <span class="hljs-function">() =></span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'API rodando na porta 3000'</span>));</code></pre><h3 id="mrmsoares-content-contrato-com-zod--validação-em-runtime">Contrato com Zod — validação em runtime</h3><p>Essa é a lacuna mais perigosa. TypeScript valida em compile time. Mas dados de API chegam em runtime. TypeScript não existe em runtime.</p><p>Instale o Zod:</p><pre><code class="hljs language-bash">npm install zod</code></pre><p>Agora crie contratos reais:</p><pre><code class="hljs language-javascript"><span class="hljs-comment">// contracts/user.js</span><span class="hljs-keyword">import</span> { z } <span class="hljs-keyword">from</span> <span class="hljs-string">'zod'</span>;<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-title class_">CreateUserSchema</span> = z.<span class="hljs-title function_">object</span>({  <span class="hljs-attr">name</span>: z.<span class="hljs-title function_">string</span>().<span class="hljs-title function_">min</span>(<span class="hljs-number">2</span>).<span class="hljs-title function_">max</span>(<span class="hljs-number">100</span>),  <span class="hljs-attr">email</span>: z.<span class="hljs-title function_">string</span>().<span class="hljs-title function_">email</span>(),  <span class="hljs-attr">age</span>: z.<span class="hljs-title function_">number</span>().<span class="hljs-title function_">int</span>().<span class="hljs-title function_">min</span>(<span class="hljs-number">18</span>).<span class="hljs-title function_">max</span>(<span class="hljs-number">120</span>).<span class="hljs-title function_">optional</span>(),});<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-title class_">UserResponseSchema</span> = z.<span class="hljs-title function_">object</span>({  <span class="hljs-attr">id</span>: z.<span class="hljs-title function_">number</span>(),  <span class="hljs-attr">name</span>: z.<span class="hljs-title function_">string</span>(),  <span class="hljs-attr">email</span>: z.<span class="hljs-title function_">string</span>().<span class="hljs-title function_">email</span>(),  <span class="hljs-attr">createdAt</span>: z.<span class="hljs-title function_">string</span>().<span class="hljs-title function_">datetime</span>(),});<span class="hljs-comment">// Tipos derivados automaticamente</span><span class="hljs-keyword">export</span> type <span class="hljs-title class_">CreateUserInput</span> = z.<span class="hljs-property">infer</span>&#x3C;<span class="hljs-keyword">typeof</span> <span class="hljs-title class_">CreateUserSchema</span>>;<span class="hljs-keyword">export</span> type <span class="hljs-title class_">UserResponse</span> = z.<span class="hljs-property">infer</span>&#x3C;<span class="hljs-keyword">typeof</span> <span class="hljs-title class_">UserResponseSchema</span>>;</code></pre><p>Use no middleware do Express:</p><pre><code class="hljs language-javascript"><span class="hljs-comment">// middleware/validate.js</span><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">validate</span>(<span class="hljs-params">schema</span>) {  <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =></span> {    <span class="hljs-keyword">const</span> result = schema.<span class="hljs-title function_">safeParse</span>(req.<span class="hljs-property">body</span>);    <span class="hljs-keyword">if</span> (!result.<span class="hljs-property">success</span>) {      <span class="hljs-keyword">return</span> res.<span class="hljs-property">st</span>---<span class="hljs-title class_">Leia</span> o artigo completo em [<span class="hljs-attr">https</span>:<span class="hljs-comment">//vivodecodigo.com.br/backend/lacunas-criticas-javascript-api-npm-opensource-webdev](https://vivodecodigo.com.br/backend/lacunas-criticas-javascript-api-npm-opensource-webdev)</span></code></pre></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pesquisadores transformam resíduos da produção de bourbon em materiais para armazenamento de energia]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/pesquisadores-transformam-residuos-da-producao-de-bourbon-em-materiais-para-armazenamento-de-energia</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/pesquisadores-transformam-residuos-da-producao-de-bourbon-em-materiais-para-armazenamento-de-energia</guid>
            <pubDate>Wed, 08 Apr 2026 11:37:47 GMT</pubDate>
            <description><![CDATA[Pesquisadores apresentaram uma técnica para transformar resíduos da produção de bourbon, um tipo de uísque, em materiais voltados ao armazenamento de energia, com potencial aplicação em v...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Pesquisadores apresentaram uma técnica para transformar resíduos da produção de bourbon, um tipo de uísque, em materiais voltados ao armazenamento de energia, com potencial aplicação em veículos elétricos e redes elétricas.</p><p>Atualmente, esses resíduos, formados por grãos usados e água, em um volume de 6 a 10 vezes maior que cada barril produzido, precisam passar por um processo de secagem antes de serem reutilizados como ração ou fertilizante, o que demanda tempo ou métodos caros de aquecimento.</p><p>A proposta elimina essa etapa ao converter diretamente o material úmido em um pó de carbono, que pode ser refinado em carbono ativado, adequado para supercapacitores, e em carbono duro, com estrutura semelhante ao grafite e eficiente no armazenamento de íons como lítio e sódio, utilizados em baterias.</p><p>Nos testes, os pesquisadores desenvolveram supercapacitores com densidade de energia de até 48 watt-hora por quilograma, valor comparável ao de dispositivos comerciais, além de um supercapacitor híbrido de íon-lítio capaz de armazenar até 25 vezes mais energia do que modelos convencionais.</p><p>A equipe acredita que a solução pode contribuir para atender à crescente demanda por materiais para baterias, especialmente diante da expansão da indústria de veículos elétricos.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Polícia de Londres investiga ex-funcionário da Meta suspeito de baixar 30 mil imagens privadas de usuários do Facebook]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/policia-de-londres-investiga-ex-funcionario-da-meta-suspeito-de-baixar-30-mil-imagens-privadas-de-usuarios-do-facebook</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/policia-de-londres-investiga-ex-funcionario-da-meta-suspeito-de-baixar-30-mil-imagens-privadas-de-usuarios-do-facebook</guid>
            <pubDate>Wed, 08 Apr 2026 11:35:28 GMT</pubDate>
            <description><![CDATA[A polícia de Londres investiga um ex-funcionário da Meta suspeito de ter baixado cerca de 30 mil imagens privadas de usuários do Facebook. O indivíduo teria desenvolvido um programa capaz...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A polícia de Londres investiga um ex-funcionário da Meta suspeito de ter baixado cerca de 30 mil imagens privadas de usuários do Facebook. O indivíduo teria desenvolvido um programa capaz de acessar fotos pessoais na plataforma ao contornar mecanismos de verificação de segurança.</p><p>A empresa afirma que identificou a violação há mais de um ano e realizou a demissão imediata do funcionário. O suspeito foi preso em novembro de 2025, liberado sob fiança e deverá se apresentar novamente à polícia em maio. A Meta também informa que notificou os usuários afetados e que, desde então, reforçou seus sistemas de segurança.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como abri meu launcher para plugins de terceiros (e por que foi mais difícil do que parecia)]]></title>
            <link>https://www.tabnews.com.br/Derlys/como-abri-meu-launcher-para-plugins-de-terceiros-e-por-que-foi-mais-dificil-do-que-parecia</link>
            <guid>https://www.tabnews.com.br/Derlys/como-abri-meu-launcher-para-plugins-de-terceiros-e-por-que-foi-mais-dificil-do-que-parecia</guid>
            <pubDate>Wed, 08 Apr 2026 05:42:48 GMT</pubDate>
            <description><![CDATA[No post anterior eu expliquei como construí a Bely — um launcher para Windows com 70+ ferramentas usando Tauri 2 e React. Agora quero contar sobre uma decisão que tomei essa semana: abrir...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>No <a href="https://www.tabnews.com.br/Derlys/como-construi-um-launcher-com-70-ferramentas-usando-tauri-2-e-react">post anterior</a> eu expliquei como construí a Bely — um launcher para Windows com 70+ ferramentas usando Tauri 2 e React. Agora quero contar sobre uma decisão que tomei essa semana: abrir o app para plugins externos.</p><h2 id="derlys-content-por-que-plugins">Por que plugins</h2><p>A Bely já tem muita coisa built-in. Mas eu sei que em algum momento vou precisar que outras pessoas consigam estender o app sem depender de mim pra cada feature nova. Integração com API interna de empresa, lookup de pacote npm, ferramentas de nicho — são coisas que fazem sentido pra alguém mas não pra todo mundo.</p><p>Ao invés de esperar essa demanda aparecer, decidi construir a infraestrutura agora enquanto o projeto ainda é pequeno e eu consigo iterar rápido. Se der errado, pelo menos aprendi. Se der certo, o app já está pronto pra escalar.</p><h2 id="derlys-content-o-problema-do-iframe-sandbox">O problema do iframe sandbox</h2><p>A primeira decisão foi: como isolar o código de terceiros? Eu não posso simplesmente executar JS arbitrário no contexto do meu app — isso daria acesso ao filesystem, clipboard, e todas as APIs do Tauri.</p><p>A solução foi usar iframes com <code>sandbox="allow-scripts"</code>. O plugin roda num documento HTML separado, carregado via blob URL, sem acesso ao DOM pai. Toda comunicação passa por <code>postMessage</code>.</p><p>Parece simples, mas tem uma cascata de problemas:</p><p><strong>1. O iframe não herda o tema.</strong> O plugin renderiza num contexto CSS completamente isolado. Tive que coletar todas as CSS variables do tema glass (<code>--glass-bg</code>, <code>--glass-text</code>, <code>--accent</code>, etc — são mais de 40) e injetar como inline style no HTML do iframe. Se o usuário troca o tema, preciso mandar uma mensagem pro iframe atualizar.</p><p><strong>2. O iframe rouba o foco da janela.</strong> Esse foi o bug mais irritante. No Windows, quando o acrylic blur está ativo e o usuário clica dentro do iframe (num input de busca do plugin, por exemplo), o <code>window</code> do documento pai dispara um evento <code>blur</code>. O app interpretava isso como "janela perdeu foco" e trocava o background de translúcido para opaco — matando o efeito glass.</p><p>A correção foi trocar o listener de <code>window.blur/focus</code> do DOM pela API nativa do Tauri (<code>getCurrentWindow().onFocusChanged()</code>), que detecta foco no nível do sistema operacional. O iframe está na mesma janela do OS, então o foco continua "ativo" mesmo quando o usuário interage com o plugin.</p><p><strong>3. CORS mata tudo.</strong> Os plugins precisam fazer fetch pra APIs externas (npm registry, GitHub, etc). Mas o fetch roda no contexto do host app que está em <code>http://tauri.localhost</code>. A maioria das APIs bloqueia por CORS.</p><p>A solução foi criar um proxy no Rust. O plugin manda uma mensagem <code>{ type: "api-call", method: "fetch", args: [url, options] }</code>, o host repassa pro backend Rust que faz o request via <code>reqwest</code> (sem restrição de CORS) e devolve o resultado.</p><h2 id="derlys-content-o-sdk">O SDK</h2><p>Não dá pra esperar que alguém escreva HTML cru com postMessage. Criei um SDK (<code>@usebely/sdk</code>) que abstrai tudo:</p><pre><code class="hljs language-tsx"><span class="hljs-keyword">import</span> { mount, <span class="hljs-title class_">List</span>, useFetch } <span class="hljs-keyword">from</span> <span class="hljs-string">"@usebely/sdk"</span>;<span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) {  <span class="hljs-keyword">const</span> [query, setQuery] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">""</span>);  <span class="hljs-keyword">const</span> { data, loading } = <span class="hljs-title function_">useFetch</span>(    query.<span class="hljs-property">length</span> >= <span class="hljs-number">2</span>      ? <span class="hljs-string">`https://registry.npmjs.org/-/v1/search?text=<span class="hljs-subst">${query}</span>`</span>      : <span class="hljs-literal">null</span>  );  <span class="hljs-keyword">return</span> (    <span class="xml"><span class="hljs-tag">&#x3C;<span class="hljs-name">List</span> <span class="hljs-attr">searchBarPlaceholder</span>=<span class="hljs-string">"Buscar pacotes..."</span> <span class="hljs-attr">onSearchChange</span>=<span class="hljs-string">{setQuery}</span> <span class="hljs-attr">isLoading</span>=<span class="hljs-string">{loading}</span>></span>      {data?.objects?.map((obj) => (        <span class="hljs-tag">&#x3C;<span class="hljs-name">List.Item</span>          <span class="hljs-attr">key</span>=<span class="hljs-string">{obj.package.name}</span>          <span class="hljs-attr">title</span>=<span class="hljs-string">{obj.package.name}</span>          <span class="hljs-attr">subtitle</span>=<span class="hljs-string">{obj.package.description}</span>        /></span>      ))}    <span class="hljs-tag">&#x3C;/<span class="hljs-name">List</span>></span></span>  );}<span class="hljs-title function_">mount</span>(<span class="xml"><span class="hljs-tag">&#x3C;<span class="hljs-name">App</span> /></span></span>);</code></pre><p>O SDK fornece componentes que já seguem o design system glass da Bely: <code>List</code>, <code>Detail</code>, <code>Form</code>, <code>Grid</code>, <code>Action</code>, <code>ActionPanel</code>. Todos usam as CSS variables injetadas, então o plugin automaticamente respeita o tema do usuário.</p><p>O <code>useFetch</code> tem debounce de 300ms e roteia pelo proxy Rust. O <code>mount()</code> cuida de montar o React, receber mensagens do host, e notificar quando o plugin está pronto.</p><h2 id="derlys-content-permissões">Permissões</h2><p>Cada plugin declara no manifest quais APIs precisa:</p><pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>  <span class="hljs-attr">"permissions"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"fetch"</span><span class="hljs-punctuation">,</span> <span class="hljs-string">"clipboard.write"</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">}</span></code></pre><p>Se o plugin tenta chamar algo que não declarou, o host bloqueia. As permissões disponíveis são: <code>fetch</code>, <code>clipboard.read</code>, <code>clipboard.write</code>, <code>fs.read</code>, <code>fs.write</code>, <code>system.info</code>. O usuário vê as permissões antes de instalar.</p><h2 id="derlys-content-a-plugin-store">A Plugin Store</h2><p>O fluxo:</p><ol><li>Dev builda o plugin e abre Plugin Store > Enviar na Bely</li><li>Preenche metadados (nome, ícone, categoria) e seleciona a pasta do plugin</li><li>O app cria um <code>.tar.gz</code> com o código completo (incluindo source pra review) e faz upload pro S3</li><li>Plugin fica pendente até ser aprovado no painel admin</li><li>Quando aprovado, aparece na store pra instalar</li></ol><p>Versionamento: versão aprovada não pode ser editada — precisa submeter uma nova. Versões pendentes podem ser editadas antes da aprovação. Bundle tem limite de 5MB.</p><p>No app, quando um plugin instalado tem versão nova na store, o card mostra "Atualizar" em vez de "Instalado". O detail view mostra o changelog de cada versão.</p><h2 id="derlys-content-o-que-aprendi">O que aprendi</h2><p><strong>Isolamento é caro.</strong> O iframe sandbox resolve segurança mas cria uma barreira de comunicação. Cada feature que funciona "de graça" no app principal (tema, foco, fetch, clipboard) precisa de uma ponte explícita pro plugin.</p><p><strong>O SDK é o produto.</strong> Se for difícil criar um plugin, ninguém vai criar. Investir tempo nos componentes e na DX valeu mais do que qualquer feature da store.</p><p><strong>Review manual é o certo por enquanto.</strong> Hoje eu baixo o bundle, leio o source, testo. Não escala, mas com zero plugins de terceiros no momento, é melhor garantir qualidade do que automatizar algo que ninguém está usando.</p><p><strong>Glass theme em iframes é sofrimento.</strong> A quantidade de edge cases entre transparência, composição de rgba, e comportamento diferente entre Windows 10 e 11 é absurda. Se eu fosse começar de novo, talvez considerasse web components no mesmo documento ao invés de iframes.</p><h2 id="derlys-content-status">Status</h2><p>O sistema de plugins está na v1.26.0. O SDK é funcional e já tem um plugin de exemplo (NPM Lookup) na store. A documentação está em <a href="https://bely.my/docs/plugins" rel="nofollow">https://bely.my/docs/plugins</a></p><p>A Bely está em whitelist beta: <a href="https://bely.my" rel="nofollow">https://bely.my</a></p><p>Feedback técnico é bem-vindo — especialmente de quem já lidou com plugin systems ou iframe sandboxing.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como uma edição de título de PR quebrou minha pipeline por algumas horas]]></title>
            <link>https://www.tabnews.com.br/aguillarops/como-uma-edicao-de-titulo-de-pr-quebrou-minha-pipeline-por-algumas-horas</link>
            <guid>https://www.tabnews.com.br/aguillarops/como-uma-edicao-de-titulo-de-pr-quebrou-minha-pipeline-por-algumas-horas</guid>
            <pubDate>Wed, 08 Apr 2026 02:22:20 GMT</pubDate>
            <description><![CDATA[Se liga nessa situação que rolou comigo há algum tempo... dia tranquilo até que a pipeline caiu "do nada" (sempre assim né? xD). O erro apontava para a VM, mas a causa real estava escondi...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Se liga nessa situação que rolou comigo há algum tempo... dia tranquilo até que a pipeline caiu <strong>"do nada"</strong> (sempre assim né? xD). O erro apontava para a VM, mas a causa real estava escondida em três mudanças de uma PR que ninguém tinha percebido.</p><hr><h2 id="aguillarops-content-o-problema">O problema</h2><p>Um dev me pingou: "Tá dando erro estranho na pipe, olha aí?" Parei o que eu estava fazendo e fui investigar.</p><p>Acessei o build e de primeira já verifiquei que falhou na etapa de instalação do <strong>Angular</strong>. Isso já me deu o palpite de que podia ser um problema na VM, pois essa pipeline usava um agente self-hosted (para contexto, nessa situação estamos falando de Azure DevOps e Bitbucket).</p><hr><h2 id="aguillarops-content-a-investigação">A investigação</h2><p>Abri a task de instalação do Angular e a primeira mensagem que vi foi: <em><strong>ENOTEMPTY: directory not empty, rename '.../cli' -> '.../cli-Xuqet0PR'</strong></em></p><p>Exatamente desse jeito, inclusive vou deixar o output aqui para ficar mais fácil de entender:</p><pre><code>2000-00-00T13:00:57Z [command] npm install -g @angular/cli@XX.X.12000-00-00T13:01:15Z npm error code ENOTEMPTY2000-00-00T13:01:15Z npm error syscall rename2000-00-00T13:01:15Z npm error path   .../node_modules/@angular/cli2000-00-00T13:01:15Z npm error dest   .../node_modules/@angular/.cli-Xuqet0PR2000-00-00T13:01:15Z npm error errno  -392000-00-00T13:01:15Z npm error ENOTEMPTY: directory not empty, rename '.../cli' -> '.../cli-Xuqet0PR'2000-00-00T13:01:16Z ##[error]Error: Npm failed with return code: 217</code></pre><p>De primeira dá para notar que o npm tentou renomear uma pasta e não conseguiu... como eu não sabia a fundo como funcionava o processo de instalação, dei uma pesquisada rápida e descobri que ao instalar o Angular, o npm tenta renomear o diretório atual <strong>(<code>cli</code>)</strong> para um nome temporário <strong>(<code>.cli-Xuqet0PR</code>)</strong> e se der certo esse rename, ele faz a instalação do Angular na pasta /cli, esse processo é basicamente para liberar o caminho no diretório antes de escrever a nova versão. O problema é que de alguma forma já existia um temporário lá e já estava com conteúdo, então o rename falhou, o processo morreu, o build foi junto.</p><p><strong>Agora a grande pergunta não era o que quebrou. Era o porquê esse diretório temporário estava ali.</strong></p><p>Aqui começa a investigação de verdade... Fui na lista de builds no Azure DevOps, procurei o último lote de builds com sucesso e identifiquei o momento exato em que as falhas começaram. Abri o build correspondente, acessei a PR em andamento e encontrei uma alteração no YAML da pipeline: <strong>o dev tinha removido a etapa de instalação do Angular.</strong></p><pre><code class="hljs language-yaml"><span class="hljs-comment"># trecho removido da pipeline pelo dev</span><span class="hljs-bullet">-</span> <span class="hljs-attr">task:</span> <span class="hljs-string">Npm@1</span>  <span class="hljs-attr">inputs:</span>    <span class="hljs-attr">command:</span> <span class="hljs-string">'custom'</span>    <span class="hljs-attr">customCommand:</span> <span class="hljs-string">'install -g @angular/cli@XX.X.1'</span>  <span class="hljs-attr">displayName:</span> <span class="hljs-string">'Install Angular CLI'</span></code></pre><p>Esse tipo de mudança é estranho, mas como o dev é novato e está começando, eu relevei e entendi que talvez ele não soube como resolver o problema do ENOTEMPTY, e usou IA para resolver mas não passou contexto suficiente.</p><h3 id="aguillarops-content-antes-de-continuar-investigando-preciso-liberar-o-fluxo">Antes de continuar investigando, preciso liberar o fluxo...</h3><p>Pipeline parada é prioridade máxima. Como DevOps, minha função é acelerar o ciclo de entrega do time, e build travado é o oposto disso.</p><p>Dei um change request na PR, chamei o dev no privado para avisar sobre a alteração do YAML e comuniquei ao time no grupo que eu já estava verificando o problema com a pipeline. Com isso feito, ativei a VPN e acessei a VM via SSH.</p><p>Tava lá. O diretório temporário abandonado, exatamente como o erro dizia.</p><p>Como eu falei anteriormente, o fluxo do npm é renomear a pasta /cli para um nome temporário e processar o pacote. <strong>Se o processo é interrompido no meio, o diretório temporário fica para trás.</strong> Na próxima execução, quando o npm tenta renomear de novo, encontra um diretório não vazio e explode com <code>ENOTEMPTY</code>.</p><p>Para resolver eu simplesmente apaguei as pastas...</p><p>Rodei a pipeline de novo e passou. Problema resolvido, avisei o time no grupo que a pipe estava liberada. Agora preciso entender a causa raiz.</p><h3 id="aguillarops-content-quem-interrompeu-o-processo">Quem interrompeu o processo?</h3><p>Um princípio que carrego na minha carreira é: <strong>nada acontece do nada.</strong></p><p>De cara, minha dedução foi que o problema estava na alteração do YAML que o novato fez. Mas fui checar o histórico da PR e notei que ele só removeu a instalação do Angular no terceiro commit. O erro já estava quebrando a pipeline antes disso.</p><p>Fui ver nos logs do agente na VM (aqui aprendi na marra algo que eu não tinha prestado atenção antes: <strong>a VM estava em UTC e eu estava em UTC-3</strong>) e os builds que via no Azure DevOps como falho às 08:53 correspondia a 11:53 na VM. Isso importa na hora de correlacionar logs, demorei uns minutos para lembrar disso xD</p><pre><code class="hljs language-bash">$ <span class="hljs-built_in">cat</span> /home/vm-admin/myagent/_diag/Agent_*.<span class="hljs-built_in">log</span> | grep <span class="hljs-string">"Running job"</span>[2000-00-00 01:00:39Z] Running job: Build Frontend[2000-00-00 01:03:25Z] Running job: Build Frontend[2000-00-00 01:05:58Z] Running job: Build Frontend[2000-00-00 02:00:20Z] Running job: Job[2000-00-00 02:10:37Z] Running job: Job[2000-00-00 02:20:45Z] Running job: Job[2000-00-00 11:49:37Z] Running job: Job  ← suspeito[2000-00-00 11:50:35Z] Running job: Job  ← suspeito[2000-00-00 11:53:12Z] Running job: Job  ← falhou</code></pre><p>Ao ler o log, fui por eliminação... como eu sabia que tinha pipe que rodou de madrugada por schedule e o build que eu procurava era das 11:53, sobraram dois jobs que não apareciam na interface do Azure DevOps. Foi só nesse momento que notei o número do build que havia falhado: <code>#20000000.3</code>. Tava na minha cara o tempo todo. O sufixo (3) já indicava que era a terceira execução do dia. Não vi antes... mas acontece xD.</p><h3 id="aguillarops-content-lendo-os-logs-dos-workers">Lendo os logs dos Workers</h3><p>Bom, agora que eu sei que tem dois builds que foram apagados e não aparecem na interface, e tenho informações de horário, vou até os logs de Workers. Lá é um arquivo por build, e o melhor, com o horário de início em UTC no próprio nome do arquivo.</p><pre><code class="hljs language-bash">$ <span class="hljs-built_in">ls</span> /home/vm-admin/myagent/_diag/Worker_20000000-114938-utc.logWorker_20000000-115038-utc.log</code></pre><p>Achei esses dois logs, e os minutos batem com o log que analisei anteriormente... Só podiam ser esses.</p><p>Log era enorme, então copiei, joguei para a IA e perguntei: <em>"o que aconteceu com esse build? Foi deletado, cancelado, crashou?"</em></p><p>A IA respondeu:</p><pre><code>Pipeline:     [empresa] - Dashboard (Staging)Build:        20000000.1 | Motivo: PullRequestResultado:    CanceledMomento:      durante o passo Cache npmConsequência: todos os passos seguintes foram skippedNesse log não aparece quem cancelou.O log mostra apenas que o agente recebeu um sinal de cancelamento.</code></pre><p>Opa, agora sei que os dois builds foram cancelados. Não foi crash, não foi a VM. Receberam um sinal externo. Mas de quem?</p><h3 id="aguillarops-content-o-culpado">O culpado</h3><p>Builds cancelados podem não aparecer na interface gráfica do Azure DevOps, mas da API não tem como, ela expõe isso. Montei a URL com ajuda de IA, já autenticado no portal, e o JSON retornou:</p><pre><code class="hljs language-json"><span class="hljs-attr">"deletedBy"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Microsoft.VisualStudio.Services.TFS"</span><span class="hljs-punctuation">,</span><span class="hljs-attr">"deletedReason"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"The build was manually deleted."</span><span class="hljs-punctuation">,</span><span class="hljs-attr">"pr.autoCancel"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"true"</span></code></pre><p>Aí o culpado... <strong>Não foi o dev. Não foi ninguém do time.</strong> Foi o próprio Azure DevOps, pelo <code>pr.autoCancel</code> que cancela <strong>automaticamente</strong> qualquer build em andamento <strong>toda vez que a PR é atualizada.</strong></p><p>Fui até a PR no Bitbucket para tirar a prova real, e reconstruí a sequência, olha que dahora:</p><ol><li>Dev abriu a PR → build <strong>20000000.1</strong> inicia</li><li>Dev marcou como <strong>DRAFT</strong> → auto-cancel derruba o build <strong>.1</strong> → build <strong>20000000.2</strong> inicia</li><li>Dev editou o título da PR → auto-cancel derruba o build <strong>.2</strong> durante o npm install → <strong>.cli-Xuqet0PR</strong> fica incompleto na VM → build <strong>20000000.3</strong> inicia → <strong>ENOTEMPTY</strong> → todos os builds seguintes quebram.</li></ol><blockquote><p><strong>Insight:</strong> Olha que massa, eu realmente não sabia que editar o título de uma PR também disparava um novo build. E na verdade qualquer atualização na PR com um build em andamento aciona o <code>pr.autoCancel</code>. Se o cancelamento ocorre no meio de um processo com estado em disco, como o <code>npm install</code>, o rastro fica na VM e quebra todos os builds seguintes até alguém limpar manualmente.</p></blockquote><p>Caraca, fiquei de cara quando entendi o problema pela raiz... e qual foi o aprendizado? <strong>Só crie a PR quando ela estiver 100% pronta. xD</strong></p><p>Obviamente que esse problema não podemos colocar na conta do novato... nem eu sabia que podia dar problema... mas uma boa prática é você abrir a PR tendo a certeza que ela está pronta... ou já abrir ela como draft.</p><p>E é isso, basicamente essas 3 mudanças rápidas que o dev fez (literalmente uma em seguida da outra) foi matando os builds com o autocancel e na última alteração deu ruim.</p><p>Bom, isso ocorreu há um tempo atrás... mas conhecimento nunca ocupa espaço, então ficou de aprendizado haha</p><p>Já tinha visto esse B.O antes? Conta aí</p><hr><h2 id="aguillarops-content-ficou-em-aberto">Ficou em aberto</h2><p><strong>Por que o npm não faz cleanup ao receber o sinal de cancelamento?</strong> Dependendo de como o sinal é entregue e em que ponto do rename o processo estava, o cleanup pode não acontecer. Não investiguei a fundo.</p><p><strong>O <code>pr.autoCancel</code> tem configuração granular?</strong> Não verifiquei se é possível desativar por pipeline específica ou se é global.</p><p><strong>Dá para tornar o step idempotente?</strong> Uma limpeza antes do <code>npm install -g</code> eliminaria o problema independentemente de cancelamentos futuros:</p><pre><code class="hljs language-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">script:</span> <span class="hljs-string">|    rm -rf $(node_modules_path)/@angular/cli    rm -rf $(node_modules_path)/@angular/.cli-*</span>  <span class="hljs-attr">displayName:</span> <span class="hljs-string">'Clean Angular'</span></code></pre><p>Não implementei ainda. Não sei se gera efeito colateral em builds paralelos no mesmo agente.</p><hr><h2 id="aguillarops-content-referências">Referências</h2><ul><li><a href="https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds?view=azure-devops-rest-7.1" rel="nofollow">Azure DevOps REST API - Builds</a></li><li><a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/bitbucket?view=azure-devops&#x26;tabs=yaml#pr-triggers" rel="nofollow">Azure Pipelines - PR Triggers e autoCancel</a></li><li><a href="https://docs.npmjs.com/cli/v10/commands/npm-install" rel="nofollow">npm CLI - npm install</a></li></ul><hr><p><em>Vinicius Aguilar — DevOps Engineer</em></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Criei uma IDE de terminal pra trabalhar com agentes de IA (Claude Code, Gemini CLI, Codex)]]></title>
            <link>https://www.tabnews.com.br/germanheller/criei-uma-ide-de-terminal-pra-trabalhar-com-agentes-de-ia-claude-code-gemini-cli-codex</link>
            <guid>https://www.tabnews.com.br/germanheller/criei-uma-ide-de-terminal-pra-trabalhar-com-agentes-de-ia-claude-code-gemini-cli-codex</guid>
            <pubDate>Wed, 08 Apr 2026 02:10:10 GMT</pubDate>
            <description><![CDATA[Fala pessoal, Sou o Germán, dev solo de Buenos Aires. Nos últimos meses tenho trabalhado full-time com agentes de IA (principalmente Claude Code e Gemini CLI) e percebi que faltava uma fe...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Fala pessoal,</p><p>Sou o Germán, dev solo de Buenos Aires. Nos últimos meses tenho trabalhado full-time com agentes de IA (principalmente Claude Code e Gemini CLI) e percebi que faltava uma ferramenta decente pra gerenciar essa bagunça toda de terminais.</p><p>O problema é simples: quando você roda 3-4 agentes de IA ao mesmo tempo, cada um num terminal diferente, fica impossível acompanhar qual precisa de input, qual tá processando, qual já terminou. Alt-tab entre 6 janelas o dia todo não é produtividade, é sofrimento.</p><h2 id="germanheller-content-o-que-eu-construí">O que eu construí</h2><p><strong>Patapim</strong> — uma IDE de terminal (não é editor de código) feita especificamente pra quem trabalha com agentes de IA.</p><p>As features principais:</p><p><strong>Grid de 9 terminais</strong> — Tudo na mesma tela, cada terminal com borda colorida: vermelho = agente trabalhando, verde = precisa do seu input. Parece bobagem mas isso mudou meu workflow completamente. Antes eu ficava checando terminal por terminal.</p><p><strong>Ditado por voz local</strong> — Usa Whisper rodando local, nada sai da sua máquina. Eu uso porque já tive problemas com eye floaters e ficar digitando o dia todo é complicado. Mas qualquer um que prefere falar ao invés de digitar comandos longos vai curtir.</p><p><strong>Acesso remoto pelo celular</strong> — Gera um QR code, abre um túnel via Cloudflare, e você controla seus terminais do celular. Eu uso quando preciso sair do computador mas tenho agentes rodando.</p><p><strong>Browser embutido como MCP server</strong> — O Claude Code consegue controlar um browser real direto do terminal. Pra automação e testes é muito útil.</p><h2 id="germanheller-content-stack-técnico-pra-quem-curte">Stack técnico (pra quem curte)</h2><ul><li>Electron + xterm.js + node-pty</li><li>WebSocket pra comunicação em tempo real entre terminais</li><li>Cloudflare Workers pro túnel remoto</li><li>Whisper.cpp compilado local pra ditado</li><li>O browser se registra como MCP server automaticamente</li></ul><h2 id="germanheller-content-preço">Preço</h2><p>Tier grátis com tudo que importa (9 terminais, 3 projetos, 30 min ditado/dia). Pro a <span class="math math-inline">6.99/mês ou </span>29.99 lifetime pra quem quer projetos ilimitados e ditado ilimitado.</p><h2 id="germanheller-content-por-que-tô-postando-aqui">Por que tô postando aqui</h2><p>Eu sei que TabNews valoriza conteúdo técnico, não propaganda. Não vim aqui vender nada — vim compartilhar porque genuinamente acho que quem tá usando Claude Code ou Gemini CLI no dia-a-dia vai entender o problema que isso resolve.</p><p>Se alguém quiser testar, posso dar licença Pro gratuita. Sem compromisso nenhum, só quero feedback.</p><p><strong>Site:</strong> patapim.ai</p><p>Aceito perguntas técnicas, críticas, sugestões. Se alguém quiser que eu faça um post mais deep-dive sobre alguma parte da arquitetura (tipo como integrei o Whisper, ou como funciona o MCP server), me fala que eu escrevo.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitch: LLM-MAR: Um CLI para criar agentes rápido]]></title>
            <link>https://www.tabnews.com.br/renatojrrs/llm-mar-um-cli-para-criar-agentes-rapido</link>
            <guid>https://www.tabnews.com.br/renatojrrs/llm-mar-um-cli-para-criar-agentes-rapido</guid>
            <pubDate>Wed, 08 Apr 2026 02:09:06 GMT</pubDate>
            <description><![CDATA[Hoje, quero apresentar um projeto empolgante que venho desenvolvendo: LLM-MAR (Multi Agent Reasoning). Este é um CLI compacto e poderoso que permite criar agentes de LLM, fazer debates en...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Hoje, quero apresentar um projeto empolgante que venho desenvolvendo: <strong>LLM-MAR</strong> (Multi Agent Reasoning). Este é um CLI compacto e poderoso que permite criar agentes de LLM, fazer debates entre eles, responder perguntas e construir workflows complexos.</p><h2 id="renatojrrs-content-o-que-é-llm-mar">O que é LLM-MAR?</h2><p>LLM-MAR é uma ferramenta de linha de comando que simplifica o trabalho com Large Language Models (LLMs) em cenários multi-agente. A sigla MAR significa "Multi Agent Reasoning" - raciocínio multi-agente. A ideia é permitir que diferentes agentes especializados colaborem, debatam e cheguem a conclusões mais robustas.</p><h3 id="renatojrrs-content-principais-recursos">Principais Recursos</h3><ul><li><strong>Criação de Agentes</strong>: Defina agentes com personalidades, objetivos e instruções específicas</li><li><strong>Debates Inteligentes</strong>: Faça agentes debaterem tópicos complexos</li><li><strong>Workflows Flexíveis</strong>: Construa pipelines de processamento com múltiplos agentes</li><li><strong>Integração OpenAI</strong>: Suporte nativo para modelos GPT via LangChain</li><li><strong>Formato YAML</strong>: Configurações fáceis de versionar e compartilhar</li></ul><h2 id="renatojrrs-content-por-que-multi-agent-reasoning">Por que Multi-Agent Reasoning?</h2><p>Os LLMs são incrivelmente poderosos, mas têm limitações quando trabalham isoladamente. O raciocínio multi-agente oferece várias vantagens:</p><ol><li><strong>Perspectivas Diversas</strong>: Diferentes agentes podem abordar problemas de ângulos únicos</li><li><strong>Validação Cruzada</strong>: Agentes podem verificar e refinar as respostas uns dos outros</li><li><strong>Especialização</strong>: Cada agente pode se focar em aspectos específicos do problema</li><li><strong>Robustez</strong>: Reduz alucinações através de consenso e debate</li></ol><h2 id="renatojrrs-content-como-começar">Como Começar</h2><h3 id="renatojrrs-content-instalação">Instalação</h3><pre><code class="hljs language-bash">npm install -g llm-mar</code></pre><h3 id="renatojrrs-content-configuração">Configuração</h3><p>Configure sua chave da OpenAI:</p><pre><code class="hljs language-bash"><span class="hljs-built_in">export</span> OPENAI_API_KEY=sua_chave_aqui</code></pre><h3 id="renatojrrs-content-primeiro-agente">Primeiro Agente</h3><p>Crie um agente simples:</p><pre><code class="hljs language-bash">llm-mar create agent meu_agente \  --model gpt-4 \  --goal <span class="hljs-string">"Responder perguntas de forma clara e precisa"</span> \  --role <span class="hljs-string">"Assistente Técnico"</span> \  --system-prompt <span class="hljs-string">"Você é um assistente técnico especializado em desenvolvimento de software."</span> \  --instructions <span class="hljs-string">"Pense passo a passo,Seja conciso mas completo"</span> \  --output text</code></pre><h3 id="renatojrrs-content-executando-o-agente">Executando o Agente</h3><pre><code class="hljs language-bash">llm-mar run default/meu_agente.yaml --input <span class="hljs-string">"Como implementar autenticação JWT em Node.js?"</span></code></pre><h2 id="renatojrrs-content-casos-de-uso-avançados">Casos de Uso Avançados</h2><h3 id="renatojrrs-content-debates-filosóficos">Debates Filosóficos</h3><p>Imagine um debate entre agentes representando diferentes filósofos:</p><ul><li><strong>Sócrates</strong>: Focado em questionamento e maiêutica</li><li><strong>Aristóteles</strong>: Ênfase em lógica e observação empírica</li><li><strong>Platão</strong>: Perspectiva idealista e formas puras</li></ul><h3 id="renatojrrs-content-análise-de-código">Análise de Código</h3><p>Agentes especializados em diferentes aspectos:</p><ul><li><strong>Segurança</strong>: Foca em vulnerabilidades</li><li><strong>Performance</strong>: Otimização e eficiência</li><li><strong>Manutenibilidade</strong>: Legibilidade e padrões</li></ul><h3 id="renatojrrs-content-tomada-de-decisão-empresarial">Tomada de Decisão Empresarial</h3><ul><li><strong>Analista Financeiro</strong>: Foca em ROI e custos</li><li><strong>Especialista em UX</strong>: Considera experiência do usuário</li><li><strong>Desenvolvedor</strong>: Avalia viabilidade técnica</li></ul><h2 id="renatojrrs-content-arquitetura-técnica">Arquitetura Técnica</h2><p>O LLM-MAR é construído com tecnologias modernas:</p><ul><li><strong>Node.js</strong>: Runtime JavaScript eficiente</li><li><strong>Commander.js</strong>: Para interface de linha de comando robusta</li><li><strong>LangChain</strong>: Framework para aplicações LLM</li><li><strong>YAML</strong>: Formato de configuração legível por humanos</li><li><strong>Zod</strong>: Validação de esquemas TypeScript</li></ul><h2 id="renatojrrs-content-benefícios-para-desenvolvedores">Benefícios para Desenvolvedores</h2><ol><li><strong>Prototyping Rápido</strong>: Crie agentes complexos em minutos</li><li><strong>Versionamento</strong>: Configurações em YAML facilitam controle de versão</li><li><strong>Extensibilidade</strong>: Arquitetura modular permite novos tipos de agentes</li><li><strong>Integração</strong>: Funciona com qualquer LLM suportado pelo LangChain</li><li><strong>Open Source</strong>: Código disponível para contribuição e auditoria</li></ol><h2 id="renatojrrs-content-futuro-do-projeto">Futuro do Projeto</h2><p>Estamos trabalhando em várias melhorias:</p><ul><li><strong>Suporte a mais provedores</strong>: Anthropic, Google, local LLMs</li><li><strong>Integração com ferramentas</strong>: GitHub Actions, CI/CD</li><li><strong>Templates pré-configurados</strong>: Agentes para casos comuns</li><li><strong>Avaliação automática</strong>: Métricas de qualidade das respostas</li></ul><h2 id="renatojrrs-content-contribuição">Contribuição</h2><p>O projeto é open source, se você tem ideias para melhorar o LLM-MAR:</p><ol><li>Abra uma issue no <a href="https://github.com/renatojuniorrs/llm-mar">GitHub</a></li><li>Faça um fork e envie um PR</li></ol></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LLM Wiki: Como Construir uma Base de Conhecimento Pessoal que Evolui Sozinha]]></title>
            <link>https://www.tabnews.com.br/andersonlimadev/llm-wiki-como-construir-uma-base-de-conhecimento-pessoal-que-evolui-sozinha</link>
            <guid>https://www.tabnews.com.br/andersonlimadev/llm-wiki-como-construir-uma-base-de-conhecimento-pessoal-que-evolui-sozinha</guid>
            <pubDate>Wed, 08 Apr 2026 00:55:38 GMT</pubDate>
            <description><![CDATA[Este post é baseado no artigo de Andrej Karpathy publicado em abril de 2026, onde ele propõe um padrão inovador para gerenciar conhecimento pessoal com o auxílio de LLMs. O Problema com R...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><blockquote><p>Este post é baseado no artigo de Andrej Karpathy publicado em abril de 2026, onde ele propõe um padrão inovador para gerenciar conhecimento pessoal com o auxílio de LLMs.</p></blockquote><h2 id="andersonlimadev-content-o-problema-com-rag-tradicional">O Problema com RAG Tradicional</h2><p>A maioria das pessoas que usa LLMs com documentos segue o mesmo padrão: você envia arquivos, o modelo recupera fragmentos relevantes e gera uma resposta. É o que chamamos de RAG (Retrieval-Augmented Generation).</p><p>Funciona. Mas tem um problema fundamental que Karpathy identifica com precisão:</p><blockquote><p>"Nada é construído. O LLM redescobre conhecimento do zero a cada pergunta."</p></blockquote><p>Toda vez que você faz uma pergunta, o modelo parte da estaca zero. Não há acúmulo. Não há síntese persistente. Não há memória real — apenas recuperação.</p><h2 id="andersonlimadev-content-a-proposta-um-wiki-mantido-por-llms">A Proposta: Um Wiki Mantido por LLMs</h2><p>A ideia central do <strong>LLM Wiki</strong> é simples, mas poderosa: em vez de usar o LLM apenas para recuperar documentos brutos, você o usa para <strong>construir e manter um wiki persistente</strong>.</p><p>Esse wiki é uma coleção estruturada e interligada de arquivos Markdown que fica entre você e suas fontes originais. Quando você adiciona um novo documento, o LLM não apenas o indexa — ele:</p><ol><li>Lê o documento inteiro</li><li>Extrai as informações-chave</li><li>Integra-as ao wiki existente</li><li>Atualiza páginas de entidades relacionadas</li><li>Revisa sínteses já existentes</li><li>Sinaliza contradições entre fontes</li></ol><p>A diferença crucial: <strong>o wiki é um artefato persistente e composto</strong>. As referências cruzadas já existem. As contradições já foram identificadas. O trabalho intelectual de conexão não precisa ser refeito a cada consulta.</p><h2 id="andersonlimadev-content-as-três-camadas-da-arquitetura">As Três Camadas da Arquitetura</h2><p>O padrão é elegantemente dividido em três camadas:</p><h3 id="andersonlimadev-content-1-fontes-brutas">1. Fontes Brutas</h3><p>Seus documentos originais — artigos, papers, notas, dados. São imutáveis. O LLM lê, mas nunca altera.</p><h3 id="andersonlimadev-content-2-o-wiki">2. O Wiki</h3><p>Um diretório de arquivos Markdown <strong>gerados e mantidos pelo LLM</strong>. Contém resumos, páginas de entidades, sínteses temáticas, e conexões entre conceitos.</p><h3 id="andersonlimadev-content-3-o-schema-claudemd">3. O Schema (CLAUDE.md)</h3><p>Um documento de configuração que instrui o LLM sobre a estrutura do seu wiki, as convenções de nomenclatura, e os fluxos de trabalho esperados. É aqui que você define as regras do jogo.</p><h2 id="andersonlimadev-content-as-três-operações-principais">As Três Operações Principais</h2><h3 id="andersonlimadev-content-ingest">Ingest</h3><p>Quando uma nova fonte entra, o LLM a processa completamente: cria uma página de resumo, atualiza o índice, e modifica 10 a 15 páginas correlatas do wiki. O trabalho que levaria horas para um humano acontece em minutos.</p><h3 id="andersonlimadev-content-query">Query</h3><p>Ao fazer uma pergunta, o LLM busca páginas relevantes do wiki (não os documentos brutos), sintetiza uma resposta com citações, e pode opcionalmente arquivar os achados como novas páginas — fazendo o conhecimento crescer por exploração, não apenas por ingestão.</p><h3 id="andersonlimadev-content-lint">Lint</h3><p>Uma verificação periódica de saúde do wiki: contradições entre fontes, claims desatualizados, páginas órfãs sem referências, lacunas de cobertura. Como um compilador, mas para conhecimento.</p><h2 id="andersonlimadev-content-arquivos-especiais">Arquivos Especiais</h2><p>O padrão define dois arquivos de controle:</p><ul><li><strong>index.md</strong> — catálogo orientado ao conteúdo, organizado por categoria. Sua visão geral de tudo que existe no wiki.</li><li><strong>log.md</strong> — registro cronológico e append-only de todas as operações. Permite auditar o que foi processado e quando.</li></ul><h2 id="andersonlimadev-content-onde-usar">Onde Usar</h2><p>Karpathy sugere vários contextos práticos:</p><ul><li><strong>Rastreamento pessoal</strong> — objetivos, saúde, psicologia, journaling estruturado</li><li><strong>Pesquisa aprofundada</strong> — mergulhos em tópicos complexos com síntese progressiva</li><li><strong>Leitura de livros</strong> — personagens, temas e conexões entre obras mantidos automaticamente</li><li><strong>Wikis de equipe</strong> — alimentados por transcrições de reuniões e documentos internos</li><li><strong>Análise competitiva</strong> — due diligence, benchmarking, monitoramento de mercado</li></ul><h2 id="andersonlimadev-content-por-que-isso-importa">Por Que Isso Importa</h2><p>A ideia remete ao conceito de <strong>Memex</strong> de Vannevar Bush (1945) — uma máquina para estender a memória humana através de associações. A diferença é que, em 1945, manter essas associações seria trabalho humano intenso. Hoje, os LLMs resolvem exatamente essa parte.</p><p>Como Karpathy coloca:</p><blockquote><p>"O LLM não se entedia, não esquece de atualizar referências cruzadas e toca 15 arquivos de uma vez."</p></blockquote><p>O humano continua no papel que faz sentido: curar fontes e fazer as perguntas certas. O LLM executa o trabalho de síntese, arquivamento e manutenção de consistência.</p><h2 id="andersonlimadev-content-minha-leitura">Minha Leitura</h2><p>O que me chama atenção nesse padrão é o <strong>compounding</strong>. Conhecimento que cresce por uso, não apenas por acumulação. Cada consulta bem respondida pode se tornar uma nova entrada no wiki. Cada nova fonte processada enriquece as conexões existentes.</p><p>É uma mudança de paradigma sobre o que significa "usar um LLM": de uma ferramenta de consulta pontual para um <strong>parceiro de curadoria intelectual contínua</strong>.</p><p>Se você trabalha com pesquisa, escrita, ou qualquer domínio onde o acúmulo de conhecimento importa, vale experimentar esse padrão.</p><hr><p><em>Leia o artigo original de Andrej Karpathy no GitHub Gist.</em></p><p><a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f">https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f</a></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[55k seguidores no Instagram] Construí audiência no último ano, agora quero construir pra ela.. só não sei o que]]></title>
            <link>https://www.tabnews.com.br/jotacurityba/55k-seguidores-no-instagram-construi-audiencia-no-ultimo-ano-agora-quero-construir-pra-ela-so-nao-sei-o-que</link>
            <guid>https://www.tabnews.com.br/jotacurityba/55k-seguidores-no-instagram-construi-audiencia-no-ultimo-ano-agora-quero-construir-pra-ela-so-nao-sei-o-que</guid>
            <pubDate>Wed, 08 Apr 2026 00:30:48 GMT</pubDate>
            <description><![CDATA[Construí audiência no instagram no último ano sem aparecer, tenho uma página de filosofia, focada em estoicismo, e já não é de hoje que penso nisso, mas agora tomei a decisão de botar pra...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Construí audiência no instagram no último ano sem aparecer, tenho uma página de filosofia, focada em estoicismo, e já não é de hoje que penso nisso, mas agora tomei a decisão de botar pra frente.. quero construir apps pra minha audiência, testar, iterar... aproveitar a distribuição e a credibilidade que construí até aqui.</p><p>Obviamente não quero construir mais um habit tracker, app de meditação, ou diário, como outros mihões que já existem.. Caso alguém tenha alguma ideia que gostaria de compartilhar ou interesse em conversar sobre construirmos algo juntos, confere minha página e o meu email pra contato abaixo:</p><p>Minha página é a <a href="https://www.instagram.com/stoicus.filosofia/" rel="nofollow">stoicus.filosofia</a>.</p><p>E-mail para contato: <a href="mailto:stoicusfilosofia@gmail.com">stoicusfilosofia@gmail.com</a></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Microsoft vai forçar atualização de dispositivos com Windows 11 24H2 para 25H2]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/microsoft-vai-forcar-atualizacao-de-dispositivos-com-windows-11-24h2-para-25h2</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/microsoft-vai-forcar-atualizacao-de-dispositivos-com-windows-11-24h2-para-25h2</guid>
            <pubDate>Tue, 07 Apr 2026 21:51:11 GMT</pubDate>
            <description><![CDATA[A Microsoft anunciou que passará a forçar a atualização de dispositivos ainda em execução no Windows 11 24H2 para a versão mais recente, o 25H2. O suporte ao 24H2 será encerrado em 13 de...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A Microsoft anunciou que passará a forçar a atualização de dispositivos ainda em execução no Windows 11 24H2 para a versão mais recente, o 25H2. O suporte ao 24H2 será encerrado em 13 de outubro.</p><p>A distribuição obrigatória será direcionada especificamente a dispositivos com as edições Home e Pro do Windows 11 24H2. Máquinas gerenciadas por organizações ou departamentos de TI, por enquanto, não estão incluídas nesse processo.</p><p>A liberação será conduzida por um sistema de atualização inteligente baseado em aprendizado de máquina, responsável por determinar quando cada dispositivo está pronto para receber o update. No entanto, não foram divulgados detalhes sobre os critérios utilizados para essa decisão.</p><p>Usuários ainda poderão adiar a atualização por um período limitado, embora esse intervalo não tenha sido especificado. Também será possível iniciar o processo manualmente por meio do Windows Update.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Grupos de ransomware publicam mais de 7,6 mil reivindicações de vítimas em pouco mais de um ano]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/grupos-de-ransomware-publicam-mais-de-7-6-mil-reivindicacoes-de-vitimas-em-pouco-mais-de-um-ano</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/grupos-de-ransomware-publicam-mais-de-7-6-mil-reivindicacoes-de-vitimas-em-pouco-mais-de-um-ano</guid>
            <pubDate>Tue, 07 Apr 2026 21:46:21 GMT</pubDate>
            <description><![CDATA[Entre 1º de março de 2025 e 11 de março de 2026, grupos de ransomware divulgaram 7.655 reivindicações de vítimas em sites públicos de vazamento, anúncios nos quais afirmam ter invadido or...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Entre 1º de março de 2025 e 11 de março de 2026, grupos de ransomware divulgaram 7.655 reivindicações de vítimas em sites públicos de vazamento, anúncios nos quais afirmam ter invadido organizações e roubado seus dados. O volume equivale a uma média de cerca de 20 casos por dia, ou uma nova organização exposta a cada 71 minutos.</p><p>Os grupos com maior número de reivindicações no período foram Qilin, com 1.179 registros, Akira, com 706, e INC Ransom, com 415.</p><p>Em relação aos setores, o de manufatura lidera com 890 reivindicações, no qual interrupções operacionais tendem a aumentar a pressão pelo pagamento de resgates. Na sequência aparecem os setores de tecnologia, com 843, e saúde, com 537.</p><p>No recorte por países, os EUA concentram 3.101 reivindicações, seguidos por Alemanha, com 315, e Canadá, com 311. O Brasil aparece na 8ª posição, com 132 casos.</p><p>Os dados foram compilados a partir de publicações em sites de vazamento monitorados por rastreadores públicos de atividades de ransomware. As contagens não representam necessariamente invasões confirmadas, mas sim alegações feitas publicamente pelos próprios grupos criminosos.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Anthropic anuncia Project Glasswing]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/anthropic-anuncia-project-glasswing</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/anthropic-anuncia-project-glasswing</guid>
            <pubDate>Tue, 07 Apr 2026 21:43:30 GMT</pubDate>
            <description><![CDATA[A Anthropic anunciou o Project Glasswing, uma iniciativa que reúne empresas como AWS, Apple, CrowdStrike, Google, Linux Foundation, Microsoft e Nvidia com o objetivo de fortalecer a segur...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A Anthropic anunciou o Project Glasswing, uma iniciativa que reúne empresas como AWS, Apple, CrowdStrike, Google, Linux Foundation, Microsoft e Nvidia com o objetivo de fortalecer a segurança dos softwares mais críticos do mundo.</p><p>O núcleo do projeto é o modelo Claude Mythos Preview, ainda não lançado, mas que, segundo a empresa, já apresenta um nível de capacidade capaz de superar a maioria dos humanos na identificação e exploração de vulnerabilidades.</p><p>Como parte da iniciativa, as empresas parceiras passarão a utilizar a tecnologia em suas operações de segurança defensiva. O acesso também foi ampliado para mais de 40 organizações responsáveis pelo desenvolvimento ou manutenção de infraestruturas críticas.</p><p>De acordo com a Anthropic, nas últimas semanas o Mythos Preview foi empregado na identificação de milhares de vulnerabilidades zero-day, muitas classificadas como críticas, abrangendo todos os principais sistemas operacionais e navegadores.</p><p>Entre os casos identificados estão uma vulnerabilidade de 27 anos no OpenBSD, que permitia derrubar remotamente qualquer máquina conectada ao sistema; uma falha de 16 anos no FFmpeg, localizada em um trecho de código amplamente testado sem que o problema fosse detectado; além de múltiplas vulnerabilidades no Linux kernel, que possibilitavam a escalada de privilégios de um usuário comum para controle total da máquina. Todas as falhas já foram corrigidas.</p><p>Ainda não há previsão para a disponibilização pública da tecnologia.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cloudflare pretende alcançar segurança totalmente resistente a computadores quânticos até 2029]]></title>
            <link>https://www.tabnews.com.br/NewsletterOficial/cloudflare-pretende-alcancar-seguranca-totalmente-resistente-a-computadores-quanticos-ate-2029</link>
            <guid>https://www.tabnews.com.br/NewsletterOficial/cloudflare-pretende-alcancar-seguranca-totalmente-resistente-a-computadores-quanticos-ate-2029</guid>
            <pubDate>Tue, 07 Apr 2026 21:40:43 GMT</pubDate>
            <description><![CDATA[A Cloudflare anunciou o objetivo de implementar, até 2029, um modelo de segurança totalmente resistente a computadores quânticos. A urgência aumentou após avanços recentes no setor, inclu...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>A Cloudflare anunciou o objetivo de implementar, até 2029, um modelo de segurança totalmente resistente a computadores quânticos.</p><p>A urgência aumentou após avanços recentes no setor, incluindo o desenvolvimento, pelo Google, de um algoritmo capaz de quebrar criptografia de curva elíptica, amplamente utilizada em conexões HTTPS, certificados digitais, aplicativos de mensagens com criptografia de ponta a ponta e criptomoedas.</p><p>Esses progressos indicam que o chamado “Q-Day”, momento em que computadores quânticos conseguirão comprometer os padrões atuais de criptografia, pode ocorrer por volta de 2030.</p><p>Desde 2022, a Cloudflare já adota criptografia pós-quântica em sites sob sua proteção como forma de mitigar ataques do tipo “coletar agora, descriptografar depois”, estratégia em que invasores interceptam e armazenam dados criptografados hoje para decifrá-los no futuro, quando dispuserem de tecnologia suficiente. Agora, o principal risco passa a ser a quebra de mecanismos de autenticação, o que pode permitir que agentes maliciosos se passem por sistemas legítimos ou forjem credenciais válidas.</p><p>A empresa afirma que pretende disponibilizar essas proteções de forma padrão e sem custo adicional assim que estiverem disponíveis no futuro.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como eu parei de inventar números e passei a derivar tokens de design com Fibonacci e Φ]]></title>
            <link>https://www.tabnews.com.br/MolinariCode/como-eu-parei-de-inventar-numeros-e-passei-a-derivar-tokens-de-design-com-fibonacci-e-f</link>
            <guid>https://www.tabnews.com.br/MolinariCode/como-eu-parei-de-inventar-numeros-e-passei-a-derivar-tokens-de-design-com-fibonacci-e-f</guid>
            <pubDate>Tue, 07 Apr 2026 21:31:20 GMT</pubDate>
            <description><![CDATA[Vou contar um problema que qualquer dev que cuida do próprio front já viveu: você abre o CSS de um projeto com seis meses, procura o gap entre dois componentes e encontra 12px num lugar,...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Vou contar um problema que qualquer dev que cuida do próprio front já viveu: você abre o CSS de um projeto com seis meses, procura o gap entre dois componentes e encontra <code>12px</code> num lugar, <code>14px</code> em outro, <code>13px</code> num terceiro. Ninguém sabe de onde vieram. Provavelmente de um "parece certo" feito em três momentos diferentes, com estados de espírito diferentes.</p><p>Isso tem nome: é decisão sem critério. E ela acumula.</p><p>Passei alguns meses construindo um sistema para resolver isso de forma que fosse <strong>auditável</strong> — onde qualquer token publicado tivesse uma cadeia de raciocínio rastreável. O resultado foi um framework de derivação matemática usando três constantes: a Razão Áurea (Φ), a Sequência de Fibonacci e o Ângulo Áureo (θ).</p><p>O artigo explica o método. Não é magia — é uma estrutura de decisão.</p><h2 id="molinaricode-content-o-problema-que-eu-queria-resolver">O problema que eu queria resolver</h2><p>Decisões arbitrárias de espaçamento e tipografia não são apenas esteticamente incômodas. Elas criam <strong>dívida técnica de design</strong>: valores sem critério que nenhum novo membro do time consegue reconstituir, exceções que se acumulam sem registro, sistemas que funcionam parte por parte mas não comunicam unidade formal.</p><p>A primeira pergunta que me fiz foi: existe uma forma de derivar tokens a partir de um método reproduzível, que qualquer pessoa com acesso à documentação consiga reconstruir do zero?</p><p>A resposta foi usar matemática como estrutura de relações — não como garantia de beleza, mas como <strong>fonte de consistência</strong>.</p><h2 id="molinaricode-content-por-que-fibonacci-para-espaçamento">Por que Fibonacci para espaçamento?</h2><p>A Sequência de Fibonacci (<code>1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...</code>) tem uma propriedade útil para design: ela é <strong>aditiva com saltos crescentes</strong>. Isso produz uma escala que cobre bem o range de micro (2–8px) a macro (55–144px) sem exigir interpolação arbitrária.</p><p>A ideia é simples: você escolhe uma âncora — um step Fibonacci que vai corresponder a um valor em px que faz sentido ergonômico para o seu produto — e deriva o resto por proporção.</p><p><strong>Exemplo com âncora F(9)=34 → 16px:</strong></p><pre><code>space(n) = F(n) × (16/34)F(8)=21  →  9.88px  → quantizado para 10pxF(9)=34  → 16.00px  ← âncoraF(10)=55 → 25.88px  → quantizado para 26pxF(11)=89 → 41.88px  → quantizado para 42px</code></pre><p>O token publicado não é <code>9.88px</code> — é <code>10px</code>. A derivação fica documentada internamente; o CSS recebe valores limpos.</p><pre><code class="hljs language-css"><span class="hljs-selector-pseudo">:root</span> {  <span class="hljs-attr">--space-10</span>:  <span class="hljs-number">10px</span>;  <span class="hljs-attr">--space-16</span>:  <span class="hljs-number">16px</span>;   <span class="hljs-comment">/* âncora F(9) */</span>  <span class="hljs-attr">--space-26</span>:  <span class="hljs-number">26px</span>;  <span class="hljs-attr">--space-42</span>:  <span class="hljs-number">42px</span>;  <span class="hljs-attr">--space-68</span>:  <span class="hljs-number">68px</span>;  <span class="hljs-attr">--space-110</span>: <span class="hljs-number">110px</span>;}</code></pre><p>E os componentes nunca usam esses primitivos diretamente — usam tokens semânticos:</p><pre><code class="hljs language-css"><span class="hljs-selector-pseudo">:root</span> {  <span class="hljs-attr">--space-inset-md</span>:  <span class="hljs-built_in">var</span>(--space-<span class="hljs-number">10</span>);  <span class="hljs-comment">/* padding de botão */</span>  <span class="hljs-attr">--space-gap-lg</span>:    <span class="hljs-built_in">var</span>(--space-<span class="hljs-number">16</span>);  <span class="hljs-comment">/* gap entre grupos */</span>  <span class="hljs-attr">--space-section-sm</span>: <span class="hljs-built_in">var</span>(--space-<span class="hljs-number">42</span>); <span class="hljs-comment">/* entre seções */</span>}<span class="hljs-selector-class">.button</span> {  <span class="hljs-attribute">padding</span>: <span class="hljs-built_in">var</span>(--space-inset-md); <span class="hljs-comment">/* correto */</span>  <span class="hljs-comment">/* padding: var(--space-10);   ← nunca isso */</span>}</code></pre><p>Quando você muda a âncora, reconstrói a escala inteira. Quando você muda a semântica, refatora os tokens sem mexer no CSS dos componentes.</p><h2 id="molinaricode-content-por-que-φ-para-tipografia">Por que Φ para tipografia?</h2><p>A Razão Áurea (Φ ≈ 1.618) gera progressões geométricas com razão constante e auto-similar. Em tipografia, isso significa que cada step tem a mesma relação com os adjacentes.</p><p>Mas — e esse "mas" é importante — <strong>Φ não é bala de prata</strong>. Para dashboards e interfaces densas, uma escala com Φ produz headings gigantes:</p><table><thead><tr><th>Nível</th><th>Razão Φ (BASE=16px)</th><th>Quarta Perfeita (1.333)</th></tr></thead><tbody><tr><td>Body</td><td>16px</td><td>16px</td></tr><tr><td>H2</td><td>41.9px</td><td>28.4px</td></tr><tr><td>H1</td><td>67.8px</td><td>37.9px</td></tr></tbody></table><p>Um H1 de 67px convive bem num hero de landing page. Num dashboard onde heading e corpo dividem a mesma tela, é inapropriado. A escolha da razão é editorial — o framework oferece um menu de razões com nomes baseados em intervalos musicais:</p><table><thead><tr><th>Razão</th><th>Nome</th><th>Caráter</th><th>Melhor para</th></tr></thead><tbody><tr><td>1.125</td><td>Seg. Maior</td><td>Sutil</td><td>Admin panels, documentação</td></tr><tr><td>1.250</td><td>Terça Maior</td><td>Equilibrado</td><td>SaaS, dashboards</td></tr><tr><td>1.333</td><td>Quarta Perf.</td><td>Clara</td><td>Marketing, landing pages</td></tr><tr><td>1.618</td><td>Phi</td><td>Expressivo</td><td>Luxury brands, hero sections</td></tr></tbody></table><p>Em tipografia fluida com <code>clamp()</code>, os limites mínimo e máximo de cada step derivam das duas âncoras — base mobile e base desktop:</p><pre><code class="hljs language-css"><span class="hljs-comment">/* Quarta Perfeita, BASE mobile=14px → desktop=18px */</span><span class="hljs-attr">--text-body</span>: <span class="hljs-built_in">clamp</span>(<span class="hljs-number">0.875rem</span>, <span class="hljs-number">0.696rem</span> + <span class="hljs-number">0.536</span>vi, <span class="hljs-number">1.125rem</span>);<span class="hljs-attr">--text-h2</span>:   <span class="hljs-built_in">clamp</span>(<span class="hljs-number">1.556rem</span>, <span class="hljs-number">1.238rem</span> + <span class="hljs-number">0.952</span>vi, <span class="hljs-number">2.000rem</span>);<span class="hljs-attr">--text-h1</span>:   <span class="hljs-built_in">clamp</span>(<span class="hljs-number">2.075rem</span>, <span class="hljs-number">1.651rem</span> + <span class="hljs-number">1.270</span>vi, <span class="hljs-number">2.669rem</span>);</code></pre><h2 id="molinaricode-content-o-golden-angle-para-distribuição-de-cores">O Golden Angle para distribuição de cores</h2><p>O Ângulo Áureo (θ ≈ 137.508°) distribui matizes no círculo cromático de forma que cada nova cor adicionada ocupa o ponto de maior separação angular das já existentes. É uma propriedade matematicamente verificável, não apenas estética.</p><pre><code>hue(n) = (H₀ + n × 137.508°) mod 360°Com H₀ = 220° (azul-marca):  accent-1: 220.0°  (azul)  accent-2: 357.5°  (vermelho-rosa)  accent-3: 135.0°  (verde)  accent-4: 272.5°  (roxo)  accent-5:  50.0°  (âmbar)</code></pre><p>Para os tokens de cor, o framework usa <code>oklch</code> — um espaço de cor com luminosidade perceptualmente uniforme. <code>hsl(60, 100%, 50%)</code> (amarelo) parece muito mais claro que <code>hsl(240, 100%, 50%)</code> (azul) mesmo com <code>L=50%</code>. Em oklch, o canal L corresponde à luminância percebida pelo olho humano.</p><p><strong>Um aviso importante, que descobri na prática:</strong> nem toda combinação de L, C e H em oklch cabe no gamut sRGB. Antes de publicar tokens em produção, valide clipping de gamut usando <a href="https://oklch.com" rel="nofollow">oklch.com</a>. Copiar os valores sem verificar pode gerar comportamentos inconsistentes entre navegadores.</p><h2 id="molinaricode-content-o-que-a-matemática-não-resolve--e-o-documento-não-esconde">O que a matemática não resolve — e o documento não esconde</h2><p>Esse é talvez o ponto mais importante, e o que diferencia esse framework de um manifesto:</p><p><strong>Proporções matematicamente perfeitas frequentemente precisam de compensação óptica.</strong> Um círculo precisa ser ligeiramente maior que um quadrado de mesma área para parecer do mesmo tamanho. Texto centralizado geometricamente num botão parece baixo demais — o olho humano não lê o centro matemático como centro visual.</p><p><strong>Harmonia proporcional não garante boa UX.</strong> Um componente com espaçamentos perfeitos pode ter hierarquia confusa, affordance inadequada, ergonomia insuficiente.</p><p><strong>Phi não é lei perceptiva universal.</strong> Estudos sobre preferência pela proporção áurea têm resultados mistos e metodologias contestadas. O que Φ oferece é <strong>consistência de razão</strong> — não preferência universal garantida.</p><p>O framework foi escrito para deixar isso explícito. A matemática organiza o espaço de decisão. Dentro dele, julgamento editorial, contexto de produto e pesquisa de usuário continuam determinantes.</p><hr><h2 id="molinaricode-content-a-arquitetura-de-governança">A arquitetura de governança</h2><p>O que diferencia esse projeto de uma tabela de valores é a camada de governança. Cada token tem:</p><ul><li>derivação documentada (de qual fórmula veio)</li><li>erro de quantização registrado</li><li>mapeamento semântico explícito</li><li>critério para abrir exceção</li><li>sinal para recalibrar a âncora</li></ul><p>Por exemplo, se mais de 25% dos componentes precisam de correção manual de line-height, o problema não está nos componentes — está na âncora de leading. Recalibrar é a resposta certa; acumular exceções é dívida técnica disfarçada de flexibilidade.</p><p>O documento define cinco níveis de precedência quando há conflito:</p><pre><code>1 — Acessibilidade (absoluta — contraste WCAG, reduced motion)2 — Ergonomia (tamanhos mínimos de toque, legibilidade)3 — Percepção óptica (compensações necessárias)4 — Coerência semântica (a intenção do token deve ser preservada)5 — Derivação matemática (menor precedência em conflito)</code></pre><p>A matemática tem a menor precedência. Ela é ponto de partida, não ponto de chegada obrigatório.</p><h2 id="molinaricode-content-o-resultado-em-números">O resultado em números</h2><p>O sistema derivado para um SaaS com base 16px, Quarta Perfeita (1.333) e T=150ms de animação:</p><pre><code class="hljs language-css"><span class="hljs-comment">/* Escala de espaçamento completa */</span><span class="hljs-attr">--space-2</span>: <span class="hljs-number">2px</span>;  <span class="hljs-attr">--space-4</span>: <span class="hljs-number">4px</span>;   <span class="hljs-attr">--space-6</span>: <span class="hljs-number">6px</span>;<span class="hljs-attr">--space-10</span>: <span class="hljs-number">10px</span>; <span class="hljs-attr">--space-16</span>: <span class="hljs-number">16px</span>; <span class="hljs-attr">--space-26</span>: <span class="hljs-number">26px</span>;<span class="hljs-attr">--space-42</span>: <span class="hljs-number">42px</span>; <span class="hljs-attr">--space-68</span>: <span class="hljs-number">68px</span>; <span class="hljs-attr">--space-110</span>: <span class="hljs-number">110px</span>;<span class="hljs-comment">/* Durações de animação derivadas de Φ */</span><span class="hljs-attr">--duration-instant</span>: <span class="hljs-number">57ms</span>;   <span class="hljs-comment">/* 150 × Φ⁻² */</span><span class="hljs-attr">--duration-fast</span>:    <span class="hljs-number">93ms</span>;   <span class="hljs-comment">/* 150 × Φ⁻¹ */</span><span class="hljs-attr">--duration-normal</span>:  <span class="hljs-number">150ms</span>;  <span class="hljs-comment">/* âncora */</span><span class="hljs-attr">--duration-slow</span>:    <span class="hljs-number">243ms</span>;  <span class="hljs-comment">/* 150 × Φ¹ */</span><span class="hljs-comment">/* Easing baseado em Φ⁻¹ = 0.618 */</span><span class="hljs-attr">--ease-harmonic</span>: <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.618</span>, <span class="hljs-number">0.000</span>, <span class="hljs-number">0.382</span>, <span class="hljs-number">1.000</span>);<span class="hljs-attr">--ease-out-phi</span>:  <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.000</span>, <span class="hljs-number">0.000</span>, <span class="hljs-number">0.382</span>, <span class="hljs-number">1.000</span>);</code></pre><h2 id="molinaricode-content-onde-encontrar-o-documento-completo">Onde encontrar o documento completo</h2><p>O framework está documentado num arquivo <code>.md</code> de aproximadamente 2.000 linhas, com:</p><ul><li>Derivação matemática de cada subsistema (espaçamento, tipografia, cor, animação, grid, border radius, elevação)</li><li>Tabelas de referência por contexto (SaaS, marketing, editorial, mobile, dashboard)</li><li>Critérios de validação por camada</li><li>Anti-padrões documentados</li><li>Processo de recalibração</li><li>Métricas de sucesso para medir se o sistema está funcionando em produção</li></ul><p>Se houver interesse, o repositorio é: <a href="https://github.com/MolinariBR/NebulaDesign">https://github.com/MolinariBR/NebulaDesign</a>. Aceito perguntas nos comentários — especialmente sobre os trade-offs de escolha de razão tipográfica e os casos onde o framework tem aplicabilidade limitada.</p><p><em>Uma observação final: esse framework é um método, não uma biblioteca. Os tokens são instanciações de uma configuração específica de âncoras. O valor real não está nos números — está na cadeia de decisão que eles tornam auditável.</em></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitch: Show TN: Coding Planets - suas contribuções do github como planeta e em áudio]]></title>
            <link>https://www.tabnews.com.br/jnettome/show-tn-coding-planets-suas-contribucoes-do-github-como-planeta-e-em-audio</link>
            <guid>https://www.tabnews.com.br/jnettome/show-tn-coding-planets-suas-contribucoes-do-github-como-planeta-e-em-audio</guid>
            <pubDate>Tue, 07 Apr 2026 21:17:05 GMT</pubDate>
            <description><![CDATA[Sempre pensei em código como poesia, mas nunca encontrei uma maneira visual de mostrar. Eu AMO áudio (sou dj nas horas vagas) e espaço. Enquanto estava trabalhando em refazer meu site pes...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Sempre pensei em código como poesia, mas nunca encontrei uma maneira visual de mostrar.</p><p>Eu AMO áudio (sou dj nas horas vagas) e espaço.</p><p>Enquanto estava trabalhando em refazer meu site pessoal, resolvi dar um jeito de mostrar essa beleza que eu vejo.</p><p>Assim surgiu o Code Planets - suas contribuções do github como planetas e música.</p><p>Você também pode criar o seu, clica no planeta ali dentro e informa o seu user.<br>Compartilhando pelo link, as configurações de filtros do áudio e do planeta vão junto &#x3C;3</p><p>Valeu galera!</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitch: Como transformei as regras da CLT em um algoritmo Python]]></title>
            <link>https://www.tabnews.com.br/lucasnt/como-transformei-as-regras-da-clt-em-um-algoritmo-python</link>
            <guid>https://www.tabnews.com.br/lucasnt/como-transformei-as-regras-da-clt-em-um-algoritmo-python</guid>
            <pubDate>Tue, 07 Apr 2026 20:54:54 GMT</pubDate>
            <description><![CDATA[Fala, pessoal! Recentemente resolvi criar uma nova ferramenta utilitária para o meu blog e acabei esbarrando num desafio de regra de negócio muito interessante: - calcular uma rescisão de...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Fala, pessoal!</p><p>Recentemente resolvi criar uma nova ferramenta utilitária para o meu blog e acabei esbarrando num desafio de regra de negócio muito interessante:<br><strong>- calcular uma rescisão de contrato CLT.</strong></p><p>Para quem já precisou ler a legislação trabalhista, sabe que ela é cheia de particularidades. Para a lógica de programação, o maior desafio não está nas operações matemáticas em si, mas sim no controle rigoroso das frações de tempo.</p><p>O pulo do gato está na famosa "regra dos 15 dias". Uma fração igual ou superior a 15 dias de trabalho no mês quebrado dá ao empregado o direito a 1/12 extra de férias e de 13º salário. Além disso, existe o cálculo do aviso prévio proporcional, que exige o acréscimo de 3 dias para cada ano completo trabalhado limitado a 90 dias.</p><p>Dessa forma decidi estruturar um algoritmo em Python. Separei as regras trabalhistas em funções modulares. Por exemplo, a lógica de cálculo de férias proporcionais ficou com esse formato para lidar com os meses fechados e o mês "quebrado":</p><pre><code class="hljs language-py"><span class="hljs-keyword">def</span> <span class="hljs-title function_">calcular_ferias_proporcionais</span>(<span class="hljs-params">adm, dem, salario</span>):    anos = dem.year - adm.year    meses = dem.month - adm.month    dias = dem.day - adm.day    <span class="hljs-keyword">if</span> dias &#x3C; <span class="hljs-number">0</span>:        meses -= <span class="hljs-number">1</span>    <span class="hljs-keyword">if</span> meses &#x3C; <span class="hljs-number">0</span>:        anos -= <span class="hljs-number">1</span>        meses += <span class="hljs-number">12</span>    meses_trabalhados = (anos * <span class="hljs-number">12</span>) + meses    meses_ferias = meses_trabalhados % <span class="hljs-number">12</span>    <span class="hljs-keyword">if</span> dias >= <span class="hljs-number">15</span>:        meses_ferias += <span class="hljs-number">1</span>    meses_ferias = <span class="hljs-built_in">min</span>(meses_ferias, <span class="hljs-number">12</span>)    base_ferias = (salario / <span class="hljs-number">12</span>) * meses_ferias    um_terco = base_ferias / <span class="hljs-number">3</span>    <span class="hljs-keyword">return</span> base_ferias + um_terco</code></pre><p>Outro ponto crítico foi criar condicionais pois se o motivo da rescisão for justa causa, o código aborta imediatamente a soma de 13º e férias proporcionais. Além disso, precisei implementar um max(0, total_receber) no retorno final. Afinal, se o funcionário pede demissão e falta no aviso prévio, os descontos podem superar os ganhos matematicamente, mas juridicamente o trabalhador não pode "sair devendo" a empresa.</p><p>Lá, eu também traduzi essa lógica para o Front-end e criei a calculadora online rodando na prática, onde você pode preencher os dados e ver a mágica acontecer em tempo real.</p><p>Link da acesso a calculadora e a explicação do código: <a href="https://descomplicandoalgoritmos.com.br/calculadora-de-rescisao-clt" rel="nofollow">https://descomplicandoalgoritmos.com.br/calculadora-de-rescisao-clt</a></p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitch: Minha maior dor como founder virou um SaaS que já enviou 5 milhões de emails]]></title>
            <link>https://www.tabnews.com.br/paulocastellano/minha-maior-dor-como-founder-virou-um-saas-que-ja-enviou-5-milhoes-de-emails</link>
            <guid>https://www.tabnews.com.br/paulocastellano/minha-maior-dor-como-founder-virou-um-saas-que-ja-enviou-5-milhoes-de-emails</guid>
            <pubDate>Tue, 07 Apr 2026 19:39:33 GMT</pubDate>
            <description><![CDATA[Eu rodo alguns SaaS. Por um bom tempo pagava uns $300/mês em duas ferramentas separadas: uma para email transacional e outra para marketing e sequences. Não era só o custo que incomodava....]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Eu rodo alguns SaaS. Por um bom tempo pagava uns $300/mês em duas ferramentas separadas: uma para email transacional e outra para marketing e sequences.</p><p>Não era só o custo que incomodava. Era o trabalho manual. Entrar na ferramenta, montar template, configurar drip campaign... sendo dev, isso parece perda de tempo.</p><p>O ponto de virada veio numa conversa com o Pedro Campos, founder da <a href="https://templated.io" rel="nofollow">templated.io</a>. Ele me contou que tinha desistido de contratar uma ferramenta de email porque nenhuma tinha suporte a MCP. Quando ele falou isso eu pensei: se nem a gente, que é dev, quer fazer isso na mão, imagina os outros.</p><p>Pesquisei o mercado. Não achei nada parecido. Foi aí que comecei a codar o <a href="https://sendkit.dev?utm_source=tab-news&#x26;utm_medium=post&#x26;utm_campaign=porque-criei-minha-propria-infra-de-email" rel="nofollow">SendKit.dev</a>.</p><p><strong>O que aprendi no caminho:</strong></p><p><strong>O momento AHA precisa ser rápido</strong></p><p>Usei o PostHog para rastrear onde os usuários travavam. O AHA moment do SendKit é mandar o primeiro email. Reconstruí o onboarding inteiro em volta disso. Você pega sua API key, a gente mostra o SDK, e você está enviando em literalmente um minuto.</p><p><strong>Ninguém quer montar sequência de email</strong><br>Por isso o SendKit é MCP native. Você fala pro seu AI agent criar uma sequência de onboarding e ele monta tudo: templates e automação.</p><p>Gravei uma demo onde crio um onboarding de 14 dias com 7 emails pro Changelogfy. O MCP foi no site, entendeu as cores, pegou o logo, entendeu o produto e montou todos os templates sozinho. O que antes levaria alguns dias, ficou pronto em 3 minutos.</p><p><strong>Lista de supressão automática</strong></p><p>Ninguém limpa lista. Então a lista tem que se limpar sozinha. Deu bounce, foi para supressão. Marcou como spam, mesma coisa. Sua reputação de envio fica protegida sem você precisar lembrar de nada.</p><p><strong>Validação de email de verdade</strong><br>Temos uma API separada de validação. Você manda um endereço e a gente responde se é real, descartável, catch-all ou email de função tipo admin@ e info@. Dá para usar no signup do seu produto e barrar fakes antes de entrarem na base.</p><p>Depois de um beta fechado com mais de 5 milhões de emails enviados, abrimos para todo mundo. Já passamos de 100 clientes.</p><p>Se você está cansado de pagar várias ferramentas que ainda exigem trabalho manual, vale conhecer o <a href="https://sendkit.dev?utm_source=tab-news&#x26;utm_medium=post&#x26;utm_campaign=porque-criei-minha-propria-infra-de-email" rel="nofollow">SendKit.dev</a>.</p><p>Oferecemos 3.000 emails grátis por mês no plano free.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[Atualização] - De 0 ao quase Break Even em 1 mês: O que aprendi lançando meu SaaS B2B (+ próximos passos)]]></title>
            <link>https://www.tabnews.com.br/Nathanvsn/atualizacao-de-0-ao-quase-break-even-em-1-mes-o-que-aprendi-lancando-meu-saas-b2b-proximos-passos</link>
            <guid>https://www.tabnews.com.br/Nathanvsn/atualizacao-de-0-ao-quase-break-even-em-1-mes-o-que-aprendi-lancando-meu-saas-b2b-proximos-passos</guid>
            <pubDate>Tue, 07 Apr 2026 19:26:16 GMT</pubDate>
            <description><![CDATA[Boa tarde galera, vim trazer um pouco das atualizações do meu SaaS que postei aqui faz um pouco mais de 1 mês. Aproveitando, queria dar uma repassada sobre o que rolou de lá pra cá, os ac...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Boa tarde galera, vim trazer um pouco das atualizações do meu SaaS que postei aqui faz um pouco mais de 1 mês. Aproveitando, queria dar uma repassada sobre o que rolou de lá pra cá, os acertos e quais são os próximos passos.</p><p>Sempre quis fazer algo que realmente impactasse, e como estou inserido na comunidade DEV, acho que é o melhor lugar para encontrar e resolver dores reais. Peguei algo que eu mesmo já sofri no passado e que hoje as IAs ainda alucinam demais: pegar grandes documentos como extratos, contratos, boletos, fazer toda a extração de texto e imagem, e devolver em forma estruturada e sem alucinação.</p><p>A primeira coisa que fiz depois da primeira postagem aqui no TabNews foi tentar trazer pessoas para dar feedbacks, e nisso vocês foram brabos demais. Encontraram alguns bugs envolvendo navegadores tipo Brave e umas questões de créditos, o que consegui corrigir rápido.</p><p>Logo depois, fui para uma área que não tinha tanto conhecimento, o SEO. Certamente essa foi a melhor decisão que tomei. Na prática, foquei em fazer o básico bem feito: ajustei a semântica do HTML da landing page, melhorei o tempo de carregamento e comecei a atacar palavras-chave de cauda longa, focadas exatamente nas dores de quem lida com documentos o dia todo. Todo dia tenho visibilidade e pessoas novas entrando no meu site. Desse tráfego orgânico saíram meus primeiros clientes pagantes e 2 contratos enterprise que estou aguardando fechar. Hoje estou a poucos passos do meu Break Even, e como é bom trabalhar sabendo que o projeto já quase se paga, isso dá muito ânimo. Outra coisa muito boa com o SEO foi ver os termos que as pessoas pesquisam, o que vem validando demais a necessidade do Structura.</p><p><img src="https://i.imgur.com/BaNdtNi.png" alt="CONSOLE SEO"></p><p>Uma coisa que notei foi que, apesar de equilibrar o site para 2 modelos (tanto API quanto dashboard), a grande procura foi para Enterprise. Faz muito sentido, quem trabalha com papéis com certeza lida com mais de 1000 páginas por mês.</p><p>Mas o maior destaque foi aprender na prática como o mercado B2B funciona. Notei que empresas querem segurança e contato próximo. Eles precisam saber que, se algo parar de funcionar ou surgir uma dúvida, eu estarei lá para resolver rapidamente. E como estou bem próximo e focado no projeto, conseguimos resolver tudo muito rápido.</p><p>Outra coisa que validei é que tratar o projeto como uma empresa séria desde o primeiro dia me trouxe muita credibilidade. Usar emails próprios, ter disparos organizados e tratar o Structura como uma estrutura sólida (apesar de ter poucas pessoas envolvidas) traz mais confiança tanto para o cliente quanto para mim na hora das conversas.</p><p>Meus próximos passos:</p><p>Agora estou focando em algumas melhorias. Notei que existem alguns atritos no começo da plataforma e alguns clientes encontram certa dificuldade para entender como funciona logo de cara, então vou trabalhar para facilitar esse primeiro contato. Além disso, estou melhorando um pouco mais o SEO e vou começar a rodar algumas campanhas pagas com Google Ads para ver o potencial de escala e validar novas ideias.</p><p><img src="https://i.imgur.com/tINu7wp.png" alt="CONSOLE ADS"></p><p>No mais, queria devolver um pouco do que aprendi. Se alguém tiver alguma dúvida, quiser saber mais sobre como foi esse início, a parte de SEO, ou como lidar com B2B no começo, deixa aí nos comentários que eu faço questão de responder.</p><p>E claro, pra quem sofre com extração de dados e quiser dar uma olhada de como a ferramenta está ficando, convido vocês a conhecerem o <a href="https://structura.com.br/" rel="nofollow">https://structura.com.br/</a>.</p><p>Valeu galera!</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitch: Criei um site com ferramentas que eu sempre precisei como dev e nunca achava sem propaganda]]></title>
            <link>https://www.tabnews.com.br/jeancarlodev/criei-um-site-com-ferramentas-que-eu-sempre-precisei-como-dev-e-nunca-achava-sem-propaganda</link>
            <guid>https://www.tabnews.com.br/jeancarlodev/criei-um-site-com-ferramentas-que-eu-sempre-precisei-como-dev-e-nunca-achava-sem-propaganda</guid>
            <pubDate>Tue, 07 Apr 2026 18:41:46 GMT</pubDate>
            <description><![CDATA[Sabe quando você precisa: formatar um JSON decodificar um base64 gerar um hash converter timestamp E cai em sites lotados de propaganda, captcha e pop-up? Eu cansei disso e comecei a cria...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><p>Sabe quando você precisa:</p><ul><li>formatar um JSON</li><li>decodificar um base64</li><li>gerar um hash</li><li>converter timestamp</li></ul><p>E cai em sites lotados de propaganda, captcha e pop-up?</p><p>Eu cansei disso e comecei a criar minhas próprias ferramentas, focadas em:</p><ul><li>rapidez</li><li>zero login</li><li>uso direto</li></ul><p>Subi algumas tools já em: <a href="https://quickeasy.tools" rel="nofollow">https://quickeasy.tools</a></p><p>Meu objetivo é subir novas tools toda semana. Feedbacks são muito bem-vindos.<br>Vou adicionar novas toda semana.</p></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[PITCH] Uma lib de moderaçao de chat toxico 100% open source]]></title>
            <link>https://www.tabnews.com.br/Fiasco/pitch-uma-lib-opensource-para-moderacao-de-chat-em-pt-br</link>
            <guid>https://www.tabnews.com.br/Fiasco/pitch-uma-lib-opensource-para-moderacao-de-chat-em-pt-br</guid>
            <pubDate>Tue, 07 Apr 2026 17:39:52 GMT</pubDate>
            <description><![CDATA[O problema ## Eu estou desenvolvendo um app que conecta pessoas com problema de vicio em pornografia (diaum). Em algum momento eu bati em um problema que parece simples na teoria, mas na...]]></description>
            <content:encoded><![CDATA[<div class="markdown-body"><h2 id="fiasco-content-o-problema">O problema</h2><p>Eu estou desenvolvendo um app que conecta pessoas com problema de vicio em pornografia (<a href="https://www.tabnews.com.br/Fiasco/pitch-um-aplicativo-anti-pornografia-e-os-desafios-que-eu-to-enfrentando">diaum</a>).</p><p>Em algum momento eu bati em um problema que parece simples na teoria, mas na pratica é bem mais chato de resolver por que a maioria das soluçoes sao em ingles.</p><p><strong>Repositorio.</strong><br><a href="https://github.com/Diaum/toxibr">Github</a></p><p><strong>Live do projeto.</strong><br>Teste o chat: <a href="https://toxibr.vercel.app" rel="nofollow">Browser</a></p><p><img src="https://raw.githubusercontent.com/Diaum/toxibr/bdead02496d967ed21f2a132e7c0837a3159fd8f/assets/screenshot.png" alt="Implementaçao web do ToxiBr"><br>Teste o chat: <a href="https://toxibr.vercel.app" rel="nofollow">ToxiBr web</a></p><p><strong>Moderaçao de chat.</strong><br>Nao é sobre bloquear palavrao. Isso qualquer lista de palavras resolve.<br>O problema real é entender o contexto. O Diaum é um app que lida com um tema sensivel e uma coisa que acontece com frequencia é o usuario se colocar para baixo.</p><blockquote><p>"eu me sinto um lixo"<br>"eu sou um bosta"</p></blockquote><p>Se eu simplesmente bloqueasse essas palavras eu estaria silenciando exatamente o momento onde o usuario mais precisa falar.<br>Mas ao mesmo tempo eu nao posso permitir que um usuario ofenda o outro, foi daqui que nasceu a ToxiBR para resolver o meu problema e talvez o teu.</p><p>Voce pode ver a implementaçao dela no navegador aqui: <a href="toxibr.vercel.app">ToxiBr web</a></p><p><strong>O que é a ToxiBR?</strong><br>A <a href="https://github.com/Diaum/toxibr">ToxiBR</a> é uma biblioteca em JavaScript focada em moderaçao de conteudo em português com analise de contexto.<br>A ideia central é simples:</p><p>Nem toda palavra toxica deve ser bloqueada<br>Nem toda frase aparentemente inocente deve passar</p><p><strong>Como funciona?</strong><br>A <a href="https://github.com/Diaum/toxibr">ToxiBR</a> trabalha com classificaçao de palavras e analise de contexto.</p><p>Cada palavra pode ter:</p><ol><li>Um peso</li><li>Uma categoria</li><li>Uma regra de bloqueio</li></ol><p><strong>Categorias</strong></p><ol><li>Ofensa direta</li><li>Conteudo sexual</li><li>Racismo</li><li>Homofobia</li><li>Apologia</li><li>Dados pessoais</li></ol><p><strong>Tipos de tratamento</strong></p><ol><li>Hard block</li><li>Palavras que sao bloqueadas independente do contexto</li><li>Soft block</li></ol><p><strong>Palavras que dependem do contexto</strong><br>Exemplo</p><blockquote><p>"caralho hoje ta quente"</p></blockquote><p>Aqui nao tem ataque a ninguem. É expressao.</p><p>Agora</p><blockquote><p>"Pega no meu caralho"</p></blockquote><p>Aqui muda completamente.</p><p>A <a href="https://github.com/Diaum/toxibr">ToxiBR</a> tenta entender isso olhando o entorno da frase e a intencao.</p><p>Nao é perfeito.<br>Mas é muito melhor do que um if com lista de palavroes.</p><p><strong>Proteçao de dados no chat</strong></p><p>Outro problema que precisei resolver foi troca de informaçao pessoal.</p><ol><li>Telefone</li><li>Endereco</li><li>Rede social</li></ol><p>Em um ambiente anonimo isso quebra completamente a proposta.</p><p>Entao a <a href="https://github.com/Diaum/toxibr">ToxiBR</a> tambem faz parsing de padroes:</p><ol><li>Detecta numero de telefone</li><li>Detecta tentativa de enviar arroba de rede social</li><li>Detecta padroes de endereco</li><li>Analisa as ultimas 5 mensagens para detectar envio fracionado de dados</li></ol><p>Tudo isso entra como categoria separada e pode gerar bloqueio ou alerta dependendo da regra.</p><p><strong>Por que nao usar IA?</strong><br>Essa pergunta sempre vem.<br>Por que nao usar uma LLM para moderar o chat?</p><p>Resposta curta<br>Privacidade e controle.<br>O Diaum é 100% anonimo. Nao existe log de conversa, nao existe armazenamento de mensagem</p><p>Enviar isso para um serviço externo quebraria tudo.<br>Principalmente a confiança do usuario.<br>Mesmo usando algo como o moderate: Ainda existe dependencia externa, Risco juridico, LGPD, Perda de controle</p><p><strong>Casos de uso</strong></p><ol><li>Jogos online com chat</li><li>Comunidades anonimas</li><li>Apps de suporte emocional</li><li>Marketplaces com interaçao entre usuarios</li><li>Qualquer sistema com chat em tempo real</li></ol><p>Se existe interaçao humana, existe necessidade de moderaçao.</p><p>Voce pode ver a implementaçao dela no navegador aqui: <a href="toxibr.vercel.app">ToxiBr web</a></p><p><strong>Limitaçoes</strong><br>Nao existe soluçao perfeita.<br>Contexto é dificil,Ironia é dificil, sarcasmo é dificil, usuarios mal intencionados tambem<br>A ToxiBR resolve uma grande parte dos problemas mas ainda depende de evoluçao constante. Por isso é open source.<br>Se voce esta criando qualquer produto com interaçao entre pessoas voce vai enfrentar esse problema.</p><p>Mais cedo ou mais tarde e a pior coisa que voce pode fazer é ignorar isso no inicio.<br>A ToxiBR nasceu de um problema real dentro de um contexto sensivel com uma necessidade muito clara. Talvez ela resolva o seu tambem.</p></div>]]></content:encoded>
        </item>
    </channel>
</rss>