<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Omarchy | AkitaOnRails.com</title><link>https://akitaonrails.github.io/tags/omarchy/</link><description>Blog do Fabio Akita do Canal do YouTube 'Akitando' falando sobre tecnologia, carreira e coisas geek.</description><generator>Hugo -- gohugo.io</generator><language>pt-BR</language><lastBuildDate>Mon, 19 Oct 2026 23:20:48 +0000</lastBuildDate><atom:link href="https://akitaonrails.github.io/tags/omarchy/index.xml" rel="self" type="application/rss+xml"/><item><title>Usuários Linux: sempre escolham BTRFS, não EXT4</title><link>https://akitaonrails.github.io/2026/10/12/usuarios-linux-sempre-escolham-btrfs-nao-ext4/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/10/12/usuarios-linux-sempre-escolham-btrfs-nao-ext4/</guid><pubDate>Mon, 12 Oct 2026 23:00:00 -0300</pubDate><description>&lt;p&gt;Este texto é continuação direta do &lt;a href="https://akitaonrails.github.io/2026/10/06/desastre-no-meu-nas-como-quase-perdi-90-tb-de-dados/"&gt;desastre no meu NAS&lt;/a&gt;. Resumo pra quem chegou agora: meu Synology, com oito discos em SHR (paridade simples), perdeu dois discos numa tacada durante um upgrade. Sobrevivi por detalhe de implementação do SHR, comprei um QNAP às pressas, passei uma semana copiando e verificando 91 TB, e não perdi nenhum arquivo por acidente. O QNAP novo roda ZFS em RAID-6; o Synology, refeito, agora roda SHR-2.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Este texto é continuação direta do <a href="/2026/10/06/desastre-no-meu-nas-como-quase-perdi-90-tb-de-dados/">desastre no meu NAS</a>. Resumo pra quem chegou agora: meu Synology, com oito discos em SHR (paridade simples), perdeu dois discos numa tacada durante um upgrade. Sobrevivi por detalhe de implementação do SHR, comprei um QNAP às pressas, passei uma semana copiando e verificando 91 TB, e não perdi nenhum arquivo por acidente. O QNAP novo roda ZFS em RAID-6; o Synology, refeito, agora roda SHR-2.</p>
<p>Embaixo dessa história toda tem uma decisão que quase ninguém faz conscientemente: <strong>o filesystem</strong>. O Synology usava btrfs o tempo todo. O QNAP usa ZFS. E a sua máquina Linux, muito provavelmente, veio de fábrica com ext4 sem ninguém te perguntar nada. É sobre isso.</p>
<h2>De onde vieram os dois<span class="hx:absolute hx:-mt-20" id="de-onde-vieram-os-dois"></span>
    <a href="#de-onde-vieram-os-dois" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O ext4 é o final de uma dinastia de mais de três décadas. O ext (extended filesystem) nasceu com o próprio Linux, o ext2 virou padrão nos anos 90, o ext3 adicionou journal em 2001 pra não precisar de fsck épico depois de cada queda de energia, e o ext4 chegou em 2008 com extents, alocação atrasada e volumes de até 1 exbibyte. O objetivo de design sempre foi o mesmo: ser o filesystem padrão, rápido, simples e previsível. Ele é excelente nisso. E parou aí.</p>
<p>O btrfs nasceu em 2007, na Oracle, com o Chris Mason, com um objetivo completamente diferente: ser a resposta do Linux ao ZFS. Em vez de escrever dado por cima de dado, ele é copy-on-write: toda escrita vai pra um bloco novo e os ponteiros são atualizados em cascata na árvore. Essa decisão única é a mãe de tudo que interessa nele.</p>
<p>O que cada um entrega, na lista:</p>
<p><strong>ext4:</strong></p>
<ul>
<li>journaling (metadados consistentes depois de queda)</li>
<li>extents e alocação atrasada (boa performance)</li>
<li>maduro, estável, em todo lugar, qualquer ferramenta funciona</li>
</ul>
<p><strong>btrfs:</strong></p>
<ul>
<li>copy-on-write em tudo</li>
<li>checksum de dados e metadados em cada bloco</li>
<li>snapshots instantâneos e baratos</li>
<li>subvolumes independentes dentro do mesmo volume</li>
<li>compressão transparente (zstd, lzo, zlib)</li>
<li>RAID nativo e scrub (varredura de verificação)</li>
<li>send/receive de snapshots pra backup incremental</li>
<li>reflinks (cópias que não duplicam blocos)</li>
</ul>
<p>A lista já responde a pergunta do título. Vamos por partes.</p>
<h2>Até o NTFS e o APFS passaram o ext4<span class="hx:absolute hx:-mt-20" id="até-o-ntfs-e-o-apfs-passaram-o-ext4"></span>
    <a href="#at%c3%a9-o-ntfs-e-o-apfs-passaram-o-ext4" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E se a comparação com o btrfs parece injusta, olha pro lado. O NTFS nasceu em 1993, com o Windows NT, já com journaling de metadados e ACLs, e ainda nos anos 2000 ganhou o log de todas as mudanças do volume e as cópias de sombra (o &ldquo;Versões Anteriores&rdquo; do Windows). O APFS, que a Apple lançou em 2017 feito pra flash, é copy-on-write como o btrfs: snapshots nativos (é o que o Time Machine usa pra restauração local), clones instantâneos de arquivo que compartilham blocos, volumes compartilhando o espaço do mesmo container e criptografia por arquivo.</p>
<p>Leia de novo a lista do ext4 e compare: sem snapshot, sem checksum de dados, sem CoW, sem compressão. O filesystem do Windows e o do Mac, que ninguém considera exemplos de sofisticação, protegem os seus dados melhor que o padrão do Linux, cuja última grande feature saiu em 2008. O btrfs é o que coloca o Linux na mesma geração dos outros dois, e não uma década atrás.</p>
<h2>Por que o btrfs é muito superior<span class="hx:absolute hx:-mt-20" id="por-que-o-btrfs-é-muito-superior"></span>
    <a href="#por-que-o-btrfs-%c3%a9-muito-superior" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>O que é copy-on-write, pra quem nunca parou pra pensar<span class="hx:absolute hx:-mt-20" id="o-que-é-copy-on-write-pra-quem-nunca-parou-pra-pensar"></span>
    <a href="#o-que-%c3%a9-copy-on-write-pra-quem-nunca-parou-pra-pensar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Nos filesystems clássicos, a escrita é destrutiva por definição: atualizar um bloco significa gravar o conteúdo novo por cima do velho, no mesmo lugar do disco. Se a máquina morre no meio da escrita, o arquivo fica metade velho, metade novo. O journal do ext3/ext4 cobre isso para os <strong>metadados</strong> (a estrutura de diretórios não corrompe), mas o seu dado em si fica por conta da sorte.</p>
<p>Copy-on-write inverte a ordem: <strong>nada nunca é sobrescrito</strong>. Escrever num arquivo aloca um bloco novo, grava o conteúdo novo ali, e só quando está tudo seguro no disco o filesystem troca os ponteiros pra versão nova, de forma atômica. A qualquer instante, você tem ou a versão velha inteira ou a versão nova inteira. Nunca uma mistura das duas.</p>
<p>O que isso compra na prática:</p>
<ul>
<li><strong>Snapshots quase de graça.</strong> Os blocos velhos já persistem por natureza do CoW; um snapshot é só o filesystem segurando o ponteiro de raiz daquele instante, pura contabilidade.</li>
<li><strong>Queda de energia não corrompe.</strong> Uma escrita interrompida deixa a versão anterior intacta, porque ela nunca foi tocada. Pra quem já perdeu imagem de VM ou banco de dados pra queda no meio da escrita, isso vale o filesystem inteiro.</li>
<li><strong>Verificação possível.</strong> Como cada bloco é escrito uma vez e nunca mexido, faz sentido guardar checksum dele pra sempre. É a base da proteção contra corrupção que detalho mais abaixo.</li>
</ul>
<p>O custo existe e eu pago ele sabendo: arquivos de escrita aleatória intensa (disco de VM, banco de dados) fragmentam e duplicam bloco, porque cada reescrita vira um bloco novo. Pra esses casos se desliga o CoW por diretório com <code>chattr +C</code>, que precisa ser marcado <strong>antes</strong> do arquivo ser criado. No meu layout, a imagem de VM feita com o <code>+C</code> certo ficou saudável; a feita sem virou o caso de fragmentação de livro-texto.</p>
<h3>Snapshots são a feature que muda a sua vida<span class="hx:absolute hx:-mt-20" id="snapshots-são-a-feature-que-muda-a-sua-vida"></span>
    <a href="#snapshots-s%c3%a3o-a-feature-que-muda-a-sua-vida" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Snapshot no btrfs é uma foto instantânea de um subvolume, e custa quase nada, porque o CoW já mantém os blocos velhos enquanto alguém referencia eles. Criar um snapshot é operação de segundo, não de horas. Na prática: antes de cada upgrade, o sistema tira uma foto. Se o upgrade quebrar, você não &ldquo;desinstala pacote&rdquo;: você boota de volta na foto anterior e pronto. A seção de recuperação de boot, mais abaixo, mostra isso acontecendo de verdade.</p>
<h3>Subvolumes são o jeito certo de organizar o disco<span class="hx:absolute hx:-mt-20" id="subvolumes-são-o-jeito-certo-de-organizar-o-disco"></span>
    <a href="#subvolumes-s%c3%a3o-o-jeito-certo-de-organizar-o-disco" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Subvolume é um namespace independente dentro do mesmo filesystem, com política própria de snapshot. E tem uma propriedade matadora: <strong>snapshot não é recursivo</strong>. Um subvolume filho dentro de outro fica automaticamente de fora do snapshot do pai.</p>
<p>Eu uso isso pra tudo. No meu desktop, os diretórios de cache que dá pra baixar de novo (mise, rustup, npm, opencode, caches de IA) estão virando subvolumes aninhados dentro do <code>@home</code>: ficam no mesmo lugar pra qualquer programa, mas de fora de qualquer snapshot. Só essa separação tira 165 GiB de escopo de snapshot, e os caches grandes (Hugging Face, yay, uv, pip) já moram fora do volume do sistema, com symlinks apontando pra eles: menos 148 GiB de snapshot, parte já migrada e parte em andamento. O snapshot fica pequeno, o restore fica rápido, e o que pode ser rebaixado da internet nunca entra na foto.</p>
<p>O custo real, medido no QNAP novo (ZFS, mas a matemática de CoW é a mesma): 27 snapshots de hora em hora de uma pasta com quase 80 TB, e quase todos consomem megabytes, porque entre uma hora e outra quase nada mudou. Snapshot barato é o que permite essa rotina existir sem culpa.</p>
<p><img src="qnap-snapshot-manager.png" alt="Snapshot Manager do QNAP com 27 snapshots horários da pasta CHAD, a maioria consumindo entre 3 e 300 MB"  loading="lazy" /></p>
<h3>Deduplicação por reflink<span class="hx:absolute hx:-mt-20" id="deduplicação-por-reflink"></span>
    <a href="#deduplica%c3%a7%c3%a3o-por-reflink" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Antes, a ressalva que importa: o btrfs não tem deduplicação online nativa igual ao ZFS (que mantém uma tabela de dedup em RAM e cobra caro por isso). O que ele tem são duas coisas práticas: <strong>reflink</strong> e dedup offline. Reflink é cópia que compartilha blocos: <code>cp --reflink=auto</code> cria um arquivo novo que aponta pros mesmos blocos do original, instantâneo e de graça, e cada um passa a divergir só onde for escrito. Na era de dezenas de checkouts, worktrees e builds parecidos, isso economiza uma montanha de blocos. Pra dedup retroativo existem ferramentas de userspace como <a href="https://github.com/markfasheh/duperemove"target="_blank" rel="noopener">duperemove</a> e <a href="https://github.com/Zygo/bees"target="_blank" rel="noopener">bees</a>.</p>
<h3>Proteção contra corrupção de verdade<span class="hx:absolute hx:-mt-20" id="proteção-contra-corrupção-de-verdade"></span>
    <a href="#prote%c3%a7%c3%a3o-contra-corrup%c3%a7%c3%a3o-de-verdade" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Todo bloco do btrfs, dado ou metadado, carrega checksum. Quando o filesystem lê e o checksum não bate, ele sabe que o bloco apodreceu, e se houver uma segunda cópia (RAID ou metadata DUP) ele se autocorrige. O ext4 não checa dado nenhum: bit rot passa silencioso até você abrir o arquivo anos depois.</p>
<p>Duas peças da minha configuração mostram o que isso compra na prática, e o que o ext4 simplesmente não oferece. A primeira é o metadado em modo DUP. Num ext4, cada estrutura do volume existe uma vez só: um setor ruim bem posicionado corrompe a tabela de diretórios e o disco inteiro deixa de montar. No btrfs, mesmo com um único disco, todo bloco de metadado existe duplicado. O setor ruim continua existindo, mas o checksum acusa o bloco podre na leitura e a segunda cópia responde no lugar, sem você perceber. É a diferença entre perder o volume e anotar um aviso no log.</p>
<p>A segunda é o scrub mensal. Um ext4 nunca relê nada pra conferir saúde: se um bloco apodrece, você descobre no dia em que alguém tenta abrir aquele arquivo específico, talvez anos depois, quando já não tem conserto. O scrub é uma varredura agendada que relê o volume inteiro validando checksums, e encontra a podridão enquanto ela ainda é pequena e recuperável. Quando o contador do <code>btrfs device stats</code> sai de zero, é a sirene pra trocar o disco antes do desastre, não depois.</p>
<h3>Compressão transparente, medida<span class="hx:absolute hx:-mt-20" id="compressão-transparente-medida"></span>
    <a href="#compress%c3%a3o-transparente-medida" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Todo mount do meu desktop usa <code>compress=zstd:1</code>. O nível 1 custa uns pontos percentuais de um núcleo de CPU, e o btrfs detecta o que não comprime (blob de modelo, vídeo) e grava cru, sem custo. O resultado, medido essa semana nos meus dois discos novos:</p>
<p><img src="btrfs-compressao-economia.png" alt="Tabela de economia com compressão: 2,2 TB de dados ocupando 1,6 TB em disco, com 35% de economia no sistema, 39% nas camadas de Docker e zero nos pesos de modelos de IA"  loading="lazy" /></p>
<p>São <strong>630 GB de espaço grátis</strong> em 2,2 TB: 15% a mais de disco, sem pagar nada. Na migração inicial o ganho foi ainda maior, 45% no volume de sistema, porque havia mais texto e menos binário. Repare nos detalhes da tabela: programas e bibliotecas comprimem bem, camadas de Docker comprimem melhor ainda (39%), log de texto comprime 4,5x, e peso de modelo de IA não comprime nada, o que é esperado e não custa nada. Código-fonte, que é o que mais produzimos na era da IA, comprime lindamente.</p>
<h2>Synology usa btrfs, QNAP usa ZFS<span class="hx:absolute hx:-mt-20" id="synology-usa-btrfs-qnap-usa-zfs"></span>
    <a href="#synology-usa-btrfs-qnap-usa-zfs" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sendo justo com o ZFS: pra NAS grande ele é superior, e foi o que eu escolhi pro QNAP. Checksum e autocorreção nativos, RAIDZ maduro, send/receive excelente. O preço é complexidade e recurso: o ZFS quer RAM pro cache ARC (meu QNAP tem 7 GB pra um pool de 174 TB, e sinto a falta), a deduplicação online dele precisaria de uns 190 GB de RAM só pra tabela no meu volume, e o modelo de provisionamento dele me deu um susto de graça quando o snapshot foi recusado com 20 TB livres (a história do thick vs thin está no artigo do NAS).</p>
<p>O btrfs é o equilíbrio certo pra máquina de consumo. Leve, nativo no kernel, faz quase tudo que o ZFS faz sem exigir um administrador de storage. Desktop, notebook, homelab, NAS pequeno ou médio: btrfs. O Synology provou na prática, duas vezes: o volume btrfs sobreviveu legível com dois discos fora, e os snapshots dele salvaram 11 álbuns que eu deletei por engano no meio da limpeza, byte a byte.</p>
<blockquote>
  <p>NAS grande e sério, com RAM de sobra: ZFS. Todo o resto: btrfs. E pra máquina Linux de uso pessoal, não é nem discussão.</p>

</blockquote>
<h2>Recuperação de boot por snapshot<span class="hx:absolute hx:-mt-20" id="recuperação-de-boot-por-snapshot"></span>
    <a href="#recupera%c3%a7%c3%a3o-de-boot-por-snapshot" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A feature que já me salvou de verdade, contada nas duas máquinas.</p>
<p>No desktop, o <a href="https://omarchy.org"target="_blank" rel="noopener">Omarchy</a> configura o <a href="https://snapper.io/"target="_blank" rel="noopener">snapper</a> pra tirar snapshot antes de cada update e o <code>limine-snapper-sync</code> publica cada snapshot como entrada de boot no <a href="https://github.com/limine-bootloader/limine"target="_blank" rel="noopener">Limine</a>. Kernel novo não sobe? No menu de boot você escolhe o snapshot de ontem e a máquina volta como se nada tivesse acontecido. Na minha máquina a rotina agendada roda via <a href="https://github.com/teejee2008/timeshift"target="_blank" rel="noopener">Timeshift</a> em cron (a cada boot e de hora em hora), com o snapper cobrindo os pontos de update: o mecanismo de retorno é o mesmo. (A gotcha: cada entrada de snapshot carrega a imagem do kernel junto, então ESP pequena enche rápido. A minha de 1 GB já recusou um update de kernel por falta de espaço; o sistema seguiu bootável no kernel velho, que é o comportamento certo.)</p>
<p>No servidor, que roda <a href="https://get.opensuse.org/microos/"target="_blank" rel="noopener">openSUSE MicroOS</a>, é ainda mais forte: o sistema inteiro é btrfs transacional, e cada update é um snapshot novo. Semana passada, o kernel 7.2.9 derrubou o controlador NVMe em silêncio, duas vezes, no meio do backup noturno. O conserto foi um <code>transactional-update rollback</code> e um reboot de volta pro 7.2.6, que rodou a carga inteira (754 GiB de leitura de backup com download concorrente) sem um soluço. Regressão de kernel virou reboot agendado, não madrugada de recovery. Uma ressalva documentada: o <code>/etc</code> mora dentro do snapshot, então o rollback desfaz mudanças de configuração junto. Depois de qualquer rollback, confira de novo as suas units.</p>
<h2>Manutenção não é opcional (e o arquivo deletado que não some)<span class="hx:absolute hx:-mt-20" id="manutenção-não-é-opcional-e-o-arquivo-deletado-que-não-some"></span>
    <a href="#manuten%c3%a7%c3%a3o-n%c3%a3o-%c3%a9-opcional-e-o-arquivo-deletado-que-n%c3%a3o-some" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Filesystem CoW moderno entrega muito, mas cobra duas rotinas que o ext4 nunca pediu.</p>
<p>A primeira é o scrub, que já apareceu aqui: reler tudo e conferir checksums, mensalmente, em todas as máquinas. Ele é o detector de bit rot em ação, e sem ele o checksum só te avisa da podridão quando você tentar ler o arquivo. O segundo ponto é mais sutil: <strong>snapshot prende bloco de arquivo deletado</strong>. Quando você apaga um arquivo dentro de um subvolume com snapshot, o espaço não volta, porque o bloco continua referenciado pela foto. Foi exatamente o que aconteceu no meu NAS: a limpeza de 2,14 TB que rodei no Synology só liberou espaço de verdade depois que os snapshots velhos foram removidos; até lá, os blocos ficaram presos.</p>
<p>O tratamento é rotina simples. A retenção tem que ser automática, com o snapper ou o Timeshift apagando os snapshots antigos conforme a política (no QNAP, a política de retenção do Snapshot Manager faz o mesmo papel). Espaço que não volta depois de deletar snapshot velho geralmente é chunk alocado demais: um <code>btrfs balance start -dusage=50</code> devolve os pedaços pouco usados pro pool livre (aqui em casa eu não agendo balance cego, eu monitoro o espaço não-alocado e ajo quando aperta). E no lado do restic, <code>forget</code> sozinho só remove a referência do snapshot: o espaço do repositório só é recuperado com o <code>prune</code> junto, <code>forget --prune</code>.</p>
<h2>A limpeza da casa na era do AI coding<span class="hx:absolute hx:-mt-20" id="a-limpeza-da-casa-na-era-do-ai-coding"></span>
    <a href="#a-limpeza-da-casa-na-era-do-ai-coding" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora a parte que quase ninguém conecta com filesystem: a era do agente produz lixo em velocidade industrial. Eu sei porque medi.</p>
<ul>
<li><strong>Rust é o maior poluidor de disco do mundo dev.</strong> Cada build deixa pra trás binários de teste de 100 a 180 MB, e eles se acumulam a cada edição. No meu desktop, os diretórios <code>target/</code> somavam <strong>920 GiB</strong>. Só o ai-memory respondia por 704 GiB. A ferramenta de higiene que eu usava é o <a href="https://github.com/holmgr/cargo-sweep"target="_blank" rel="noopener">cargo-sweep</a>, semanal. Um leitor avisou que o projeto se declara sem mantenedor, e o próprio README manda pro <a href="https://github.com/dnlmlr/cargo-clean-all"target="_blank" rel="noopener">cargo-clean-all</a>, que faz diferente: em vez de podar artefato velho dentro de um <code>target/</code>, ele acha todos os projetos Rust abaixo de um diretório e apaga o <code>target/</code> inteiro dos que você filtrar, por exemplo <code>cargo clean-all --keep-days 7 ~</code> pra limpar só o que não compila há uma semana.</li>
<li><strong>Docker não fica atrás.</strong> Na minha máquina achei 1,26 TB de build cache mais 938 GB de imagens. Uma faxina única recuperou uns 600 GB. No servidor, a limpeza semanal recolhe de 0,6 a 4,5 GB todo domingo.</li>
<li><strong>Caches de IA e de pacotes incham quietos.</strong> O cache do Hugging Face tinha 86 GB até eu apagar três modelos mortos e ele cair pra 21. Pacman tinha 22 GB de pacotes superados. yay, uv e pip, mais 125 GB.</li>
<li><strong>E os agentes criam diretórios temporários sem pedir licença.</strong> Projeto complexo com várias branches significa worktrees, e cada worktree de release tem seu próprio <code>CARGO_TARGET_DIR</code> cheio de binário de teste. No ai-memory isso já estourou o disco, e virou regra obrigatória no AGENTS.md do projeto: depois de cada release, <code>cargo clean</code> em cada worktree criado e remoção dos worktrees terminados, sem exceção.</li>
</ul>
<p>A solução é automatizar o varrimento. O meu exemplo mínimo, um timer de usuário que roda dia 1 e 15 de madrugada, com Nice e I/O idle:</p>
<ul>
<li>apaga diretórios <code>target/</code> de projetos parados há mais de 14 dias</li>
<li>limpa o cache do yay</li>
<li>poda só o build cache do Docker com mais de 30 dias, nunca imagem ou volume</li>
</ul>
<p>E a parte que virou padrão aqui em casa: <strong>instruir os agentes a limpar o que criam</strong>. Três regras reais dos meus projetos, pra você copiar:</p>
<blockquote>
  <p><strong>No AGENTS.md do desktop:</strong> &ldquo;Nunca rode limpezas amplas como <code>docker system prune</code> sem autorização explícita do usuário depois de um inventário read-only. Limpeza usa lista exata de IDs; parado, antigo ou sem referência não significa descartável.&rdquo;</p>

</blockquote>
<blockquote>
  <p><strong>No CLAUDE.md do homelab:</strong> &ldquo;Antes de terminar qualquer tarefa, remova as coisas temporárias que a tarefa criou, e só elas. Nunca delete o que você não criou ou não consegue atribuir à tarefa. Na dúvida, liste pro dono.&rdquo;</p>

</blockquote>
<blockquote>
  <p><strong>No AGENTS.md do ai-memory:</strong> &ldquo;<code>target/</code> cresce sem limite: cada edição num crate compartilhado deixa pra trás uma cópia de cada binário de teste de 100-180 MB (visto a 157 GiB). <code>cargo sweep --time 7</code> semanal, e <code>cargo clean</code> obrigatório depois de cada release.&rdquo;</p>

</blockquote>
<h2>E o backup de verdade: restic<span class="hx:absolute hx:-mt-20" id="e-o-backup-de-verdade-restic"></span>
    <a href="#e-o-backup-de-verdade-restic" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Snapshot mora no mesmo disco, então snapshot não é backup: se o disco morre, o snapshot morre junto. O último item do kit é o <a href="https://restic.net/"target="_blank" rel="noopener">restic</a>, que pra mim é o melhor sistema de backup do Linux hoje.</p>
<p>O restic é um binário único, open source, escrito em Go, que faz backup deduplicado, criptografado e versionado pra praticamente qualquer destino: outro diretório, outro NAS via SFTP ou REST, S3, Glacier. O truque central é o content-defined chunking: ele fatia cada arquivo em blocos de tamanho variável definidos pelo conteúdo, tira o hash de cada bloco e só grava no repositório os blocos que ainda não existem lá. Por isso o delta é barato: o backup de hoje carrega os blocos que mudaram desde ontem, não os arquivos que mudaram. Editar um banco de 100 GB no meio custa alguns megabytes de backup, não 100 GB de novo. Cada execução vira um snapshot do repositório, um ponto de restauração que você navega com <code>restic mount</code> como se fosse filesystem, e o <code>restic check</code> audita a integridade do repositório inteiro quando você pedir.</p>
<p>A configuração importa mais que a ferramenta, então vai a nossa, com os erros inclusos. No desktop, o repositório mora no NAS e a retenção é <code>keep-daily 7, keep-weekly 4, keep-monthly 6, keep-yearly 1</code>. No servidor, o backup roda diário de madrugada pro repositório no QNAP, cobrindo <code>/etc</code>, <code>/usr/local/bin</code>, <code>/home</code> e os volumes dos containers, com a senha fora da máquina e <code>pg_dump</code> antes dos bancos, porque snapshot de filesystem não garante consistência de banco escrevendo. A primeira carga completa foi 729 GiB em menos de uma hora, e o restic atravessou ileso, na base do retry, a janela em que a montagem NFS ficou read-only por engano durante a migração.</p>
<p>A parte mais importante da configuração é o que <strong>não</strong> entra no backup. As nossas exclusões, todas com motivo:</p>
<ul>
<li>caches de modelo de IA (Immich, Hugging Face, EasyOCR): se perder, baixa de novo;</li>
<li>métricas do Prometheus: histórico que se regenera sozinho;</li>
<li>o banco do Fulcrum: reindexa a partir do bitcoind;</li>
<li>os pesos dos classificadores de decisão: rebaixáveis por hash de revisão (e o glob dessa exclusão vai entre aspas dentro do array do bash, porque sem aspa ele vira fonte de backup em vez de exclusão);</li>
<li><code>node_modules</code>, <code>target/</code>, registry do cargo, toolchains do rustup: build artifact puro.</li>
</ul>
<p>E um aprendizado de retenção pra fechar. Quando encurtamos a política do servidor pra &ldquo;ontem, 2 diários, 2 semanais e 1 mensal&rdquo;, a tradução correta pros flags é <code>--keep-daily 3 --keep-weekly 3 --keep-monthly 2</code>, não 2/2/1: os níveis do restic se sobrepõem, e o snapshot de ontem também é o mais novo desta semana e deste mês, então cada número precisa ser um a mais que os pontos antigos que você quer guardar. O detalhe pegou a gente no contrapé: o script estava com 2/2/1 literal, e com ele o nível mensal nunca seguraria nada mais velho que a noite passada. Na prática, a intenção era guardar 5 pontos de restauração, e o 2/2/1 entrega só 3: ontem, mais um diário, mais um semanal. Erramos, medimos, corrigimos.</p>
<p>Uma nota de humildade vinda do desastre: os repositórios antigos ficaram no Synology por decisão minha (quase 2 TB de histórico abandonado, porque o conteúdo já estava re-coberto no QNAP novo). Repositório de backup também envelhece, e revisitar o escopo dele faz parte da higiene.</p>
<h2>Conclusão: na era da IA, disco não é detalhe<span class="hx:absolute hx:-mt-20" id="conclusão-na-era-da-ia-disco-não-é-detalhe"></span>
    <a href="#conclus%c3%a3o-na-era-da-ia-disco-n%c3%a3o-%c3%a9-detalhe" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agentes codificando o dia inteiro mudam a matemática do armazenamento nas duas pontas. Na ponta do volume: builds, caches, worktrees e modelos enchem o disco muito mais rápido do que qualquer hábito humano enchia, e sem rotina de limpeza você descobre quando estoura. Na ponta da segurança: quanto mais código gerado, mais você precisa de ponto de retorno barato, porque nem toda mudança de agente é boa.</p>
<p>O btrfs cobre as duas. A compressão transparente devolve 15% de disco de graça, e código-fonte é exatamente o tipo de dado que mais comprime. Snapshots e subvolumes te dão volta atrás instantânea no sistema e isolamento do que não precisa de proteção. Checksums e scrub vigiam a saúde dos blocos que o ext4 simplesmente ignora. O ext4 teve seus 15 anos de reinado merecido. Em 2026, escolher ele num Linux novo é abrir mão de proteção que você vai precisar, cedo ou tarde. Escolha btrfs e configure a limpeza hoje.</p>
]]></content:encoded><category>linux</category><category>armazenamento-e-backup</category><category>homelab</category><category>omarchy</category></item><item><title>Criei um Widget de Waybar pra Omarchy pra Monitorar Uso de Planos de LLM: ai-usagebar</title><link>https://akitaonrails.github.io/2026/05/24/criei-widget-waybar-omarchy-monitorar-uso-llms-ai-usagebar/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/05/24/criei-widget-waybar-omarchy-monitorar-uso-llms-ai-usagebar/</guid><pubDate>Sun, 24 May 2026 00:01:00 -0300</pubDate><description>&lt;p&gt;Quem acompanha o blog já sabe que eu uso um monte de vendor de LLM diferente. Os principais são Claude e GPT, via Claude Code e Codex. Eu uso o harness de cada um porque estou preso aos planos de assinatura deles (Pro, Plus, Max), que saem muito mais baratos do que pagar crédito por token tipo OpenRouter. Mesmo assim, também uso OpenRouter pra acessar outros modelos pra teste, e tenho até uma assinatura Z.AI GLM pra coisas pequenas.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Quem acompanha o blog já sabe que eu uso um monte de vendor de LLM diferente. Os principais são Claude e GPT, via Claude Code e Codex. Eu uso o harness de cada um porque estou preso aos planos de assinatura deles (Pro, Plus, Max), que saem muito mais baratos do que pagar crédito por token tipo OpenRouter. Mesmo assim, também uso OpenRouter pra acessar outros modelos pra teste, e tenho até uma assinatura Z.AI GLM pra coisas pequenas.</p>
<p>O problema de ter vários planos é acompanhar quanto já gastei de cada um. Eu vinha usando o <a href="https://github.com/mryll/claudebar"target="_blank" rel="noopener">claudebar</a>, um widget de Waybar que mostra o uso do plano da Anthropic. Gosto dele, mas queria ver todos os meus vendors num lugar só, pra bater o olho e saber onde estou. E não queria encher minha Waybar de widget separado pra cada vendor. Então resolvi fazer o meu: o <strong><a href="https://github.com/akitaonrails/ai-usagebar"target="_blank" rel="noopener">ai-usagebar</a></strong>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-waybar.png" alt="Widget na Waybar mostrando “cld 29% · 1h 12m” no canto superior direito, com tooltip aberto exibindo o plano Claude Max 20x: Session 29%, Weekly 47%, Sonnet only 0%, Extra usage $0.00 sobre limite de $1100, e horário da última atualização."  loading="lazy" /></p>
<p>É um port em Rust do claudebar, drop-in compatível, estendido pra quatro vendors: Anthropic Claude, OpenAI Codex/ChatGPT, Z.AI (GLM) e OpenRouter. Mantém os mesmos parâmetros (<code>--icon</code>, <code>--format</code>, <code>--tooltip-format</code>, etc.), o mesmo tooltip minimalista com borda Pango, e a mesma auto-detecção do tema do Omarchy. A diferença é que agora os quatro vendors aparecem no mesmo lugar, em vez de 865 linhas de bash cuidando de um só.</p>
<h2>Como ele autentica em cada vendor<span class="hx:absolute hx:-mt-20" id="como-ele-autentica-em-cada-vendor"></span>
    <a href="#como-ele-autentica-em-cada-vendor" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Essa é a parte que vale explicar, porque cada vendor faz diferente. Claude e Codex usam OAuth: os CLIs oficiais (<code>claude</code> e <code>codex</code>) já escreveram as credenciais no disco quando você logou, e o ai-usagebar lê esses mesmos arquivos. Não precisa de variável de ambiente nenhuma, o token até se renova sozinho.</p>
<p>Z.AI e OpenRouter usam API key, então pra esses você precisa setar uma chave (via env var ou inline no config).</p>
<table>
  <thead>
      <tr>
          <th>Vendor</th>
          <th>Método</th>
          <th>O que você precisa fazer</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Anthropic</td>
          <td>OAuth, lê de <code>~/.claude/.credentials.json</code></td>
          <td>Roda <code>claude</code> uma vez pra logar. Token renova sozinho.</td>
      </tr>
      <tr>
          <td>OpenAI</td>
          <td>OAuth, lê de <code>~/.codex/auth.json</code></td>
          <td>Roda <code>codex login</code> uma vez. Token renova sozinho.</td>
      </tr>
      <tr>
          <td>Z.AI</td>
          <td>API key (<code>ZAI_API_KEY</code> ou <code>[zai] api_key</code> no config)</td>
          <td>Seta uma das duas.</td>
      </tr>
      <tr>
          <td>OpenRouter</td>
          <td>API key (<code>OPENROUTER_API_KEY</code> ou <code>[openrouter] api_key</code>)</td>
          <td>Seta uma das duas.</td>
      </tr>
  </tbody>
</table>
<h2>A interface além da Waybar<span class="hx:absolute hx:-mt-20" id="a-interface-além-da-waybar"></span>
    <a href="#a-interface-al%c3%a9m-da-waybar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Além do widget na barra, tem uma TUI com abas (<code>ai-usagebar-tui</code>) pra ver tudo de uma vez. Navega com Tab / h / l entre os vendors, atualiza a cada 60s. Dá pra abrir clicando no widget da Waybar, ou rodar direto no terminal (mais sobre isso na próxima seção).</p>
<p>A aba do OpenRouter mostra saldo de crédito, gasto de hoje / semana / mês e o tier:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-tui-openrouter.png" alt="ai-usagebar-tui na aba OpenRouter: gauge de saldo de crédito em 98% em vermelho ($13.67 restante de $900), bloco de uso por período (hoje/semana/mês), tier pago."  loading="lazy" /></p>
<p>E tem um overlay de settings pra escolher o vendor primário e colar as API keys sem editar o config na mão:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-tui-settings.png" alt="Overlay de settings flutuando sobre a TUI: radio de vendor primário (Anthropic selecionado), API key da Z.AI mascarada (•••), API key do OpenRouter mascarada (•••), botão Save, atalhos no rodapé."  loading="lazy" /></p>
<h2>Não usa Omarchy nem Hyprland? Roda como TUI standalone<span class="hx:absolute hx:-mt-20" id="não-usa-omarchy-nem-hyprland-roda-como-tui-standalone"></span>
    <a href="#n%c3%a3o-usa-omarchy-nem-hyprland-roda-como-tui-standalone" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O widget de Waybar é opcional. Os dois binários são independentes, então se você não usa Omarchy, nem Hyprland, nem Waybar (ou simplesmente prefere checar o uso de vez em quando em vez de ter na barra o tempo todo), o <code>ai-usagebar-tui</code> funciona como app de terminal totalmente standalone:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ai-usagebar-tui    <span class="c1"># abre no seu terminal atual</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Roda em qualquer emulador de terminal (Kitty, Alacritty, Foot, Ghostty, etc.), funciona até numa sessão SSH pura, e não depende de compositor nem de feature de window manager. Todos os controles e o overlay de settings funcionam igual. Os mesmos quatro vendors, as mesmas abas:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/24/ai-usagebar/ai-usagebar-tui-openai.png" alt="ai-usagebar-tui na aba OpenAI rodando num terminal: gauges de Codex 5h e semanal, bloco de Credits com faixas de contagem de mensagens, abas Claude / OpenAI / GLM (Z.AI) / OpenRouter no topo, atalhos de tecla no rodapé."  loading="lazy" /></p>
<p>Uso típico fora do Omarchy: uma checada rápida antes de começar uma sessão longa (&ldquo;será que tô perto do limite semanal do Claude?&rdquo;), um monitor num painel de tmux enquanto você programa, ou uma ferramenta só de shell em máquina remota (instala o binário e pronto, sem dependência de Waybar ou Hyprland). A TUI é a forma canônica de ver os quatro vendors de uma vez, independente de você configurar o widget ou não.</p>
<h2>Instalação<span class="hx:absolute hx:-mt-20" id="instalação"></span>
    <a href="#instala%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No Arch tem pacote no AUR, dois sabores:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">yay -S ai-usagebar-bin    <span class="c1"># binário pré-compilado do GitHub Releases (~5s)</span>
</span></span><span class="line"><span class="cl">yay -S ai-usagebar        <span class="c1"># compila do fonte (~30-60s)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ou do fonte direto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cargo build --release
</span></span><span class="line"><span class="cl">sudo make install                  <span class="c1"># → /usr/local/bin</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ou</span>
</span></span><span class="line"><span class="cl">make install <span class="nv">PREFIX</span><span class="o">=</span><span class="nv">$HOME</span>/.local   <span class="c1"># → ~/.local/bin</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A config de Waybar recomendada é um único módulo com scroll pra ciclar entre os vendors, e clique pra abrir a TUI:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;custom/aibar&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;ai-usagebar --format &#39;{vendor_short} {session_pct}% · {session_reset}&#39;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;return-type&#34;</span><span class="p">:</span> <span class="s2">&#34;json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="mi">300</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;signal&#34;</span><span class="p">:</span> <span class="mi">13</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tooltip&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;ai-usagebar-tui&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-scroll-up&#34;</span><span class="p">:</span>   <span class="s2">&#34;ai-usagebar --cycle-next&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-scroll-down&#34;</span><span class="p">:</span> <span class="s2">&#34;ai-usagebar --cycle-prev&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se preferir ver os quatro vendors ao mesmo tempo, dá pra usar um módulo por vendor. O <a href="https://github.com/akitaonrails/ai-usagebar"target="_blank" rel="noopener">README</a> tem o detalhe completo de config, placeholders de formato, e as variações.</p>
<h2>Por que fiz<span class="hx:absolute hx:-mt-20" id="por-que-fiz"></span>
    <a href="#por-que-fiz" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Esse parecia um projetinho de sábado à noite, então resolvi só fazer. E foi: portar o claudebar pra Rust e adicionar os vendors extras que eu queria foi tranquilo. Saí de uma noite com um widget que faz exatamente o que eu precisava e ainda é mais confiável (testado, modular) do que o shell script original.</p>
<p>Se você usa outros vendors que eu não cobri, ou achar bug, manda issue ou pull request: <a href="https://github.com/akitaonrails/ai-usagebar"target="_blank" rel="noopener">github.com/akitaonrails/ai-usagebar</a>. É MIT.</p>
]]></content:encoded><category>ai-usagebar</category><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>llms</category></item><item><title>NW-Omarchy: Trazendo Omarchy pro X11 com XLibre</title><link>https://akitaonrails.github.io/2026/05/01/omarchy-no-xlibre/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/05/01/omarchy-no-xlibre/</guid><pubDate>Fri, 01 May 2026 18:00:00 -0300</pubDate><description>&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/launcher-drun.png" alt="Launcher do NW-Omarchy: super&amp;#43;space abre rofi com todos os .desktop do sistema, ícones renderizados pelo tema Papirus" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Esse post inaugura um projeto experimental que tenho mexido nas últimas semanas: &lt;a href="https://github.com/akitaonrails/NW-Omarchy"target="_blank" rel="noopener"&gt;NW-Omarchy&lt;/a&gt;. A ideia é simples de explicar e razoavelmente teimosa de defender: pegar o look-and-feel opinativo e bonito do &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt; (que é Hyprland, ou seja, Wayland) e levar tudo isso pro mundo X11, como uma sessão paralela que você escolhe no SDDM. Sua sessão Hyprland continua intocada. Quando quiser experimentar X11, escolhe &lt;code&gt;nw-bspwm&lt;/code&gt; no login e cai num ambiente que parece o mesmo Omarchy só que com outras peças por baixo.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/launcher-drun.png" alt="Launcher do NW-Omarchy: super&#43;space abre rofi com todos os .desktop do sistema, ícones renderizados pelo tema Papirus"  loading="lazy" /></p>
<p>Esse post inaugura um projeto experimental que tenho mexido nas últimas semanas: <a href="https://github.com/akitaonrails/NW-Omarchy"target="_blank" rel="noopener">NW-Omarchy</a>. A ideia é simples de explicar e razoavelmente teimosa de defender: pegar o look-and-feel opinativo e bonito do <a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy</a> (que é Hyprland, ou seja, Wayland) e levar tudo isso pro mundo X11, como uma sessão paralela que você escolhe no SDDM. Sua sessão Hyprland continua intocada. Quando quiser experimentar X11, escolhe <code>nw-bspwm</code> no login e cai num ambiente que parece o mesmo Omarchy só que com outras peças por baixo.</p>
<p>A pergunta óbvia é &ldquo;por quê&rdquo;. A Red Hat já comunicou em 2025 que o <code>xorg-server</code> upstream sai do RHEL 10, e o discurso oficial do mundo Linux corporativo virou &ldquo;use Wayland e pronto&rdquo;. Como sempre, em open source a gente não precisa concordar. Existe XLibre, um fork do xorg-server retomando manutenção ativa, e existe muita gente com hardware velho, driver legado ou software legado pra qual Wayland ainda não é caminho viável. NW-Omarchy é pra esse cenário: dar uma sobrevida elegante pra esse equipamento e, de quebra, deixar ele bonito.</p>
<h2>O que é XLibre e por que ele importa<span class="hx:absolute hx:-mt-20" id="o-que-é-xlibre-e-por-que-ele-importa"></span>
    <a href="#o-que-%c3%a9-xlibre-e-por-que-ele-importa" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>XLibre é um fork do xorg-server iniciado em 2025, depois que ficou claro que o upstream não tinha mais energia pra evoluir. O X.Org em si só recebia patches críticos de segurança, e o principal financiador histórico do desenvolvimento (Red Hat) <a href="https://www.redhat.com/en/blog/rhel-10-plans-wayland-and-xorg-server"target="_blank" rel="noopener">comunicou que vai parar</a> com o RHEL 10. XLibre pegou a base e voltou a fazer cleanup, security fixes, modernização e bumps de driver-ABI. A primeira release pública foi a <a href="https://www.phoronix.com/news/XLibre-25.0-Released"target="_blank" rel="noopener">XLibre 25.0</a>, e o projeto vive em <a href="https://github.com/X11Libre/xserver"target="_blank" rel="noopener">github.com/X11Libre/xserver</a>.</p>
<p>A pegada técnica do XLibre é ser drop-in replacement pro xorg-server. Mesmo protocolo X11, mesma API client (libxcb/libx11), mesmo grafo de dependência no pacman. Seu xterm, seu Firefox, seu Steam, seu emulador favorito de fliperama dos anos 90, nada disso sabe que o servidor X mudou. Distros que já adotam XLibre como default ou tier-one:</p>
<ul>
<li><strong>Artix Linux</strong> (<a href="https://linuxiac.com/artix-linux-2026-04-released-with-xlibre-as-default-x-serve/"target="_blank" rel="noopener">2026.04+</a>) usa como X server padrão.</li>
<li><strong>Fedora</strong> tem <a href="https://fedoraproject.org/wiki/Changes"target="_blank" rel="noopener">Change proposal aberta</a> pra migrar.</li>
<li><strong>Arch Linux</strong> tem repo binário oficial em <code>x11libre.net/repo/arch_based/</code>. É exatamente esse que NW-Omarchy usa.</li>
</ul>
<p>Comparando o que tá vivo:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>xorg-server</th>
          <th>XLibre</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Última release não-security</td>
          <td>21.1 (2022)</td>
          <td>25.0 (2025)</td>
      </tr>
      <tr>
          <td>Trabalho ativo no codebase</td>
          <td>nenhum</td>
          <td>sim</td>
      </tr>
      <tr>
          <td>Driver ABI</td>
          <td>congelado</td>
          <td>atualizado (<code>X-ABI-VIDEODRV_VERSION=28.0</code> no 25.0)</td>
      </tr>
      <tr>
          <td>Futuro declarado</td>
          <td>&ldquo;use Wayland&rdquo;</td>
          <td>continuar evolução do X server</td>
      </tr>
      <tr>
          <td>Convive com <code>xorg-xwayland</code></td>
          <td>sim</td>
          <td>sim</td>
      </tr>
  </tbody>
</table>
<p>Se o seu argumento pra ficar no X11 é qualquer um dos clássicos (driver proprietário antigo de Nvidia, GPU Intel vintage, laptop Optimus com muxing esquisito, dependência de <code>xdotool</code>/<code>wmctrl</code>/<code>xprop</code>/<code>xinput</code> pra acessibilidade ou ferramentas de remap, <code>ssh -X</code> pra rodar app remoto, clipboard sem prompt de permissão, screen reader que precisa ler input de qualquer janela), o XLibre é o caminho que mantém esse stack em manutenção ativa.</p>
<h2>Por que esse projeto existe<span class="hx:absolute hx:-mt-20" id="por-que-esse-projeto-existe"></span>
    <a href="#por-que-esse-projeto-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu rodo Omarchy no meu Thinkpad T14 Gen 6 (<a href="/2026/04/18/omarchy-no-thinkpad-t14-gen-6/">escrevi sobre isso aqui</a>) e gosto bastante. O DHH fez um trabalho de curadoria muito bem pensado: tema único e consistente em tudo (terminal, launcher, top bar, lockscreen), atalhos coerentes, distinções visuais que não cansam o olho. É opinativo do jeito certo, te tira da fadiga de configurar tudo do zero.</p>
<p>O problema é que Omarchy é Hyprland, Hyprland é Wayland-only, e Wayland tem cenários onde ainda não é a ferramenta certa. Máquinas mais velhas com driver Nvidia legado, ambientes que dependem de software com integração X11 profunda, situações onde você quer <code>ssh -X</code> e não quer aprender <code>waypipe</code>, ou simplesmente máquinas que você quer manter funcionando sem trocar metade do stack. Pra esses casos, eu queria a estética e o workflow do Omarchy, mas em cima do X11. Não existia. Então fiz.</p>
<p>O nome NW-Omarchy é abreviação de &ldquo;Not Wayland Omarchy&rdquo;. É deliberadamente um sidecar: roda em paralelo, não substitui. Você instala em cima de uma instalação Omarchy existente, ele cria uma sessão SDDM separada chamada <code>nw-bspwm</code>, e nada do seu Hyprland é tocado. Quer voltar pro Hyprland? Escolhe Hyprland no SDDM no próximo login. Quer desinstalar? Tem script de uninstall que reverte exatamente o que foi instalado, baseado num manifest que rastreia cada ação.</p>
<h2>O que muda no stack (Wayland → X11)<span class="hx:absolute hx:-mt-20" id="o-que-muda-no-stack-wayland--x11"></span>
    <a href="#o-que-muda-no-stack-wayland--x11" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Hyprland é compositor + WM no mesmo binário. No mundo X11 essas duas funções vêm em peças separadas, e cada uma tem um substituto bem-conhecido. O esforço de tradução foi mapear cada componente do Omarchy pro equivalente X11 e garantir que o atalho de teclado, o tema e o comportamento ficassem o mais próximos possível.</p>
<table>
  <thead>
      <tr>
          <th>Função</th>
          <th>Omarchy/Wayland</th>
          <th>NW-Omarchy/X11</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Window manager</td>
          <td>Hyprland</td>
          <td><a href="https://github.com/baskerville/bspwm"target="_blank" rel="noopener">bspwm</a></td>
      </tr>
      <tr>
          <td>Hotkey daemon</td>
          <td>Hyprland built-in</td>
          <td><a href="https://github.com/baskerville/sxhkd"target="_blank" rel="noopener">sxhkd</a></td>
      </tr>
      <tr>
          <td>Compositor</td>
          <td>Hyprland built-in</td>
          <td><a href="https://github.com/yshui/picom"target="_blank" rel="noopener">picom</a> (upstream v13)</td>
      </tr>
      <tr>
          <td>Top bar</td>
          <td>Waybar</td>
          <td><a href="https://github.com/polybar/polybar"target="_blank" rel="noopener">polybar</a></td>
      </tr>
      <tr>
          <td>App launcher</td>
          <td>Walker</td>
          <td><a href="https://github.com/davatorium/rofi"target="_blank" rel="noopener">rofi</a></td>
      </tr>
      <tr>
          <td>Notifications</td>
          <td>Mako</td>
          <td><a href="https://github.com/dunst-project/dunst"target="_blank" rel="noopener">dunst</a></td>
      </tr>
      <tr>
          <td>Idle/lock</td>
          <td>hypridle / hyprlock</td>
          <td>xidlehook + xss-lock + i3lock-color</td>
      </tr>
      <tr>
          <td>Nightlight</td>
          <td>hyprsunset</td>
          <td>redshift</td>
      </tr>
      <tr>
          <td>Clipboard history</td>
          <td>walker <code>-m clipboard</code></td>
          <td><a href="https://github.com/cdown/clipmenu"target="_blank" rel="noopener">clipmenu</a> (rofi-backed)</td>
      </tr>
      <tr>
          <td>Screenshots</td>
          <td>hyprshot</td>
          <td>maim + slop + xclip</td>
      </tr>
      <tr>
          <td>Color picker</td>
          <td>hyprpicker</td>
          <td>xcolor</td>
      </tr>
  </tbody>
</table>
<p><strong>bspwm</strong> é tiling window manager minimalista. O WM em si só responde a comandos via socket, e o <code>bspwmrc</code> é literalmente um shell script. Atalho de teclado fica num daemon separado, <strong>sxhkd</strong>, que lê um arquivo de texto. Essa separação é típica do mundo X11: cada peça faz uma coisa só.</p>
<p><strong>picom</strong> é o compositor que dá blur, sombra, cantos arredondados, fade-in/out e regras de opacidade por janela. NW-Omarchy usa o upstream v13 (release de fevereiro de 2026), não o fork antigo <code>picom-ftlabs-git</code>, <a href="https://github.com/yshui/picom/issues"target="_blank" rel="noopener">abandonado desde 2024</a>. Os efeitos visuais que o Omarchy tem no Hyprland (cantos arredondados, fade ao abrir/fechar, blur no rofi e no dunst) vêm todos do picom no NW-Omarchy.</p>
<p><strong>polybar</strong> substitui o waybar. Mesma topologia visual: logo do Omarchy à esquerda, data no centro, indicadores de áudio/wifi/bluetooth/bateria à direita. Os ícones nerd-font são os mesmos. Click esquerdo abre os mesmos TUIs (wiremix, impala, bluetui), click direito as variantes GUI. Scroll no áudio ajusta volume, click do meio mute. Paridade prática.</p>
<p><strong>rofi</strong> substitui o walker. <code>super + space</code> abre o launcher completo com todos os <code>.desktop</code> do sistema e ícones. <code>super + shift + space</code> abre uma cheat-sheet das aplicações fixadas, mostrando o atalho ao lado do nome. Útil pra lembrar &ldquo;qual era o chord pro Signal mesmo&rdquo;.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/launcher-cheatsheet.png" alt="Cheat-sheet das aplicações fixadas: super&#43;shift&#43;space abre o rofi com cada app e o chord ao lado, parseado direto do sxhkdrc"  loading="lazy" /></p>
<p>Pra usuário que não vai abrir o <code>~/.config</code> pra customizar nada, a diferença entre as duas sessões é cosmética em níveis homeopáticos. Os mesmos atalhos do Omarchy (mais de 70 bindings) estão mapeados, os mesmos menus aparecem, o mesmo logo no canto da bar, os mesmos ícones nerd-font.</p>
<h2>O sistema de temas é o mesmo<span class="hx:absolute hx:-mt-20" id="o-sistema-de-temas-é-o-mesmo"></span>
    <a href="#o-sistema-de-temas-%c3%a9-o-mesmo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Essa parte foi a mais legal de implementar e a que mais surpreende quando você experimenta. O Omarchy tem um sistema de temas centralizado: cada tema vive em <code>~/.local/share/omarchy/themes/&lt;nome&gt;/</code>, traz um <code>colors.toml</code> com paleta universal (<code>accent</code>, <code>background</code>, <code>foreground</code>, <code>color0..15</code>), e <code>omarchy-theme-set &lt;nome&gt;</code> re-renderiza configs de cada app pra refletir essa paleta. O tema ativo fica em <code>~/.config/omarchy/current/theme/</code>, e cada app importa as cores de lá.</p>
<p>NW-Omarchy se encaixa nesse mesmo pipeline. Eu adicionei templates <code>.tpl</code> pra bspwm, polybar, rofi e dunst que seguem a mesma convenção do Omarchy, e o <code>omarchy-theme-set-templates</code> regenera tudo a cada troca de tema. O resultado é que os 19 temas que o Omarchy distribui funcionam tal e qual no NW-Omarchy, sem trabalho de portar. Catppuccin, gruvbox, kanagawa, nord, tokyo-night, todos funcionam. O wallpaper troca junto via um daemon inotify (<code>nw-omarchy-bg-watch</code>).</p>
<p>Olha alguns exemplos rodando:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/theme-ristretto.png" alt="Tema Ristretto: paleta quente em curvas marrons no wallpaper, polybar e bspwm border seguindo a mesma paleta"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/theme-lumon.png" alt="Tema Lumon: referência ao Severance, paleta corporativa fria, “United in Severance”"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/theme-everforest.png" alt="Tema Everforest: tons de verde-musgo, wallpaper de copa de árvores enevoada"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/theme-retro-82.png" alt="Tema Retro-82: synthwave, grade rosa em fundo escuro, neon nos detalhes"  loading="lazy" /></p>
<p>Quando o Omarchy ganha um tema novo via <code>omarchy-theme-update</code>, NW-Omarchy pega ele de graça. Sem trabalho extra, sem rebuild, sem precisar republicar nada do meu lado.</p>
<h2>Menu do sistema e TUIs<span class="hx:absolute hx:-mt-20" id="menu-do-sistema-e-tuis"></span>
    <a href="#menu-do-sistema-e-tuis" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O menu de sistema do Omarchy (aquele <code>super + alt + space</code> que abre o menu hierárquico com Hardware, Setup, Update, etc.) tem porte 1-pra-1 no NW-Omarchy. Mesma árvore, mesma navegação. Onde o Omarchy chama <code>walker --dmenu</code>, eu chamo <code>rofi -dmenu</code>. O resto do código é idêntico, e a maioria dos helpers que o menu invoca (<code>omarchy-pkg-add</code>, <code>omarchy-theme-set</code>, <code>omarchy-update</code>, etc.) não tem nada de Wayland-específico e funciona direto no X11.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/system-menu.png" alt="nw-omarchy-menu aberto: a árvore do menu de sistema do Omarchy, navegação por seta, mesma estética"  loading="lazy" /></p>
<p>Os TUIs também: wiremix pra áudio, impala pra wifi, bluetui pra bluetooth, btop pra recursos do sistema. Todos abrem como janela flutuante centralizada, igual o Omarchy faz no Hyprland. O bspwm tem regra (<code>bspc rule -a</code>) que reconhece a classe <code>org.nw-omarchy.&lt;cmd&gt;</code> e aplica <code>state=floating center=on rectangle=900x600</code> automaticamente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/05/01/nw-omarchy/wifi-tui.png" alt="Impala TUI rodando como janela flutuante centralizada via super&#43;ctrl&#43;w, paleta seguindo o tema ativo"  loading="lazy" /></p>
<h2>O que tem e o que não tem<span class="hx:absolute hx:-mt-20" id="o-que-tem-e-o-que-não-tem"></span>
    <a href="#o-que-tem-e-o-que-n%c3%a3o-tem" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Honestidade primeiro: tem coisa do Hyprland que é Wayland-only e não volta. Fractional scaling per-monitor não rola, X11 só faz scaling inteiro por output, então setup com mix de DPI fica torto. HDR não existe no X11. Renderização tear-free por design exige Wayland; no X11 precisa de picom + vsync e GPU cooperativa, e mesmo assim fica perto da Wayland sem chegar igual. Workspace swipe com preview ao vivo durante o gesto também não rola, porque o bspwm não tem estado de switch em progresso, então o gesto dispara comando discreto só na conclusão (você vai pra próxima workspace, mas não vê o preview deslizando). E os daemons especificamente Wayland (voxtype, walker preview pane, hyprsunset, hypridle) viram <code>redshift</code> e <code>xss-lock</code>, sem preview pane no rofi.</p>
<p>Se qualquer um desses pontos é decisivo pra você, fica no Omarchy/Hyprland. SDDM escolhe entre as duas sessões a cada login, então dá pra coexistir sem ressentimento.</p>
<p>Em compensação, o que o X11 tem de bom continua valendo. <code>xdotool</code>, <code>wmctrl</code>, <code>xprop</code> e <code>xinput</code> continuam funcionando pra automação, key remap, screen reader, AutoKey, kanata, xkeysnail. <code>xclip</code>, <code>xsel</code> e clipmenu fazem clipboard plumbing direto, sem dialog de permissão. <code>ssh -X</code> segue funcionando: você roda Firefox numa máquina remota e a janela aparece local. Driver Nvidia legacy, Intel vintage e Optimus quirky são first-class no X11. O ecossistema de tiling WM é maduro (bspwm, i3, awesome, openbox, xmonad, dwm) e configs migram entre eles com pouca dor. E o modelo de input previsível, onde qualquer cliente lê qualquer evento, é ruim pra segurança mas ótimo pra acessibilidade e ferramenta de produtividade.</p>
<p>Pra hardware mais velho, isso pesa como diferença entre &ldquo;máquina viva&rdquo; e &ldquo;máquina parada num canto&rdquo;.</p>
<h2>Instalação<span class="hx:absolute hx:-mt-20" id="instalação"></span>
    <a href="#instala%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pré-requisito: Arch Linux com Omarchy já instalado. NW-Omarchy roda em cima dele, não substitui.</p>
<p>One-liner de instalação:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://raw.githubusercontent.com/akitaonrails/NW-Omarchy/master/boot.sh <span class="p">|</span> bash</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>boot.sh</code> faz preflight (checa Arch, Omarchy, git), clona o repo pra <code>~/.local/share/nw-omarchy</code>, e roda a pipeline de install completa: pacotes, sessão <code>nw-bspwm</code>, configs em <code>~/.config</code>, e troca pro XLibre como último passo. Pede confirmação uma vez antes de tocar em qualquer coisa. Se você quer pular a confirmação:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://raw.githubusercontent.com/akitaonrails/NW-Omarchy/master/boot.sh <span class="p">|</span> bash -s -- --yes</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Quando termina, reboota. A troca do X server (xorg-server → XLibre) só vale na próxima sessão. No SDDM, você verá um picker de sessão. A gente também substituiu o tema do SDDM por uma versão com seletor, porque o tema vanilla do Omarchy tem o nome da sessão hardcoded no QML, sem UI pra trocar. Escolhe <code>nw-bspwm</code> e tá dentro.</p>
<p>Se você prefere clonar e rodar à mão pra inspecionar antes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://github.com/akitaonrails/NW-Omarchy.git ~/.local/share/nw-omarchy
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> ~/.local/share/nw-omarchy
</span></span><span class="line"><span class="cl">./install.sh           <span class="c1"># dry-run, mostra o que faria</span>
</span></span><span class="line"><span class="cl">./install.sh --apply   <span class="c1"># executa de verdade</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Atualização<span class="hx:absolute hx:-mt-20" id="atualização"></span>
    <a href="#atualiza%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando sai release nova, o caminho é:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nw-omarchy-upgrade --check    <span class="c1"># checa current vs latest, sai</span>
</span></span><span class="line"><span class="cl">nw-omarchy-upgrade            <span class="c1"># yay -Syu, fetch latest tag, migrations, install</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O script roda <code>yay -Syu</code> (ou <code>pacman -Syu</code> se você não tem yay), compara a tag local vs a remota, e se tiver release nova faz <code>git fetch &amp;&amp; git checkout v&lt;latest&gt;</code>, roda as migrations entre a versão atual e a nova, e re-aplica <code>install.sh --apply</code>. Tudo idempotente. Re-rodar numa máquina já atualizada é no-op.</p>
<h2>Desinstalação<span class="hx:absolute hx:-mt-20" id="desinstalação"></span>
    <a href="#desinstala%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se experimentou e não gostou, desinstala assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">~/.local/share/nw-omarchy/uninstall.sh --apply</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O uninstaller lê <code>~/.local/state/nw-omarchy/manifest.tsv</code> e replay reverso: remove só os pacotes que ele instalou (<code>pkg-skip</code> rows ficam intocadas; pacote que já existia continua no sistema), restaura configs originais a partir de <code>~/.local/state/nw-omarchy/backups/</code>, deleta a session entry <code>nw-bspwm</code>, limpa o state dir. Sua sessão Hyprland continua funcionando como antes. Nada do <code>~/.config/hypr/</code> ou do <code>~/.local/share/omarchy/</code> é tocado em momento algum durante a instalação ou desinstalação.</p>
<p>Pra reverter especificamente o XLibre de volta pro xorg-server (sem desinstalar o resto), o pacman resolve sozinho:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S xorg-server xorg-server-common xf86-input-libinput</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pacote <code>provides</code>/<code>conflicts</code> cuida do resto da troca atomicamente.</p>
<h2>Status: experimental, feedback bem-vindo<span class="hx:absolute hx:-mt-20" id="status-experimental-feedback-bem-vindo"></span>
    <a href="#status-experimental-feedback-bem-vindo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A versão atual tá em 1.0 mas o projeto continua novo, em fase de polimento. Os itens grandes já estão de pé: paridade de bindings, paridade de menu, paridade de temas, paridade dos TUIs, doctor pra checar saúde da instalação, manifest pra uninstall limpo. Falta lapidar, descobrir edge cases, exercitar em hardware variado, ouvir feedback de quem rodar em máquina diferente da minha (Thinkpad T14 Gen 6).</p>
<p>Se você experimentar e bater em algo (coisa que não funciona, configuração que faltou, comportamento que difere do Omarchy de um jeito que quebra fluxo), abre issue lá:</p>
<p><a href="https://github.com/akitaonrails/NW-Omarchy/issues"target="_blank" rel="noopener">github.com/akitaonrails/NW-Omarchy/issues</a></p>
<p>Reproduções, stack traces, output do <code>nw-omarchy-doctor</code>, qualquer coisa ajuda. PRs também são bem-vindos.</p>
<p>A defesa do X11 em 2026 é pragmática. A transição pro Wayland leva tempo, muito hardware e muito software ainda vivem confortavelmente do lado de cá, e a comunidade open source comporta mais de um caminho ao mesmo tempo. XLibre é a aposta de manter o X server vivo por mais alguns anos. NW-Omarchy é minha aposta de que dá pra fazer esse stack mais velho parecer tão bonito quanto o stack mais novo, sem comprometer nada do que faz X11 ainda valer a pena.</p>
<p>Se você tá em máquina nova, com GPU moderna, monitor 4K HiDPI, querendo HDR, fica no Omarchy/Hyprland. Se você tá numa máquina mais antiga, ou simplesmente prefere o ecossistema X11 por qualquer um dos motivos acima, dá uma chance pro NW-Omarchy.</p>
]]></content:encoded><category>omarchy</category><category>linux</category></item><item><title>Omarchy no Thinkpad T14 Gen 6: Mini-Review e Setup Completo</title><link>https://akitaonrails.github.io/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</guid><pubDate>Sat, 18 Apr 2026 08:30:00 -0300</pubDate><description>&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C"  loading="lazy" /></p>
<p>Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.</p>
<h2>Mini-review do Thinkpad T14 Gen 6<span class="hx:absolute hx:-mt-20" id="mini-review-do-thinkpad-t14-gen-6"></span>
    <a href="#mini-review-do-thinkpad-t14-gen-6" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-turned-off.jpg" alt="Thinkpad T14 Gen 6 aberto, tela desligada, mostrando o teclado e o selo do Intel Core Ultra 5"  loading="lazy" /></p>
<p>Vamos tirar do caminho: esse não é o notebook dos sonhos. Se eu fosse escolher por estética, pegaria um Asus Zenbook S 14 com tela OLED. Se fosse por portabilidade, o Thinkpad T14s com casca de alumínio, que é mais leve e muito mais bonito. O T14 regular tem tela IPS 1920x1200 de 14&quot;, 400 nits, 60Hz, sem HDR. Dá pro gasto, mas está longe da tela do Zenbook. A casca é de plástico com um acabamento emborrachado, o que deixa ele resistente a arranhão, mas não é premium. Revisões da <a href="https://www.notebookcheck.net/AMD-Ryzen-AI-meets-classic-ThinkPad-Lenovo-ThinkPad-T14-Gen-6-AMD-laptop-review.1222690.0.html"target="_blank" rel="noopener">NotebookCheck</a> e da <a href="https://www.xda-developers.com/lenovo-thinkpad-t14-gen-6-review/"target="_blank" rel="noopener">XDA Developers</a> batem na mesma tecla: bom custo, boa conectividade, desempenho adequado pra escritório, mas a tela é datada.</p>
<p>O que compensa:</p>
<ul>
<li>Seleção de portas. HDMI full-size. Ethernet gigabit. USB-A, USB-C Thunderbolt 4, carrega pelo USB-C (não é carregador proprietário). Pra um companion de debug, isso é exatamente o que eu queria. O Zenbook S 14, por ser mais fino, corta portas.</li>
<li>Sensor de digital funcional no Linux (Goodix MOC, funciona com libfprint em kernel 6.11+). Isso eu uso, detalho mais à frente.</li>
<li>Teclado Thinkpad. Curso de tecla de 1.5mm, trackpoint, layout clássico. Não é o melhor teclado do mundo em 2026, mas é confiável e durável.</li>
<li>Carcaça rugged. Vai cair, vai arranhar, vai viajar na mala. Se eu colocasse um Zenbook OLED ou um Macbook Pro em cima da mesa do escritório de impressão 3D, ao lado da impressora, com poeira de PLA voando, eu ficaria nervoso. O Thinkpad pode levar porrada.</li>
</ul>
<p>Se eu quisesse máquina de jogo, pegaria um Asus Zephyrus G14, meu favorito de notebook gamer. Se eu quisesse máquina de trabalho criativo, pegaria o <a href="https://www.asus.com/laptops/for-home/zenbook/zenbook-duo-ux8406/"target="_blank" rel="noopener">Asus Zenbook Duo (UX8406)</a> com duas telas OLED verticais, ótimo pra edição de vídeo e modelagem 3D. Tenho grana pra qualquer Macbook Pro ou Mac Studio, e escolhi não ir por esse caminho. Explico melhor na próxima seção.</p>
<h2>Meu caso de uso<span class="hx:absolute hx:-mt-20" id="meu-caso-de-uso"></span>
    <a href="#meu-caso-de-uso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-fastfetch.jpg" alt="Thinkpad aberto numa bancada do escritório de impressão 3D, com fastfetch mostrando Omarchy no terminal"  loading="lazy" /></p>
<p>Meu PC principal é um desktop com Ryzen 9 7950X3D, 96 GB de RAM, RTX 5090 de 32 GB. É onde eu trabalho, experimento com modelos locais, rodo containers, edito o blog. Pra jogo, tenho um mini-PC separado com RTX 4090. Esses dois atendem 100% do que eu preciso fazer em casa.</p>
<p>O notebook existe pra cobrir o 1% restante: sentar no sofá, levar no escritório de impressão 3D, levar na cozinha, levar em viagem curta. Não é pra substituir o desktop. É pra ter acesso remoto ao desktop quando eu estiver longe dele.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/ssh-to-remote-desktop-on-left.png" alt="Hyprland com dois terminais lado a lado: à esquerda SSH pro desktop principal (96 GB, RTX 5090), à direita o próprio Thinkpad. Mesma UI, duas máquinas."  loading="lazy" /></p>
<p>Na prática fica assim: abro o notebook, dou split no Hyprland, janela da esquerda dá SSH no desktop principal, janela da direita é o próprio notebook. Mesmo Omarchy nos dois, mesmos atalhos, mesmo bash. O notebook vira extensão do desktop, não um ambiente paralelo que eu tenho que reconfigurar na cabeça toda vez que alterno.</p>
<h3>SSH fora de casa: Tailscale<span class="hx:absolute hx:-mt-20" id="ssh-fora-de-casa-tailscale"></span>
    <a href="#ssh-fora-de-casa-tailscale" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Dentro da rede local, SSH é trivial, o notebook fala com o desktop via IP interno. Fora de casa é outra história. Meu IP doméstico é dinâmico, abrir porta 22 pra internet é péssima ideia, e mesmo com DDNS e port forwarding você está colocando SSH na cara da internet pra qualquer scanner achar.</p>
<p>A solução que uso é <a href="https://tailscale.com/"target="_blank" rel="noopener">Tailscale</a>. Pra quem não conhece: Tailscale é uma mesh VPN baseada no WireGuard, que cria uma rede privada entre seus dispositivos (o &ldquo;tailnet&rdquo;). Cada máquina roda o agente, autentica uma vez, e passa a ter um IP fixo na rede privada (tipo 100.x.y.z). O tráfego entre seus próprios dispositivos vai direto peer-to-peer, cifrado pelo WireGuard. Não passa por servidor central da Tailscale, eles só coordenam NAT traversal. Resultado: do meu notebook num café em qualquer lugar do mundo, eu dou <code>ssh hal9000</code> e caio no desktop de casa como se estivesse na mesma rede.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/tailscale-machines.png" alt="Painel admin da Tailscale mostrando as duas máquinas do meu tailnet, hal9000 (desktop) e hal9666 (thinkpad), ambas com SSH habilitado"  loading="lazy" /></p>
<p>Existem opções mais sofisticadas: <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"target="_blank" rel="noopener">Cloudflare Tunnel</a> com Zero Trust pra expor serviços publicamente com autenticação SSO, headscale self-hosted, WireGuard cru com config manual, Nebula, OpenVPN. Cada uma tem seu caso de uso. Se você precisa expor serviços pra terceiros, controlar acesso granular por identidade, rodar a infraestrutura inteira em casa sem depender de terceiros, essas opções ganham. No meu caso, é só notebook falando com desktop, por períodos curtos (não é trabalho de uma semana inteira, é debug rápido de fim de semana), então Tailscale grátis resolve. O tier free aceita até 100 dispositivos e 3 usuários, muito mais do que eu preciso.</p>
<p>Setup é o mais simples possível:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># No Arch/Omarchy</span>
</span></span><span class="line"><span class="cl">sudo pacman -S tailscale
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tailscaled.service
</span></span><span class="line"><span class="cl">sudo tailscale up --ssh</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A flag <code>--ssh</code> ativa o <a href="https://tailscale.com/kb/1193/tailscale-ssh/"target="_blank" rel="noopener">Tailscale SSH</a>, que faz autenticação via identidade da tailnet em vez de chave SSH local. Uma vez fez login via browser no tailscale, cada máquina registrada pode entrar nas outras com base em política de ACL definida no painel admin. Zero key management.</p>
<p>Repito no desktop, faço login com a mesma conta, e pronto. As duas máquinas aparecem no painel (hal9000 e hal9666 na screenshot acima, com SSH habilitado nas duas). Do notebook: <code>ssh hal9000</code>. Do desktop pro notebook: <code>ssh hal9666</code>. Sem port forward, sem IP público, sem expor porta 22 pra internet. Se o notebook for roubado, eu removo ele do tailnet num clique.</p>
<p>Um detalhe prático: como o tailnet dá nome estável, eu adicionei entradas no <code>~/.ssh/config</code> pra usar esses nomes curtos:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>Host hal9000
  HostName hal9000
  User akitaonrails</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Assim <code>ssh hal9000</code> funciona de qualquer lugar que tenha Tailscale conectado. É a solução mais próxima de &ldquo;it just works&rdquo; que já vi pra SSH remoto.</p>
<h3>Por que não um Mac<span class="hx:absolute hx:-mt-20" id="por-que-não-um-mac"></span>
    <a href="#por-que-n%c3%a3o-um-mac" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Eu não tenho uso pro macOS. Como dev, eu vivo melhor em Linux nativo. Toda ferramenta que eu preciso tem versão Linux de primeira, e no macOS eu teria versão de segunda via Homebrew. Não faço iOS, então não preciso do XCode. Pra mobile uso Flutter ou Hotwire Native, que rodam em qualquer OS. iTerm2 e Ghostty no Mac são bons, mas Alacritty, Kitty e o próprio Ghostty no Linux me atendem igual. Todo software bom chega primeiro no Linux, daí é portado pros outros. Arch com AUR cobre tudo num único <code>yay</code>.</p>
<p>Pra trabalho criativo, faz anos que não faço profissionalmente. DaVinci Resolve Studio no Linux é superior ao Final Cut Pro. Krita ou Affinity Photo substituem Photoshop na maioria dos casos. Clip Studio Paint no Android é superior ao Procreate. Eu simplesmente não tenho um workflow que depende da Apple, e a App Store me irrita.</p>
<p>Pra jogo, Mac é terrível. Apple Silicon tem GPU boa pra algumas coisas, mas a biblioteca de jogo pro macOS nativo é pífia comparada com Windows ou Linux. Game Porting Toolkit existe, CrossOver existe, mas pra quem joga sério, não serve. Eu não vou jogar no Thinkpad, pra isso tenho o desktop principal e o mini-PC com RTX 4090, mas se um dia bater vontade de rodar um Hollow Knight ou um indie num trem, é só instalar Steam e deixar o Proton fazer o trabalho. Linux virou plataforma de jogo de verdade nos últimos anos, com Proton/DXVK rodando quase todo o catálogo da Steam (checa <a href="https://www.protondb.com/"target="_blank" rel="noopener">ProtonDB</a>). Inclusive documentei recentemente como <a href="/2026/04/11/distrobox-de-emulacao-com-claude-code/">rodei minha biblioteca de emulação em distrobox</a> sem poluir o sistema host. Com Mac, essas opções não existem.</p>
<p>Outro argumento que sempre aparece: &ldquo;mas um Mac Mini M4 ou Mac Studio com 128GB de memória unificada roda modelos grandes localmente, é o substituto do ChatGPT&rdquo;. Já testei essa tese e escrevi um <a href="/2026/04/05/testando-llms-open-source-e-comerciais-quem-consegue-bater-o-claude-opus/">benchmark detalhado</a>. A conclusão: hardware local caro pra rodar LLM é hobby de fim de semana, não é ferramenta de produção. Os modelos open source que cabem não entregam a qualidade que o Claude Opus entrega. Eu tenho um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">home server com AMD Strix Halo e 96 GB de RAM unificada</a>, rodei modelos por dezenas de horas, e no meu fluxo real de programação eles servem pra tarefas simples. Pras tarefas complexas, Claude Opus. Antes de gastar os $4000 num Mac Studio com a justificativa de rodar modelos locais, faça o teste de verdade. Você provavelmente vai voltar a pagar Opus depois.</p>
<h2>Por que Omarchy<span class="hx:absolute hx:-mt-20" id="por-que-omarchy"></span>
    <a href="#por-que-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu uso Omarchy no desktop há meses e documentei o caminho numa <a href="/tags/omarchy/">série de artigos</a>. O <a href="/2025/08/29/new-omarchy-2-0-install/">Omarchy 2.0</a> tem instalador próprio com LUKS, Btrfs, Limine, snapper e SDDM já configurados. Escrevi sobre <a href="/2025/09/12/omarchy-2-0-instale-com-a-iso-do-omarchy/">usar a ISO oficial</a>, sobre as <a href="/2025/09/07/omarchy-2-0-zsh-configs/">customizações de ZSH</a> com atuin, starship, secrets bem organizados, sobre <a href="/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/">Mise pra múltiplas linguagens</a>, sobre <a href="/2025/09/07/omarchy-2-0-lazyvim-lazyextras/">LazyVim e LazyExtras</a>, sobre <a href="/2025/09/09/omarchy-2-0-entendendo-ssh-e-yubikeys/">SSH e Yubikeys</a>, sobre <a href="/2025/09/09/omarchy-2-0-tuis/">TUIs modernas</a>. Também tem o <a href="/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/">Omarchy 3 com dual GPU AMD + NVIDIA</a> e o <a href="/2026/01/09/omarchy-3-um-dos-melhores-agentes-pra-programacao-crush/">Crush</a> como agente de coding.</p>
<p>Pra quem não conhece: Omarchy é Arch Linux puro com uma camada de cosmética em cima do Hyprland/Wayland. Pré-configurado com defaults sãos. Eu podia montar tudo isso do zero, já fiz isso várias vezes na vida, mas por que refazer trabalho que alguém já fez bem feito? Instalo Omarchy, faço os tweaks que são meus em cima, e tenho Arch customizado numa fração do tempo.</p>
<p>Um ponto que eu levanto toda vez que recomendo Omarchy: a documentação é excelente. Tem um <a href="https://manuals.omamix.org/2/the-omarchy-manual"target="_blank" rel="noopener">manual oficial</a> que cobre desde instalação até customização de tema, keybindings, Hyprland, Waybar, tudo. Se você vem de Ubuntu ou Fedora e tem receio de Arch, esse manual resolve o grosso das dúvidas. Pra quem nunca tocou em Hyprland, abre ele e vai tangenciando. Não é um README jogado no GitHub, é manual de verdade, com capítulos e índice.</p>
<p>A história desse artigo começa num fio anterior. Eu migrei meu home server recentemente, trocando um servidor Ubuntu antigo por um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">Minisforum MS-S1 com openSUSE MicroOS configurado com Claude Code</a>. Esse foi o primeiro experimento sério de deixar o Claude Code guiar uma migração de infra inteira, com containers, NFS, serviços, networking. Deu certo. E deixou no ar a ideia: por que não usar a mesma abordagem pra configurar um notebook novo?</p>
<p>Foi o que fiz. Peguei o Thinkpad, baixei a ISO do Omarchy mais recente, gravei num pendrive, instalei por cima do Windows. Do zero ao desktop funcional, menos de uma hora. Dali pra frente, tudo é tweaking, que eu fui documentando conforme fazia.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-claude-terminal.jpg" alt="Claude Code rodando no terminal do Thinkpad, pronto pra começar a configurar o notebook"  loading="lazy" /></p>
<p>Vou detalhar as duas camadas de customização: o que precisa pra um notebook qualquer, e o que é específico desse Thinkpad.</p>
<h2>Configs específicos de notebook<span class="hx:absolute hx:-mt-20" id="configs-específicos-de-notebook"></span>
    <a href="#configs-espec%c3%adficos-de-notebook" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Um notebook tem problemas que um desktop não tem: bateria, suspensão, tampa, brilho, trackpad. Essas são as partes que Omarchy default não cobre do jeito que eu quero.</p>
<h3>Power management com TLP<span class="hx:absolute hx:-mt-20" id="power-management-com-tlp"></span>
    <a href="#power-management-com-tlp" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O default do Omarchy vem com <code>power-profiles-daemon</code>. Troquei por TLP, que dá controle granular de CPU scaling, thresholds de bateria e perfil dinâmico baseado em AC vs bateria.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S tlp tlp-rdw
</span></span><span class="line"><span class="cl">sudo systemctl mask power-profiles-daemon.service
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tlp.service</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>mask</code> é necessário porque o upower traz o <code>power-profiles-daemon</code> de volta se você só der <code>disable</code>.</p>
<p>Thresholds de carga: 60% pra começar, 85% pra parar. O notebook fica a maior parte do tempo plugado na mesa do escritório, e manter a bateria em 100% 24/7 detona a capacidade ao longo do tempo. Com 60/85, a bateria passa a maior parte do tempo na faixa saudável de lítio e ainda sobra capacidade útil decente.</p>
<p>Perfis: <code>balanced</code> com <code>balance_power</code> na bateria, <code>performance</code> no AC. O <code>low-power</code> do TLP era agressivo demais no Core Ultra 5 235U, a resposta de janela e terminal ficava perceptível. Balanced dá a melhor relação consumo/responsividade pra uso normal.</p>
<p>Tem uma pegadinha: <code>tlp auto</code> depois de <code>tlp ac</code> nem sempre reaplica o perfil de bateria. Criei um pequeno script ligado ao <code>Super+Ctrl+P</code> que lê o estado atual e chama <code>tlp bat</code> ou <code>tlp ac</code> explicitamente:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">profile</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null <span class="o">||</span> <span class="nb">echo</span> unknown<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">on_ac</span><span class="o">=</span><span class="k">$(</span>cat /sys/class/power_supply/AC*/online 2&gt;/dev/null <span class="p">|</span> head -1 <span class="o">||</span> <span class="nb">echo</span> 0<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$profile</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;performance&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$on_ac</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;1&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp auto &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;Plugged in — back to AC auto&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">else</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp bat &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;On battery — normal profile&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: off&#34;</span> <span class="s2">&#34;</span><span class="nv">$label</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  sudo /usr/bin/tlp ac &gt;/dev/null
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: on&#34;</span> <span class="s2">&#34;Forcing AC profile&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No waybar, um módulo custom <code>custom/perf</code> mostra o estado atual (󰓅 PERF, 󰌪 ECO, ou vazio pra balanced) e aceita clique pra alternar. O script de output é bem curto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nv">p</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> in
</span></span><span class="line"><span class="cl">  performance<span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;󰓅 PERF&#39;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  low-power<span class="o">)</span>   <span class="nb">printf</span> <span class="s1">&#39;󰌪 ECO&#39;</span>  <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  balanced<span class="p">|</span><span class="s2">&#34;&#34;</span><span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;&#39;</span>       <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  *<span class="o">)</span>           <span class="nb">printf</span> <span class="s1">&#39;%s&#39;</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Suspend, hibernate, e tampa<span class="hx:absolute hx:-mt-20" id="suspend-hibernate-e-tampa"></span>
    <a href="#suspend-hibernate-e-tampa" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Isso aqui é o que mudou em relação aos notebooks que eu usava em 2015. O T14 Gen 6 fecha a tampa, suspende, e acorda quando você abre de novo. Sem bug, sem delay estranho, sem precisar dar login de novo no meio da sessão gráfica. O hyprlock pega depois do suspend, aceita digital ou senha, e volta pro desktop em segundos. Isso é o comportamento que a gente tem na Apple há anos e que no Linux era uma aventura. Em 2026, em hardware moderno com kernel 6.11+, simplesmente funciona.</p>
<p>Mem sleep mode é s2idle (sem deep sleep). Hibernação habilitada via swapfile Btrfs de ~30 GB e <code>resume=/dev/mapper/root resume_offset=...</code> no kernel cmdline do Limine. Raramente uso, mas está lá.</p>
<p>O hypridle tem timeouts agressivos pra notebook:</p>
<ul>
<li>2.5 min → screensaver</li>
<li>5 min → lock</li>
<li>5.5 min → DPMS off + keyboard backlight off</li>
</ul>
<p>Depois de trancado, passa mais 5 min e a tela apaga de vez. No unlock, restaura brilho de tela e de teclado pro nível anterior. Essas timings são muito mais curtas que as do desktop (20-40 min lá). A diferença de bateria ao longo do dia é mensurável.</p>
<h3>Brilho e backlight de teclado<span class="hx:absolute hx:-mt-20" id="brilho-e-backlight-de-teclado"></span>
    <a href="#brilho-e-backlight-de-teclado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><code>brightnessctl</code> controla os dois. Fn+Space alterna o backlight do teclado em três níveis. Hypridle salva o nível atual antes de apagar e restaura no retorno. Comando que uso no script:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brightnessctl -sd <span class="s1">&#39;*::kbd_backlight&#39;</span> <span class="nb">set</span> <span class="m">0</span>    <span class="c1"># salva e desliga</span>
</span></span><span class="line"><span class="cl">brightnessctl -rd <span class="s1">&#39;*::kbd_backlight&#39;</span>          <span class="c1"># restaura</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Touchpad<span class="hx:absolute hx:-mt-20" id="touchpad"></span>
    <a href="#touchpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>touchpad {
    natural_scroll = true
    clickfinger_behavior = true
    disable_while_typing = true
    scroll_factor = 0.4
}
gesture = 3, horizontal, workspace</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>clickfinger_behavior</code> troca o clique de 2 dedos como botão direito (mais confortável que acertar a zona inferior direita). <code>disable_while_typing</code> é palm rejection básico. Três dedos horizontais alternam workspaces, o gesto mais útil no Hyprland.</p>
<h2>Configs específicos do Thinkpad<span class="hx:absolute hx:-mt-20" id="configs-específicos-do-thinkpad"></span>
    <a href="#configs-espec%c3%adficos-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui entra o que é particular desse modelo. Algumas coisas o Linux moderno já cobre sozinho, outras exigem configuração específica.</p>
<h3>Sensor de digital<span class="hx:absolute hx:-mt-20" id="sensor-de-digital"></span>
    <a href="#sensor-de-digital" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Goodix MOC <code>27c6:6594</code>, funciona com libfprint 1.94.9+ em kernel 6.11+. Pacote é <code>fprintd</code>.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S fprintd
</span></span><span class="line"><span class="cl">fprintd-enroll                        <span class="c1"># dedo indicador direito por default</span>
</span></span><span class="line"><span class="cl">fprintd-enroll -f left-index-finger   <span class="c1"># outro dedo</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pro <code>sudo</code> aceitar digital, adiciono <code>auth sufficient pam_fprintd.so</code> acima da linha do <code>pam_unix.so</code> em <code>/etc/pam.d/sudo</code>. Com <code>sufficient</code>, se a digital passar, autentica direto. Se falhar ou se eu digitar ESC, cai pro prompt de senha. Isso vale a pena de verdade: dezenas de vezes por dia, <code>sudo pacman -Syu</code> ou <code>sudo systemctl restart algo</code>, e é só encostar o dedo.</p>
<p>No hyprlock, uso a configuração nativa do próprio hyprlock, não o PAM:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>auth {
    fingerprint {
        enabled = true
        ready_message = Scan fingerprint or type password
        present_message = Scanning...
        retry_delay = 250
    }
}</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A razão é que o caminho PAM dá prompt duplo. Configurado nativo, o hyprlock aceita digital ou senha, o que vier primeiro desbloqueia.</p>
<p>No SDDM (login inicial), deixei senha apenas. O motivo: a senha de login destrava o keyring do GNOME, e a digital não consegue fornecer plaintext pra isso. Depois que o keyring está destrancado, o hyprlock pode usar digital sem problema.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/sudo-asks-for-fingerprinting.png" alt="Prompt do sudo pedindo leitura de digital"  loading="lazy" /></p>
<p>Na prática, o sudo fica assim. Encosta o dedo, autentica, segue.</p>
<h3>Teclado brasileiro do Thinkpad<span class="hx:absolute hx:-mt-20" id="teclado-brasileiro-do-thinkpad"></span>
    <a href="#teclado-brasileiro-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O teclado brasileiro do Thinkpad tem uma peculiaridade chata. A tecla <code>/?</code> fica na posição que seria o Ctrl direito (keycode 97), não na posição AB11 tradicional do ABNT2 (keycode 89). Se você usar o layout padrão <code>br(abnt2)</code>, essa tecla fica inacessível. Literalmente não imprime nada.</p>
<p>A solução é o variant <code>br(thinkpad)</code> que existe em <code>/usr/share/X11/xkb/symbols/br</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>xkb_symbols &#34;thinkpad&#34; {
    include &#34;br(abnt2)&#34;
    name[Group1]=&#34;Portuguese (Brazil, IBM/Lenovo ThinkPad)&#34;;
    key &lt;RCTL&gt; { [ slash, question, degree, questiondown ] };
};</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>kb_layout = br
kb_variant = thinkpad
kb_model = thinkpad60</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E system-wide pra TTY/X11:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo localectl set-keymap br-abnt2
</span></span><span class="line"><span class="cl">sudo localectl set-x11-keymap br thinkpad thinkpad60</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Escrevi um pequeno Python que lê scancodes brutos de <code>/dev/input/event*</code> pra diagnosticar essas esquisitices. Útil quando uma tecla decide não funcionar e você precisa descobrir se é hardware, kernel, ou xkb.</p>
<h3>Input method: fcitx5<span class="hx:absolute hx:-mt-20" id="input-method-fcitx5"></span>
    <a href="#input-method-fcitx5" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Junto com o layout eu instalo fcitx5. Input method, pra quem não conhece, é a camada que transforma sequência de teclas em caracteres. É onde entram deadkeys (til pra nasalizar, acento agudo, circunflexo), composição de caracteres que não estão no teclado (ç, Ç, letras acentuadas em maiúscula), suporte a emoji. Em app Qt ou GTK, o input method também cuida dos menus de contexto pra cedilha e acentos.</p>
<p>Pacotes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed fcitx5 fcitx5-configtool fcitx5-gtk fcitx5-qt</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E as variáveis de ambiente pros toolkits encontrarem o fcitx5. Criei <code>~/.config/environment.d/fcitx.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>INPUT_METHOD=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>environment.d</code> do systemd é carregado antes das sessões gráficas, então Brave, Alacritty, VS Code e qualquer GTK/Qt pegam automaticamente. Habilito autostart no Hyprland:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>exec-once = fcitx5 -d</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Digitando <code>~a</code> vira <code>ã</code>, <code>'e</code> vira <code>é</code>, <code>ç</code> funciona como deveria em toda aplicação. Num teclado Thinkpad brasileiro, isso é a diferença entre conseguir escrever em português com naturalidade ou ficar catando letra.</p>
<h3>Áudio SOF<span class="hx:absolute hx:-mt-20" id="áudio-sof"></span>
    <a href="#%c3%a1udio-sof" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Codec Realtek ALC3306/ALC287 via Sound Open Firmware. Sem o <code>sof-firmware</code>, o módulo de kernel carrega mas o DSP nunca boota e o PipeWire cai silenciosamente pra <code>auto_null</code>. Resultado: você acha que o alto-falante está no mudo, mas na verdade o PipeWire não tem device nenhum.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed sof-firmware alsa-ucm-conf pipewire pipewire-pulse wireplumber</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se precisar forçar SOF em vez do HDA legacy:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;options snd-intel-dspcfg dsp_driver=3&#34;</span> <span class="p">|</span> sudo tee /etc/modprobe.d/alsa.conf</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Reload sem reboot:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo modprobe -r snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">sudo modprobe snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">systemctl --user restart wireplumber pipewire pipewire-pulse</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Firmware updates pelo fwupd<span class="hx:absolute hx:-mt-20" id="firmware-updates-pelo-fwupd"></span>
    <a href="#firmware-updates-pelo-fwupd" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/bios-update.jpg" alt="Firmware update da Lenovo (ME Corp) rodando no boot"  loading="lazy" /></p>
<p><code>fwupdmgr update</code> funciona, mas com Limine tem uma pegadinha: o fwupd tenta escrever em <code>/boot/EFI/systemd/</code> ou <code>/boot/EFI/arch/</code>, que não existem. O workaround:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /boot/EFI/arch
</span></span><span class="line"><span class="cl">sudo fwupdmgr update -y --no-reboot-check
</span></span><span class="line"><span class="cl">fwupdmgr get-history  <span class="c1"># deve mostrar &#34;Success&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>HiDPI / fractional scaling<span class="hx:absolute hx:-mt-20" id="hidpi--fractional-scaling"></span>
    <a href="#hidpi--fractional-scaling" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Painel 14&quot; em 1920x1200 numa resolução do Hyprland livre. O auto 1.5x do Omarchy ficava chunky demais. Fixei em 1.333x:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>env = GDK_SCALE,1
monitor=,preferred,auto,1.3333,vrr,2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Efetivo 1440x900. GTK com <code>GDK_SCALE=1</code> renderiza 1:1 com o Hyprland (não magnifica duplo). VRR mode 2 só em fullscreen, porque painéis LCD tendem a cintilar em conteúdo estático com VRR ativa.</p>
<p>Flags do Brave e Chromium pra renderizar bem nessa escala:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>--ozone-platform=wayland
--enable-features=WaylandFractionalScaleV1,UseOzonePlatform,VaapiVideoDecoder,VaapiVideoEncoder
--enable-gpu-rasterization</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O VAAPI faz diferença real na bateria em YouTube.</p>
<h2>Tunando Omarchy pra ser meu<span class="hx:absolute hx:-mt-20" id="tunando-omarchy-pra-ser-meu"></span>
    <a href="#tunando-omarchy-pra-ser-meu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Omarchy vem com defaults bons. O que eu ajusto é no topo deles, sem tocar em <code>~/.local/share/omarchy/</code> (que é clobbered pelo <code>omarchy-update</code>). Toda customização fica em <code>~/.config/</code>.</p>
<h3>Infra: Btrfs, snapshots, Snapper<span class="hx:absolute hx:-mt-20" id="infra-btrfs-snapshots-snapper"></span>
    <a href="#infra-btrfs-snapshots-snapper" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Omarchy já vem com Btrfs e subvolumes separados:</p>
<table>
  <thead>
      <tr>
          <th>Subvolume</th>
          <th>Mount</th>
          <th>Entra nos snapshots?</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>@</code></td>
          <td><code>/</code></td>
          <td>sim</td>
      </tr>
      <tr>
          <td><code>@home</code></td>
          <td><code>/home</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@log</code></td>
          <td><code>/var/log</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@pkg</code></td>
          <td><code>/var/cache/pacman/pkg</code></td>
          <td>não</td>
      </tr>
  </tbody>
</table>
<p><code>@home</code> separado significa que <code>~/.cache</code>, <code>~/.config/BraveSoftware</code>, etc. não incham snapshots do root. Snapshot é de sistema, não de perfil.</p>
<p>Swap: zram de 4 GB com prioridade 100 (hit primeiro), mais swapfile de 30 GB com prioridade 0 (habilita hibernação, dimensionado pra RAM).</p>
<p>O stack de snapshot: Snapper tira snapshot antes e depois de cada <code>pacman -Syu</code> via snap-pac. <code>limine-snapper-sync</code> escreve esses snapshots no menu do Limine, então dá pra bootar num snapshot anterior pra reverter. Se algo quebra depois de update, você segura uma tecla no boot, escolhe o snapshot pré-update, boota read-only pra verificar, e se estiver bom, faz <code>snapper rollback</code>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/btrfs-snapshots-config.png" alt="Subvolumes Btrfs separados pra que snapshots do root não inchem com cache de usuário"  loading="lazy" /></p>
<p>Omarchy deixa o <code>snapper-cleanup.timer</code> e o <code>snapper-boot.timer</code> desabilitados por default. Habilitei os dois e configurei retenção pra caber num SSD de 1 TB sem explodir:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>TIMELINE_LIMIT_HOURLY=10
TIMELINE_LIMIT_DAILY=0
TIMELINE_LIMIT_WEEKLY=1
TIMELINE_LIMIT_MONTHLY=1
NUMBER_LIMIT=50</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Um detalhe que custa debug pra quem esquece: Docker e Ollama escrevem gigabytes em <code>/var/lib/docker</code> e <code>/var/lib/ollama</code>. Se isso cai dentro de <code>@</code>, os snapshots catastrofizam. Cada imagem Docker ou modelo Ollama baixado triplica em tamanho. Criei subvolumes aninhados pros dois, com <code>chattr +C</code> pra desligar CoW:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo btrfs subvolume create /var/lib/docker
</span></span><span class="line"><span class="cl">sudo chattr +C /var/lib/docker
</span></span><span class="line"><span class="cl">sudo btrfs subvolume create /var/lib/ollama</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso tem que ser feito ANTES de o Docker ou Ollama escrever dados. Se já tem dados lá, precisa migrar.</p>
<h3>NFS pro NAS Synology<span class="hx:absolute hx:-mt-20" id="nfs-pro-nas-synology"></span>
    <a href="#nfs-pro-nas-synology" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Meu Synology expõe três volumes. No desktop, monto normal. No notebook, tem que ser mais defensivo. O notebook anda, esquece a rede, conecta em WiFi público. Fstab do notebook:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>nfs4  _netdev,noauto,nofail,x-systemd.automount,x-systemd.idle-timeout=10min,x-systemd.mount-timeout=15s,noatime,nodiratime,nconnect=4,actimeo=10,soft,timeo=30,retrans=2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Diferença crítica em relação ao desktop: <code>soft</code> com timeouts curtos (não fica pendurado pra sempre), <code>x-systemd.idle-timeout=10min</code> (auto-unmount quando ocioso), sem <code>network-online.target</code> no require (não atrasa boot). Resultado prático: <code>cd /mnt/gigachad</code> em casa monta lazy, fora de casa falha rápido sem trancar shell.</p>
<p>Outro detalhe importante: meu user no notebook tem UID 1026, que bate com a permissão do share no Synology. O Linux default cria user em 1000, o Synology impõe identidade via UID no fio. Se os UIDs não batem, você não consegue ler os arquivos, ou ainda pior, escreve como nobody. Rodei de TTY (com usuário deslogado) os <code>usermod</code>/<code>groupmod</code> pra remapear o user pra 1026/1026 e fiz <code>chown -R</code> em <code>/home</code>.</p>
<h3>Hardening de WiFi público<span class="hx:absolute hx:-mt-20" id="hardening-de-wifi-público"></span>
    <a href="#hardening-de-wifi-p%c3%bablico" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Notebook vai sair de casa. Num aeroporto ou café, eu não quero anunciar hostname, não quero MAC rastreável, não quero serviço escutando porta aberta.</p>
<p><code>/etc/NetworkManager/conf.d/00-macrandomize.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=stable
ethernet.cloned-mac-address=stable
connection.stable-id=${CONNECTION}/${BOOT}

ipv6.ip6-privacy=2
ipv6.addr-gen-mode=stable-privacy</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>MAC aleatório por scan (anti-fingerprinting passivo). MAC clonado estável por SSID (o portal cativo não te re-pergunta login toda vez) mas diferente entre redes. IPv6 com endereços temporários e interface ID derivado de segredo estável, não do MAC (sem vazar EUI-64).</p>
<p><code>/etc/systemd/resolved.conf.d/hardening.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Resolve]
LLMNR=no
MulticastDNS=no</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mata broadcast de hostname em LLMNR e mDNS. Também desabilito avahi:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl disable --now avahi-daemon.service avahi-daemon.socket</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>UFW firewall:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw default deny incoming
</span></span><span class="line"><span class="cl">sudo ufw default allow outgoing
</span></span><span class="line"><span class="cl">sudo ufw --force enable</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>SSH server já é off por default no Omarchy. Nada escutando. Mesmo que o firewall vaze, não tem superfície.</p>
<p>Tudo isso entra num único ritual de setup inicial.</p>
<h3>Persistência de SSH agent (keyring + keychain)<span class="hx:absolute hx:-mt-20" id="persistência-de-ssh-agent-keyring--keychain"></span>
    <a href="#persist%c3%aancia-de-ssh-agent-keyring--keychain" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você usa SSH sério, quer digitar a passphrase uma vez por boot e ter <code>ssh</code>, <code>git push</code>, <code>scp</code> mudos pelo resto do dia. No Arch atual isso tem uma pegadinha: o <code>gnome-keyring</code> 50 deixou de oferecer componente SSH, e o substituto (<code>gcr-ssh-agent</code>) é um agente plain em memória, sem persistência de passphrase. A caixa &ldquo;lembrar esta chave&rdquo; que você viu em guias antigos simplesmente não existe mais.</p>
<p>A combinação que funciona tem três peças:</p>
<ol>
<li><code>gcr-ssh-agent.socket</code> gerenciado pelo systemd serve o <code>SSH_AUTH_SOCK</code> em <code>$XDG_RUNTIME_DIR/gcr/ssh</code></li>
<li><code>pam_gnome_keyring</code> no login SDDM destrava o keyring com a senha de login (usado por apps GUI tipo Brave, não pelo SSH)</li>
<li><code>keychain</code> (wrapper) mantém um <code>ssh-agent</code> vivo entre logouts, sobrescreve o <code>SSH_AUTH_SOCK</code> pra apontar pra esse agent persistente, e cacheia o PID em <code>~/.keychain/&lt;host&gt;-sh</code></li>
</ol>
<p>Primeiro, instalo o keyring:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed gnome-keyring seahorse keychain</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Depois, edito <code>/etc/pam.d/sddm</code> pra o login password destravar o keyring automaticamente. Adiciono no topo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-auth      optional    pam_gnome_keyring.so</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E no final:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-session   optional    pam_gnome_keyring.so    auto_start</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O hífen na frente (<code>-auth</code>, <code>-session</code>) marca como opcional, se o módulo não carregar, não quebra login.</p>
<p>Pino o <code>SSH_AUTH_SOCK</code> pra sessões gráficas e TTY via <code>~/.config/environment.d/ssh-agent.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>SSH_AUTH_SOCK=%t/gcr/ssh</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>%t</code> resolve pra <code>$XDG_RUNTIME_DIR</code>, tipo <code>/run/user/1026</code>. Habilito o socket do gcr e o linger do usuário (pra user daemons sobreviverem ao logout):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl --user <span class="nb">enable</span> --now gcr-ssh-agent.socket
</span></span><span class="line"><span class="cl">sudo loginctl enable-linger <span class="nv">$USER</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Por fim, no <code>~/.config/bash/init.sh</code> o keychain inicia ou reusa o agent:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="k">if</span> <span class="nb">command</span> -v keychain <span class="p">&amp;</span>&gt;/dev/null <span class="o">&amp;&amp;</span> <span class="o">[[</span> -r ~/.ssh/id_ed25519 <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">eval</span> <span class="s2">&#34;</span><span class="k">$(</span>keychain --eval --quiet ~/.ssh/id_ed25519<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>--eval</code> emite atribuições shell (<code>SSH_AUTH_SOCK</code>, <code>SSH_AGENT_PID</code>) apontando pro agent do keychain, que passa por cima do gcr setado pelo environment.d. <code>--quiet</code> cala o banner depois que a chave está carregada.</p>
<p>Fluxo na prática: boot → primeiro terminal → keychain pede passphrase uma vez → chave fica carregada. Logout → login de novo → novos shells re-atacham no mesmo agent (via <code>~/.keychain/&lt;host&gt;-sh</code>) → zero prompt. <code>ssh-add -l</code> confirma que a chave está lá, <code>echo $SSH_AUTH_SOCK</code> confirma que está no caminho do keychain.</p>
<p>Quando você vai digitar a passphrase de novo: reboot, <code>ssh-add -D</code>, ou <code>keychain --clear</code>. Em uso normal, uma vez por dia.</p>
<h3>Bash em vez de ZSH<span class="hx:absolute hx:-mt-20" id="bash-em-vez-de-zsh"></span>
    <a href="#bash-em-vez-de-zsh" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No desktop uso ZSH. No notebook fui de Bash pra alinhar com o default do Omarchy, sem dupla de camadas modulares pra manter. <code>~/.bashrc</code> é um symlink pra <code>~/.config/bash/bashrc</code>, que faz source dos defaults do Omarchy primeiro e depois empilha as minhas customizações:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">source</span> ~/.local/share/omarchy/default/bash/rc
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/envs.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/aliases.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/mounts.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/init.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/secrets    <span class="c1"># gitignored, chmod 600</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>envs.sh</code> tem o que é meu: OpenRouter base URL, Ollama apontando pro GPU box da rede local (192.168.0.14), AWS region, analytics do Hugo, configs de zoxide e SSH agent. <code>aliases.sh</code> tem os atalhos de TLP, um alias pra <code>shell-gpt</code> via Docker, e functions pra hardenar o PATH quando rodo <code>makepkg</code> ou <code>yay</code> (prevenir injeção de binário via user config malicioso).</p>
<p><code>init.sh</code> faz o trabalho de integração. Atuin com bind manual do Ctrl-R (pra deixar a seta pra cima com o history-search padrão do bash, que eu uso mais). Keychain carregando <code>~/.ssh/id_ed25519</code> uma vez por boot e reusando nos shells seguintes (sem ter que re-autenticar SSH toda hora). Blesh se estiver instalado (autosuggestion estilo ZSH pra Bash). E uma função que manda o PROMPT_COMMAND ajustar o título da janela com o pwd atual e o comando em execução:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">__title_idle<span class="o">()</span> <span class="o">{</span> <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">__title_busy<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">cmd</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">BASH_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;__title_&#34;</span>* <span class="o">||</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> *<span class="s2">&#34;PROMPT_COMMAND&#34;</span>* <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s — %s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -n <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="p">-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle; </span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="nb">trap</span> <span class="s1">&#39;__title_busy&#39;</span> DEBUG</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No idle, título mostra só o pwd. Com um comando rodando, <code>trap DEBUG</code> pega o <code>BASH_COMMAND</code> em execução e atualiza o título. Integra com o <code>hyprland/window</code> do waybar pra mostrar tudo lá.</p>
<p>Pro toolbelt Rust moderno, a lista:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed <span class="se">\
</span></span></span><span class="line"><span class="cl">  eza bat fd ripgrep sd git-delta dust procs bottom duf tokei hyperfine <span class="se">\
</span></span></span><span class="line"><span class="cl">  zoxide atuin tldr starship</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>eza</code> substitui <code>ls</code>. <code>bat</code> substitui <code>cat</code> com syntax highlight. <code>fd</code> substitui <code>find</code>. <code>ripgrep</code> substitui <code>grep</code>. <code>sd</code> substitui <code>sed</code>. <code>delta</code> pluga no git pra diff side-by-side colorido. <code>dust</code> pro <code>du</code> visual. <code>procs</code> pro <code>ps</code>. <code>btm</code> (bottom) pro <code>top</code>. <code>duf</code> pro <code>df</code>. <code>tokei</code> conta linhas de código. <code>hyperfine</code> pra benchmark de comando. <code>zoxide</code> é <code>cd</code> com memória (muito útil). <code>atuin</code> é history do shell com sync criptografado (aponto pro meu home server via <code>sync_address = &quot;http://192.168.0.90:8888&quot;</code>). <code>starship</code> é o prompt. <code>tldr</code> é man page em 10 linhas.</p>
<p>O <code>atuin key</code> tem que ser backupeado offline. Se você perde, perde o histórico criptografado. Salvei no meu Bitwarden self-hosted (Vaultwarden), que eu documentei no <a href="/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/">artigo sobre Bitwarden self-hosted</a>.</p>
<p>O git passa diff pelo delta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[core]        pager = delta
[interactive] diffFilter = delta --color-only
[delta]       navigate side-by-side line-numbers hyperlinks, light=false
[merge]       conflictstyle = zdiff3</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Hyprland e Waybar<span class="hx:absolute hx:-mt-20" id="hyprland-e-waybar"></span>
    <a href="#hyprland-e-waybar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Customizações visuais e de UX que fiz em cima do default.</p>
<p>No <code>hypr/looknfeel.conf</code>, gaps menores (2/5 vs 5/10 do default), animação de slide entre workspaces, VFR ligado (reduz consumo quando a tela está estática), <code>allow_session_lock_restore</code> (se o hyprlock crasha, volta pra tela de lock em vez de jogar pro desktop).</p>
<p>No <code>hypr/bindings.conf</code>:</p>
<table>
  <thead>
      <tr>
          <th>Binding</th>
          <th>Ação</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Super+B</code></td>
          <td>Brave</td>
      </tr>
      <tr>
          <td><code>Super+L</code></td>
          <td>Lock screen (default era layout toggle)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+L</code></td>
          <td>Layout toggle (movi pra cá)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+P</code></td>
          <td>Toggle TLP perf mode</td>
      </tr>
  </tbody>
</table>
<p>No Waybar, três módulos custom que recomendo:</p>
<p><strong>Título de janela</strong>: o módulo <code>hyprland/window</code> mostra o que tá focado. No bash, o PROMPT_COMMAND atualiza o título pra algo como &ldquo;~/Projects/blog — hugo server&rdquo;. Então no waybar aparece o diretório e o comando em execução, sem eu precisar olhar pro terminal.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---window-title-on-waybar.png" alt="Waybar mostrando workspaces à esquerda e o título da janela focada com o pwd e comando em execução"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---another-window-title-on-waybar.png" alt="Outro exemplo do título da janela no waybar, dessa vez mostrando “Claude Code”"  loading="lazy" /></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;hyprland/window&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{title}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;max-length&#34;</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rewrite&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;(.{47}).+&#34;</span><span class="p">:</span> <span class="s2">&#34;$1…&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>Perf mode</strong>: o <code>custom/perf</code> executa um script que lê o estado do TLP e mostra um ícone:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;custom/perf&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-waybar.sh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-toggle.sh&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Vazio em balanced, 󰓅 PERF em performance, 󰌪 ECO em low-power. Clique alterna. Útil pra ver rapidamente em que modo a máquina está.</p>
<p><strong>Claudebar</strong>: integrei o <a href="https://github.com/alfredopiquet/claudebar"target="_blank" rel="noopener">claudebar</a> num módulo custom que mostra a % de uso da sessão do Claude Code e o gasto extra inline no waybar. Sem ter que abrir outra janela.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---power-profile-and-claudebar-next-to-traybar.png" alt="Claudebar mostrando 9%, 1h16m restantes e $1120.74 de uso extra, seguido do indicador PERF e o tray"  loading="lazy" /></p>
<p>O clock:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;clock&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A %d %B - %H:%M}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format-alt&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A W%V %Y - %H:%M}&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Exibe &ldquo;quinta 17 abril - 14:32&rdquo; por padrão, clique alterna pra &ldquo;quinta W16 2026 - 14:32&rdquo; com número da semana do ano, útil pra planejar artigos e tarefas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---better-date-time-on-waybar-center.png" alt="Clock do waybar no centro com data e hora em português"  loading="lazy" /></p>
<h3>Atuin self-hosted<span class="hx:absolute hx:-mt-20" id="atuin-self-hosted"></span>
    <a href="#atuin-self-hosted" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Atuin roda no meu home server em 192.168.0.90:8888. Criei uma conta separada pro notebook (<code>akitaonrails-thinkpad</code>), não misturo histórico com desktop de propósito. <code>atuin sync</code> roda a cada 5 minutos e todo histórico é criptografado antes de ir pro server. O server não vê os comandos, só vê bytes criptografados.</p>
<h2>Conclusão: escolhendo notebook pra Linux<span class="hx:absolute hx:-mt-20" id="conclusão-escolhendo-notebook-pra-linux"></span>
    <a href="#conclus%c3%a3o-escolhendo-notebook-pra-linux" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se tem uma coisa que eu aprendi nessa jornada: escolher notebook pra rodar Linux confortavelmente não é trivial. Precisa checar a <a href="https://wiki.archlinux.org/title/Laptop"target="_blank" rel="noopener">ArchWiki</a> pelo modelo específico antes de comprar. A do <a href="https://wiki.archlinux.org/title/Lenovo_ThinkPad_T14s_%28AMD%29_Gen_6"target="_blank" rel="noopener">T14s Gen 6 AMD</a>, por exemplo, cataloga cada peculiaridade de hardware e como contornar. Sem essa referência, você descobre os problemas instalando.</p>
<p>Regra que sigo: nunca comprar modelo recém-lançado. Deixar passar uns 6 a 12 meses depois do lançamento. Isso dá tempo pra comunidade iron out os bugs, pros drivers entrarem no mainline, pra ArchWiki ter uma página decente, pra libfprint incluir o sensor de digital, pro kernel cobrir o WiFi e a câmera IR. Comprar de primeira é assumir o papel de tester beta.</p>
<p>Marcas com trilha Linux decente: Lenovo (especialmente Thinkpad, eles oferecem Ubuntu e Fedora pré-instalados), Dell (a linha XPS e Latitude), Asus (Zenbook e ROG têm suporte razoável), Framework (fábrica direto pra Linux). Mac qualquer geração recente é cortado do Linux mainline ou via Asahi com caveats.</p>
<p>O Thinkpad T14 Gen 6 não é o notebook mais bonito que eu podia ter comprado. Mas é rugged, tem as portas certas, o sensor de digital funciona, e a carcaça plástica aceita cair, arranhar, viajar na mala sem eu ficar nervoso. Pra servir de companion de debug remoto, é o que eu precisava. Se esse é o seu perfil de uso também, recomendo. Se você quer OLED e metal, vai de Zenbook ou de T14s. Cada premium tem seu compromisso, nenhum notebook Linux em 2026 é perfeito.</p>
<p>Tudo que descrevi aqui ficou versionado num repo privado meu. Se eu precisar reinstalar amanhã, rodo meia dúzia de passos em ordem e volto ao mesmo lugar. Esse é o ponto todo de manter configuração em Git: notebook é commodity, config é minha.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>hardware</category><category>reviews</category></item><item><title>Omarchy 3: Setup de Dual GPUs com AMD e NVIDIA</title><link>https://akitaonrails.github.io/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/</guid><pubDate>Wed, 21 Jan 2026 15:29:35 -0300</pubDate><description>&lt;p&gt;Mais um post só pra eu não me esquecer destes detalhes na configuração do &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hyprland não funciona bem com NVIDIA&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dá pra usar. Mas tem vários probleminhas, em particular com &lt;a href="https://github.com/basecamp/omarchy/issues/1147"target="_blank" rel="noopener"&gt;Hyprlock&lt;/a&gt;, em particular com DPMS onde eu deixo meu computador em idle, daí ele se bloqueia, e depois de um timeout desliga os monitores pra economizar energia, não ter burn in, etc.&lt;/p&gt;
&lt;p&gt;Quando eu tento acordar do sleep, o Hyprlock crasheou e eu preciso ir pra outro TTY pra reiniciar, até fiz um script &lt;code&gt;~/.local/bin/hypr_unlock.sh&lt;/code&gt; assim:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Mais um post só pra eu não me esquecer destes detalhes na configuração do <a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy</a>:</p>
<blockquote>
  <p>Hyprland não funciona bem com NVIDIA</p>

</blockquote>
<p>Dá pra usar. Mas tem vários probleminhas, em particular com <a href="https://github.com/basecamp/omarchy/issues/1147"target="_blank" rel="noopener">Hyprlock</a>, em particular com DPMS onde eu deixo meu computador em idle, daí ele se bloqueia, e depois de um timeout desliga os monitores pra economizar energia, não ter burn in, etc.</p>
<p>Quando eu tento acordar do sleep, o Hyprlock crasheou e eu preciso ir pra outro TTY pra reiniciar, até fiz um script <code>~/.local/bin/hypr_unlock.sh</code> assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hyprctl --instance <span class="m">0</span> <span class="s1">&#39;keyword misc:allow_session_lock_restore 1&#39;</span>
</span></span><span class="line"><span class="cl">hyprctl --instance <span class="m">0</span> <span class="s1">&#39;dispatch exec hyprlock&#39;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mas aí desbloqueia e eu vejo que meu Brave crasheou também. A nvidia realmente não gosta que desliguem o monitor enquanto ele tá ativo. Disseram que isso acontecia no Hyprlock 0.9.1 mas eu já estou no 0.9.2 e continua crasheando. Tentei habilitar serviços como nvidia-suspend/resume/hibernate mas nada também.</p>
<p>No fim do dia resolvi que não vale a pena brigar com isso: eu tenho uma <strong>AMD 7850X3D</strong> e essa CPU tem uma iGPU (GPU integrada), uma AMD Raphael, que pra coisas como renderizar um gerenciador de janelas, é mais do que potente o suficiente.</p>
<p>Primeiro, detectar as GPUs:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ ls /dev/dri/by-path
</span></span><span class="line"><span class="cl">Permissions Size User Date Modified Name
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:01:00.0-card -&gt; ../card1
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:01:00.0-render -&gt; ../renderD128
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:1a:00.0-card -&gt; ../card2
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:1a:00.0-render -&gt; ../renderD129</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pra saber qual é AMD e qual é NVIDIA só executar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ lspci <span class="p">|</span> grep -i vga
</span></span><span class="line"><span class="cl">01:00.0 VGA compatible controller: NVIDIA Corporation GB202 <span class="o">[</span>GeForce RTX 5090<span class="o">]</span> <span class="o">(</span>rev a1<span class="o">)</span>
</span></span><span class="line"><span class="cl">1a:00.0 VGA compatible controller: Advanced Micro Devices, Inc. <span class="o">[</span>AMD/ATI<span class="o">]</span> Raphael <span class="o">(</span>rev c9<span class="o">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto, pelo ID de PCI sabemos que card1 é NVIDIA e card2 é AMD. Agora precisa configurar meu <code>~/.config/hypr/hyprland.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">....
</span></span><span class="line"><span class="cl"><span class="c1"># NVIDIA environment variables</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> NVD_BACKEND,direct
</span></span><span class="line"><span class="cl"><span class="c1">#env = LIBVA_DRIVER_NAME,nvidia</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> LIBVA_DRIVER_NAME,radeonsi
</span></span><span class="line"><span class="cl"><span class="c1">#env = __GLX_VENDOR_LIBRARY_NAME,nvidia</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Comment these out when using AMD as primary</span>
</span></span><span class="line"><span class="cl"><span class="c1">#env = __NV_PRIME_RENDER_OFFLOAD,1</span>
</span></span><span class="line"><span class="cl"><span class="c1">#env = __VK_LAYER_NV_optimus,NVIDIA_only</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># card1=nvidia, card2=amdgpu (verify with: cat /sys/class/drm/card*/device/uevent)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># AMD first for iGPU primary:</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> AQ_DRM_DEVICES,/dev/dri/card2:/dev/dri/card1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> ELECTRON_OZONE_PLATFORM_HINT,auto</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Eu deixei as configurações específicas de NVIDIA comentadas, nenhuma delas pode estar ativa. Mas a linha mais importante é a do <code>AQ_DRM_DEVICES</code> que lista a ordem pro Hyprland pegar a GPU. Card2/AMD tem que estar primeiro. E pronto, só rebootar e recolocar os cabos HDMI na saída da iGPU.</p>
<p>Com isso eu posso escolher agora dar offload de somente alguns apps da NVIDIA usando Prime. Pra isso primeiro eu criei os script <code>~/.local/bin/nvidia-load.sh</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nv">__NV_PRIME_RENDER_OFFLOAD</span><span class="o">=</span><span class="m">1</span> <span class="nv">__VK_LAYER_NV_optimus</span><span class="o">=</span>NVIDIA_only <span class="nv">__GLX_VENDOR_LIBRARY_NAME</span><span class="o">=</span>nvidia <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Finalmente, configurei alguns bindings em <code>~/.config/hypr/bindings.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, B, Blender, exec, ~/.local/bin/nvidia-load.sh blender
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, L, Bambu Studio, exec, ~/.local/bin/nvidia-load.sh bambu-studio
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, P, Blender, exec, ~/.local/bin/nvidia-load.sh plasticity
</span></span><span class="line"><span class="cl">...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Desta forma, somente os apps Blender, Plasticity e Bambu Studio, que vão primariamente usar a NVIDIA pra renderizar 3D em real time. Todos os outros apps vão abrir na iGPU AMD.</p>
<p>Ferramentas de IA como ComfyUI, Ollama ou LM Studio automaticamente reconhecem a NVIDIA e escolhem lá. E com isso eu também tenho mais VRAM livre pra carregar LLMs.</p>
<p>Se for usar XLibre/X.org, dá pra ficar de boa em NVIDIA. Mas se for usar Wayland, nvidia ainda não é totalmente estável, em particular com Hyprland. Dá menos dor de cabeça colocar uma segunda GPU AMD só pra isso.</p>
]]></content:encoded><category>omarchy</category><category>hardware</category><category>linux</category></item><item><title>Omarchy 3 - Um dos Melhores Agentes pra Programação: Crush</title><link>https://akitaonrails.github.io/2026/01/09/omarchy-3-um-dos-melhores-agentes-pra-programacao-crush/</link><guid isPermaLink="true">https://akitaonrails.github.io/2026/01/09/omarchy-3-um-dos-melhores-agentes-pra-programacao-crush/</guid><pubDate>Fri, 09 Jan 2026 20:01:04 -0300</pubDate><description>&lt;p&gt;Ano passado eu estava recomendando o &lt;a href="https://aider.chat/"target="_blank" rel="noopener"&gt;Aider&lt;/a&gt; como agente pra auxiliar programação. Mas sinto que ele meio que parou no tempo. Comparado com os Cursor ou Windsurf da vida, ficou bem pra trás.&lt;/p&gt;
&lt;p&gt;Felizmente, no mundo open source existem novas opções. O DHH resolveu trazer o &lt;a href="https://opencode.ai/"target="_blank" rel="noopener"&gt;OpenCode&lt;/a&gt; no Omarchy 3.x.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://x.com/dhh/status/2007589042485883374"target="_blank" rel="noopener"&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109200839_screenshot-2026-01-09_20-08-17.png" alt="dhh opencode" loading="lazy" /&gt;&lt;/a&gt;
Depois que fiz o upgrade (rodar &lt;code&gt;omarchy-update&lt;/code&gt;) vi que também veio a opção de instalar o que estou começando a usar agora, o &lt;a href="https://github.com/charmbracelet/crush"target="_blank" rel="noopener"&gt;&lt;strong&gt;CRUSH&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Ano passado eu estava recomendando o <a href="https://aider.chat/"target="_blank" rel="noopener">Aider</a> como agente pra auxiliar programação. Mas sinto que ele meio que parou no tempo. Comparado com os Cursor ou Windsurf da vida, ficou bem pra trás.</p>
<p>Felizmente, no mundo open source existem novas opções. O DHH resolveu trazer o <a href="https://opencode.ai/"target="_blank" rel="noopener">OpenCode</a> no Omarchy 3.x.</p>
<p><a href="https://x.com/dhh/status/2007589042485883374"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109200839_screenshot-2026-01-09_20-08-17.png" alt="dhh opencode"  loading="lazy" /></a>
Depois que fiz o upgrade (rodar <code>omarchy-update</code>) vi que também veio a opção de instalar o que estou começando a usar agora, o <a href="https://github.com/charmbracelet/crush"target="_blank" rel="noopener"><strong>CRUSH</strong></a>.</p>
<p>Crush é do mesmo pessoal que vem fazendo diversas bibliotecas pra facilitar desenvolvimento de TUIs (Terminal User Interface Apps), como o <a href="https://github.com/charmbracelet/bubbletea"target="_blank" rel="noopener">BubbleTea</a> e <a href="https://github.com/charmbracelet/gum"target="_blank" rel="noopener">Gum</a>. Recomendo olhar esses repositórios também. É muito mais interessante fazer apps pra terminal, hoje em dia, especialmente ferramentas pra dev ou Linux em geral.</p>
<p>É um TUI muito bem feito. Essa é a cara dele:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109202710_screenshot-2026-01-09_20-26-58.png" alt="Crush UI"  loading="lazy" /></p>
<p>Como primeira impressão, rodei no meu projetinho deste blog, que é um site estático gerado pelo <a href="https://akitaonrails.com/2025/09/10/meu-novo-blog-como-eu-fiz/"target="_blank" rel="noopener">Hugo</a>.</p>
<p>Como eu já tenho variáveis de ambiente pra <a href="https://openrouter.ai/docs/quickstart"target="_blank" rel="noopener">OpenRouter</a>, nem precisei configurar nada. Só rodar <code>crush</code> no diretório do projeto.</p>
<p>A primeira coisa que fez foi analisar meu projeto. Como é pequeno, foi bem rápido. Não sei como lida com projetos gigantes. Mas sai vasculhando o código-fonte e no final anota tudo num arquivo <a href="https://github.com/akitaonrails/akitaonrails.github.io/blob/master/AGENTS.md"target="_blank" rel="noopener">AGENTS.md</a>. E fiquei impressionado que fez um excelente trabalho em resumir o projeto, veja um trecho:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109201559_screenshot-2026-01-09_20-15-47.png" alt="agents.md"  loading="lazy" />
Eu nem sabia que tinha a opção de rodar <code>scripts/dev.sh new-post</code> pra automaticamente gerar o sub-diretório com timestamp pra um novo post. Eu estava fazendo manualmente toda vez 😅.</p>
<p>Eu sabia que meu script de <a href="https://github.com/akitaonrails/akitaonrails.github.io/blob/master/scripts/generate_index.rb"target="_blank" rel="noopener"><code>scripts/generate_index.rb</code></a> estava meio bagunçado então perguntei ao Crush se ele conseguiria refatorar:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109201839_screenshot-2026-01-09_20-18-30.png" alt="refactor generate_index"  loading="lazy" />
No final ele refatorou bonitinho, sem introduzir novos bugs, sem reescrever coisas que não precisa. Melhorou muito mesmo refatorar só o que precisa. Mudou coisas como usar <code>Dir.glob</code> em vez de <code>Find.find</code>, trocou pra usar symbols em vez de strings (mais idiomático), etc.</p>
<p>Gostei que ele roda a versão modificada e checa se continua executando como deveria.</p>
<p>Segui pedindo pra fazer a mesma coisa com o <a href="https://github.com/akitaonrails/akitaonrails.github.io/blob/master/scripts/dev.sh"target="_blank" rel="noopener"><code>scripts/dev.sh</code></a>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109202153_screenshot-2026-01-09_20-21-44.png" alt="refactor dev.sh"  loading="lazy" />
E nesse caso ele até encontrou um bug que eu não tinha percebido. Novamente, ele editou esse shell script pra deixar mais seguro, separou constantes, melhor checagem de erro, etc.</p>
<p>Este é o <a href="https://github.com/akitaonrails/akitaonrails.github.io/commit/440470b09e822af0dc23a7c6aec73b4ead89caf7"target="_blank" rel="noopener">commit com as modificações</a>. Dêem uma olhada. Ele realmente não colocou nenhum código desnecessário. Tudo continua funcionando como antes, mas agora está mais organizado. E ainda corrigiu um bug que eu não tinha visto.</p>
<p>Neste pequeno exemplo, escolhi usar o modelo <strong>Claude Opus 4.5</strong>. Todo o código foi gerado por ele. O Crush é só um Agente que usa o modelo e instrui com o contexto adequado.</p>
<p>Por enquanto só fiz coisas bestas e simples. Diz a documentação que ele integra com LSPs e MCPs pra ter ainda mais contexto sobre o código, mas não testei isso ainda.</p>
<p>De qualquer forma, resolvi fazer um post rápido só pra dizer que essas novas opções como Crush e OpenCode já estão muito boas pra usar no dia a dia. Vale a pena testar no seu projeto.</p>
<h3>Segundo Teste<span class="hx:absolute hx:-mt-20" id="segundo-teste"></span>
    <a href="#segundo-teste" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como o Crush se deu bem com esse teste básico de web, resolvi pegar o desafio que fiz ano passado. Fiz um pequeno projeto de linha de comando que é um chat básico, feito do zero, usando direto a biblioteca llama.cpp, com CUDA, e em Zig - que é uma linguagem de baixo nível, ainda experimental e inacabada. Justamente o desafio é porque pouca gente usa, então tem pouca documentação e exemplos. A LLM vai ter que suar pra fazer funcionar.</p>
<p>Diferente de uma página Web com React e Tailwind - que tem milhares de posts em fóruns, tutoriais, blog posts e tudo mais, Zig não tem quase nada. O único app popular que eu conheço que usa Zig é o Ghostty.</p>
<p>Pra piorar, saiu versão nova recentemente, a 0.15, que muda bastante toda a API de IO (em preparação pra suportar melhor coisas como Async IO). Saiu versões novas de Llama, Cuda, etc. Então a idéia seria usar o Crush com Claude Opus pra ver se consegue refatorar, consertar bugs, atualizar as APIs e conseguir chegar até o ponto de compilar um binário que funciona.</p>
<p>Em resumo: <strong>conseguiu!</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109211613_screenshot-2026-01-09_21-15-57.png" alt="crush - qwen-cli-zig"  loading="lazy" />
Na primeira rodada de refatoramento, consumiu só USD 5.64 de crédito da minha conta na Anthropic. Conseguiu pegar o macarrão monolítico (que eu fiz de propósito como desafio) em arquivos menores como <code>chat.zig</code> e <code>llama.zig</code>.</p>
<p>Conseguiu mapear as funções em C do Llama como funções no Zig. Conseguiu descobrir que coisas como ArrayList mudaram no Zig novo. Conseguiu descobrir que todas as APIs de IO mudaram no 0.15. E conseguiu modificar os lugares certos.</p>
<p>Ele foi rodando <code>zig build</code>, checando os erros e fazendo correções que fazem sentido, até conseguir gerar o binário final.</p>
<p>Vocês podem checar o <a href="https://github.com/akitaonrails/qwen-cli-zig/pull/1/files"target="_blank" rel="noopener">Pull Request</a> com tudo que ele fez. Foi uma mudança bem razoável e não deixou o projeto quebrado.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109212115_screenshot-2026-01-09_21-21-03.png" alt="llama.cpp externs"  loading="lazy" />
O fato dele ter conseguido consultar a documentação do Zig 0.15, também inferir corretamente quais funções novas do Llama.cpp deveria fazer extern, foi bem impressionante.</p>
<p>De qualquer forma, na primeira rodada, ele conseguiu chegar até o ponto onde compila. Mas não significa que funciona. E de fato, quando tentei executar, terminou com um segmentation fault:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109213331_screenshot-2026-01-09_21-33-22.png" alt="qwen-cli-zig segmentation fault"  loading="lazy" /></p>
<p>Então pedi ao Crush pra executar e checar esse erro. Ele encontrou o bug e fez as modificações necessárias. Ele encontrou uma struct errada e ainda encontrou um problema de memory leak. Resolveu ambos os problemas e agora o programa roda como deveria:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109213702_screenshot-2026-01-09_21-36-23.png" alt="qwen-cli-zig"  loading="lazy" />
Como disse antes, é um programinha besta de chat, que usa Llama.cpp direto pra carregar o modelo Qwen3 e abrir um chat pra eu conversar. É só um exercício porque um chat assim já existe, basta usar o Ollama. Mas eu queria fazer um do zero, em baixo nível, como exercício pra LLMs. Até ano passado nenhuma LLM que eu testei conseguiu finalizar esse programa de forma adequada. Mas agora foi.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260109213930_screenshot-2026-01-09_21-39-22.png" alt="crush explanation of the crash"  loading="lazy" /></p>
<p>E como podem ver, no final gastei quase 8 dólares pra refatorar, consertar os bugs, e fazer esse programa funcionar corretamente. Não foi barato, mas pelo menos não foram créditos jogados fora, como acontecia 1 ano atrás. Não testei com LLMs locais ainda, pra ver se o Crush consegue chegar em resultados semelhantes.</p>
<p>Mas se ele consegue lidar com uma linguagem obscura como Zig me deixa bem animado pra brincar mais com isso. Finalmente as ferramentas e LLMs chegaram num ponto que realmente é prático de usar. Não estou dizendo que resolve tudo, mas comparado com 1 ano atrás, foi um salto significativo.</p>
<p>Recomendo muito testar Crush com outros modelos. Eu só brinquei um pouco com o Opus mas outros modelos podem dar resultados diferentes dependendo do problema que está tentando resolver.</p>
]]></content:encoded><category>omarchy</category><category>agentes-de-codigo</category><category>llms</category></item><item><title>Omarchy - Não entrar em Sleep enquanto Copia</title><link>https://akitaonrails.github.io/2025/11/20/omarchy-no-sleep-on-copy/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/11/20/omarchy-no-sleep-on-copy/</guid><pubDate>Thu, 20 Nov 2025 14:00:00 -0300</pubDate><description>&lt;p&gt;Esta dica não é específica de Omarchy mas de Linux em geral, mas coloquei na categoria de Omarchy só pra ficar consistente no meu blog.&lt;/p&gt;
&lt;h3&gt;Introdução&lt;span class="hx:absolute hx:-mt-20" id="introdução"&gt;&lt;/span&gt;
&lt;a href="#introdu%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Quando eu me afasto do meu PC, o Hyprland vai usar as configurações em &lt;code&gt;~/.config/hypr/hypridle.conf&lt;/code&gt; pra saber em que timeout desligar o monitor e depois, quando colocar meu PC pra dormir (sleep). Podemos configurar o tempo que quisermos lá, como 10 min pra apagar a tela, 20 min sem atividade pra dormir.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Esta dica não é específica de Omarchy mas de Linux em geral, mas coloquei na categoria de Omarchy só pra ficar consistente no meu blog.</p>
<h3>Introdução<span class="hx:absolute hx:-mt-20" id="introdução"></span>
    <a href="#introdu%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Quando eu me afasto do meu PC, o Hyprland vai usar as configurações em <code>~/.config/hypr/hypridle.conf</code> pra saber em que timeout desligar o monitor e depois, quando colocar meu PC pra dormir (sleep). Podemos configurar o tempo que quisermos lá, como 10 min pra apagar a tela, 20 min sem atividade pra dormir.</p>
<p>Se tiver algum app que queira fazer alguma manutenção em background que demore mais que isso pra terminar, ele pode sinalizar pro sistema não dormir. Dá pra ver quais apps fazem isso usando o comando <code>systemd-inhibit --list</code>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20251120140935_screenshot-2025-11-20_14-09-09.png" alt="inhibit list"  loading="lazy" /></p>
<h3>O Problema<span class="hx:absolute hx:-mt-20" id="o-problema"></span>
    <a href="#o-problema" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Vira e mexe eu deixo copiando grandes quantidades de arquivos, por exemplo, do meu NAS pra um micro SD Card. Pode levar mais de 1 hora fácil (minhas cópias de ROMs pra emuladores):</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20251120141114_screenshot-2025-11-20_13-50-46.png" alt="copiando usb"  loading="lazy" /></p>
<p>O problema é que antes disso o <code>hypridle</code> vai entrar em ação e colocar meu PC pra dormir, pausando essa cópia. E normalmente eu queria deixar copiando, ir dormir, e estar pronto quando acordar. Só que sempre esqueço disso e quando acordo ainda não terminou. Bem inconveniente. Não sei porque o Nautilus já não sinaliza pra inibir sleep quando tem atividades assim acontecendo.</p>
<p>Pode ser que tenha alguma configuração de <code>gsettings</code> que eu não saiba? (se tiver algo assim, não deixem de mandar nos comentários).</p>
<h3>A Solução<span class="hx:absolute hx:-mt-20" id="a-solução"></span>
    <a href="#a-solu%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Enquanto não descubro algo melhor, só tem uma solução: ficar fazendo polling de <code>iostat</code> pra manualmente inibir.</p>
<p>Pra começar precisamos instalar estes dois pacotes no Arch:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -S sysstat bc</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora, criar um script que cheque, vamos chamar de <code>~/.local/bin/io_inhibit.sh</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># --- Configuration ---</span>
</span></span><span class="line"><span class="cl"><span class="c1"># UTIL_THRESHOLD: Percentage of time the device is busy (%util) that must be exceeded to inhibit sleep.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 10.0% is a safe low threshold to catch any continuous I/O.</span>
</span></span><span class="line"><span class="cl"><span class="nv">UTIL_THRESHOLD</span><span class="o">=</span>10.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># CHECK_INTERVAL: How often (in seconds) to check I/O activity.</span>
</span></span><span class="line"><span class="cl"><span class="nv">CHECK_INTERVAL</span><span class="o">=</span><span class="m">5</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># File to track the PID of the systemd-inhibit process.</span>
</span></span><span class="line"><span class="cl"><span class="nv">PID_FILE</span><span class="o">=</span><span class="s2">&#34;/tmp/io_inhibit_pid&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># --- Functions ---</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Function to check if the inhibit process is currently running</span>
</span></span><span class="line"><span class="cl">is_inhibitor_running<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$PID_FILE</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">kill</span> -0 <span class="k">$(</span>cat <span class="s2">&#34;</span><span class="nv">$PID_FILE</span><span class="s2">&#34;</span><span class="k">)</span> 2&gt;/dev/null<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="m">0</span> <span class="c1"># True</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="m">1</span> <span class="c1"># False</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Function to get the maximum I/O utilization (%util) across all monitored devices</span>
</span></span><span class="line"><span class="cl">get_max_io_util<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># We use -x (extended stats) and monitor all devices.</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># The &#39;awk&#39; script finds the column index for &#39;%util&#39; dynamically.</span>
</span></span><span class="line"><span class="cl">    iostat -x <span class="m">1</span> <span class="m">2</span> <span class="p">|</span> awk <span class="s1">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">        BEGIN { max_util = 0.0; f = 0; util_col = 0; }
</span></span></span><span class="line"><span class="cl"><span class="s1">        
</span></span></span><span class="line"><span class="cl"><span class="s1">        # 1. Look for the header line (contains &#39;</span>r/s<span class="s1">&#39; and &#39;</span>util<span class="s1">&#39;). Set flag (f) to start processing.
</span></span></span><span class="line"><span class="cl"><span class="s1">        #    We only do this check in the second block.
</span></span></span><span class="line"><span class="cl"><span class="s1">        /avg-cpu:/ { if (f == 0) f = 1; else if (f == 1) f = 2; next }
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">        # 2. In the second block (f == 2), check for the header line to map columns
</span></span></span><span class="line"><span class="cl"><span class="s1">        (f == 2 &amp;&amp; $1 == &#34;Device&#34;) {
</span></span></span><span class="line"><span class="cl"><span class="s1">            # Find the column index for the &#34;%util&#34; header
</span></span></span><span class="line"><span class="cl"><span class="s1">            for (i=1; i&lt;=NF; i++) {
</span></span></span><span class="line"><span class="cl"><span class="s1">                if ($i == &#34;%util&#34;) {
</span></span></span><span class="line"><span class="cl"><span class="s1">                    util_col = i;
</span></span></span><span class="line"><span class="cl"><span class="s1">                    break;
</span></span></span><span class="line"><span class="cl"><span class="s1">                }
</span></span></span><span class="line"><span class="cl"><span class="s1">            }
</span></span></span><span class="line"><span class="cl"><span class="s1">            # Skip the header line after mapping
</span></span></span><span class="line"><span class="cl"><span class="s1">            next
</span></span></span><span class="line"><span class="cl"><span class="s1">        }
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">        # 3. Process data lines only after the column has been mapped
</span></span></span><span class="line"><span class="cl"><span class="s1">        (f == 2 &amp;&amp; util_col &gt; 0) { 
</span></span></span><span class="line"><span class="cl"><span class="s1">            # Match lines starting with a common device prefix
</span></span></span><span class="line"><span class="cl"><span class="s1">            if ($1 ~ /^(sd|nvme|loop|hd|dm|zram|mmc)/) {
</span></span></span><span class="line"><span class="cl"><span class="s1">                # Use the dynamically found column index
</span></span></span><span class="line"><span class="cl"><span class="s1">                util = $(util_col);
</span></span></span><span class="line"><span class="cl"><span class="s1">                if (util &gt; max_util) {
</span></span></span><span class="line"><span class="cl"><span class="s1">                    max_util = util;
</span></span></span><span class="line"><span class="cl"><span class="s1">                }
</span></span></span><span class="line"><span class="cl"><span class="s1">            }
</span></span></span><span class="line"><span class="cl"><span class="s1">        }
</span></span></span><span class="line"><span class="cl"><span class="s1">        END { print max_util; }
</span></span></span><span class="line"><span class="cl"><span class="s1">    &#39;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># --- Main Loop ---</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> true<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 1. Get current I/O activity</span>
</span></span><span class="line"><span class="cl">    <span class="nv">MAX_UTIL</span><span class="o">=</span><span class="k">$(</span>get_max_io_util<span class="k">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Use &#39;bc&#39; for floating-point comparison</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">((</span> <span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$MAX_UTIL</span><span class="s2"> &gt; </span><span class="nv">$UTIL_THRESHOLD</span><span class="s2">&#34;</span> <span class="p">|</span> bc -l<span class="k">)</span> <span class="o">))</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># I/O is active and exceeds the %util threshold</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> ! is_inhibitor_running<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">            setsid systemd-inhibit --what<span class="o">=</span>idle:sleep --why<span class="o">=</span><span class="s1">&#39;Active I/O Detected (%util)&#39;</span> --mode<span class="o">=</span>block sleep infinity <span class="p">&amp;</span>
</span></span><span class="line"><span class="cl">            <span class="nb">echo</span> <span class="nv">$!</span> &gt; <span class="s2">&#34;</span><span class="nv">$PID_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">fi</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># I/O is idle or below threshold</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> is_inhibitor_running<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">            <span class="nb">kill</span> <span class="k">$(</span>cat <span class="s2">&#34;</span><span class="nv">$PID_FILE</span><span class="s2">&#34;</span><span class="k">)</span> 2&gt;/dev/null
</span></span><span class="line"><span class="cl">            rm <span class="s2">&#34;</span><span class="nv">$PID_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">fi</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Wait before checking again</span>
</span></span><span class="line"><span class="cl">    sleep <span class="nv">$CHECK_INTERVAL</span> 
</span></span><span class="line"><span class="cl"><span class="k">done</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>(sim, este script foi vibe coded e precisei ajustar algumas vezes até funcionar, as versões que o Gemini me dava não funcionavam kkkk).</p>
<p>O principal é o <code>awk</code> processando a saída do comando <code>iostat -x 1 2</code>. Meu micro SD card aparece como <code>/dev/sda</code>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20251120141644_screenshot-2025-11-20_14-16-36.png" alt="iostat"  loading="lazy" /></p>
<p>Note que no segundo bloco, quando estou copiando vários arquivos, ele mostra 99.61 e fica variando entre 90 a 100% de uso, que é o desejável: significa que está usando toda a banda disponível de IO pra ele.</p>
<p>Então, queremos que, enquanto estiver numa taxa acima de zero, tipo, maior que 10% de atividade, o HyprIdle não ative o sleep no timeout normal.</p>
<p>Com esse script, agora temos o seguinte quando listamos <code>systemd-inhibit --list</code>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20251120141859_screenshot-2025-11-20_14-18-48.png" alt="sleep infinity"  loading="lazy" /></p>
<p>Agora apareceu uma nova linha dizendo:</p>
<ul>
<li>
<p><code>sleep infinity</code>: Este é o nome do processo que iniciou meu script e segura o lock.</p>
</li>
<li>
<p><code>sleep:idle</code>: Esta é a parte crucial. Diz ao systemd e logind pra bloquear tanto sleep (system suspend) quanto idle (prevenindo timers de idle como do hypridle).</p>
</li>
<li>
<p><code>Active I/O Detected (%util)</code>: Esta é a razão especificada no script.</p>
</li>
</ul>
<p>E pronto, pra garantir que temos este script sempre rodando, basta alterar o <code>~/.config/hypr/autostart.conf</code> pra ter esta linha:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>exec-once = /home/akitaonrails/.local/bin/io_inhibit.sh &amp;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Em teoria, agora posso deixar essas atividades longas de IO rodando e não me preocupar do meu Arch suspender e dormir.</p>
<p>Alguém conhece alguma solução mais simples do que essa? Se tiver idéias, mandem nos comentários.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>automacao</category></item><item><title>Omarchy 2.0 - Básico de LazyVim</title><link>https://akitaonrails.github.io/2025/09/12/omarchy-2-0-basico-de-lazyvim/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/12/omarchy-2-0-basico-de-lazyvim/</guid><pubDate>Fri, 12 Sep 2025 15:00:00 -0300</pubDate><description>&lt;p&gt;Droga, eu falei que o post anterior seria o último da série de &lt;a href="https://akitaonrails.github.io/tags/omarchy/"&gt;Omarchy&lt;/a&gt;, mas achei que a oportunidade é boa pra evangelizar um pouco de Vim também. Já deixei a recomendação pra seguir o canal do &lt;a href="https://www.youtube.com/@EustaquioRangel"target="_blank" rel="noopener"&gt;@Taq&lt;/a&gt;, onde ele explica muito mais a fundo como o NeoVim funciona. Também existe o &lt;a href="https://github.com/ThePrimeagen/vim-be-good"target="_blank" rel="noopener"&gt;tutorial &amp;ldquo;vim-be-good&amp;rdquo; do Primeagen&lt;/a&gt;. Esse segundo, em particular, é um tutorial interativo dentro do próprio NeoVim, pra praticar a navegação - que muitos podem achar difícil no começo.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Droga, eu falei que o post anterior seria o último da série de <a href="/tags/omarchy/">Omarchy</a>, mas achei que a oportunidade é boa pra evangelizar um pouco de Vim também. Já deixei a recomendação pra seguir o canal do <a href="https://www.youtube.com/@EustaquioRangel"target="_blank" rel="noopener">@Taq</a>, onde ele explica muito mais a fundo como o NeoVim funciona. Também existe o <a href="https://github.com/ThePrimeagen/vim-be-good"target="_blank" rel="noopener">tutorial &ldquo;vim-be-good&rdquo; do Primeagen</a>. Esse segundo, em particular, é um tutorial interativo dentro do próprio NeoVim, pra praticar a navegação - que muitos podem achar difícil no começo.</p>
<p>Vou fazer somente este um artigo sobre isso e não pretendo cobrir mais do que a ponta do Iceberg. A idéia é servir pra quem está vindo de outros editores como Sublime Text ou VS Code e não consegue começar a navegar ou até mesmo quitar do Vim kkk 🤣.</p>
<h3>Comandos Iniciais<span class="hx:absolute hx:-mt-20" id="comandos-iniciais"></span>
    <a href="#comandos-iniciais" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como falei no <a href="https://akitaonrails.com/2025/09/07/omarchy-2-0-lazyvim-lazyextras/"target="_blank" rel="noopener">post anterior sobre LazyVim</a>, vou assumir que já entendeu pelo menos como instalar suporte à sua linguagem com <strong>LazyExtras</strong> e já aprendeu a versionar usando <a href="https://akitaonrails.com/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/"target="_blank" rel="noopener"><strong>Mise</strong></a>.</p>
<p>Sem nem entrar no LazyVim, a primeira coisa a saber é que ele instala todas as configurações relevantes no diretório <code>~/.config/nvim</code>. Normalmente não precisa mexer nada lá. Deixa arquivos como <code>lazyvim.json</code> sem mexer. Notem que ele faz a mesma coisa quem um NPM da vida: tem um arquivo <code>lazy-lock.json</code> que declara a versão/commit de cada plugin instalado. O Lazyvim faz algo parecido com um <code>npm install</code> da vida. Só curiosidade pra você saber como ele se organiza.</p>
<p>Se precisar customizar algo, normalmente vai ser no diretório <code>~/.config/nvim/lua/config</code>. Foi lá onde eu adicionei suporte a Mise, por exemplo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">~/.config/nvim
</span></span><span class="line"><span class="cl">❯ cat lua/config/mise.lua
</span></span><span class="line"><span class="cl">-- Prepend mise shims to PATH
</span></span><span class="line"><span class="cl">vim.env.PATH <span class="o">=</span> vim.env.HOME .. <span class="s2">&#34;/.local/share/mise/shims:&#34;</span> .. vim.env.PATH</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Vão ser sempre scripts escritos em Lua. E nem precisa saber Lua a fundo. De bater o olho é uma linguagem muito simples, não muito diferente de um Python ou Javascript e qualquer programador deve ser capaz de ler qualquer trecho sem nenhum problema. Além disso, na maioria dos casos você vai copiar configurações que tirou da documentação, wiki ou chatgpt mesmo, então é só saber que as coisas vão nesse local.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912110425_screenshot-2025-09-12_11-04-07.png" alt="primeiros passos"  loading="lazy" /></p>
<p>Entenda que NeoVim tem o conceito de tecla &ldquo;<strong>Leader</strong>&rdquo;, é uma tecla que precede hotkeys pra outros comandos (também tem <strong>localleader</strong> que é barra invertida <strong>\</strong>). Isso é configurável mas no LazyVim o Leader é a tecla <strong>&ldquo;Espaço/Space&rdquo;</strong>. Em muita documentação vamos ver falando <em>&ldquo;apertem Leader-w&rdquo;</em>, que significa <strong>Espaço+w</strong> e agora você sabe o que isso significa.</p>
<p>Pra abrir um arquivo tem pelo menos 3 formas diferentes, 2 delas mostradas na foto acima:</p>
<blockquote>
  <p><strong>Space+E</strong> abre o <strong>NeoTree</strong> que é esse sidebar na esquerda que se parece com o Windows Explorer. Dá pra navegar com teclado ou com mouse mesmo. Ache seu arquivo e pressione &ldquo;Enter&rdquo; pra abrir, daí &ldquo;Space+E&rdquo; de novo pra esconder o sidebar. Se quiser saber como criar um novo arquivo, um novo sub-diretório, renomear e tals, digite <strong>?</strong> (tecla de interrogação) pra ver esta ajuda:</p>

</blockquote>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912142438_neotree.gif" alt="NeoTree"  loading="lazy" /></p>
<p>A terceira forma é manualmente com o comando <strong>:e</strong> seguida do nome do arquivo no diretório local. Tem auto-complete também, esse é o jeito mais rápido, se souber o que está procurando.</p>
<p>Sempre que quiser cancelar qualquer coisa ou fechar &ldquo;floating windows&rdquo; (pop-ups, dialog boxes). Só apertar &ldquo;Esc&rdquo;. Esc é fundamental no NeoVim.</p>
<p>Aberto um arquivo, ele fica no <strong>Buffer</strong>. Pense em Buffer como &ldquo;Abas Abertas&rdquo; no seu VS Code. Pra navegar por Buffer (tipo alt+tab entre seus arquivos já abertos) é simples:</p>
<ul>
<li><strong>]+b</strong> pra próxima &ldquo;aba&rdquo; (próximo Buffer)</li>
<li><strong>[+b</strong> Buffer anterior</li>
<li><strong>Space+bd</strong> pra &ldquo;fechar a aba&rdquo; (fechar o Buffer)</li>
<li><strong>Space+bo</strong> pra ficar onde está e fechar os outros buffers</li>
</ul>
<p>Abra quantos arquivos quiser. Se um deles for um daqueles logs enormes que abriu por acidente, <code>Space+bd</code> pra fechar e pronto.</p>
<p>Falando em fechar, <strong>como que sai do NeoVim?</strong> Tem vários jeitos:</p>
<ul>
<li><strong>Space+q</strong></li>
<li><strong>:q</strong></li>
<li><strong>:q!</strong></li>
</ul>
<p>A diferença: o primeiro é o jeito customizado no LazyVim. O Segundo é o jeito padrão usando o recurso de &ldquo;comandos&rdquo; que começa sempre com &ldquo;dois pontos&rdquo;. E o terceiro é se você modificou algo no arquivo mas cancelar, sair sem salvar nada, por isso a exclamação.</p>
<p>Normalmente eu uso <strong>:wq</strong> que significa &ldquo;write&rdquo; e &ldquo;quit&rdquo;. Então ele primeiro salva as mudanças no arquivo e depois já quita do programa. É útil quando estou só editando um arquivo de configuração rápido.</p>
<h3>Navegação Básica<span class="hx:absolute hx:-mt-20" id="navegação-básica"></span>
    <a href="#navega%c3%a7%c3%a3o-b%c3%a1sica" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora tenho um arquivo aberto. Como navegar por ele? Primeiro, como ir até o fim do arquivo e depois voltar pro começo do arquivo? É uma coisa que uso bastante, só digitar <strong>Shift+g</strong> pra ir pro fim do arquivo e depois <strong>gg</strong> pra voltar pro começo. Simples assim.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912143147_home-end.gif" alt="home-end"  loading="lazy" /></p>
<p>Agora vamos aprender vários comandos de uma só vez:</p>
<ul>
<li>Digite <strong>v</strong>. Isso inicia o <strong>&ldquo;modo de visualização&rdquo;</strong> que, na prática, significa começar a selecionar a partir de onde se encontra seu cursor.</li>
<li>Digite <strong>j</strong>. Que é o equivalente à &ldquo;seta pra baixo&rdquo; pra ir pra linha de baixo. Já deve ter ouvido falar que em Vim se navega com &ldquo;hjkl&rdquo; que são, respectivamente, pra esquerda, pra baixo, pra cima, pra direita.</li>
<li>Digite <strong>x</strong>. Que é o equivalente a &ldquo;cortar&rdquo; e colocar o conteúdo no clipboard. Feito isso, digitando <strong>p</strong> você dá &ldquo;paste&rdquo;, que é colar.</li>
<li>Digite <strong>u</strong>. Que é o comando que mais se usa: o de <strong>Undo</strong> ou desfazer a última modificação.</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912143741_marcar-apagar.gif" alt="marcar-apagar"  loading="lazy" /></p>
<p>Isso tudo funciona no chamado <strong>&ldquo;modo de comando&rdquo;</strong>, que é o modo padrão que o Vim abre todo arquivo. Nesse modo não dá pra digitar nenhum texto. Como podem ver, cada letra sozinha é um comando, como &ldquo;x&rdquo; pra cut ou &ldquo;p&rdquo; pra paste.</p>
<p>Pra digitar, primeiro precisa digitar <strong>i</strong> (só a letra &ldquo;i&rdquo; em minúsculo), que daí muda do modo de comando pro <strong>&ldquo;modo de edição&rdquo;</strong>. Agora é só digitar seu texto normalmente, como em qualquer editor. Quando quiser algum comando, basta digitar <strong>ESC</strong> pra voltar pro modo de comando. Vamos fazer isso o tempo todo, por isso muita gente re-mapeia a tecla &ldquo;caps lock&rdquo; do teclado pra ser a ESC e ficar fácil só tocar com o mindinho esquerdo.</p>
<h3>Combinando Comandos<span class="hx:absolute hx:-mt-20" id="combinando-comandos"></span>
    <a href="#combinando-comandos" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><blockquote>
  <p>Ainda no modo de comando, como navegamos pelo arquivo mais fácil?</p>

</blockquote>
<p>Além das teclas &ldquo;hjkl&rdquo;, podemos navegar mais fácil usando <strong>b</strong> pra &ldquo;palavra anterior&rdquo; ou <strong>w</strong> pra palavra (<em>word</em>) posterior:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912144226_words.gif" alt="words"  loading="lazy" /></p>
<p>O modo de comando permite combinar comandos, portanto podemos fazer:</p>
<ul>
<li><strong>dw</strong> pra apagar a próxima palavra</li>
<li><strong>db</strong> pra apagar a palavra anterior</li>
<li><strong>d4w</strong> pra apagar (delete) as 4 palavras (words) seguintes</li>
<li><strong>d4j</strong> pra apagar as 4 linhas pra baixo</li>
</ul>
<p>O <a href="https://github.com/ThePrimeagen/vim-be-good"target="_blank" rel="noopener">tutorial do Primeagen</a> tem vários exercícios pra esse tipo de navegação, recomendo se exercitar. Num VS Code todo mundo está acostumado a primeiro pegar o mouse, marcar o bloco que quer apagar visualmente, depois apertar delete ou backspace. No Vim, olhamos onde está o cursor, apertamos ESC pra estar no modo de comando, e digitamos a operação e a localização. Teste todas as combinações que conseguir imaginar.</p>
<p>Esta é a <strong>mudança de paradigma</strong> que incomoda os preguiçosos. Mas uma vez aprendido isso, você vai achar incômodo um editor que te obrigado a usar mouse pra coisas básicas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912144801_change.gif" alt="change in place"  loading="lazy" /></p>
<p>Agora fica mais interessante: <em>e se em vez de apagar uma palavra, eu queira substituir a palavra onde meu cursor está pra outra palavra?</em></p>
<p>Num editor normal, você marcaria com o mouse (ou usando alguma combinação como &ldquo;ctrl+shift+seta&rdquo;), e digitaria por cima ou apagaria a palavra.</p>
<p>No LazyVim tem plugins configurados pra coisas mais interessantes. No video acima veja como estou substituindo palavras <em>&ldquo;in-place&rdquo;</em>. Isso se faz com o comando <strong>ciw</strong>.</p>
<ul>
<li><strong>ciw</strong> apaga a palavra inteira embaixo do cursor e abre o modo de edição pra você digitar a substituição</li>
<li><strong>ce</strong> apaga a partir do cursor até o fim da palavra (preserva o começo da palavra) e também abre pra você digitar no lugar</li>
<li><strong>Shift-c</strong> (C maiúsculo) apaga tudo a partir do seu cursor até o fim da linha inteira e abre pra você digitar.</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912145439_bloco.gif" alt="Mudar Bloco Vertical"  loading="lazy" /></p>
<p>Mas isso ainda não parece tãaaaao legal. E se quiser mudar só a primeira letra de várias linhas ao mesmo tempo, por exemplo, no texto do video acima, quero mudar só o hífen (&quot;-&quot;) de cada linha de tags?</p>
<p>Falei antes que apertando <strong>v</strong> no modo de comando ele começa o modo de visualização e dá pra selecionar a partir dali. Mas existe <strong>Ctrl+v</strong> que abre o modo de marcação de blocos verticais.</p>
<p>Nesse modo usamos as teclas &ldquo;hjkl&rdquo; normalmente, como <strong>j</strong> pra ir pra baixo, mas em vez de marcar a próxima linha inteira, ele marca só o caracter logo abaixo do seu cursor. Agora posso apagar com <strong>d</strong> e digitar <strong>Shift-i</strong> (&ldquo;I&rdquo; maiúsculo) pra entrar em modo de edição no começo do bloco e substituir pelo que quiser.</p>
<p>LazyVim tem plugins pra comentários, mas essa é outra alternativa se quiser adicionar &ldquo;//&rdquo; ou &ldquo;#&rdquo; no começo de várias linhas pra comentar, por exemplo. No caso, leia sobre o plugin <a href="https://github.com/folke/ts-comments.nvim"target="_blank" rel="noopener"><strong>ts-comments</strong></a> pra opções melhores pra comentário. Pra iniciar um novo bloco de comentário, digite <strong>gco</strong> pra adicionar um comentário abaixo.</p>
<p><em>&ldquo;Modo de bloco&rdquo;</em> como mostrei acima, é uma das coisas que eu mais uso em código.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912150112_search-replace.gif" alt="Search and Replace"  loading="lazy" /></p>
<p>Mas só isso é muito pouco. E se quiser substituir <strong>TODAS AS PALAVRAS</strong> iguais do texto de uma só vez. No video de exemplo acima, quero substituir &ldquo;domínio&rdquo; por &ldquo;DOMAIN&rdquo; e &ldquo;Cloudflare&rdquo; por &ldquo;AWS Amazon&rdquo;, como faço? Isso é &ldquo;Search and Replace&rdquo; que tem em todo editor e em Vim é muito fácil:</p>
<p>Digitamos <strong>:%s/domínio/DOMAIN/</strong>.</p>
<p>Se você é programador já deve ter visto essa sintaxe antes. É a sintaxe de <strong>REGEX MATCH</strong>. Sim, tem que saber Regex (e não, não é nem PCRE e nem Unicode, é um dialeto de Regex do próprio NeoVim, mas é parecido).</p>
<p>Como falei antes, &ldquo;dois pontos&rdquo; abre o box de digitar comandos, <strong>&quot;%s&quot;</strong> inicia &ldquo;search com regex&rdquo; e entre as barras &ldquo;//&rdquo; primeiro vai o que procura e depois com o que quer substituir.</p>
<p>Mas esse é o jeito no NeoVim puro, no LazyVim, tem o plugin <a href=""><strong>grug-far</strong></a> e se ativa com o comando <strong>SPACE+sr</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912150648_screenshot-2025-09-12_15-06-32.png" alt="grug-far"  loading="lazy" /></p>
<p>Agora sim, mais parecido com do VS Code, né? Use o que achar mais fácil.</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como falei, isto é somente a ponta da ponta do iceberg, o mínimo do mínimo suficiente pra pelo menos começar editando arquivos simples de configuração sem abrir Nano ou VS Code só pra isso.</p>
<p>Leia a documentação do LazyVim. Veja os <a href="https://www.lazyvim.org/keymaps"target="_blank" rel="noopener">keymaps</a> pra descobrir outros comandos. Preste atenção em cada letra que aperta no modo de comando, o LazyVim mostra as opções disponíveis. Por exemplo, digamos que eu apertei <strong>g</strong> (goto), ele vai mostrar uma ajuda no canto inferior direito:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912151849_screenshot-2025-09-12_15-18-38.png" alt="ajuda"  loading="lazy" /></p>
<p>Assim você sempre pode descobrir novos comandos ou relembrar comandos que usa pouco. Por isso recomendo o LazyVim, que já vem bem configurado pra te ajudar. Quem faz essa funcionalidade é o plugin <a href="https://github.com/folke/which-key.nvim"target="_blank" rel="noopener"><strong>which-key</strong></a>, caso queira a mesma coisa num NeoVim que você configurou do zero.</p>
<p>Existem diversos <a href="https://vim.rtorr.com/"target="_blank" rel="noopener"><strong>Cheatsheets</strong></a> por aí com tabelas de combinações de comandos importantes. Vale explorar.</p>
<p>Mas não é só isso, LazyVim vem com dezenas de <a href="https://www.lazyvim.org/plugins"target="_blank" rel="noopener">plugins</a> pra formatação, linting, LSP integrado, GIT integrado, e muito mais. Não tem como eu documentar um a um aqui. Cada um deles tem sua própria documentação na página de plugins do LazyVim.org.</p>
<p>Novamente, não esqueça de chamar o <strong>:LazyExtras</strong> e instalar os plugins opcionais das suas linguagens.</p>
]]></content:encoded><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>tutoriais</category></item><item><title>Omarchy 2.0 - Indicado pra Iniciantes?</title><link>https://akitaonrails.github.io/2025/09/12/omarchy-2-0-indicado-pra-iniciantes/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/12/omarchy-2-0-indicado-pra-iniciantes/</guid><pubDate>Fri, 12 Sep 2025 12:00:00 -0300</pubDate><description>&lt;p&gt;O video mais importante do meu &lt;a href="https://www.youtube.com/@Akitando"target="_blank" rel="noopener"&gt;canal de YouTube&lt;/a&gt; é o &amp;ldquo;Não Terceirize suas Decisões&amp;rdquo;:&lt;/p&gt;
&lt;div class="embed-container"&gt;
&lt;iframe
src="https://www.youtube.com/embed/D3L8IOncLkg"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;As perguntas que eu mais recebo, literalmente todos os dias, são no formato: &lt;em&gt;&amp;ldquo;Akita, devo fazer faculdade?&lt;/em&gt;, &lt;em&gt;&amp;ldquo;Akita, o que você acha que eu devo estudar?&amp;rdquo;&lt;/em&gt; e variações dessas.&lt;/p&gt;
&lt;p&gt;Velho, eu não te conheço, nunca vou saber nem me interessar em saber quem você é, o que almeja, quais suas aspirações, ambições, gostos, preferência. Nada. Nem eu, nem &lt;strong&gt;NINGUÉM&lt;/strong&gt;. Só você sabe o que é melhor pra você. Se não sabe, trate de procurar saber. É isso que &lt;strong&gt;VIVER&lt;/strong&gt; significa.&lt;/p&gt;</description><content:encoded><![CDATA[<p>O video mais importante do meu <a href="https://www.youtube.com/@Akitando"target="_blank" rel="noopener">canal de YouTube</a> é o &ldquo;Não Terceirize suas Decisões&rdquo;:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/D3L8IOncLkg"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>As perguntas que eu mais recebo, literalmente todos os dias, são no formato: <em>&ldquo;Akita, devo fazer faculdade?</em>, <em>&ldquo;Akita, o que você acha que eu devo estudar?&rdquo;</em> e variações dessas.</p>
<p>Velho, eu não te conheço, nunca vou saber nem me interessar em saber quem você é, o que almeja, quais suas aspirações, ambições, gostos, preferência. Nada. Nem eu, nem <strong>NINGUÉM</strong>. Só você sabe o que é melhor pra você. Se não sabe, trate de procurar saber. É isso que <strong>VIVER</strong> significa.</p>
<p>O que você não admite é que quer que alguém que considera mais importante ou relevante aprovando sua escolha e dizendo que está certo.</p>
<p>Nunca espere isso de mim, eu nunca vou te validar.</p>
<p>Sempre vou dizer: <strong>SE VIRA</strong>. Foi assim que eu me tornei quem eu sou. Eu nunca segui ninguém, nunca perguntei pra ninguém o que deveria fazer. Simplesmente ia lá e fazia. Quebrava a cara, caía, levantava, e tentava de novo. É a vida.</p>
<p>Deixa eu mostrar o que me <strong>INCOMODA</strong> mesmo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912124608_screenshot-2025-09-12_12-45-47.png" alt="pergunta idiota"  loading="lazy" /></p>
<p>Vamos ver no <a href="https://learn.omacom.io/2/the-omarchy-manual/93/security"target="_blank" rel="noopener">manual</a>?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912124657_screenshot-2025-09-12_12-46-45.png" alt="Manual"  loading="lazy" /></p>
<p>O DHH se deu ao trabalho de escrever um manual. Tem uma seção chamada &ldquo;Security&rdquo;. Se tivesse ido no Google, teria achado. Ou esta outra pérola:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912124836_screenshot-2025-09-12_12-48-24.png" alt="devops"  loading="lazy" /></p>
<p>Como quer ser &ldquo;DEVOPS&rdquo; (que tem que saber TUDO de Linux) começando assim. Já começou errado. Senta a bunda na cadeira, arregaça as mangas, e testa um por um, e aprende.</p>
<h3>Linux pra Iniciante?<span class="hx:absolute hx:-mt-20" id="linux-pra-iniciante"></span>
    <a href="#linux-pra-iniciante" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Isso dito, assista meu video. Mas como tenho falado bastante de <a href="/tags/omarchy/">Omarchy</a> já digo que sim, este é o que eu uso no meu dia a dia e é único que vou recomendar no futuro próximo (depois posso mudar de idéia). Tendo usado distros desde que Linux foi inventado no começo dos anos 90, eu sei que existem dezenas de distros e nem eu tenho paciência pra experimentar todos.</p>
<p><em>Por que Omarchy?</em></p>
<p>Primeiro porque ele fez a escolha certa da distro base: <strong>Arch Linux</strong>. Considero que é a melhor distro que existe hoje por dois fatores: ele tem pouco &ldquo;bloat&rdquo; (não instala um monte de coisas que você nunca vai usar, como um Ubuntu, Fedora, Mint, Deepin ou qualquer outros desses &ldquo;pra iniciantes&rdquo;).</p>
<p>Segundo, Arch Linux tem o AUR, que é um repositório de pacotes feitos pro usuários que tem basicamente tudo. Não precisa ficar caçando repositórios de terceiros ou ter que instalar manualmente. Com um único comando, o <code>yay</code>, instala-se tudo. Não existe isso de <code>apt-repository add</code> ou ter que fazer <code>make install</code> nem nada disso. O AUR gerencia tudo pra você.</p>
<p>Terceiro, ele instala Hyprland (que eu já usava e gostava), com configurações muito boas, escolha de pacotes muito bons. Tudo que eu mesmo instalaria manualmente. Então é uma opção mil vezes mais fácil pra ter o que eu teria muito mais trabalho pra fazer sozinho. Veja minha <a href="/tags/omarchy/">série de posts sobre Omarchy</a> pra ver essas opções.</p>
<h3>Linux pra Iniciantes?<span class="hx:absolute hx:-mt-20" id="linux-pra-iniciantes"></span>
    <a href="#linux-pra-iniciantes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><em>Iniciante em que?</em></p>
<p>Eu odeio essa pergunta. Se você é um usuário amador mesmo, não programador, talvez seja um contador, talvez seja só um adolescente gamer. A primeira pergunta que faço é: <em>pra que você quer usar Linux??</em></p>
<p>Digamos que seja porque ouviu falar que é mais seguro (de fato é). Então tanto faz, qualquer distro serve. Instale Ubuntu, instale Manjaro, instale Garuda. Não faz diferença, porque você nunca vai lidar com nada por baixo dos panos. Vai abrir o Chrome, vai abrir o Steam, e é só isso. O resto vai ser web-apps.</p>
<p>Digamos que é só pra jogar, então instale <a href="https://bazzite.gg/"target="_blank" rel="noopener">Bazzite</a> no seu mini-PC ou handheld. Ou só instale seus jogos num Windows separado só pra jogos como eu fiz. Tanto faz.</p>
<p>Ou fique no Windows ou MacOS mesmo. Se for totalmente amador, provavelmente vai usar a mesma senha fraca pra tudo, vai sair clicando em links do Whatsapp sem ver de quem é. Literalmente tanto faz qual OS vai usar. Nenhuma segurança de nenhum OS vai proteger seus maus hábitos e ignorância.</p>
<p>Se for iniciante em programação ou tecnologia, aí eu não tenho dó: aprenda Linux direito. Você quer ser um profissional, seja um profissional, aprenda do jeito certo: aprenda a ter 100% de controle sob sua própria máquina. Não tem passo a passo nem tutorial pra isso. É algo que você vai fazer continuamente pro resto da vida. Eu tenho mais de 30 anos na área e continuo aprendendo coisas novas todos os dias.</p>
<h3>Hardware<span class="hx:absolute hx:-mt-20" id="hardware"></span>
    <a href="#hardware" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O <strong>MAIOR</strong> problema que qualquer pessoa vai ter, com QUALQUER distro vai ser suporte a hardware. E eis porque você não deve só seguir o que alguém te recomenda:</p>
<p><strong>Ninguém tem o mesmo PC que você.</strong></p>
<p>Qual é seu notebook? Um Lenovo? Um Dell? Um Positivo? De que ano? Qual modelo?</p>
<p>Tudo vai variar: qual é o dispositivo de Wi-fi e bluetooth? qual é a placa gráfica? Qual firmware está rodando? Com que suportes de perfis de energia? Tem necessidade de dispositivos FIDO2 pra coisas como leitor de impressão digital? Hardware keys? Tem TPU na sua máquina? Vai precisar de Secure Boot?</p>
<p>Não sei. Você que tem que saber.</p>
<p>Um exemplo prático, eu tenho um notebook <strong>Asus Zephyrus G14</strong> que uso com Windows porque serve só na minha oficina pra rodar Bambu Studio pra controlar minha Impressora 3D X1C. Ainda não parei pra instalar Omarchy nele, mas digamos que eu queira. Vai funcionar?</p>
<p>Felizmente existe <a href="https://wiki.archlinux.org/title/ASUS_ROG_Zephyrus_G16_%282023%29_GU603"target="_blank" rel="noopener">uma página no ArchWiki</a> dedicada a este modelo. Ao que parece, funciona tudo &ldquo;out-of-the-box&rdquo;. Mas se fosse a <a href="https://wiki.archlinux.org/title/ASUS_ROG_Zephyrus_G14_%282022%29_GA402"target="_blank" rel="noopener">versão do ano anterior</a> já teria que checar mais ítens extras. Tem problemas no Wi-fi, por exemplo.</p>
<p>Cada máquina diferente vai ter problemas diferentes.</p>
<h3>Live Env e Ventoy<span class="hx:absolute hx:-mt-20" id="live-env-e-ventoy"></span>
    <a href="#live-env-e-ventoy" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><em>&ldquo;O que eu faço então, me ph0di?</em></p>
<p>É por isso que praticamente toda boa distro oferece a ISO de instalação que vem com um ambiente vivo (Live Environment). Já vi que tem muita gente no Windows que tem dificuldade do que fazer com uma ISO. É muito simples.</p>
<p><img src="https://etcher.balena.io/images/Etcher_steps.gif" alt="Balena Etcher"  loading="lazy" /></p>
<p>O programa mais fácil de usar é o <a href="https://etcher.balena.io/"target="_blank" rel="noopener">Balena Etcher</a> Você baixa o arquivo com extensão <code>.iso</code>, seja do Ubuntu, Mint, Elementary, etc (SEMPRE DO SITE OFICIAL!!!!). Abre o Balena e só tem 2 passos: selecione a imagem (o arquivo ISO), selecione o drive (seu pen drive, cuidado pra não escolher seu HD!), e pronto.</p>
<p>Agora é só bootar seu PC e entrar na BIOS pra selecionar o pen drive pra bootar ou usar uma tecla como F12 (varia de BIOS pra BIOS) pro UEFI selecionar seu pen drive.</p>
<p>Isso vai bootar o Live Environment direto do pen drive.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912120806_try-ubuntu-install-ubuntu-800x530.jpeg" alt="Try Ubuntu"  loading="lazy" /></p>
<p>A maioria das distros começa abrindo uma tela de &ldquo;Bem Vindo&rdquo; parecida com a de cima. Esse aplicativo de instalação se chama <a href="https://calamares.io/"target="_blank" rel="noopener"><strong>Calamares</strong></a> e todo mundo com instalação gráfica usa ele. Por isso é parecido em todos. É o mesmo passo a passo. Se instalou uma distro já instalou todas.</p>
<p>Só que você não precisa seguir o Calamares. Pode fechar ele. E agora está já no ambiente gráfico da distro que escolheu pra instalar. <strong>USE ELE.</strong> Tente configurar seu Wi-fi, tente parear seu fone ou mouse Bluetooth, tente ligar a WebCam, coloque um micro-SD card e veja se ele aparece. Tente navegar na web e sinta a performance.</p>
<p>Se nesse ponto conseguir fazer todas as coisas básicas, significa que as chances de tudo funcionar é grande. Se já neste ponto começar a ter problemas, como não conseguir conectar no seu Wi-fi, possivelmente essa distro vai te dar dor de cabeça. Comece indo no Google e veja se alguém já solucionou o problema pro seu modelo de notebook ou PC, <strong>antes</strong> de continuar com o Calamares.</p>
<p>Digamos que você decidiu tirar o dia pra testar várias distros pra ver qual roda melhor na sua máquina. Ótima decisão, mas já deve ter entendido que vai ser um enorme saco ter vários pen drives, um pra cada distro. Ou toda hora ter que voltar pro Windows e usar o Balena pra sobrescrever uma nova distro no seu único pendrive.</p>
<p>Não precisa fazer isso.</p>
<p>Basta baixar e instalar primeiro o <a href="https://www.ventoy.net/en/index.html"target="_blank" rel="noopener"><strong>Ventoy</strong></a> no seu pendrive. Veja a <a href="https://www.ventoy.net/en/doc_start.html"target="_blank" rel="noopener">documentação</a> no site deles, mas é ridiculamente simples.</p>
<p><img src="https://www.ventoy.net/static/img/screen/screen_uefi_en.png?v=4" alt="Ventoy Menu"  loading="lazy" /></p>
<p>Depois de instalar no seu pendrive, agora é só copiar <strong>TODAS AS ISOS</strong> que quiser de uma só vez no pendrive. Quando bootar por ele, vai entrar no menu do Ventoy, que vai deixar escolher qualquer uma das ISOs que copiou lá. Se não gostou da distro atual, só rebootar no Ventoy de novo, e escolher outra ISO. É assim simples.</p>
<p><img src="https://www.ventoy.net/static/img/ventoy2disk_en.png" alt="Ventoy"  loading="lazy" /></p>
<h3>Distrobox<span class="hx:absolute hx:-mt-20" id="distrobox"></span>
    <a href="#distrobox" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Digamos que você é um programador, ou um devops, ou qualquer profissional na área de tecnologia. Sua preocupação não é tanto a interface gráfica (que dá pra testar com Ventoy), mas sim se a infra do OS vai funcionar com seus requerimentos de desenvolvimento.</p>
<p>Digamos que você use Fedora. Será que se eu for pro Mint, vai ter os pacotes pro K8S do jeito que eu preciso? Será que tem suporte à versão de Java que eu uso? Será que se eu buildar um pacote <code>.deb</code> no meu Fedora, vai instalar direitinho no Ubuntu?</p>
<p>Ter que fazer dual boot ou instalar uma VM parece pesado demais, trabalhoso demais, só pra testar 2 linhas de comando, por exemplo.</p>
<p><img src="https://user-images.githubusercontent.com/598882/144294862-f6684334-ccf4-4e5e-85f8-1d66210a0fff.png" alt="Distrobox"  loading="lazy" /></p>
<p>Pra isso existe <a href="https://distrobox.it/"target="_blank" rel="noopener"><strong>Distrobox</strong></a>. Ele precisa do Docker ou Podman já instalado na sua máquina. Mas depois é só fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">distrobox create -n debian-test --init --image debian:latest --additional-packages <span class="s2">&#34;build-essential&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Uma vez criado o box é só entrar nele:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">distrobox enter debian-test</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Acabou, você está dentro do Debian, super rápido. Como é um container docker, tem como mapear diretórios na sua máquina local pra dentro do container, então fica tudo integrado. E o mais importante: carrega super rápido, porque é só um container Docker.</p>
<p>O guia <a href="https://distrobox.it/#quick-start"target="_blank" rel="noopener">Quick Start</a> explica tudo isso e tem este video com um tour pra demonstrar como funciona:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/Q2PrISAOtbY"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Sério. Com Distrobox não tem desculpa pra não testar outra distro em 2 minutos. Não fique perdendo tempo mandando DM pra &ldquo;influencer&rdquo;. Veja você mesmo! Se não é capaz de fazer isso, talvez esteja na profissão errada.</p>
<p>Todo &ldquo;dev&rdquo; ou profissional de tecnologia, seja de devops, cybersec, data analyst, bla bla bla, seja lá qual título da moda hoje em dia, <strong>DEVE</strong> ter controle sobre sua própria máquina. <strong>DEVE</strong> saber lidar com segurança (por isso fiz posts sobre Vaultwarden, Cloudflare, SSH, etc).</p>
<p><strong>É SUA RESPONSABILIDADE!</strong></p>
<p>Não terceirize sua responsabilidade pros outros. Não procure validação. Seja <strong>promíscuo</strong> e teste quais distros quiser, e faça o que quiser nessas distros: é sua! Não existe &ldquo;distro pra iniciante&rdquo;, &ldquo;distro pra dev&rdquo;, &ldquo;distro pra devops&rdquo;. Distro é Distro. Linux é Linux. É tudo igual, o que varia é <strong>sua habilidade</strong>. Se não tem habilidade: conquiste! Aprenda! Quebre a cabeça! Vare noites tunando configs! Leia as documentações oficiais! Não perca tempo achando que vai aprender em rede social. Não vai.</p>
<p>Eu uso Linux desde o começo dos anos 90 e não fico usando Slackware só porque foi a primeira que aprendi e sinto necessidade de validar minha primeira escolha. Eu uso todas que quiser. Agora mesmo, eu tinha minha própria instalação de Hyprland, resolvi que quero aprender e usar Omarchy. Passei a semana quebrando cabeça, escrevi meia dúzia de posts no blog. E agora eu aprendi. Eu sei Omarchy: mais um pra coleção.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>tutoriais</category></item><item><title>Omarchy 2.0 - Instale com a ISO do Omarchy</title><link>https://akitaonrails.github.io/2025/09/12/omarchy-2-0-instale-com-a-iso-do-omarchy/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/12/omarchy-2-0-instale-com-a-iso-do-omarchy/</guid><pubDate>Fri, 12 Sep 2025 10:00:00 -0300</pubDate><description>&lt;p&gt;Pra finalizar a série de &lt;a href="https://akitaonrails.github.io/tags/omarchy/"&gt;Omarchy&lt;/a&gt; por enquanto, acho que faltou comentar rapidamente sobre a instalação via a ISO do próprio Omarchy.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912093827_screenshot-2025-09-12_09-38-05.png" alt="ISO" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Só ir no &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;site oficial&lt;/a&gt; e clicar em &amp;ldquo;ISO&amp;rdquo; pra baixar. Usar um Rufus ou Balena Etcher no Windows (ou &lt;a href="https://github.com/ifd3f/caligula"target="_blank" rel="noopener"&gt;Caligula&lt;/a&gt; em Linux) pra gravar num pen drive e bootar com ele. Dali em diante é seguir o passo-a-passo e em menos de 5 minutos vai ter tudo instalado.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Pra finalizar a série de <a href="/tags/omarchy/">Omarchy</a> por enquanto, acho que faltou comentar rapidamente sobre a instalação via a ISO do próprio Omarchy.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250912093827_screenshot-2025-09-12_09-38-05.png" alt="ISO"  loading="lazy" /></p>
<p>Só ir no <a href="https://omarchy.org/"target="_blank" rel="noopener">site oficial</a> e clicar em &ldquo;ISO&rdquo; pra baixar. Usar um Rufus ou Balena Etcher no Windows (ou <a href="https://github.com/ifd3f/caligula"target="_blank" rel="noopener">Caligula</a> em Linux) pra gravar num pen drive e bootar com ele. Dali em diante é seguir o passo-a-passo e em menos de 5 minutos vai ter tudo instalado.</p>
<p><img src="https://learn.omacom.io/u/configurator-iGH96F.png" alt="Omarchy install"  loading="lazy" /></p>
<p>Como expliquei no <a href="https://akitaonrails.com/2025/08/29/new-omarchy-2-0-install/"target="_blank" rel="noopener">primeiro artigo</a> eu fiz diferente: instalei o <a href="https://archlinux.org/download/"target="_blank" rel="noopener">Arch Linux</a> puro, tipo Desktop, com Hyprland + SDDM. Depois instalei Omarchy usando a linha de comando manual:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://omarchy.org/install <span class="p">|</span> bash</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Dá pra fazer dos dois jeitos, no segundo tem mais controle, mas depois de ganhar mais experiência e ler os scripts de install, eu recomendo que baixe a ISO do próprio Omarchy, vai ser mais fácil mesmo.</p>
<h3>Limine vs Grub<span class="hx:absolute hx:-mt-20" id="limine-vs-grub"></span>
    <a href="#limine-vs-grub" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O motivo de ter instalado da forma mais manual foi porque eu não tinha certeza se o Omarchy tinha suporte a dar rollback de BTRFS via snapshots. Eu tinha ouvido falar que o bootload <a href="https://codeberg.org/Limine/Limine"target="_blank" rel="noopener">Limine</a> não suportava isso. Mas me enganei, o Omarchy instala Limine com suporte a <strong>Snapper</strong> (que é similar ao Timeshift que eu costumo usar). Leia no <a href="https://wiki.archlinux.org/title/Limine"target="_blank" rel="noopener">ArchWiki seção 6.2</a>, portanto deve ser uma opção superior à minha instalação de GRUB+Timeshift que falei no primeiro artigo.</p>
<p>Como eu já instalei de forma manual, vou manter como está porque na prática é a mesma coisa. Mas se fosse instalar de novo, agora instalaria com Limine+Snapper pra experimentar.</p>
<p>Significa que existe suporte a snapshot do seu filesystem inteiro com BTRFS antes de um update de pacotes e, se algo der errado, é possível rebootar e dar rollback pra um snapshot anterior. Isso te dá segurança de não perder um dia inteiro tentando consertar alguma coisa, caso algum pacote importante do sistema venha com bugs ou corrompido. É o recurso mais importante.</p>
<h3>SDDM vs UWSM<span class="hx:absolute hx:-mt-20" id="sddm-vs-uwsm"></span>
    <a href="#sddm-vs-uwsm" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Outra coisa diferente que notei foi o login manager. No Arch puro, ele instala Hyprland por padrão com <a href="https://wiki.archlinux.org/title/SDDM"target="_blank" rel="noopener">SDDM</a>, que é o mesmo que o KDE usa.</p>
<p>Omarchy usa UWSM, que faz login automático com seu usuário no boot. Então não tem tela de login, ele já abre o Hyprland automaticamente.</p>
<p><em>&ldquo;Mas isso não é inseguro??&rdquo;</em></p>
<p>Não, porque a ISO do Omarchy pré-configura seu SSD com LUKS, antes do filesystem.</p>
<p>Pra quem não sabe, <a href="https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system"target="_blank" rel="noopener">LUKS</a> é o <strong>Linux Unified Key Setup</strong>, que dá suporte a encriptar seu disco inteiro. A vantagem dele em relação a um BitLocker do Windows, é que ele é <strong>agnóstico a filesystem</strong>. Ou seja, funciona com BTRFS ou EXT4 ou qualquer outro, porque na sequência de boot, depois do bootloader (seja Limine ou Grub), ele carrega <strong>antes</strong> do filesystem. É um encriptador em nível de blocos.</p>
<p><img src="https://learn.omacom.io/u/arch-encryption-urjrDm.png" alt="install luks"  loading="lazy" /></p>
<p>Portanto, quando você bootar seu sistema, primeiro vai pedir a senha de decriptar seu disco. Daí abre o filesystem e o kernel do Linux pode continuar o boot normal com o disco aberto. Então você é obrigado a <strong>sempre</strong> digitar a senha segura do seu usuário no boot pra decriptar o disco.</p>
<p>Portanto, ter que digitar senha novamente num login manager seria redundante e desnecessário, por isso imagino que escolheram usar UWSM em vez de SDDM.</p>
<p>Especialmente em notebook, ou em casos onde mais gente mora com você, é <strong>essencial</strong> garantir que seu disco esteja encriptado, não importa o sistema operacional. Digamos que saia pra trabalhar ou vá viajar e seu notebook é roubado. Sem encriptação, acabou, não importa se tem um login manager. Ele não protege seus dados. Basta tirar o SSD do seu notebook, plugar em outro computador e pronto, dá pra copiar tudo bootando como Root.</p>
<p>Com encriptação, sem a senha pra decriptar, é impossível acessar seus dados. Impossível mesmo, porque em qualquer computador modernos dos últimos 15 anos, a CPU vem com instruções aceleradas em hardware pra encriptar usando AES 256.</p>
<p>Sendo um pouco mais nerd, a chave de decriptação <strong>não é sua senha</strong>. Durante o processo de instalação vai ser gerada uma nova senha mais forte e segura usando um processo de <strong>derivação de chaves</strong> (KDF - Key Derivation Function), hoje em dia é com Argon2id, antigamente era com PBKDF2. Explico sobre isso neste video:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/HCHqtpipwu4"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Portanto, quando digita sua senha, na verdade ele decripta essa chave segura, e é com essa chave segura que seu disco está encriptado. Por isso não dá pra decriptar seus dados na força-bruta.</p>
<p>Além disso AES 256 é outro algoritmo de criptografia que é <strong>quantum resistant</strong>. Mesmo se fosse possível um computador quântico (não é), nem ele conseguiria decriptar seu disco. Este é o nível de segurança.</p>
<p><em>&ldquo;Mas não vai ficar mais lento?&rdquo;</em></p>
<p>Não. É praticamente imperceptível, porque AES - como já disse - é acelerado via hardware pela sua CPU, não depende de software do seu sistema operacional. No dia a dia, dificilmente vai notar. A performance é praticamente a mesma. Não existe motivo pra não ativar encriptação, especialmente num notebook.</p>
<p>No meu caso pessoal, onde instalei num PC desktop, que eu mesmo controlo numa rede local segura - porque eu sei implementar segurança em rede, não tem problema. Os dados mais importantes pra mim ficam no meu NAS (que é encriptado), em backups (que são encriptados), eu não tenho dados sensíveis neste PC e o pouco que tenho está em arquivos encriptados pelo <a href="https://veracrypt.io/en/Downloads.html"target="_blank" rel="noopener">Veracrypt</a> num sub-volume separado.</p>
<p>Por isso não habilitei LUKS no meu PC. Daí mantive o SDDM que o Arch puro instalou. Só que ele é <strong>BEM</strong> feio por padrão, então só fica uma pequena dica: instalar ou o tema <a href="https://github.com/MarianArlt/sddm-sugar-dark"target="_blank" rel="noopener">sddm-sugar-dark</a> ou o <a href="https://github.com/simonesestito/dark-arch-sddm"target="_blank" rel="noopener">dark-arch-sddm</a>. Eu prefiro esse segundo por ser mais minimalista e fica assim:</p>
<p><img src="https://github.com/simonesestito/dark-arch-sddm/raw/master/base/screenshot.png" alt="dark arch sddm"  loading="lazy" /></p>
<p>Eu customizei e troquei o logo do Arch pelo do Omarchy e pronto.</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Vou repetir: só depois que instalei manualmente que vi como o Omarchy instala e hoje eu prefiro o jeito do Omarchy. Se fosse instalar do zero, usaria a ISO do Omarchy e deixaria com Limine+Snapper e Hyprland+UWSM com suporte a rollback de snapshot, encriptação total do disco, login automático pro Hyprland.</p>
<p>Dá pra ver que o pessoal fazendo o Omarchy tem experiência e já escolheu componentes que fazem sentido pra funcionar tudo junto da forma mais conveniente e segura possível. Eu tive receio que por ser uma distro nova talvez eles não tivessem se preocupado com isso, mas fico feliz de dizer que eu estava errado.</p>
<p>Usem a ISO oficial do Omarchy.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>tutoriais</category></item><item><title>Omarchy 2.0 - Bitwarden Self-Hosted / VaultWarden</title><link>https://akitaonrails.github.io/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/</guid><pubDate>Wed, 10 Sep 2025 20:00:00 -0300</pubDate><description>&lt;p&gt;Continuando a &lt;a href="https://akitaonrails.github.io/tags/omarchy/"&gt;série de Omarchy&lt;/a&gt; e fazendo cross-over com a série de &lt;a href="https://akitaonrails.github.io/tags/homeserver"&gt;home server&lt;/a&gt;, vamos falar sobre Gerenciador de Senhas e 2FA. Quem me acompanha que eu falo frequentemente sobre segurança digital pessoal, a importância de prestar atenção em links pra não cair em golpes, phishing, nem instalar malware sem querer.&lt;/p&gt;
&lt;p&gt;Mais importante: ter uma senha forte, aleatória, exclusiva e diferente para &lt;strong&gt;CADA&lt;/strong&gt; site, app ou serviço que usa. Nunca, jamais, reusar uma senha. Por que? Porque todo dia um desses sites é invadido e as senhas são vazadas. Se você procurar por você mesmo no site &lt;a href="https://haveibeenpwned.com/"target="_blank" rel="noopener"&gt;Have I Been Pwned&lt;/a&gt; certamente vai achar contas suas que já vazaram. E se você compartilha essa mesma senha com 10 outros sites, alguém já deve ter entrado na sua conta a essa altura.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Continuando a <a href="/tags/omarchy/">série de Omarchy</a> e fazendo cross-over com a série de <a href="/tags/homeserver">home server</a>, vamos falar sobre Gerenciador de Senhas e 2FA. Quem me acompanha que eu falo frequentemente sobre segurança digital pessoal, a importância de prestar atenção em links pra não cair em golpes, phishing, nem instalar malware sem querer.</p>
<p>Mais importante: ter uma senha forte, aleatória, exclusiva e diferente para <strong>CADA</strong> site, app ou serviço que usa. Nunca, jamais, reusar uma senha. Por que? Porque todo dia um desses sites é invadido e as senhas são vazadas. Se você procurar por você mesmo no site <a href="https://haveibeenpwned.com/"target="_blank" rel="noopener">Have I Been Pwned</a> certamente vai achar contas suas que já vazaram. E se você compartilha essa mesma senha com 10 outros sites, alguém já deve ter entrado na sua conta a essa altura.</p>
<p>Assista meu video sobre segurança:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/s7ldn31OEFc"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Ter preguiça de usar um gerenciador de senhas é só uma desculpa idiota de gente preguiçosa. E um programador sequer tem direito de usar essa desculpa.</p>
<h3>Omarchy 1Password<span class="hx:absolute hx:-mt-20" id="omarchy-1password"></span>
    <a href="#omarchy-1password" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Quem acompanha o DHH desde os primórdios de quando Macs eram a melhor plataforma pra desenvolvedores, lembra que ele sempre foi fã do 1Password, um dos que funcionava melhor em iPhones.</p>
<p>Eu migrei de volta pra Android e Linux muitos anos atrás, em 2015. Eu usava <strong>1Password</strong>, mas em Android o app era tenebroso de feio de ruim de usar. Por isso desisti dele e fiquei migrando entre vários outros apps. Seja Google Authenticator, seja Lastpass (que não recomendo).</p>
<p>Sei que tem diversos outros open source que as pessoas preferem, mas eu acabei caindo no Bitwarden, que é <strong>BONITO</strong> tanto em Android como a extension pra navegadores. Além disso ele tem componentes abertos e permite <strong>self-hosting</strong>.</p>
<p>Mais do que isso, ele não dificulta que você exporte todos os dados da sua conta e importe em outro lugar. Diferente de apps como o Twilio Authy, que te bloqueia de tudo e por isso deixei de usar.</p>
<p>Bitwarden tem gerador seguro de senhas aleatórias, tem suporte a <strong>2FA TOTP</strong>, dá pra armazenar anotações (tipo mini textos) seguras e muito mais. Os apps integram com biometria do celular, então é bem conveniente de usar.</p>
<p>Ainda mantenho meu Bitwarden dentro do <a href="https://www.samsung.com/global/sustainability/popup/popup_doc/AYUqoB6qDDMAIx_C/"target="_blank" rel="noopener">Secure Vault</a> da Samsung, o <strong>Samsung Knox Vault</strong>. Então são 2 níveis de segurança. E quando preciso andar em algum lugar suspeito, não levo meu celular principal, só um burner-phone sem nada de importante logado.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910193713_bitwarden-generator.png" alt="Bitwarden Generator"  loading="lazy" /></p>
<p>Olhem como é bonito. Eu gosto dele e uso já faz alguns anos. Minhas senhas variam entre 21 a 42 caracteres aleatórios, um diferente pra cada site. Eu atualizei todas as senhas de tudo mais de uma vez nos últimos anos, e todas as contas tem 2FA/TOTP cadastrado no Bitwarden também, assim consegui sair do Authy.</p>
<h3>Instalando VaultWarden Self-Hosted<span class="hx:absolute hx:-mt-20" id="instalando-vaultwarden-self-hosted"></span>
    <a href="#instalando-vaultwarden-self-hosted" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Mais importante, chegou a hora de hostear meu próprio servidor de Bitwarden, o <a href="https://github.com/dani-garcia/vaultwarden"target="_blank" rel="noopener"><strong>vaultwarden</strong></a> que é uma alternativa open source, código aberto no GitHub, então você mesmo pode fuçar pra aprender ou até contribuir com ele. Novamente, subo tudo com Docker Compose no meu Home Server, então só precisei adicionar este trecho no meu arquivo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">  </span><span class="nt">vaultwarden</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">vaultwarden/server:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">vaultwarden</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">DOMAIN</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://bitwarden.fabioakita.dev&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SIGNUPS_ALLOWED</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;false&#34;</span><span class="w">          </span><span class="c"># set to true only to create first user</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">WEBSOCKET_ENABLED</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ADMIN_TOKEN</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;iA...Q9&#34;</span><span class="w">  </span><span class="c"># for /admin</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># SMTP (recommended)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_HOST</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;smtp.gmail.com&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_PORT</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;587&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_SECURITY</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;starttls&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_USERNAME</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;boss@akitaonrails.com&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_PASSWORD</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;xxx&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">SMTP_FROM</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;boss@akitaonrails.com&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/home/akitaonrails/vaultwarden/data:/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;9999:80&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">healthcheck</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">test</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CMD&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;wget&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;-q&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;-O&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;-&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;http://localhost/health&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">interval</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">5s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">retries</span><span class="p">:</span><span class="w"> </span><span class="m">5</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Importante:</p>
<ul>
<li>Crie um <code>ADMIN_TOKEN</code> longo e aleatório. Use o próprio Bitwarden pra isso, mantenha secreto.</li>
<li>Mude <code>SIGNUPS_ALLOWED</code> pra <code>true</code> somente uma vez, entre no site local e crie sua nova conta. Depois mude no arquivo pra <code>false</code>, reinicie o container. Dessa forma ninguém mais poderá criar nenhuma nova conta.</li>
<li>É recomendado configurar um GMAIL SMTP pra mandar emails de notificações. Pra isso precisa criar uma senha de aplicativo no Google.</li>
</ul>
<p>Pra criar uma senha exclusivamente pro vaultwarden, acesse <a href="https://myaccount.google.com/apppasswords"target="_blank" rel="noopener">Google App Passwords</a> e gere uma nova senha secreta exclusiva:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910194453_screenshot-2025-09-10_16-34-48.png" alt="App Password"  loading="lazy" /></p>
<p>Ele só vai mostrar essa senha uma única vez. Copie e cole direto no yaml do docker compose. Configurando e-mail bonitinho, toda vez que alguém fizer login, ele manda um e-mail notificando. Isso é bom pra ter certeza que não tem ninguém suspeito mexendo no seu servidor:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910201642_screenshot-2025-09-10_20-16-25.png" alt="notification"  loading="lazy" /></p>
<p>Agora só preciso subir o container:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose -f utils-docker-compose.yml up -d</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Roteando túnel do Cloudflared<span class="hx:absolute hx:-mt-20" id="roteando-túnel-do-cloudflared"></span>
    <a href="#roteando-t%c3%banel-do-cloudflared" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como já mostrei no <a href="https://akitaonrails.com/2025/09/09/acessando-meu-home-server-com-dominio-de-verdade/"target="_blank" rel="noopener">post de Cloudflared</a> agora quero poder acessar remotamente, via túnel seguro, usando uma URL pública como <code>https://bitwarden.fabioakita.dev</code>. Pra fazer isso temos que editar aquele arquivo <code>/etc/cloudflared/config.yml</code> e adicionar no final dele assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">bitwarden.fabioakita.dev</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">http://192.168.0.200:9999</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">originRequest</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">httpHostHeader</span><span class="p">:</span><span class="w"> </span><span class="l">bitwarden.fabioakita.dev</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">http2Origin</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">http_status:404</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Depois temos que reiniciar o serviço e também adicionar a rota manualmente:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo cloudflared tunnel route dns homelab bitwarden.fabioakita.dev
</span></span><span class="line"><span class="cl">sudo systemctl restart cloudflared</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E pronto! Talvez demore até 5 minutos pros DNS sincronizarem e tudo mais, mas daí é só entrar no seu navegador e vai ver isto:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910194927_screenshot-2025-09-10_19-49-14.png" alt="VaultWarden Login"  loading="lazy" /></p>
<p>Se aquele <code>SIGNUPS_ALLOWED</code> estiver <code>true</code> também vai ter um link pra &ldquo;Criar nova conta&rdquo;. No meu caso eu já fiz isso e desliquei, então só tem login mesmo.</p>
<h3>Importando seus Dados<span class="hx:absolute hx:-mt-20" id="importando-seus-dados"></span>
    <a href="#importando-seus-dados" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Antes de continuar, vamos abrir a extension do Bitwarden - que continua logado na versão cloud em bitwarden.com e exportar todos os meus dados:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910195209_bitwarden-export.png" alt="Export Vault"  loading="lazy" /></p>
<p>Basta se autenticar, daí na barra inferior de ícones vai ter &ldquo;Settings&rdquo;, depois &ldquo;Vault Options&rdquo; e, finalmente &ldquo;Export vault&rdquo;. Deixe o padrão no formato JSON mesmo (vai ser um <strong>JSON encriptado</strong>) e faça download desse arquivo pra algum lugar seguro.</p>
<p>Agora podemos logar de volta na nossa versão self-hosted em <code>https://bitwarden.fabioakita.dev</code> e seguir pelo mesmo menu, mas escolher &ldquo;Import&rdquo;:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910195410_screenshot-2025-09-10_19-53-56.png" alt="Import"  loading="lazy" /></p>
<p>E pronto! Agora minha versão self-hosted está <strong>idêntica</strong> à versão cloud que vinha usando até agora.</p>
<h3>Logando no novo servidor self-hosted<span class="hx:absolute hx:-mt-20" id="logando-no-novo-servidor-self-hosted"></span>
    <a href="#logando-no-novo-servidor-self-hosted" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora basta deslogar tanto do App mobile quanto da extension do navegador. Daí na tela de login vai ter a seguinte opção:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910195632_bitwarden-login.png" alt="Login self-hosted"  loading="lazy" /></p>
<p>Na extension web a janela não deixa ver essa opção, use o scroll do mouse e scrole até o fim da janela e vai ter essa opção pequena. Escolha &ldquo;self-hosted&rdquo; e vai abrir uma janela pra digitar a URL <code>https://bitwarden.fabioakita.dev</code> e pronto!</p>
<p>A partir daqui o uso é exatamente o mesmo de antes. A interface é a mesma, as opções são as mesmas. Configure <strong>biometria</strong>, PIN, timeout pra lock e tudo mais pra deixar do jeito que você gosta.</p>
<p>Faça a mesma coisa no app mobile e pronto!</p>
<p>Nessa nova conta que criamos no servidor self-hosted, não esqueça de habilitar 2FA também, que é a opção &ldquo;Authenticator App&rdquo; em &ldquo;Settings/Security&rdquo;:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910200009_screenshot-2025-09-10_19-59-55.png" alt="2FA"  loading="lazy" /></p>
<p>Pra todas as outras contas, podemos registrar o 2FA dentro do Bitwarden. Mas pra conta master do próprio Bitwarden/Vaultwarden, precisamos usar um segundo app só pra isso.</p>
<p>Não sei se é o melhor, mas eu tenho gostado de usar o <a href="https://getaegis.app/"target="_blank" rel="noopener">Aegis Authenticator</a> no meu Android:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910203243_hero.7C782sEM.png" alt="Aegis"  loading="lazy" /></p>
<p>É open source, o código está no <a href="https://github.com/beemdevelopment/aegis"target="_blank" rel="noopener">GitHub</a>, então parece minimamente confiável. Também deixo ele dentro do Samsung Knox Vault. Só preciso dele quando preciso re-logar no Bitwarden/Vaultwarden. Pra logar nos Google, Steam ou qualquer outra conta, o 2FA de cada uma está dentro do Vaultwarden mesmo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910200449_2fa.png" alt="2FA"  loading="lazy" /></p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora só faltou mesmo me logar com minha conta antiga em <strong>bitwarden.com</strong>, que é a versão &ldquo;oficial&rdquo; no cloud e deletar minha conta, pra garantir que ninguém mais tenha acesso.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250910200615_screenshot-2025-09-10_20-06-04.png" alt="Deletar"  loading="lazy" /></p>
<p>E pronto, <strong>PERMANENTEMENTE APAGADO</strong>! Não existe mais minhas contas num servidor qualquer que eu não controlo, mesmo que fosse encriptado.</p>
<p>Estou bem contente com esta solução. Agora meu Vaultwarden está num container, os dados do home server tem backup automático pro meu NAS, tudo é encriptado e só tem acesso via túnel seguro da Cloudflare. O risco é bem baixo e ninguém tem chance de ter acesso aos meus dados, porque eles não estão mais no &ldquo;cloud&rdquo;.</p>
<p>Meus dados são somente meus.</p>
]]></content:encoded><category>omarchy</category><category>homelab</category><category>containers</category><category>seguranca</category></item><item><title>Omarchy 2.0 - Entendendo SSH e Yubikeys</title><link>https://akitaonrails.github.io/2025/09/09/omarchy-2-0-entendendo-ssh-e-yubikeys/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/09/omarchy-2-0-entendendo-ssh-e-yubikeys/</guid><pubDate>Tue, 09 Sep 2025 12:00:00 -0300</pubDate><description>&lt;p&gt;Este post não tem nada a ver diretamente com Omarchy mas resolvi incluir na &lt;a href="https://akitaonrails.github.io/tags/omarchy/"&gt;mesma série&lt;/a&gt; porque é uma dica importante pra programadores.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Todo programador precisa saber como gerenciar suas chaves SSH.&lt;/strong&gt; No mínimo porque toda conta no GitHub exige uma chave.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-09_12-19-38.png" alt="GitHub SSH" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Toda vez que fizer &lt;code&gt;git push&lt;/code&gt; pra um repositório seu, ele vai pedir a passphrase dessa chave:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;❯ git push origin master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Enter passphrase &lt;span class="k"&gt;for&lt;/span&gt; key &lt;span class="s1"&gt;&amp;#39;/home/akitaonrails/.ssh/id_ed25519&amp;#39;&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;O que significa isso?&lt;/p&gt;</description><content:encoded><![CDATA[<p>Este post não tem nada a ver diretamente com Omarchy mas resolvi incluir na <a href="/tags/omarchy/">mesma série</a> porque é uma dica importante pra programadores.</p>
<p><strong>Todo programador precisa saber como gerenciar suas chaves SSH.</strong> No mínimo porque toda conta no GitHub exige uma chave.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-09_12-19-38.png" alt="GitHub SSH"  loading="lazy" /></p>
<p>Toda vez que fizer <code>git push</code> pra um repositório seu, ele vai pedir a passphrase dessa chave:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ git push origin master
</span></span><span class="line"><span class="cl">Enter passphrase <span class="k">for</span> key <span class="s1">&#39;/home/akitaonrails/.ssh/id_ed25519&#39;</span>:</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O que significa isso?</p>
<p>SSH é um conjunto de ferramentas tanto de cliente quanto servidor pra criar uma conexão segura, encriptada, pela internet. Ela tem diversas utilidades e eu expliquei como fazer Proxy SSH neste video:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/T-jHuFnxZ2k"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>O processo todo se inicia instalando SSH na sua máquina, e no Omarchy/ArchLinux é só fazer isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">yay -S openssh</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se nunca criou um par de chaves (sim, é um par) é só executar este comando:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-keygen -t ed25519 -a 100 -C &#34;your_email@example.com&#34; -f ~/.ssh/id_ed25519</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>ED25519</strong> é um algoritmo de chave-pública, ou seja, cria um par de chaves: uma privada que <strong>jamais deve sair da sua máquina</strong>, e uma pública que pode ser exposta na internet aberta (a que você registra na sua conta no GitHub, por exemplo). Eu expliquei sobre chaves-públicas neste outro video:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/HCHqtpipwu4"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>ED25519 é um algoritmo mais moderno que o antigo RSA (que acho que ainda é o padrão no ssh-keygen se não fizer a escolha explícita - ela continua sendo segura, mas curva elíptica é ainda mais segura).</p>
<p>Ela é baseada em criptografia de curva elíptica (ECC). Pros paranóicos, sim, é inclusive considerada <strong>quantum-resistant</strong>, ou seja, mesmo se fosse possível fazer um computador quântico, ela não conseguiria quebrar uma chave ED25519.</p>
<p>Dois arquivos serão criados depois de rodar <code>ssh-keygen</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>.rw-------   464 akitaonrails 14 Nov  2017  󰌆 id_ed25519
.rw-r--r--   108 akitaonrails 14 Nov  2017  󰷖 id_ed25519.pub</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Note as permissões desses arquivos. É importante que o diretório <code>~/.ssh</code> e os arquivos de chave privada dentro sempre estejam com permissão <code>600</code> , ou seja, read-write somente pro seu usuário, e nenhuma permissão pra grupos ou qualquer outro usuário. Ninguém deve ser capaz sequer de listar o diretório se não for você mesmo.</p>
<p>Já os arquivos <code>*.pub</code>, que são as chaves públicas, tem permissão <code>644</code> que é read-write pra você e somente-leitura pra outros grupos e usuários. Como falei, a chave pública pode ser exposta publicamente. A minha, por exemplo, é esta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>❯ cat id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEWG5bHK02sMqilMiYu67xqdaBsk3TtCQ564bcJibDiO akitaonrails@Miner42.local</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>ED25519 tem outra vantagem, ela é ordens de grandeza mais segura que RSA e ainda oferece uma chave pública muito mais curta, o que facilita na hora de copiar e colar por aí.</p>
<p>Uma chave privada tem um envelope neste formato:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-----BEGIN RSA PRIVATE KEY-----
MIIEpA ...
...
XfI0X....
...
... nQ5w==
-----END RSA PRIVATE KEY-----</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Repetindo: <strong>ESTE ARQUIVO JAMAIS DEVE SAIR DA SUA MÁQUINA</strong>. Nunca deixe largado num pen drive, por exemplo. E sempre garanta que a permissão é <code>chmod 600</code> como expliquei.</p>
<h3>Yubikey 5<span class="hx:absolute hx:-mt-20" id="yubikey-5"></span>
    <a href="#yubikey-5" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A forma considerada mais segura e que muitas empresas até enforçam, é o uso de uma <strong>HARDWARE-KEY</strong>. A chave privada nunca é gravada na sua máquina local e sim gerada dentro de um hardware seguro, de onde é impossível tentar ler essa chave privada. Exemplos são Yubikey ou FIDO2.</p>
<p>Sobre Yubikey, cuidado, você quer os modelos mais novos <strong>Yubikey Series 5</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/yubikey.webp" alt="Yubikey 5"  loading="lazy" /></p>
<p>Se tiver o antigo - que normalmente é o de cor azul - ele é o Security Key v4.3.1 e só suporta <strong>U2F (FIDO U2F)</strong> mas não <strong>FIDO2/WebAuthn</strong> e não applets <strong>PIV/OpenPGP/OTP</strong>. Pra ter certeza, instale estes pacotes no seu Arch:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -S yubikey-manager libfido2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Daí cheque com este comando:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ ykman info
</span></span><span class="line"><span class="cl">WARNING: PC/SC not available. Smart card <span class="o">(</span>CCID<span class="o">)</span> protocols will not <span class="k">function</span>.
</span></span><span class="line"><span class="cl">Device type: FIDO U2F Security Key
</span></span><span class="line"><span class="cl">Firmware version: 4.3.1
</span></span><span class="line"><span class="cl">Enabled USB interfaces: FIDO
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Applications
</span></span><span class="line"><span class="cl">Yubico OTP   Not available
</span></span><span class="line"><span class="cl">FIDO U2F     Enabled
</span></span><span class="line"><span class="cl">FIDO2        Not available
</span></span><span class="line"><span class="cl">OATH         Not available
</span></span><span class="line"><span class="cl">PIV          Not available
</span></span><span class="line"><span class="cl">OpenPGP      Not available
</span></span><span class="line"><span class="cl">YubiHSM Auth Not available</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Veja como ele acha o Yubikey conectado via USB mas tudo está como &ldquo;Not available&rdquo;. Não é o correto, esse Yubikey só serve como Two-Factor Authentication em Websites. Não é inútil, mas pro nosso caso não funciona porque:</p>
<ul>
<li>não tem applet PIV então não serve de smartcard</li>
<li>não tem applet OpenPGP então não consegue guardar chaves privadas GPG ou SSH</li>
<li>não tem FIDO2 então não dá pra rodar <code>ssh-keygen -t ed25519-sk</code>.</li>
</ul>
<p>Um novo, no Mercado Livre hoje, vai custar uns BRL 800. Se for usar pra trabalhar por política de segurança da empresa, eles tem que providenciar ou ressarcir pra você. Mas mesmo pra uso pessoal, recomendo investir um pouco mais na segurança.</p>
<p>Tendo um Yubikey 5, o procedimento é o seguinte. Comece garantindo que tem os pacotes na sua máquina:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo pacman -S yubikey-manager yubico-piv-tool opensc</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Inicialize a aplicação PIV mudando o PIN:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ykman piv reset                # wipes PIV, careful
ykman piv access change-pin    # default PIN is 123456
ykman piv access change-puk    # default PUK is 12345678</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Gere um novo par de chaves <strong>dentro</strong> do Yubikey:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ykman piv keys generate 9a pubkey.pem</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Extraia somente a chave pública pro seu diretório local <code>~/.ssh</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-keygen -D /usr/lib/opensc-pkcs11.so -e &gt; ~/.ssh/id_yubikey.pub</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O conteúdo desse arquivo <code>~/.ssh/id_yubikey.pub</code> é que você vai adicionar no arquivo <code>~/.ssh/authorized_keys</code> do seu servidor remoto que quer conectar via SSH. Pra abrir uma conexão SSH pra ele, conecte o Yubikey na porta USB e execute assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh -I /usr/lib/opensc-pkcs11.so seu-user@server</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ele vai pedir seu PIN e autorizar a conexão. Se não quiser ficar digitando esse <code>-I</code> toda vez, basta editar o <code>~/.ssh/config</code> com isto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># ~/.ssh/config
Host server
  PKCS11Provider /usr/lib/opensc-pkcs11.so
  User seu-user</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>PORÉM</strong></p>
<p>Este procedimento vai usar o gerador de chaves de dentro da Yubikey, que só suporta <strong>RSA (1024–2048)</strong> ou <strong>ECC (P-256, P-384)</strong>. Se quiser gerar uma chave ED25519, o fluxo é diferente, temos que executar assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-keygen -t ed25519-sk -a 100 -C &#34;you@example.com&#34; -f ~/.ssh/id_ed25519_sk</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Esse arquivo <code>id_ed25519_sk</code> que ele gera na sua máquina local <strong>não é a chave-privada</strong> é somente um &ldquo;stub&rdquo; que aponta pra sua Yubikey. Então a chave fica armazenada no hardware e nunca passa pela sua máquina.</p>
<p>Pra adicionar sua chave-pública no servidor remoto, basta manualmente adicionar no arquivo <code>~/.ssh/authorized_keys</code> como fizemos antes ou rodar este comando pra logar com sua senha e ele vai adicionar a chave-pública pra você:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub seu-user@server</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pra usar sua chave pra logar agora é só fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh -i ~/.ssh/id_ed25519_sk seu-user@server</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso só funciona porque a Yubikey 5 tem suporte a FIDO2. As antigas não tem, por isso não dá pra fazer isso.</p>
<p>Ah sim, no seu home server ou outro servidor, <strong>DEPOIS</strong> que adicionar sua chave no <code>authorized_keys</code> eu recomendo <strong>DESABILITAR</strong> a opção de login por senha (pra que nenhum bot fique tentando logar por força bruta). No servidor edite:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM no
...
PubkeyAuthentication yes</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ou seja, desligue todas as opções de login e deixe somente por chave pública. Agora só reinicie o serviço:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo systemctl restart sshd</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>SSH-Agent<span class="hx:absolute hx:-mt-20" id="ssh-agent"></span>
    <a href="#ssh-agent" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Pra ficar claro: a forma considerada mais segura pra gerenciar chaves privadas é via um hardware de segurança externo, no caso a Yubikey 5.</p>
<p>Mas, não é obrigatório. Se você tem um PC exclusivo pra trabalhar, com seu Arch Linux ou Omarchy instalado, e você não fica instalando softwares suspeitos - como jogos pirateados - nem fica acessando sites suspeitos e clicando em qualquer link (risco de malware), não é completamente ruim ter suas chaves localmente na sua máquina. Eu mesmo uso assim faz anos e nunca tive problemas - porque eu sou paranóico com segurança da minha máquina.</p>
<p>Lembre-se, um dos tipos de malware mais comuns são que fazem upload dos seus arquivos ou que encripta seus arquivos e depois pedem resgate de criptomoeda pra devolver. O bom e velho <strong>RANSOMWARE</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ransomware-message.jpg" alt="Ransomware"  loading="lazy" /></p>
<p>Isso tem não só em Windows como Mac e Linux também. E navegadores web são o principal vetor, especialmente emails de phishing com links maliciosos que você sai clicando, ou links que vem em canais de Discord, Telegram ou Whatsapp.</p>
<p><strong>NUNCA CLIQUE EM LINKS</strong>. Copie o link, cole num terminal e veja que tipo de link que é. Se não for um domínio obviamente oficial como &ldquo;whatspp.com&rdquo; ou &ldquo;google.com&rdquo;, não siga em frente.</p>
<p>isso tudo dito. Digamos que você criou suas chaves localmente e cadastrou no <code>authorized_keys</code> do seu servidor e na sua conta de GitHub. Agora, toda vez que fizer <code>ssh</code> ou <code>git push</code> ele vai pedir pra digitar sua <strong>passphrase</strong> (que, se você não for bobo, fez uma passphrase <strong>BEM LONGA</strong>).</p>
<p>Isso é extremamente inconveniente de ficar digitando o tempo todo. Por isso tem um recurso no SSH pra ajudar: cachear sua autenticação durante algum tempo fixo usando ssh-agent.</p>
<p>Comece criando este serviço de usuário pro systemd:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="c"># ~/.config/systemd/user/ssh-agent.service</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">Unit</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">Description</span><span class="p">=</span><span class="nx">SSH</span> <span class="nx">Agent</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">Service</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">Type</span><span class="p">=</span><span class="nx">simple</span>
</span></span><span class="line"><span class="cl"><span class="nx">Environment</span><span class="p">=</span><span class="nx">SSH_AUTH_SOCK</span><span class="p">=</span><span class="err">%</span><span class="nx">t</span><span class="err">/</span><span class="nx">ssh-agent</span><span class="p">.</span><span class="nx">socket</span>
</span></span><span class="line"><span class="cl"><span class="nx">ExecStart</span><span class="p">=</span><span class="err">/</span><span class="nx">usr</span><span class="err">/</span><span class="nx">bin</span><span class="err">/</span><span class="nx">ssh-agent</span> <span class="nx">-D</span> <span class="nx">-a</span> <span class="err">$</span><span class="nx">SSH_AUTH_SOCK</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">Install</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">WantedBy</span><span class="p">=</span><span class="nx">default</span><span class="p">.</span><span class="nx">target</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Habilite com privilégios do seu user (sem sudo):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>systemctl --user enable --now ssh-agent.service</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Exponha isso no seu <code>.bashrc</code> ou <code>.zshrc</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># ~/.zshenv (or ~/.profile)</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$XDG_RUNTIME_DIR</span><span class="s2">/ssh-agent.socket&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora, toda vez que fizer login no seu sistema e começar a trabalhar, adicione sua chave de trabalho:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-add -t 30m ~/.ssh/id_ed25519</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ele vai pedir sua passphrase uma vez, mas durante <strong>30 minutos</strong> (que é essa opção <code>-t 30m</code>), não vai mais precisar re-digitar a passphrase e pode ficar acessando <code>ssh</code> ou fazendo <code>git push</code> de forma mais conveniente.</p>
<p>Se quiser remover o cache do agente, antes do timeout, pode fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ssh-add -d ~/.ssh/id_ed25519</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se sua rotina de trabalho envolve usar ssh, em vez de manualmente fazer <code>ssh-add</code> pode adicionar a seguinte configuração no seu <code>~/.ssh/config</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># ~/.ssh/config</span>
</span></span><span class="line"><span class="cl">Host *
</span></span><span class="line"><span class="cl">  AddKeysToAgent yes
</span></span><span class="line"><span class="cl">  IdentitiesOnly yes
</span></span><span class="line"><span class="cl">  IdentityFile ~/.ssh/id_ed25519</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E toda vez que abrir o terminal, ele vai pedir pra digitar sua passphrase. E isso vai durar enquanto sua sessão estiver logada.</p>
<p>Por fim, o nome do arquivo nos exemplos é sempre <code>id_ed25519</code> mas isso não tem relevância nenhuma, você pode renomear como quiser e inclusive criar múltiplas chaves pra usar em serviços separados, se quiser ser extra-seguro. Basta gerar chaves como <code>heroku_id_ed25519</code> ou <code>google_cloud_id_ed25519</code> e assim por diante. Crie quantas chaves quiser ou achar necessário. Isso vale tanto pra chaves locais quanto chaves na Yubikey 5.</p>
<p>Acho que estes são os aspectos que considero mais importante saber sobre chaves SSH, esqueci alguma outra coisa importante? Não deixe de mandar mais dicas nos comentários abaixo.</p>
]]></content:encoded><category>omarchy</category><category>seguranca</category><category>linux</category></item><item><title>Omarchy 2.0 - TUIs (Terminal User Interface Apps)</title><link>https://akitaonrails.github.io/2025/09/09/omarchy-2-0-tuis/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/09/omarchy-2-0-tuis/</guid><pubDate>Tue, 09 Sep 2025 01:00:00 -0300</pubDate><description>&lt;p&gt;Uma das coisas mais frustrantes pra um usuário de Linux é que existem muito poucos Apps gráficos bem feitos. Veja um Gimp ou LibreOffice. São feios, antiquados, muito parecidos com a primeira vez que usei eles mais de 20 anos atrás.&lt;/p&gt;
&lt;p&gt;Os apps mais &amp;ldquo;modernos&amp;rdquo; são basicamente front-ends web enlatados dentro de um wrapper Electron. O problema? São &lt;strong&gt;PESADOS&lt;/strong&gt; consomem RAM como se não houvesse amanhã. Comece a abrir Discord, Spotify, e vários desses e veja se seu notebook velho de 8GB de RAM vai aguentar.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Uma das coisas mais frustrantes pra um usuário de Linux é que existem muito poucos Apps gráficos bem feitos. Veja um Gimp ou LibreOffice. São feios, antiquados, muito parecidos com a primeira vez que usei eles mais de 20 anos atrás.</p>
<p>Os apps mais &ldquo;modernos&rdquo; são basicamente front-ends web enlatados dentro de um wrapper Electron. O problema? São <strong>PESADOS</strong> consomem RAM como se não houvesse amanhã. Comece a abrir Discord, Spotify, e vários desses e veja se seu notebook velho de 8GB de RAM vai aguentar.</p>
<p>Mas, especialmente se você é um programador, deveria dar mais atenção pra TUIs. Num primeiro momento alguns devem virar o nariz: <em>&ldquo;apps de terminal são feios, preto e branco, quadrados, blerg&rdquo;</em></p>
<p>Se fosse 20 anos atrás, estariam certos. Mas é 2025 e hoje em dia terminais suportam 256 cores (mais que suficiente), suportam várias resoluções e, mais importante, suportam fontes, em particular <a href="https://www.nerdfonts.com/"target="_blank" rel="noopener">Nerd Fonts</a>, fontes que tem ícones dentro. É assim que funciona uma ferramenta como <a href="https://github.com/eza-community/eza"target="_blank" rel="noopener">eza</a>, que eu uso todo dia com alias pra <code>ls</code> e fica assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_16-50-25.png" alt="eza"  loading="lazy" /></p>
<p>Não é só isso, existem bibliotecas modernas, pra diversas linguagens, como <a href="https://github.com/charmbracelet/bubbletea"target="_blank" rel="noopener"><strong>BubbleTea</strong></a>, que é um framework pra construir TUIs. Chequem o GitHub deles mas tem as ferramentas pra fazer interfaces assim:</p>
<p><img src="https://camo.githubusercontent.com/e2b13cfb4ea64e98028ab21e0dca97a6af46d8eeb78ef092c5cd4669ea7b7bef/68747470733a2f2f73747566662e636861726d2e73682f627562626c657465612f627562626c657465612d6578616d706c652e676966" alt="BubbleTea"  loading="lazy" /></p>
<p>E se quiser só um widget simples pra complementar um script Bash que está fazendo, eles tem o <a href="https://github.com/charmbracelet/gum"target="_blank" rel="noopener"><strong>Gum</strong></a>, que permite interfaces assim:</p>
<p><img src="https://camo.githubusercontent.com/cea695e2df946b14838196a5cfb7d6608f03387ba42c7a7fb5afa6432371635c/68747470733a2f2f7668732e636861726d2e73682f7668732d31715935375272516c584375796473456744703638472e676966" alt="Gum"  loading="lazy" /></p>
<p>E pra usar é só instalar o binário e no seu script fazer linhas assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># exemplos de Gum</span>
</span></span><span class="line"><span class="cl">gum choose <span class="s2">&#34;fix&#34;</span> <span class="s2">&#34;feat&#34;</span> <span class="s2">&#34;docs&#34;</span> <span class="s2">&#34;style&#34;</span> <span class="s2">&#34;refactor&#34;</span> <span class="s2">&#34;test&#34;</span> <span class="s2">&#34;chore&#34;</span> <span class="s2">&#34;revert&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">gum input --placeholder <span class="s2">&#34;scope&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">gum confirm <span class="s2">&#34;Commit changes?&#34;</span> <span class="o">&amp;&amp;</span> git commit -m <span class="s2">&#34;</span><span class="nv">$SUMMARY</span><span class="s2">&#34;</span> -m <span class="s2">&#34;</span><span class="nv">$DESCRIPTION</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E se usa <a href="https://akitaonrails.com/tags/omarchy/"target="_blank" rel="noopener"><strong>Omarchy</strong></a> eles ainda trazem uma funcionalidade extra pra TUIs. Basta clicar &ldquo;SUPER+ALT+SPACE&rdquo; pra trazer o menu principal, depois escolher &ldquo;INSTALL&rdquo; e &ldquo;TUI&rdquo;. Ou simplesmente abrir o terminal e executar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>$OMARCHY_PATH/bin/omarchy-tui-install</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-08_23-22-50.png" alt="omarchy-tui-install"  loading="lazy" /></p>
<p>Ele vai pedir um nome pro App e a linha de comando pra executar. Dá pra escolher icones também no <a href="https://dashboardicons.com/"target="_blank" rel="noopener">Dashboard Icons</a>. Registrando dessa forma, quando chamar o launcher Rofi com &ldquo;SUPER+SPACE&rdquo; e digitar &ldquo;lazy&rdquo; vai aparecer o LazyDocker como se fosse um app normal:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/hdmi-a-3.png" alt="Rofi LazyDocker"  loading="lazy" /></p>
<p>E como em Hyprland não tem barra de título nem nada, apps TUI ou webapps (tem <code>omarchy-webapp-install</code> também) abrem como se fossem apps &ldquo;nativos&rdquo;:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-09_00-49-28.png" alt="tiles windows"  loading="lazy" /></p>
<p>Leiam as seções de <a href="https://learn.omacom.io/2/the-omarchy-manual/59/tuis"target="_blank" rel="noopener">TUIs</a> e <a href="https://learn.omacom.io/2/the-omarchy-manual/63/web-apps"target="_blank" rel="noopener">Web-Apps</a> no manual do Omarchy.</p>
<p>Obviamente, isso é só se você é daqueles que prefere a sensação de estar executando &ldquo;Apps&rdquo;, mas é a mesma coisa se abrir um Terminal e simplesmente digitar o <code>lazydocker</code> na linha de comando - que é minha preferência. O que esses scripts do Omarchy fazem é criar um arquivo <code>.desktop</code> em <code>~/.local/share/applications</code>. O exemplo do <code>LazyDocker.desktop</code> gera isto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>❯ cat ~/.local/share/applications/LazyDocker.desktop
[Desktop Entry]
Version=1.0
Name=LazyDocker
Comment=LazyDocker
Exec=alacritty --class TUI.tile -e lazydocker
Terminal=false
Type=Application
Icon=/home/akitaonrails/.local/share/applications/icons/LazyDocker.png
StartupNotify=true</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se não quiser mais este launcher é só apagar o arquivo ou chamar o script <code>$OMARCHY_PATH/bin/omarchy-tui-remove</code>.</p>
<p>Esse recurso é particularmente interessante no Hyprland porque diferente de GNOME ou KDE, a janela não tem barra superior de título, então não entrega que você está só abrindo um terminal ou navegador web. É assim que ele já vem pré-configurado com coisas como ChatGPT ou Grok parecendo que são apps &ldquo;nativos&rdquo;, mas na verdade são só janelas de Chromium abrindo direto as URLs de cada um:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-09_00-54-52.png" alt="WebApps Omarchy"  loading="lazy" /></p>
<h2>Alguns TUIs que eu gosto<span class="hx:absolute hx:-mt-20" id="alguns-tuis-que-eu-gosto"></span>
    <a href="#alguns-tuis-que-eu-gosto" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Na minha opinião, já que não tem Apps com GUIs bonitas pra Linux, é melhor mesmo usar os respectivos web-apps como Canva ou ChatGPT dessa forma, mas mais interessante é ter TUIs mesmo. Como falei, hoje em dia não é difícil fazer TUIs bonitas. Pra um programador, a vantagem é não tem que lidar, primeiro com frameworks de front-end, segundo, ter que fazer deploy em algum lugar na internet.</p>
<p>TUIs são leves, usam poucos recursos na máquina, são fáceis pra qualquer programador fazer, e você pode ter um home server ou um servidor num cloud qualquer, acessar via SSH e acessar a TUI, sem ter que lidar com X11 ou RDP ou qualquer coisa mais pesada só pra ter um GUI.</p>
<p>Alguns TUIs são óbvios, no <a href="https://akitaonrails.com/2025/09/07/omarchy-2-0-lazyvim-lazyextras/"target="_blank" rel="noopener">post anterior</a> já falei de <a href="https://www.lazyvim.org/"target="_blank" rel="noopener"><strong>LazyVim</strong></a> e como ele é um editor de textos tão competente e completo quando um VS Code, usando só uma fração dos recursos da máquina. Todo mundo deve conhecer ferramentas como HTOP ou BTOP. Além dos <a href="https://github.com/jesseduffield/lazygit"target="_blank" rel="noopener">LazyGit</a> ou <a href="https://github.com/jesseduffield/lazydocker"target="_blank" rel="noopener">LazyDocker</a> também. Esses todos já vem no Omarchy.</p>
<p>Mas tem muito mais, por exemplo, <a href="https://github.com/danvergara/dblab"target="_blank" rel="noopener"><strong>dblab</strong></a> que é um TUI cliente de banco de dados como MySQL ou Postgres:</p>
<p><img src="https://github.com/danvergara/dblab/raw/main/screenshots/dblab-cover.png" alt="dblab"  loading="lazy" /></p>
<p>Outro similar é <a href="https://github.com/jorgerojas26/lazysql"target="_blank" rel="noopener">LazySQL</a>, feito em Go:</p>
<p><img src="https://github.com/jorgerojas26/lazysql/raw/main/images/lazysql.png" alt="LazySQL"  loading="lazy" /></p>
<p>Ou se você prefere ferramentas feitas em Rust, tem o <a href="https://github.com/achristmascarl/rainfrog"target="_blank" rel="noopener"><strong>rainfrog</strong></a>:</p>
<p><img src="https://github.com/achristmascarl/rainfrog/raw/main/vhs/demo.gif" alt="rainfrog"  loading="lazy" /></p>
<p>Pra quem não consegue usar CURL na linha de comando e prefere usar Postman pra chamar e explorar APIs, tem o TUI <a href="https://github.com/darrenburns/posting"target="_blank" rel="noopener"><strong>Posting</strong></a> que faz a mesma coisa:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/422760155-78359ab0-5e0c-4c0b-a60b-dce06b11bbf5.png" alt="Posting"  loading="lazy" /></p>
<p>Pra nós que rodamos muitos containers Docker, já falei do LazyDocker, mas tem também o <a href="https://github.com/mrjackwills/oxker"target="_blank" rel="noopener"><strong>oxker</strong></a>:</p>
<p><img src="https://github.com/mrjackwills/oxker/raw/main/.github/demo_01.webp" alt="oxker"  loading="lazy" /></p>
<p>Se usar Discord, tem o <a href="https://github.com/ayn2op/discordo"target="_blank" rel="noopener"><strong>discordo</strong></a>:</p>
<p><img src="https://github.com/ayn2op/discordo/raw/main/.github/preview.png" alt="Discordo"  loading="lazy" /></p>
<p>Quem faz muito ricing de Linux já teve que gravar ISOs em Pen Drives dezenas de vezes, pra isso tem o <code>dd</code> na linha de comando, mas tem um TUI mais legal que é o <a href="https://github.com/ifd3f/caligula"target="_blank" rel="noopener"><strong>Caligula</strong></a>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2025/09/09/omarchy-2-0-tuis/caligula-burning.png" alt="Caligula gravando uma imagem de disco no terminal: barra “Burning… 251.7 MB” no topo, um gráfico de velocidade de escrita oscilando até 32 MB/s ao longo de ~12 segundos, e um painel de Stats mostrando entrada my_cool.img.lz4, saída /dev/sdb, média de escrita de 20.2 MB/s e ETA de 24 segundos."  loading="lazy" /></p>
<p>Se seu SSD está ficando cheio e você não sabe onde diabos que tá ocupando tanto espaço, tem várias ferramentas pra analisar e te mostrar, um deles é o <a href="https://github.com/dundee/gdu"target="_blank" rel="noopener"><strong>gdu</strong></a>:</p>
<p><img src="https://camo.githubusercontent.com/d8fa7d2f7bdd10dce45a81c2accf26d597b300b82e01b97a1288ff2f1fe06c57/68747470733a2f2f61736369696e656d612e6f72672f612f3338323733382e737667" alt="gdu"  loading="lazy" /></p>
<p>E o último que achei legal pela nostalgia é o <a href="https://github.com/andmarti1424/sc-im"target="_blank" rel="noopener"><strong>sc-im</strong></a>, pense em Excel como TUI ou - pra nós que viemos dos anos 80 - pense Lotus 1-2-3 mas com key bindings de Vim:</p>
<p><img src="https://github.com/andmarti1424/sc-im/raw/main/screenshots/scim-plot-graph.gif?raw=true" alt="sc-im"  loading="lazy" /></p>
<p>Pra que abrir Google Spreadsheets só pra fazer um Todo list se dá pra fazer no Terminal?? TUIs são excepcionais!</p>
<p>Se quiser conhecer mais TUIs olhe o <a href="https://github.com/rothgar/awesome-tuis/?tab=readme-ov-file"target="_blank" rel="noopener"><strong>awesome-tuis</strong></a> no GitHub:</p>
<p><a href="https://github.com/rothgar/awesome-tuis/?tab=readme-ov-file"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2025/09/09/omarchy-2-0-tuis/awesome-tuis-banner.png" alt="awesome tuis"  loading="lazy" /></a>
De novo: zero necessidade de front-ends web pesadas pra coisas simples. Nada supera a simplicidade de uma linha de comando. E com bibliotecas como BubbleTea ou Gum, está muito fácil pra qualquer um fazer um app bonito. E com Hyprland e Omarchy, fica tudo integrado lado-a-lado de qualquer outro app com GUI.</p>
<p>Filosofando um pouco, a história das GUIs começa com interfaces gráficas <em>skeumorphic</em> que tentam imitar objetos do nosso dia a dia, em particular parecendo pseudo-3D, como era um Windows 95. Chegou nos anos 2000 e começaram a migrar pra interfaces <em>flat</em> ou <em>minimalistas</em>, tirando completamente o skeumorphismo, deixando tudo plano. Foi a partir do Metro do Windows 8, principalmente. E eu acho que isso converge pra estilo mais de TUI, dando uma volta completa, voltando a como era nos terminais dos anos 70. Eu particularmente acho isso fascinante.</p>
]]></content:encoded><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>linux</category></item><item><title>Omarchy 2.0 - Mise pra organizar ambientes de desenvolvimento</title><link>https://akitaonrails.github.io/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/</guid><pubDate>Sun, 07 Sep 2025 16:40:00 -0300</pubDate><description>&lt;p&gt;Continuando meus posts sobre &lt;a href="https://www.akitaonrails.com/tags/omarchy"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt; mais um post introdutório, mas agora sobre &lt;a href="https://mise.jdx.dev/getting-started.html"target="_blank" rel="noopener"&gt;Mise-en-place&lt;/a&gt; que já vem pré-instalado. No Omarchy, se digitar &amp;ldquo;Super+Alt+Espaço&amp;rdquo; vai abrir o menu principal. Escolha &amp;ldquo;Install&amp;rdquo; e depois &amp;ldquo;Development&amp;rdquo; e vai aparecer várias linguagens/frameworks que pode instalar, como Ruby on Rails ou Go.&lt;/p&gt;
&lt;p&gt;Mas não precisa usar estes menus. Vamos entender.&lt;/p&gt;
&lt;p&gt;Num Arch Linux ou Ubuntu da vida, um amador instalaria ruby ou python fazendo algo assim:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;# arch
yay -S ruby python3
# ubuntu
apt install ruby python3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Este é o jeito ERRADO.&lt;/strong&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<p>Continuando meus posts sobre <a href="https://www.akitaonrails.com/tags/omarchy"target="_blank" rel="noopener">Omarchy</a> mais um post introdutório, mas agora sobre <a href="https://mise.jdx.dev/getting-started.html"target="_blank" rel="noopener">Mise-en-place</a> que já vem pré-instalado. No Omarchy, se digitar &ldquo;Super+Alt+Espaço&rdquo; vai abrir o menu principal. Escolha &ldquo;Install&rdquo; e depois &ldquo;Development&rdquo; e vai aparecer várias linguagens/frameworks que pode instalar, como Ruby on Rails ou Go.</p>
<p>Mas não precisa usar estes menus. Vamos entender.</p>
<p>Num Arch Linux ou Ubuntu da vida, um amador instalaria ruby ou python fazendo algo assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># arch
yay -S ruby python3
# ubuntu
apt install ruby python3</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>Este é o jeito ERRADO.</strong></p>
<p>Esses comandos vão instalar a versão mais nova de cada linguagens e toda vez que atualizar o sistema com <code>yay -Syu</code> ou <code>apt upgrade</code>, vai puxar as versões mais novas ainda.</p>
<p>Só que se você desenvolve projetos de verdade, <strong>não quer que as versões mudem</strong>.</p>
<p>A versão do deploy no servidor no cloud e a versão na sua máquina local <strong>TEM QUE SER AS MESMAS</strong>.</p>
<p>Se está usando Ruby v3.0.7 e Node.js 22.19.0, não pode ficar refém que quando atualizar seu sistema, do nada vai aparecer Ruby 3.4.5 e Node 24.7.0. Tudo vai começar a quebrar e você vai ficar super confuso sem saber porque. Esse é o erro mais primário que um júnior comete.</p>
<p>Pra evitar isso, cada projeto que está trabalhando PRECISA ESTAR TRAVADO EM VERSÕES FIXAS.</p>
<p>O jeito mais fácil de fazer isso em 2025 é usando <strong>MISE</strong>. Como falei, ele já vem instalado e ativado no Omarchy, mas se estiver usando outra distro basta instalar Mise manualmente:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S mise

# .bashrc
eval $(mise activate bash)</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Adapte isso pra ZSH, Fish ou outro shell que estiver usando, leia a <a href="https://mise.jdx.dev/installing-mise.html"target="_blank" rel="noopener">documentação</a></p>
<p>Agora navegue pro diretório do seu projeto, por exemplo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>cd ~/Projects/AkitaOnRails.com</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E trave as versões:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mise use ruby@3.2.3
mise use node@14.21.3</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso vai criar o arquivo <code>.tool-versions</code> que você deve adicionar no git do seu repositório:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>❯ cat .tool-versions
ruby 3.2.3
nodejs 14.21.3

❯ git add .tool-versions</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E pronto, toda vez que fizer <code>cd</code> pro diretório, o Mise vai ativar exatamente a versão correta pra esse projeto. Veja:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>AkitaOnRails.com [ master][$!?⇡][ v24.7.0][💎 v3.2.3]
❯ ruby -v
ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [x86_64-linux]

AkitaOnRails.com [ master][$!?⇡][ v24.7.0][💎 v3.2.3]
❯ which ruby
/home/akitaonrails/.local/share/mise/installs/ruby/3.2.3/bin/ruby</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Note que, se estiver usando o prompt <a href="https://akitaonrails.com/2025/09/07/omarchy-2-0-zsh-configs/"target="_blank" rel="noopener">Starship</a> como expliquei no post anterior, com um preset como Pure Prompt, ele mostra no prompt as versões de cada linguagem pra que fique fácil de ver se estiver numa versão errada.</p>
<p>No caso, se leu com atenção, já deve ter notado que <strong>SIM, ESTOU NA VERSÃO ERRADA</strong> do Node.js. Olhem como no prompt ele fala que estou usando Node 24.7.0 mas no arquivo <code>.tool-versions</code> ele pede 14.21.3.</p>
<p>O motivo de estar &ldquo;missing&rdquo; é porque esta máquina é recém-instalada, mas o projeto é velho.</p>
<p>Então vamos checar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>AkitaOnRails.com [ master][$!?⇡][ v24.7.0][💎 v3.2.3]
❯ mise list
Tool    Version            Source                                              Requested
go      1.25.0             ~/.config/mise/config.toml                          latest
node    14.21.3 (missing)  /mnt/data/Projects/AkitaOnRails.com/.tool-versions  14.21.3
node    22.18.0
python  3.13.7
ruby    3.2.3              /mnt/data/Projects/AkitaOnRails.com/.tool-versions  3.2.3
ruby    3.4.5</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Veja como na listagem de <code>mise list</code> ele fala que 14.21.3 está &ldquo;missing&rdquo;. Então vamos instalar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>AkitaOnRails.com [ master][$!?⇡][ v24.7.0][💎 v3.2.3]
❯ mise use node@14.21.3
mise /mnt/data/Projects/AkitaOnRails.com/.tool-versions tools: node@14.21.3

AkitaOnRails.com [ master][$!?⇡][ v14.21.3][💎 v3.2.3]
❯</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Com o comando <code>mise use</code> podemos pedir pra instalar e usar uma versão em particular. Se já não estiver instalado, ele vai instalar. Note como depois disso o prompt do Starship mudou pra refletir que agora estamos usando 14.21.3. Esse é o jeito certo.</p>
<p>Se não estiver necessariamente num diretório de projeto com versões travadas, ainda assim é possível rodar comandos usando uma versão específica, assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mise exec ruby@3.2.1 -- ruby ...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Digamos que queira gerar um projeto de Rails numa versão específica de Ruby:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mise exec ruby@3.2.3 -- rails new todo-exercise</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mesma coisa vale pra generators em Node, como Next.js ou qualquer outro framework.</p>
<p>Não chequei se o LazyVim no Omarchy já vem configurado assim, mas caso não venha, pro NeoVim suportar Mise precisa adicionar isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="c1">-- Prepend mise shims to PATH</span>
</span></span><span class="line"><span class="cl"><span class="n">vim.env</span><span class="p">.</span><span class="n">PATH</span> <span class="o">=</span> <span class="n">vim.env</span><span class="p">.</span><span class="n">HOME</span> <span class="o">..</span> <span class="s2">&#34;/.local/share/mise/shims:&#34;</span> <span class="o">..</span> <span class="n">vim.env</span><span class="p">.</span><span class="n">PATH</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Basta colocar isso em <code>~/.config/nvim/lua/config/mise.lua</code> que ele deve carregar o path correto. Pra integrar com outros editores, cheque <a href="https://mise.jdx.dev/ide-integration.html"target="_blank" rel="noopener">esta documentação</a>. Tem um MONTE de opções avançadas que é bom ler a respeito na <a href="https://mise.jdx.dev/dev-tools/"target="_blank" rel="noopener">seção de Dev-Tools</a> mas o básico é o que listei aqui.</p>
<h2>E bancos de dados??<span class="hx:absolute hx:-mt-20" id="e-bancos-de-dados"></span>
    <a href="#e-bancos-de-dados" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O mesmo vale pra bancos de dados. Cada projeto deve estar travado numa versão específica idêntica à que está rodando no servidor de produção e nunca deve depender dos pacotes do sistema operacional. Dá pra usar mise pra isso mas o mais recomendado é usar Docker. Cada projeto <strong>DEVE</strong> ter um <code>docker-compose.yml</code> pra subir somente os bancos de dados. Não precisa subir containers pra linguagens, pra isso é melhor usar Mise.</p>
<p>Se não entende Docker, eu fiz videos ensinando:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/85k8se4Zo70"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

</br>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/-yGHG3pnHLg"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Somando Mise + Docker Compose + LazyVim, é tudo que se precisa pra ser um desenvolvedor web produtivo, além de usar os recursos da sua máquina de maneira eficiente. Todo desenvolvedor PRECISA aprender este combo de opções. Omarchy já trás tudo pré-instalado, por isso tem sido minha recomendação pra todo iniciante.</p>
<p>Não precisa se preocupar: Arch Linux (com archinstall), é tão fácil de instalar quanto um Ubuntu ou Linux Mint e o Hyprland do Omarchy é muito mais bonito e fluido que um MacOS. O melhor dos mundos. Aprenda hoje!</p>
]]></content:encoded><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>containers</category></item><item><title>Omarchy 2.0 - LazyVim - LazyExtras</title><link>https://akitaonrails.github.io/2025/09/07/omarchy-2-0-lazyvim-lazyextras/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/07/omarchy-2-0-lazyvim-lazyextras/</guid><pubDate>Sun, 07 Sep 2025 16:00:00 -0300</pubDate><description>&lt;p&gt;Continuando meus posts de dicas sobre &lt;a href="https://akitaonrails.com/tags/omarchy/"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt; resolvi postar sobre &lt;a href="https://www.lazyvim.org/"target="_blank" rel="noopener"&gt;LazyVim&lt;/a&gt; que já vem pré-instalado.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://user-images.githubusercontent.com/292349/213447056-92290767-ea16-430c-8727-ce994c93e9cc.png" alt="LazyVim" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Mesmo se não usa Omarchy, recomendo &lt;a href="https://www.lazyvim.org/installation"target="_blank" rel="noopener"&gt;instalar&lt;/a&gt; LazyVim, só fazer isso:&lt;/p&gt;
&lt;div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code"&gt;
&lt;div&gt;&lt;pre&gt;&lt;code&gt;# required
mv ~/.config/nvim{,.bak}
# optional but recommended
mv ~/.local/share/nvim{,.bak}
mv ~/.local/state/nvim{,.bak}
mv ~/.cache/nvim{,.bak}
git clone https://github.com/LazyVim/starter ~/.config/nvim
rm -rf ~/.config/nvim/.git
nvim&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"&gt;
&lt;button
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
title="Copy code"
&gt;
&lt;div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"&gt;&lt;/div&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pronto, é só isso. NeoVim, pra quem não sabe, é um fork mais moderno do antigo Vim (por isso o comando é &lt;code&gt;nvim&lt;/code&gt;, reservando &lt;code&gt;vim&lt;/code&gt; pro antigo). Ele troca o antigo VimScripts por scripts em Lua e tem várias otimizações e funcionalidades de qualidade de vida melhores. Hoje em dia, não tem porque usar o Vim antigo mais.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Continuando meus posts de dicas sobre <a href="https://akitaonrails.com/tags/omarchy/"target="_blank" rel="noopener">Omarchy</a> resolvi postar sobre <a href="https://www.lazyvim.org/"target="_blank" rel="noopener">LazyVim</a> que já vem pré-instalado.</p>
<p><img src="https://user-images.githubusercontent.com/292349/213447056-92290767-ea16-430c-8727-ce994c93e9cc.png" alt="LazyVim"  loading="lazy" /></p>
<p>Mesmo se não usa Omarchy, recomendo <a href="https://www.lazyvim.org/installation"target="_blank" rel="noopener">instalar</a> LazyVim, só fazer isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># required
mv ~/.config/nvim{,.bak}

# optional but recommended
mv ~/.local/share/nvim{,.bak}
mv ~/.local/state/nvim{,.bak}
mv ~/.cache/nvim{,.bak}

git clone https://github.com/LazyVim/starter ~/.config/nvim

rm -rf ~/.config/nvim/.git

nvim</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto, é só isso. NeoVim, pra quem não sabe, é um fork mais moderno do antigo Vim (por isso o comando é <code>nvim</code>, reservando <code>vim</code> pro antigo). Ele troca o antigo VimScripts por scripts em Lua e tem várias otimizações e funcionalidades de qualidade de vida melhores. Hoje em dia, não tem porque usar o Vim antigo mais.</p>
<p>Usando Lua dá pra configurar o Nvim como quiser. Mas dá muito trabalho configurar tudo do zero. É um bom exercício, mas sendo prático, não compensa pro dia a dia. É melhor instalar um setup pré-configurado como os antigos <a href="https://www.lunarvim.org/"target="_blank" rel="noopener">LunarVim</a> que eu usava antes e até recomendei em alguns videos de Linux do meu canal, ou o <a href="https://astronvim.com/"target="_blank" rel="noopener">AstroNvim</a> ou o <strong>LazyVim</strong> que atualmente é meu favorito. Qualquer um deles é um bom começo e vai ser preferência pessoal qual vai escolher.</p>
<p>Cada plugin que eles instalam tem diversas funcionalidades e combinações de teclas (hotkeys) próprias que precisa ler na documentação pra saber o que faz o que. Recomendo ir na seção <a href="https://www.lazyvim.org/plugins"target="_blank" rel="noopener">plugins</a> do site oficial e ler um por um. Tem muita coisa que você nem espera e todos são muito úteis.</p>
<p>LazyVim sozinho já ajuda bastante porque ele abre pop-ups documentando algumas das hotkeys. Por exemplo, o que se chama de comando <strong>Leader</strong> em LazyVim é a &ldquo;barra de espaço&rdquo;. Quando apertar, vai aparecer esse menu de contexto:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-44-17.png" alt="Leader context menu"  loading="lazy" /></p>
<p>A partir daqui, se digitar, digamos &ldquo;b&rdquo;, vai aparece outro menu de contexto:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-46-48.png" alt="Buffer context menu"  loading="lazy" /></p>
<p>E se digitar &ldquo;b&rdquo; de novo, ele vai trocar pro próximo arquivo já aberto no Buffer. <strong>Buffer</strong> é o nome em Vim onde ficam os arquivos já abertos. Deletar do Buffer é o equivalente a &ldquo;fechar o arquivo&rdquo;.</p>
<p>Da próxima vez, não precisa olhar os menus, só digitar rápido de uma só vez: &ldquo;Espaço+b+b&rdquo;. E é assim que você vai decorando os comandos que mais usa.</p>
<p>Alguns comandos que vale a pena já saber são: <strong>Espaço+Espaço&quot;</strong> (duas vezes), e vai abrir o menu que abre arquivos. digite algumas letras do nome do arquivo e vai filtrando dinamicamente:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-49-35.png" alt="find files"  loading="lazy" /></p>
<p>Ou então &ldquo;Espaço+e&rdquo; pra abrir o Explorer NeoTree. Digite &ldquo;?&rdquo; pra abrir um popup com os comandos que pode usar pra criar novos sub-diretórios ou arquivos no subdiretório:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-51-08.png" alt="NeoTree"  loading="lazy" /></p>
<p>Quando aprender os demais comandos e plugins, vai notar que nem precisa abrir NeoTree, ele é mais pra quando quiser explorar visualmente mesmo. Mas pro dia a dia comando como &ldquo;:e&rdquo; devem ser suficiente. Aliás, &ldquo;:&rdquo; (dois pontos) é o comando pra executar funções do NeoVim. Por exemplo &ldquo;:q&rdquo; é quit, ou &ldquo;:w&rdquo; é write e &ldquo;:wq&rdquo; é write e quit ao mesmo tempo.</p>
<p>Se quiser aprender mais a fundo sobre NeoVim, recomendo o canal do YouTube do camarada <a href="https://www.youtube.com/@EustaquioRangel"target="_blank" rel="noopener">Eustáquio Rangel</a> que é veterano de Linux, Rails e Vim e ele ensina NeoVim do zero (sem LazyVim).</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_16-09-53.png" alt="TaQ"  loading="lazy" /></p>
<p>Agora, digamos que já aprendeu o básico de NeoVim e LazyVim, e agora quer começar a mexer nos seus projetos de PHP, Java, C#, Ruby, Python ou o que for. Vai notar que o LazyVim não tem nenhuma funcionalidade pra nenhuma delas.</p>
<p>O que fazer agora? Instalar VS Code?? <strong>NÃO!!</strong></p>
<p>Isso porque você não executou <a href="https://www.lazyvim.org/extras"target="_blank" rel="noopener">:LazyExtras</a>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-35-36.png" alt="LazyExtras command"  loading="lazy" /></p>
<p>Digite exatamente assim e veja isto:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-36-01.png" alt="Enabled Plugins"  loading="lazy" /></p>
<p>Essa janela parece complicada mas é só uma lista de plugins dividida em seções. No começo aparecem os plugins já instalados e habilitados. Caso não queira algum deles, basta usar as setas pra descer o cursor até uma delas e apertar &ldquo;x&rdquo; pra desmarcar. Mas deixe essa seção como está. Vamos descer até a seção de &ldquo;Languages&rdquo;:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-36-43.png" alt="Languages section"  loading="lazy" /></p>
<p>É nesta seção que estão todas as linguagens que você pode habilitar o suporte. Basta descer com as setas e ir marcando com &ldquo;x&rdquo; quais quer instalar. E tem de tudo, desde Angular, Vue, Erlang, Elixir, Rust, Zig, Haskell e muito mais.</p>
<p>Ao lado de cada linguagem tem o grupo de plugins individuais que ele vai instalar. Pra saber o que cada uma faz, digite o nome delas no Google e ache a página com a documentação, onde vai ter hotkeys e configurações extras que pode fazer.</p>
<p>Com isso vai ganhar coisas como Linters, syntax highlighting, LSP, snippets e muito mais.</p>
<p>E se quiser instalar plugins a mais que não tem listado, dá pra adicionar manualmente. Leia a seção de <a href="https://www.lazyvim.org/configuration/plugins#-adding-plugins"target="_blank" rel="noopener">Adding Plugins</a> na documentação.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_16-05-15.png" alt="Linter"  loading="lazy" /></p>
<p>LazyVim + LazyExtras é 90% de tudo que precisa pro seu dia a dia de desenvolvimento de software. É mais leve e mais rápido que um VS Code, usando muito menos memória e vai ser muito melhor especialmente em máquinas mais antigas. Não tenha preguiça de aprender Vim, um programador de verdade não deveria ficar num VS Code só porque tem preguiça de aprender hotkeys extras.</p>
]]></content:encoded><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>tutoriais</category></item><item><title>Omarchy 2.0 - ZSH Configs</title><link>https://akitaonrails.github.io/2025/09/07/omarchy-2-0-zsh-configs/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/09/07/omarchy-2-0-zsh-configs/</guid><pubDate>Sun, 07 Sep 2025 15:00:00 -0300</pubDate><description>&lt;p&gt;Estou gostando bastante de usar &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt; como meu desktop manager. Leia &lt;a href="https://akitaonrails.com/2025/08/29/new-omarchy-2-0-install/"target="_blank" rel="noopener"&gt;meu post anterior&lt;/a&gt; pra ver como eu instalei e fiz modificações pra servir o meu setup. Seguindo nessa linha, o Omarchy vem por padrão com shell Bash. Mas eu prefiro ZSH. Bash é perfeitamente usável, é só preferência pessoal mesmo. Tem gente que prefere Fish ou outros. Mas o Omarchy vem só com Bash por enquanto, então resolvi modificar o setup pra suportar meu ZSH.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Estou gostando bastante de usar <a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy</a> como meu desktop manager. Leia <a href="https://akitaonrails.com/2025/08/29/new-omarchy-2-0-install/"target="_blank" rel="noopener">meu post anterior</a> pra ver como eu instalei e fiz modificações pra servir o meu setup. Seguindo nessa linha, o Omarchy vem por padrão com shell Bash. Mas eu prefiro ZSH. Bash é perfeitamente usável, é só preferência pessoal mesmo. Tem gente que prefere Fish ou outros. Mas o Omarchy vem só com Bash por enquanto, então resolvi modificar o setup pra suportar meu ZSH.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-16-57.png" alt="Meu ZSH"  loading="lazy" /></p>
<p>Se quiser mudar pra ZSH, é fácil, só fazer isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">yay -S zsh zoxide
</span></span><span class="line"><span class="cl">chsh -s <span class="k">$(</span>which zsh<span class="k">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Logout, login e pronto. Mas agora seu shell vai estar vazio. Pra baixar minha config faça isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://github.com/akitaonrails/omarchy-zsh.git ~/.config/zsh
</span></span><span class="line"><span class="cl">ln -s ~/.config/zsh/.zshrc ~/.zshrc </span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Tem duas coisas que precisa modificar. Em <code>.zshrc</code> remova esta linha:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>source ~/.config/zsh/mounts</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso é só pra eu checar meus mounts de NFS pro meu NAS. Pra você não serve pra nada então pode tirar.</p>
<p>A segunda coisa é criar um novo arquivo para segredos:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>touch ~/.config/zsh/secrets
chmod 600 ~/.config/zsh/secrets</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>É nele que vai colocar coisas como suas chaves de OpenAI ou Google Cloud ou qualquer coisa assim. Por exemplo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># ~/.config/zsh/secrets
export OPENAI_API_KEY=&#34;sk-xx-v1-xxx...xxxxx&#34;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Assim seus segredos ficam separados das suas configurações e podemos dar <code>git push</code> pra um repositório sem se preocupar que algo possa vazar no futuro. Sempre mantenha segredos, senhas, chaves, separados localmente. Isso já está no <code>.gitignore</code> então está seguro.</p>
<p>De bônus, no <code>~/.config/init</code> adicionei suporte ao <a href="https://atuin.sh/"target="_blank" rel="noopener">Atuin</a> que é uma ferramenta que serve pra sincronizar todo histórico de comandos que fez no seu shell pra um repositório no &ldquo;cloud&rdquo; (leia a documentação, você pode criar seu próprio server local também). O repositório é encriptado, então não é inseguro, mesmo se seu histórico contenha chaves secretas nos comandos.</p>
<p>Instale assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S atuin
atuin register -u &lt;seu username&gt; -e &lt;seu email&gt;
atuin import auto
atuin sync</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Logo que registrar o Atuin vai gerar uma chave de encriptação aleatório. Garanta que guardou essa chave num lugar seguro como 1password, Bitwarden ou outro cofre seguro!! Sem ela não vai conseguir decriptar numa nova instalação. Se esquecer, ainda dá pra ver antes de reinstalar, por exemplo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>atuin key</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se reinstalar sua máquina ou instalar uma nova máquina e quiser seus históricos de volta, basta instalar o Atuin e fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>atuin login -u &lt;seu username&gt;
atuin sync</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ele vai pedir sua senha e chave de encriptação e trazer todo seu histórico de volta.</p>
<p>Segundo minha config, basta digitar <code>Ctrl+R</code> pra chamar a procura do histórico (que a partir de agora vai estar num sqlite na sua máquina). Leia a <a href="https://docs.atuin.sh/"target="_blank" rel="noopener">documentação</a> pra mais funcionalidades.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-09-07_15-17-20.png" alt="Ctrl&#43;R"  loading="lazy" /></p>
<p>O DHH configurou o prompt do <strong>Starship</strong> usando o jeito antigo de variável <code>PS1</code>. Mas o Starship já tem vários prompt bem bonitos fáceis de usar como &ldquo;presets&rdquo;. Eu escolhi o Pure Prompt, que eu gosto, mas tem vários outros. Se gostar de algo mais chamativo e colorido, tem este <a href="https://starship.rs/presets/pastel-powerline"target="_blank" rel="noopener">Pastel Powerline</a>:</p>
<p><img src="https://starship.rs/presets/img/pastel-powerline.png" alt="Pastel Powerline"  loading="lazy" />
Escolha o de sua preferência na <a href="https://starship.rs/presets/"target="_blank" rel="noopener">página de Presets</a> e mude em <code>~/.config/zsh/prompt</code> no lugar desta linha:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>starship preset bracketed-segments -o ~/.config/starship.toml</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Por fim, eu deixei alguns ENVs em <code>~/.config/zsh/envs</code> que funcionam pros meus testes de Ollama e coisas assim, mas é bom você saber que estão lá pra não achar estranho se seu Ollama estiver se comportando estranho, edite o arquivo <code>~/.config/zsh/envs</code> pra ter os envs de sua preferência:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># envs
export OPENAI_API_BASE=&#34;https://openrouter.ai/api/v1&#34;
export DEFAULT_MODEL=&#34;o1-mini&#34;;
export OLLAMA_API_BASE=http://127.0.0.1:11434
export OLLAMA_HOME=http://127.0.0.1:11434
export OLLAMA_MODELS=/mnt/gigachad/ollama/models</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Também modifique o arquivo <code>~/.config/zsh/aliases</code> pra ter alias que você prefira:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># aliases
alias monhd=&#34;sudo ddcutil -d 1 setvcp 60 0x12&#34;
alias mondp=&#34;sudo ddcutil -d 1 setvcp 60 0x0F&#34;

alias sgpt=&#39;docker run --rm -e OPENAI_API_BASE=${OPENAI_API_BASE} -e OPENAI_API_KEY=${OPENROUTER_API_KEY} ghcr.io/tbckr/sgpt:latest txt &#39;

alias git=&#39;nocorrect git&#39;
git config --global alias.a &#39;add&#39;
git config --global alias.ps &#39;push&#39;
git config --global alias.pl &#39;pull&#39;
git config --global alias.l &#39;log&#39;
git config --global alias.c &#39;commit -m&#39;
git config --global alias.s &#39;status&#39;
git config --global alias.co &#39;checkout&#39;
git config --global alias.b &#39;branch&#39;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Os primeiros dois aliases são pro meu setup de 2 monitores onde um dos monitores recebe sinal tanto da entrada HDMI quanto da entrada DisplayPort (tenho 2 GPUs). Se não sabia, dá pra controlar isso usando o shell. Leia <a href="https://jeancharles.quillet.org/posts/2021-08-20-How-to-use-ddcutil-to-switch-input-of-a-Dell-screen.html"target="_blank" rel="noopener">este post sobre ddcutil</a></p>
<p>Em seguida você ganha o comando <code>sgpt</code>. Omarchy já trás Docker instalado. Agora no shell você pode perguntar ao ChatGPT sem precisar ficar abrindo um navegador web pra isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sgpt &#34;qual é a sintaxe de rsync pra sincronizar dois diretórios?&#34;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Leia <a href="https://github.com/tbckr/sgpt"target="_blank" rel="noopener">documentação do SGPT</a> pra saber outras funcionalidades ou quais LLMs você pode escolher.</p>
<p>No final temos aliases pra Git. O Omarchy já tem alias pra fazer &ldquo;g&rdquo; ser &ldquo;git&rdquo; e com este que eu adicionei você pode fazer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>git add . # antigo
g a . # novo

git commit -m &#34;initial commit&#34; # antigo
g c &#34;initial commit&#34; # novo

git commit --amend -m &#34;initial commit&#34;
g ca &#34;initial commit&#34;

git push origin master
g ps origin master

git pull origin master
g pl origin master

git log
g l

# e assim por diante</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mais prático e menos verbose. Adicione mais aliases conforme seu workflow em <code>~/.config/aliases</code>.</p>
<p>E acho que é isso, agora sim, meu Omarchy está organizado do jeito que eu gosto. Faça suas próprias configurações pra tudo ficar do seu jeito também!</p>
]]></content:encoded><category>omarchy</category><category>ferramentas-de-desenvolvimento</category><category>automacao</category></item><item><title>Instalando Omarchy 2.0 do Zero - Anotações Pessoais</title><link>https://akitaonrails.github.io/2025/08/29/new-omarchy-2-0-install/</link><guid isPermaLink="true">https://akitaonrails.github.io/2025/08/29/new-omarchy-2-0-install/</guid><pubDate>Fri, 29 Aug 2025 16:00:00 -0300</pubDate><description>&lt;p&gt;Eu tenho recomendado o &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;Omarchy 2.0&lt;/a&gt; do DHH pra qualquer um que queira um ambiente de desenvolvimento leve, bonito e totalmente equipado. É um conjunto de configurações pra Hyprland rodando em cima de Arch Linux e vem com padrões inteligentes prontos pra usar. Assista o &lt;a href="https://www.youtube.com/watch?v=TcHY0AEd2Uw"target="_blank" rel="noopener"&gt;video tour&lt;/a&gt; mostrando as principais funcionalidades.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250828_043020.jpg" alt="meu omarchy" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;No meu caso, eu passei 10 anos usando Manjaro GNOME como meu daily driver. Manjaro que é um derivado de Arch. A razão era a instalação mais simples e configurações pré-prontas. Mas hoje em dia, com &lt;a href="TODO"&gt;archinstall&lt;/a&gt;, acho que não vale mais a pena. Sei que existem outros derivados, mas é melhor ficar no original mesmo.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Eu tenho recomendado o <a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy 2.0</a> do DHH pra qualquer um que queira um ambiente de desenvolvimento leve, bonito e totalmente equipado. É um conjunto de configurações pra Hyprland rodando em cima de Arch Linux e vem com padrões inteligentes prontos pra usar. Assista o <a href="https://www.youtube.com/watch?v=TcHY0AEd2Uw"target="_blank" rel="noopener">video tour</a> mostrando as principais funcionalidades.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250828_043020.jpg" alt="meu omarchy"  loading="lazy" /></p>
<p>No meu caso, eu passei 10 anos usando Manjaro GNOME como meu daily driver. Manjaro que é um derivado de Arch. A razão era a instalação mais simples e configurações pré-prontas. Mas hoje em dia, com <a href="TODO">archinstall</a>, acho que não vale mais a pena. Sei que existem outros derivados, mas é melhor ficar no original mesmo.</p>
<p>Pra quem é de Ubuntu ou derivados de Debian, Fedora, etc, vai ter uma pequena curva de aprendizado no gerenciador de pacotes, Pacman e Yay em vez de Apt ou Dnf, mas quando entenderem o AUR, nunca mais vão querer outra coisa. Tem literalmente tudo que você precisa, sem ter que lidar com repositórios de terceiros.</p>
<p>Demorei pra testar o Omarchy porque eu já usava Hyprland antes do Omarchy ter sido criado. O DHH já tinha o Omakub antes, que era um conjunto de scripts pra customizar um Ubuntu pra ser um bom ambiente de desenvolvimento. Eu gostava dele mas como preferia Manjaro, fiz um fork chamado Omakub-MJ. Depois disso resolvi desinstalar o GNOME e GDM e instalar um outro conjunto de scripts chamado <a href="https://www.ml4w.com/"target="_blank" rel="noopener">ML4W</a>, que deixa o Hyprland bem bonito também. Então o Omarchy não tinha tanta novidade, pra mim.</p>
<p>Só que eu uso o mesmo Manjaro já faz anos. Tinha um monte de configs e scripts velhos misturados. Meu Manjaro GNOME já não tinha mais GNOME. Meu Hyprland era Frankenstein. A única barreira era minha configuração de <strong>QEMU/Libvirt</strong> pra rodar Windows com <a href="https://akitaonrails.com/2023/02/01/akitando-137-games-em-maquina-virtual-com-gpu-passthrough-entendendo-qemu-kvm-libvirt/"target="_blank" rel="noopener">GPU passthrough</a>, que era o que eu usava pra editar videos quando ainda postava no meu <a href="https://www.youtube.com/@Akitando"target="_blank" rel="noopener">canal do YouTube</a>.</p>
<p>Mas como parei de editar videos, esse Windows também não é mais tão importante. Eu tinha outra máquina virtual Windows com GPU passthrough pra games. Mas atualmente tenho um mini-PC separado com Windows que uso só pra games. Também tinha outra VM com outro Linux só pros meus experimentos de I.A., mas desde então migrei pra rodar nativo isolando tudo com Docker. Ou seja, minhas VMs já não são mais importantes. Veja meus blog posts anteriores pra saber sobre I.A. em Docker.</p>
<p>Com o lançamento do Omarchy 2.0, parece uma boa hora pra reinstalar Arch do zero com Omarchy por cima e recomeçar com tudo limpo e bonito.</p>
<h2>1 - Meu Setup<span class="hx:absolute hx:-mt-20" id="1---meu-setup"></span>
    <a href="#1---meu-setup" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250829_113734.jpg" alt="meu PC"  loading="lazy" /></p>
<p>Cada caso vai ser diferente. Este post tem como principal função servir como minha referência pessoal pro futuro, se eu precisar reinstalar tudo de novo.</p>
<p>Não, não vou usar <strong>NixOS</strong>. Eu realmente não acho que compensa. Só vale a pena se você é administrador de sala de computador ou infraestrutura de servidores e seu dia a dia é ter que reconstruir setups idênticos de maneira confiável. Pra um usuário normal, que só vai reinstalar a cada 2 ou 3 anos, não vale nem um pouco a curva de aprendizado nem o trabalho de manutenção. É perda de tempo. Eu vou gastar dias aprendendo agora, terminar o setup, passar 2 anos e já vou ter esquecido tudo. Arch Linux sozinho já é estável o suficiente pra eu não precisar disso.</p>
<p>Meu setup ainda é o mesmo da época que estava editando videos pro canal. É um <strong>Ryzen 9 7850X3D</strong> com 16 cores, 32 threads, pico de 5Ghz. Ainda é um excelente CPU que tem poder de sobra pros meus usos, por isso não me vejo querendo atualizar tão cedo. São raras as vezes que eu consigo saturar tudo isso de core ao mesmo tempo nessas velocidades. Melhor ainda: ele tem GPU integrada AMD que torna instalar Linux mil vezes mais fácil do que se eu tivesse NVIDIA.</p>
<p>Mas, eu também tenho uma GPU discreta, separada, a <strong>NVIDIA RTX 4090</strong> (não, não preciso de uma 5090, tem o mesmo tanto de VRAM). Ela vai ficar pra tarefas secundárias e não pra carregar meu ambiente gráfico. Coisas como render de Cycles no Blender, ou rodar LLMs com ollama da vida. Antes eu usava GPU passthrough pra uma VM em QEMU/Libvirt pra rodar Windows em parelelo ao Linux. Tanto pra editar video quanto pra games.</p>
<p>Como não edito mais videos, não preciso desse setup complicado então nem vou me preocupar mais em instalar Libvirt de volta. Se eu precisar de Windows, vou deixar em dual boot. Se precisar editar video, hoje em dia temos DaVinci Resolve Studio que roda nativo em Linux (mil vezes melhor que Adobe Premiere). Pra games eu tenho um mini PC separado com uma RTX 4060 ligado na minha TV. Melhor coisa é ter um PC totalmente separado pra games.</p>
<p>Então este setup é pra ser um Linux puro, com acesso ao meu <strong>NAS Synology DS 1821+</strong> de 100TB. Única coisa extra que vou precisar é configurar mounts de NFS, como já detalhei <a href="https://akitaonrails.com/2025/04/17/configurando-meu-nas-synology-com-nfs-no-linux/"target="_blank" rel="noopener">neste outro post</a>.</p>
<p>Um detalhe é que eu tenho <strong>4 NVMEs</strong> neste PC. 2TB pro meu Linux antigo. 2 TB pro dual boot/VM de Windows. 2 TB só como drive de Steam e 1 TB pra coisas aleatórias. Como vou limar a VM de Steam, também não preciso mais dedicar um NVME inteiro só pra isso. Em vez disso vou fazer o diretório &ldquo;/home&rdquo; do novo Linux ser esses 2 TB inteiro.</p>
<p>Isso vai me permitir não me preocupar mais com Docker enchendo meu drive e travando meu sistema inteiro com falta de espaço. Da última vez eu tinha &ldquo;resolvido&rdquo; isso fazendo um <a href="https://akitaonrails.com/2025/04/17/configurando-meu-nas-synology-com-nfs-no-linux/"target="_blank" rel="noopener">drive remoto com iSCSI</a> no meu NAS (que tem espaço infinito). Faz tirando minha VM de Steam vou ganhar 2TB então resolvo o problema localmente e com menos configurações.</p>
<p>RAM eu tenho de sobra, <strong>96GB de DDR5</strong>. Com isso também não preciso me preocupar com partição de swap. Swap só é importante caso você tenha menos de 32GB de RAM, se estiver rodando muito Docker e ficar batendo no máximo de consumo de RAM muito rápido. Ou, se estiver usando notebook e quer ter a opção de hibernação (poder gravar a RAM em disco, dar power off completo na máquina e conseguir voltar depois exatamente de onde parou - que é diferente de suspender, que ainda usa energia).</p>
<p>Se quiser hibernar precisa ter um pouco mais do que o tamanho da sua RAM. Então se tem 32GB é bom deixar uma margem, uns 34GB ou mais de Swap. Como meu PC é desktop em casa, não preciso de hibernação, só ativar <strong>ZRAM</strong> pros raros casos onde tiver um pico acima de 96GB (que é ultra raro). Fora que é mais fácil eu simplesmente subir pra 128GB de RAM se precisar muito. Swap pra compensar RAM só vale a pena em notebooks que já não tem espaço pra mais RAM de verdade.</p>
<h2>2 - Por que Omarchy?<span class="hx:absolute hx:-mt-20" id="2---por-que-omarchy"></span>
    <a href="#2---por-que-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Como falei, já sou usuário de Arch faz uma década e não vejo nenhum repositório de pacotes maior e mais completo do que o <strong>AUR</strong>. O único outro repositório que compete, de fato, é do NixOS. Mas como Nix está descartado pro meu caso de uso, o AUR continua imbatível.</p>
<p>Arch tem Pacman como gerenciador de pacotes. Pra acessar o AUR precisa de um segundo gerenciador. Existem vários como os antigos Pacaur, Paru e vários outros. Mas o melhor, na minha opinião, é o Yay. Ele tem exatamente a mesma sintaxe que o Pacman e substitui o Pacman. Na prática só usamos Yay pra tudo.</p>
<p>Pra procurar pacotes por nome é só fazer <code>yay -Ss spotify</code>.</p>
<p>Pra remover pacotes é só fazer <code>yay -Rns spotify</code>.</p>
<p>Pra atualizar todos os pacotes do sistema é só fazer <code>yay -Syu</code></p>
<p>Pra remover pacotes órfãos que sobram ao longo do tempo é só fazer <code>sudo pacman -Rns $(pacman -Qdtq)</code></p>
<p>E esses são os comandos que eu mais uso 99% do tempo.</p>
<p>Eu já usei tudo que é tipo de desktop manager, seja GNOME (que tem mais comportamento de Mac), KDE (que tem mais comportamento de Windows pra power users), XFCE (que baseado em GTK e é mais leve), Cinnamon (também baseado em GTK), i3 (que é sistema de tiling windows), Sway (como i3, também tiling mas se não me engano já foi feito pensado em Wayland).</p>
<p>Na prática, todo mundo usa aplicativos de dois jeitos: janela em tela cheia ou 2 janelas verticais dividindo o monitor no meio (editor de um lado, navegador do outro), ou 3 janelas (um editor vertical ocupando metade do monitor, um navegador ocupando 1/4 e um terminal ocupando outro 1/4). Daí organizamos mais apps abertos em desktops virtuais/workspaces. Esse é o jeito mais fácil de trabalhar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_12-12-58.png" alt="layout ideal"  loading="lazy" /></p>
<p>Significa que poder arrastar janelas flutuantes é perda de tempo. Eu prefiro que as janelas já abram dimensionadas num desses layouts que falei acima. Dá pra configurar GNOME ou KDE pra fazer isso. Mas tem cheiro de gambiarra. Em vez disso realmente é melhor usar i3 ou Sway.</p>
<p>Deixando as <a href="https://x.com/LundukeJournal/status/1942389827518808384"target="_blank" rel="noopener">controvérsias</a> de lado (sim, tenho um pouco de pé atrás com Wayland e gosto da existência de XLibre). Mas é um fato que <strong>X11</strong> ficou pra trás e é uma arquitetura muito velha e complicada. Wayland de fato tem um &ldquo;appeal&rdquo; melhor, apesar de ter demorado bastante pra arredondar coisas básicas como compartilhamento de tela (OBS, Zoom). Mas já faz alguns anos que uso Wayland sem ter dores de cabeça. Hoje em dia eu diria que está bem estável. Eu já usava GNOME sobre Wayland faz muito tempo. Eu não deixo de usar coisas por ter pé atrás: com tecnologia vou ser sempre absolutamente promíscuo e usar tudo.</p>
<p>Sabendo que vou usar <strong>Wayland</strong> e sabendo que quero layouts automáticos de janelas, e não preciso de janelas flutuantes, o melhor é um desktop manager com sistema de <strong>tiling windows</strong> (tiles são &ldquo;azulejos&rdquo; e estamos falando de azulejos ficarem lado a lado e nunca um em cima do outro), que organize as janelas lado a lado de forma inteligente e automática.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_12-19-25.png" alt="janelas lado a lado"  loading="lazy" /></p>
<p>Nesse caso só temos 2 opções: <strong>Sway</strong> ou <strong>Hyprland</strong> (qualquer uma das duas é boa). O Hyprland, instalado do zero, é totalmente pelado, não tem absolutamente nada. Precisamos configurar tudo através de arquivos em <code>.config/hypr</code>. É até simples, mas dá trabalho.</p>
<p>A única opção boa que se tinha pra ter um Hyprland pré-configurado e bem feito era o <strong>ML4W</strong>, que eu já usava. Mas agora temos o Omarchy que justamente instala e pré-configura tudo pra funcionar redondo no Hyprland. Essa é a melhor opção que temos hoje em dia.</p>
<p>Além de já configurar Hyprland pra funcionar com <strong>Waybar</strong>, Rofi e outros componentes, ele tem um sistema próprio pra trocar temas e estilos e deixar o sistema com o <em>&ldquo;look and feel&rdquo;</em> que quiser (e todos que já vem nele são super bonitos), mas também já instala coisas que eu uso faz tempo como Neovim com o pacote <strong>LazyVim</strong> (na minha opinião, o jeito mais fácil de fazer o Neovim não deixar nada a desejar comparado a um VS Code), <strong>Mise</strong> (a melhor forma de organizar ambientes de desenvolvimento pra conseguir ter múltiplas versões da sua linguagem de programação favorita).</p>
<p>Se estiver instalando uma distro do zero, as únicas duas coisas que precisa ter são Mise e LazyVim. Além de Docker e LazyDocker. É o suficiente pra começar um ambiente de desenvolvimento produtivo. E o Omarchy já trás tudo isso pré-configurado. Ninguém &ldquo;precisa&rdquo; do Omarchy, mas ele já trás tudo integrado e bonito. Então, pra que me dar ao trabalho de fazer tudo do zero pra ficar quase igual?</p>
<p>Além disso, isso é Linux. Não gostou de 1 dos componentes? Só trocar.</p>
<h2>3 - Faça Backup<span class="hx:absolute hx:-mt-20" id="3---faça-backup"></span>
    <a href="#3---fa%c3%a7a-backup" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A grande maioria de tudo que tenho já fica no servidor remoto, meu NAS Synology de 100TB. Isso já facilita muito. Mesmo assim ainda tem bastante coisa localmente no meu PC, então a primeira coisa a fazer é copiar tudo pro NAS. Se não tiver um NAS, então um HD externo. Qualquer coisa server, o importante é garantir que não vai perder nada antes de instalar um novo OS do zero.</p>
<p>Não esquecer diretórios como <code>.config</code> ou <code>.local</code>. Melhor fazer um <code>rsync -avz --progress .config /mnt/nas/backup/</code>, por exemplo, e copiar tudo. Mesmo o que achar que não vai precisar. Melhor copiar a mais do que faltar coisa. Via de regra, o ideal é copiar tudo que estiver na sua <code>$HOME</code> pra um drive externo ou NAS.</p>
<p>Só pra garantir que não vou esquecer nada importante, também vou gravar uma lista de todos os pacotes que tenho instalado no meu sistema antigo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -Q &gt; pacotes.txt
flatpak list &gt; flatpak.txt</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Também garantir que não vou perder configs velhas de serviços que eu fiz no systemd então também copiar tudo de <code>/etc/systemd/system</code>. Vale também gravar coisas como <code>/etc/fstab</code>. Também não esquecer de fazer backup de suas chaves de SSH com <code>tar cvfz ssh.tgz ~/.ssh</code>!!</p>
<p>Se como eu, usava QEMU/Libvirt pra VMs, é bom salvar as configs das máquinas virtuais que usava. Normalmente a ferramenta pra gerenciar VMs é o virsh então eu só fiz:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo virsh list --all
sudo virsh dumpxml &lt;vmname&gt; &gt; &lt;vmname&gt;.xml</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se eu quiser recriar as máquinas no futuro, já vai estar tudo no backup. No meu caso mantenho todos os drives virtuais no meu NAS, mas caso os seus estejam locais, também precisa salvar esses arquivos que ficam em <code>/var/lib/libvirt/images/</code></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>rsync -avh --progress /var/lib/libvirt/images/ /backup/libvirt-images/</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>4 - É difícil instalar Arch?<span class="hx:absolute hx:-mt-20" id="4---é-difícil-instalar-arch"></span>
    <a href="#4---%c3%a9-dif%c3%adcil-instalar-arch" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Arch, menos que um Gentoo, sempre teve reputação de ser a distro Linux mais brutal pra um iniciante instalar. Isso não é mentira, mas a verdade é que Arch é simultaneamente a distro mais difícil e também a mais fácil.</p>
<p>Baixe <a href="https://archlinux.org/download/"target="_blank" rel="noopener">a ISO oficial</a> e grave num pen drive (em Windows, usando <strong>Rufus</strong> ou Balena Etcher). Agora aperte F12 (depende da sua BIOS) ou configure na BIOS direto pra bootar do pen drive. Fazendo isso ele carrega o live environment do Arch que é literalmente cair numa linha de comando. Sem mais nenhuma ajuda.</p>
<p>A partir deste ponto tem que seguir o <a href="https://wiki.archlinux.org/title/Installation_guide"target="_blank" rel="noopener">Wiki de Instalação</a> do excelente ArchWiki e aprender a instalar um Linux do absoluto zero usando somente linha de comando, passo a passo, na tentativa e erro (mais errando do que acertando) e, ao final, você vai ter um &ldquo;feeling&rdquo; muito melhor de como uma distro Linux funciona de verdade.</p>
<p>Eu não fiz video de Arch mas fiz videos de <a href="https://www.youtube.com/watch?v=iQkBbRPkASo"target="_blank" rel="noopener">Slackware</a> pra explicar como um gerenciador de pacotes funciona. Também fiz um video de <a href="https://www.youtube.com/watch?v=cSyTjCUFx2A"target="_blank" rel="noopener">Gentoo</a> pra mostrar como uma distro que compila tudo do zero funciona. E fiz um video de como o <a href="https://www.youtube.com/watch?v=5F6BbhgvFOE"target="_blank" rel="noopener">Boot do Linux Funciona</a> pra entender onde fica a kernel e como ela é estruturada. Mas não fiz video de Arch porque sempre deixei como exercício pra iniciantes.</p>
<p>O jeito manual é viável, mas se está acostumado a um instalador gráfico, como o <strong>Calamaris</strong>, que tem na maioria das distros mais populares como Ubuntu ou Fedora, você vai ficar totalmente perdido. Mas aqui vem o bônus: não precisa passar por tudo isso pra ter um Arch Linux na sua máquina.</p>
<p>Pra isso existe o <a href="https://wiki.archlinux.org/title/Archinstall"target="_blank" rel="noopener"><strong>archinstall</strong></a>.</p>
<p>Quando bootar o pen drive do Arch e cair na linha de comando, basta digitar archinstall e pronto, só seguir o passo a passo que ele dá - que eu considero ainda mais simples do que Calamaris - e ele vai instalar e configurar tudo de forma automática pra você, do mesmo jeito que é instalar Fedora ou qualquer outra distro. Sério, não é pra demorar mais que 15 minutos.</p>
<p>O archinstall tem esta cara:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250828_045255.jpg" alt="archinstall"  loading="lazy" /></p>
<p>Basta entrar em cada um dos ítens da esquerda e preencher suas escolhas. Configure coisas como layout de teclado (normalmente eu escolho &lsquo;us-acentos&rsquo;). Edite o hostname da sua máquina. Escolha &ldquo;NetworkManager&rdquo; em configuração de rede (ele vai configurar tanto ethernet quanto wifi pra você), adicionar suporte a Bluetooth e Audio (escolha &ldquo;Pipewire&rdquo;). Escolha o tipo &ldquo;desktop&rdquo; em vez de &ldquo;minimal&rdquo; pra já ter os principais pacotes necessários pra um desktop. Escolha a timezone (&ldquo;America/Sao_Paulo&rdquo; no meu caso).</p>
<p>Recomendo também escolher a opção de Hyprland acho que em Applications ou Adicional Packages. Ele já vai instalar o SDDM pra ter um login gráfico.</p>
<p>Só tem duas opções que precisa de mais atenção: pra bootloader, muitos vão ficar tentados a usar um <strong>Limine</strong>, que é mais moderno e leve. Mas eu recomendo ainda usar <strong>GRUB</strong>, já explico porque.</p>
<p>A segunda opção importante é &ldquo;Disk Configuration&rdquo;. Não se preocupe, diferente de fdisk, ele é super intuitivo. Basta escolher o drive correto onde quer instalar (se tiver dual boot, cuidado pra não apagar seu Windows). Daí deixe ele fazer o layout automático das partições (só edite manualmente se tiver alguma necessidade muito especial). O mais importante, escolha <a href="https://wiki.archlinux.org/title/Btrfs"target="_blank" rel="noopener"><strong>BTRFS</strong></a> em vez do tradicional ext4.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250828_045312.jpg" alt="btrfs"  loading="lazy" /></p>
<p>Todo Linux sempre formata suas partições Linux com ext4, que é o mais antigo, mais estável e mais bem documentado file system. Hoje em dia eu recomendo BTRFS, é muito mais moderno, mais seguro (tem sistemas de proteção contra corrupção melhores), usa menos espaço (aprenda sobre CoW - <strong>Copy on Write</strong>), e o principal: tem suporte a snapshots baratos (pense o Apple Time Machine, só que melhor). Tem a maioria das funcionalidades de um sistema de arquivos dedicado pra servidor de arquivos mas muito mais simples e intuitivo de usar do que o monstro que é o ZFS (não recomendo pra usuários normais).</p>
<p>Ele tem algumas necessidades de manutenção que é bom ler no Wiki pra aprender. Mas no geral é plug and play, instala e esquece. Nas próximas seções vou mostrar algumas coisas que precisa saber, mas vai por mim: escolha BTRFS.</p>
<p>Eu sei que o Omarchy 2.0 tem opção de uma <a href="https://iso.omarchy.org/omarchy-online.iso"target="_blank" rel="noopener">ISO pré-configurada</a> que imagino que seja o Arch normal com archinstall e já o Omarchy por cima tudo de uma só vez. Mas eu não sei se eles permitem essa escolha por isso preferi ir direto no Arch puro antes. No final o efeito é o mesmo. Depois comentem abaixo se a ISO do Omarchy também tem as mesmas opções. Só garanta que no final tenha BTRFS. O futuro você vai te agradecer.</p>
<h2>5 - HOME separada<span class="hx:absolute hx:-mt-20" id="5---home-separada"></span>
    <a href="#5---home-separada" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Como expliquei antes, eu usava um dos meus 4 NVMEs pra ser o drive de Linux. Mas agora liberei outro NVME e quero mover minha $HOME pra lá e ter 2 TB dedicado só pra user space.</p>
<p>Não vou explicar como particionar e formatar esse outro drive. É simples: basta usar <a href="https://wiki.archlinux.org/title/Fdisk"target="_blank" rel="noopener">fdisk</a> ou depois instalar <strong>Gparted</strong> que é a versão gráfica da ferramenta <a href="https://wiki.archlinux.org/title/Parted"target="_blank" rel="noopener">parted</a> que dá pra usar pela linha de comando. São várias opções. O importante é só zerar minha partição antiga Windows e formatar também com BTRFS.</p>
<p>Cada um vai ter nomes de dispositivos e partições diferentes do meu. Pra saber quais são os seus use o comando <code>lsblk</code>. Veja o meu exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_12-54-42.png" alt="lsblk"  loading="lazy" /></p>
<p>No meu exemplo <code>nvme1n1</code> é o drive de 1TB pra coisas aleatórias. <code>nvme2n1</code> é meu novo Arch Linux. <code>nvme0n1</code> é o drive de dual boot de Windows antigo. <code>nvme3n1</code> é o drive de Steam que formatei com BTRFS pra virar meu novo drive de HOME.</p>
<p>Se não entendeu, HOME é o diretório <code>/home/akitaonrails</code>. Ele vai ficar num drive separado. Depois que o archinstall terminar e eu bootar no novo Linux, é só fazer o seguinte:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo mount -t btrfs /dev/nvme3n1p1 /mnt
sudo btrfs subvolume create /mnt/@home
rsync -aAXHv /home/ /mnt/@home/
sudo umount /mnt</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso vai montar a nova partição, daí usamos o comando &ldquo;btrfs&rdquo; pra criar um novo sub-volume chamado &ldquo;@home&rdquo; (de novo, leia o Wiki de BTRFS pra entender conceitos como sub-volumes).</p>
<p>Os comandos acima criam o sub-volume e copiam tudo que estava na HOME antiga pra nova. Agora precisamos que, no boot, o <code>/home</code> seja montado nessa nova partição. Pra isso precisamos saber o UUID dessa partição:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>~ ❯ sudo blkid /dev/nvme3n1p1
/dev/nvme3n1p1: LABEL=&#34;HOME&#34; UUID=&#34;84e9a1b7-a30e-...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O comando <code>blkid</code> devolve o UUID único de cada partição e, com isso, podemos editar o arquivo <code>/etc/fstab</code> usando <code>sudo nvim</code> ou <code>sudo nano</code> ou o editor que preferir:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># /etc/fstab
...
# /dev/nvme2n1p2
# UUID=da3aea43-...-aeaf8c7224d7 /home      btrfs      rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@home 0 0

# /dev/nvme3n1p1
UUID=84e9a1b7-...-7a6a17fd0395 /home      btrfs      rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@home 0 0
...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Veja como comentei a linha antiga que montava o <code>/home</code> e adicionei a nova linha com o novo UUID. O resto é tudo igual. E é só isso, basta bootar e a partir de agora meu <code>/home</code> vai montar no novo drive. Agora eu tenho 2 TB dedicados só pros meus downloads lixo kkkkkk 🤣</p>
<p>Mas não só isso, também tenho espaço pra coisas grandes como imagens de Docker ou modelos de LLM, sem correr o risco de encher o drive do sistema operacional e correr o risco dele não bootar mais por falta de espaço - como já me aconteceu várias vezes no passado. Sempre lembre de dar manutenção em Docker e LLMs e apagar coisas velhas.</p>
<p>Falando nisso, BTRFS tem suporte a snapshots. E um dos erros básicos é esquecer que diretórios de Docker ou LLM podem acabar nos snapshots e ficar ocupando espaço sem você saber. Pra evitar isso é melhor marcar esses diretórios pra não entrarem nos snapshots. Pra isso temos que dizer ao BTRFS pra ignorar esses diretórios.</p>
<p>A forma correta é criando subvolumes separados pra eles. Pra isso vou montar aquela minha mesma partição no drive separado onde montei minha $HOME:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>~ ❯ sudo mkdir /mnt/temp
~ ❯ sudo mount -o subvolid=5 -t btrfs /dev/nvme3n1p1 /mnt/temp

~ ❯ ls /mnt/temp
 @home   timeshift-btrfs

~ ❯ sudo btrfs subvolume create /mnt/temp/@docker
Create subvolume &#39;/mnt/temp/@docker&#39;

~ ❯ sudo btrfs subvolume create /mnt/temp/@ollama
Create subvolume &#39;/mnt/temp/@ollama&#39;

~ ❯ sudo umount /mnt/temp</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora é só editar o <code>/etc/fstab</code> pra montar corretamente igual fizemos com a HOME:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># /etc/fstab
...
# /dev/nvme3n1p1
UUID=84e9a1b7-...-7a6a17fd0395 /home      btrfs      rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@home 0 0
UUID=84e9a1b7-...-7a6a17fd0395 /var/lib/docker      btrfs      rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@docker 0 0
UUID=84e9a1b7-...-7a6a17fd0395 /var/lib/ollama      btrfs      rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@ollama 0 0
...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto, subvolumes limpos. Mais importante no meu caso: movi diretórios que tem tendência a crescer sem controle pra fora da partição do sistema operacional, tornando mais difícil acabar com um sistema inacessível por causa de falta de espaço. Faça a mesma coisa com outros diretórios parecidos com coisas como Kubernetes por exemplo. Qualquer coisa que fique baixando arquivos grandes, como imagens de sistemas.</p>
<p>Agora é só montar e trazer as coisas de volta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># toda vez que edita o fstab, rode isso:
sudo systemctl daemon-reload

# crie os mount points
sudo mkdir /var/lib/docker
sudo mkdir /var/lib/ollama

# monte
sudo mount /var/lib/docker
sudo mount /var/lib/ollama

# copiar o conteúdo do diretório antigo de volta
sudo rsync -aHAX --inplace /var/lib/docker.old/ /var/lib/docker/
sudo systemctl start docker</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Além de gerenciamento de espaço, qual a outra vantagem de fazer subvolumes separados? Porque a próxima seção vai ser pra tornar o sistema ainda mais robusto adicionando capacidade de snapshots e rollback pra snapshots do passado. E o ideal é tirar arquivos gigantes de snapshots que vão ficar no passado. Imagens de Docker são fáceis de recuperar: só dar <code>docker pull</code> de novo, não precisa fazer backup.</p>
<h2>6 - Instalar Omarchy<span class="hx:absolute hx:-mt-20" id="6---instalar-omarchy"></span>
    <a href="#6---instalar-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Essa é a parte mais fácil. Quando terminar de instalar com archinstall, se escolheu a opção de Hyprland, vai aparecer o SDDM pra fazer login. E quando entrar você vai ficar chocado com quão <strong>cru</strong> é o Hyprland. Não dá pra fazer basicamente nada.</p>
<p>Pra isso não virar um dia inteiro de configuração na mão, usaremos o Omarchy. Clique &ldquo;Super Enter&rdquo; pra abrir o terminal e não ligue pra quão feio as coisas estão agora. Vai melhorar.</p>
<p>No terminal só faça isso:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>curl -fsSL https://omarchy.org/install | bash</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Só seguir as instruções na tela e deixar ele fazer o resto. E pronto, acabou, não tem próximo passo.</p>
<p>Recomendo MUITO que leia o <a href="https://learn.omacom.io/2/the-omarchy-manual"target="_blank" rel="noopener">MANUAL ONLINE DO OMARCHY</a> que o DHH fez. É muito limpo, simples e direto. Todas as combinações de tecla, por exemplo, estão na <a href="https://learn.omacom.io/2/the-omarchy-manual/53/hotkeys"target="_blank" rel="noopener">seção HOTKEYS</a>. Gaste uma hora lendo o básico pra conseguir operar. Mas a essa altura você já tem praticamente tudo que precisa: Alacritty como terminal, Chromium como navegador (pode instalar Brave se preferir, como é meu caso).</p>
<p>&ldquo;Super Alt Space&rdquo; abre o menu principal do Omarchy. &ldquo;Super Space&rdquo; abre o Rofi pra digitar o nome do app que quer abrir. &ldquo;Super Enter&rdquo; abre o terminal. &ldquo;Super B&rdquo; abre o navegador e assim por diante.</p>
<h2>7 - Customizando Omarchy<span class="hx:absolute hx:-mt-20" id="7---customizando-omarchy"></span>
    <a href="#7---customizando-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Omarchy é um Hyprland customizado. Podemos editar o que quisermos diretamente em <code>~/.config/hypr</code>. E como eu estava acostumado com ML4W, resolvi mexer um pouco pra ficar bom pro meu setup. Seu setup vai variar dependendo das suas necessidades.</p>
<p>Logo que terminei de instalar Omarchy e tentei usar Gparted pra particionar aquele meu segundo NVME pra HOME, ele deu problema de autenticação. Não lembro se esta foi a solução mas é bom garantir que tenha Polkit instalado:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># make sure polkit &#43; agent exist
sudo pacman -S --needed polkit polkit-gnome xorg-xhost

# Hyprland: export full env to systemd user bus once
dbus-update-activation-environment --systemd --all</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Voltando, a primeira coisa que eu preciso resolver é que eu tenho 2 monitores. Um Asus 32&quot; 1440p 144fps como principal e outro Samsung 24&quot; 4K 60fps na vertical do lado esquerdo. A forma de configurar isso no Hyprland é editando um arquivo como <code>~/.config/hypr/monitors.conf</code> que normalmente é carregado pelo <code>~/.config/hypr/hyprland.conf</code>.</p>
<p>Em vez de fazer isso manualmente, prefiro instalar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S nwg-displays</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_13-46-04.png" alt="nwg-displays"  loading="lazy" /></p>
<p>Aqui eu configuro coisas como transform 90 graus pra girar o monitor vertical, scaling de resolução, suporte a 10-bits de cor, etc.</p>
<p>Ele vai salvar dois arquivos: <code>~/.config/monitors.conf</code> e <code>~/.config/workspaces.conf</code>. O Omarchy não carrega esse segundo arquivo então temos que editar em <code>~/.config/hypr/hyprland.conf</code> pra ficar assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>...
# Change your own setup in these files (and overwrite any settings from defaults!)
source = ~/.config/hypr/monitors.conf
source = ~/.config/hypr/workspaces.conf`
...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Já aproveitei pra adicionar algumas configurações extras nesse arquivo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>...
# animation
animations {
  enabled = yes
  bezier = easeOutQuint, 0.23, 1, 0.32, 1
  animation = workspaces, 1, 4, easeOutQuint, slide
  # optional extras:
  animation = specialWorkspace, 1, 4, easeOutQuint, slide
  animation = windows, 1, 4, easeOutQuint, popin 80%
  animation = fade, 1, 4, easeOutQuint
}

xwayland {
    force_zero_scaling = false # careful with mixing scaling wayland and x11
}

input {
  numlock_by_default = true
}

# dialogs/splash/utility ONLY
windowrulev2 = float,  xwayland:1, windowtype:^(dialog|splash|utility)$
windowrulev2 = center, xwayland:1, windowtype:^(dialog|splash|utility)$

# never center menus/tooltips
windowrulev2 = tile,   xwayland:1, windowtype:^(popup_menu|dropdown_menu|tooltip)$</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Tem gente que não gosta mas eu gosto de ter uma animação rápida quando mudo de um workspace pra outro, por isso adicionei o bloco <code>animations</code>.</p>
<p>Quando se usa aplicativos feitos pra X11, eles vão rodar em cima do XWayland. Uma coisa chata é que alguns deles abrem &ldquo;dialog boxes&rdquo;, que são janelas flutuantes. E eles podem acabar em lugares difíceis de clicar, especialmente num setup com múltiplos monitores. Por isso adicionei blocos como <code>xwayland</code> e regras <code>windowrulev2</code> pra forçar esses dialog boxes a sempre aparecerem centralizados na tela.</p>
<p>FInalmente, eu tenho um teclado numpad da 8bitdo conectado via Bluetooth, mas ele não liga com numlock carregado. Pra corrigir isso tem esse bloco <code>input</code>.</p>
<p>Voltando ao layout de monitor. Depois que o nwg-displays gerou os arquivos, ainda precisei modificar um pouco por meu caso, assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># ~/.config/monitors.conf
# Generated by nwg-displays on 2025-08-28 at 14:30:17. Do not edit manually.

#monitor=HDMI-A-3,2560x1440@143.97,1080x407,1.25,bitdepth,10
#monitor=DP-5,3840x2160@60.0,0x0,1.875,bitdepth,10
#monitor=DP-5,transform,1
#monitor=DP-1,0x0@60.0,-1x-1,1.0
#monitor=DP-1,disable

monitor=HDMI-A-3,2560x1440@143.97,2813x948,1.0,bitdepth,10
monitor=DP-5,3840x2160@60.0,1373x350,1.5,bitdepth,10
monitor=DP-5,transform,1
monitor = DP-1,disable</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O arquivo de monitor não precisei mexer nada, na real, só lembrar de desabilitar esse DP-1 que aparece no meu monitor principal (acho que é a DisplayPort dele, mas eu uso HDMI, então tem que desabilitar a DP-1).</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># ~/.config/workspaces.conf
# Generated by nwg-displays on 2025-08-28 at 13:07:02. Do not edit manually.

workspace=5,monitor:DP-5,persistent:true
workspace=1,monitor:HDMI-A-3,persistent:true
workspace=2,monitor:HDMI-A-3,persistent:true
workspace=3,monitor:HDMI-A-3,persistent:true
workspace=4,monitor:HDMI-A-3,persistent:true</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Esta também não precisei mudar muito, no próprio nwg-displays eu disse quais workspaces eu quero em cada monitor. Na minha preferência pessoal prefiro deixar o monitor vertical somente com a workspace 5 e os outros no monitor principal. A diferença aqui foi que adicionei essas opções <code>persistent:true</code> em todas, pra garantir que vai tudo funcionar direito com as workspaces &ldquo;pinadas&rdquo; nos lugares corretos. Workspaces em Hyprland são bem dinâmicos, vale ler a documentação depois, caso queira casos mais complicados.</p>
<p>Isso resolve meu setup de dois monitors do jeito que eu prefiro. Experimente mexer em coisas como scaling até ficar tudo ok pro seu setup.</p>
<p>Na sequência eu precisava resolver as hotkeys (key bindings). Eu estou acostumado com algumas combinações que vinha no ML4W então resolvi copiar de lá direto em <code>~/.config/hypr/bindings.conf</code>. Primeiro, trocar o chromium pelo Brave:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># Application bindings
$terminal = uwsm app -- alacritty
$browser = brave # omarchy-launch-browser
...</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Daí adicionei um tanto de binds no final do mesmo arquivo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>unbind = SUPER, V
bind = SUPER, V, swapsplit
bind = SUPER, M, fullscreen, 1                                                           # Maximize Window
bind = SUPER, T, togglefloating                                                          # Toggle active windows into floating mode
bind = SUPER SHIFT, right, resizeactive, 100 0                                           # Increase window width with keyboard
bind = SUPER SHIFT, left, resizeactive, -100 0                                           # Reduce window width with keyboard
bind = SUPER SHIFT, down, resizeactive, 0 100                                            # Increase window height with keyboard
bind = SUPER SHIFT, up, resizeactive, 0 -100                                             # Reduce window height with keyboard

# Display
bind = SUPER SHIFT, mouse_down, exec, hyprctl keyword cursor:zoom_factor $(awk &#34;BEGIN {print $(hyprctl getoption cursor:zoom_factor | grep &#39;float:&#39; | awk &#39;{print $2}&#39;) &#43; 0.5}&#34;) # Increase display zoom
bind = SUPER SHIFT, mouse_up, exec, hyprctl keyword cursor:zoom_factor $(awk &#34;BEGIN {print $(hyprctl getoption cursor:zoom_factor | grep &#39;float:&#39; | awk &#39;{print $2}&#39;) - 0.5}&#34;) # Decrease display zoom
bind = SUPER SHIFT, Z, exec, hyprctl keyword cursor:zoom_factor 1 # Reset display zoom

# Workspaces
bind = SUPER, 1, workspace, 1 on HDMI-A-3 # Open workspace 1
bind = SUPER, 2, workspace, 2 on HDMI-A-3  # Open workspace 2
bind = SUPER, 3, workspace, 3 on HDMI-A-3 # Open workspace 3
bind = SUPER, 4, workspace, 4 on HDMI-A-3 # Open workspace 4
bind = SUPER, 5, workspace, 5 on DP-5 # Open workspace 5

bind = SUPER SHIFT, 1, movetoworkspace, 1  # Move active window to workspace 1
bind = SUPER SHIFT, 2, movetoworkspace, 2  # Move active window to workspace 2
bind = SUPER SHIFT, 3, movetoworkspace, 3  # Move active window to workspace 3
bind = SUPER SHIFT, 4, movetoworkspace, 4  # Move active window to workspace 4
bind = SUPER SHIFT, 5, movetoworkspace, 5  # Move active window to workspace 5

bind = SUPER, Tab, workspace, m&#43;1       # Open next workspace
bind = SUPER SHIFT, Tab, workspace, m-1 # Open previous workspace

bind = SUPER CTRL, 1, exec, $HOME/.config/hypr/moveTo.sh 1  # Move all windows to workspace 1
bind = SUPER CTRL, 2, exec, $HOME/.config/hypr/moveTo.sh 2  # Move all windows to workspace 2
bind = SUPER CTRL, 3, exec, $HOME/.config/hypr/moveTo.sh 3  # Move all windows to workspace 3
bind = SUPER CTRL, 4, exec, $HOME/.config/hypr/moveTo.sh 4  # Move all windows to workspace 4
bind = SUPER CTRL, 5, exec, $HOME/.config/hypr/moveTo.sh 5  # Move all windows to workspace 5</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Note que o último bloco de scripts precisa de um script pra mover todas as janelas de uma só vez pra outro workspace. Eu copiei este <a href="https://github.com/mylinuxforwork/dotfiles/blob/main/dotfiles/.config/hypr/scripts/moveTo.sh"target="_blank" rel="noopener">moveTo.sh</a> do GitHub do ML4W e coloquei em <code>~/.config/hypr</code> direto. Não esquecer de dar permissão de execução com <code>chmod +x moveTo.sh</code> depois.
Os vários de workspace abaixo é como eu prefiro mover workspaces e mover apps pra diferentes workspaces.</p>
<p>Omarchy já vem com &ldquo;SUPER J&rdquo; pra mudar a orientação das janelas, por exemplo, se está duas janelas na horizontal um em cima do outro, com SUPER J eles ficam verticais, mas faltava o &ldquo;SUPER V&rdquo; que adicionei pra &ldquo;swapsplit&rdquo; que é trocar as janelas de lugar.</p>
<p>Eu também gosto de &ldquo;SUPER M&rdquo; pra temporariamente fazer uma das janelas ficar em tela cheia, e &ldquo;SUPER T&rdquo; pra temporariamente fazer uma janela ficar flutuante (como uma calculadora, por exemplo). Tive que dar unbind no SUPER M anterior que abria o Spotify, mas eu quase não uso Spotify no desktop então não preciso dela. Quando quero abrir esse app, vou no SUPER SPACE pra abrir o Rofi e escrevo lá.</p>
<p>Se tiver dúvidas sobre as combinações padrão, o Omarchy tem &ldquo;SUPER K&rdquo; pra abrir uma janela com uma ajuda pra todas.</p>
<p>Ainda não modifiquei combinações pra aplicativos específicos. Os que vem no Omarchy já são muito úteis como SUPER A pra abrir o ChatGPT como se fosse um app separado ou SUPER CTRL A pra abrir o Grok numa janela separada. SUPER O pra abrir o Obsidian também é muito útil pra mim. Recomendo brincar com esses binds pra fazer bindings específicos e, de novo, ler o manual pra aprender tudo mais que já vem nele. Mas até aqui é o suficiente pra deixar o Hyprland do jeito que eu gosto de usar.</p>
<h2>8 - Timeshift, Snapshots e GRUB<span class="hx:absolute hx:-mt-20" id="8---timeshift-snapshots-e-grub"></span>
    <a href="#8---timeshift-snapshots-e-grub" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Lembram que eu falei pra escolher GRUB no archinstall? É pra agora. O objetivo: deixar o sistema fazer snapshots periódicos do sistema e, caso instale algum pacote corrompido ou faça coisas no seu sistema que impeçam ele de bootar, em vez de ter que recorrer a um pendrive pra tentar bootar e diagnosticar o erro, é mais fácil só bootar, escolher um snapshot logo antes da operação destrutiva e voltar intacto.</p>
<p>Antes de prosseguir, um ajuste que acho importante: meu monitor 4K faz o GRUB ficar com letras pequenas demais pra eu conseguir ler. Prefiro letras maiores. Felizmente o GRUB usa fontes bitmap então posso usar qualquer uma. Eu fiz o seguinte:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo grub-mkfont -s 48 -o /boot/grub/fonts/caskaydia48.pf2 /usr/share/fonts/TTF/CaskaydiaMonoNerdFont-Regular.ttf</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso vai gerar uma fonte no formato que o GRUB consegue carregar. Escolha qualquer uma que gostar, o Omarchy já pré-instala várias muito boas como as da JetBrains. Se tamanho 48 for muito grande, diminua pra 32, experimente até ficar do jeito que gosta.</p>
<p>Daí é só editar <code>/etc/default/grub</code> pra, no final ter esta linha:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>GRUB_FONT=/boot/grub/fonts/caskaydia48.pf2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E agora é só regerar o bootloader:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo grub-mkconfig -o /boot/grub/grub.cfg</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Toda vez que o <code>yay -Syu</code> trouxer atualização de kernel ou drivers, o GRUB vai ser regerado com a mesma fonte. Olha como ficou pra mim, acho que está bem melhor (isso é um monitor 4K):</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250828_124009.jpg" alt="Grub Font"  loading="lazy" /></p>
<p>Agora a razão toda pra ter escolhido GRUB: permitir escolher snapshots de BTRFS pra poder bootar no passado, antes de alguma operação destrutiva, como mostra na foto acima. Pra isso precisamos do seguinte:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>pacman -S timeshift grub-btrfs
yay -S timeshift-autosnap
systemctl enable --now grub-btrfs.service</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto. A partir de agora, toda vez que o GRUB for reconstruído, vai ter uma nova opção pra escolher snapshots. Só precisamos criar esses snapshots automaticamente e, pra isso, temos o app Timeshift. Abra e siga o passo a passo dele. O importante é escolher a opção de BTRFS (sim, dá pra usar RSYNC se estiver em ext4, mas isso ocupa muito espaço, porque ele vai literalmente ficar fazendo cópias dos arquivos do seu sistema inteiro. A beleza de BTRFS é que snapshots dele não duplicam arquivos).</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_15-37-52.png" alt="Timeshift Schedule"  loading="lazy" /></p>
<p>Eu deixo ele fazendo snapshots e acumulando versões das últimas horas, últimos dias, últimas semanas e meses. Se lá na frente eu lembrar <em>&ldquo;puuuuts, tinha aquele arquivo que eu apaguei mês passado mas agora eu preciso&rdquo;</em> Basta abrir o Timeshift e explorar um snapshot do mês passado. Igual povo de Mac faz com Time Machine, mas ocupando quase nada de espaço extra.</p>
<p>Além disso, todo upgrade de pacotes vai gerar um snapshot antes. Assim, se por acaso vier um pacote corrompido ou que quebre alguma configuração sua importante, dá pra voltar exatamente como era antes da atualização. E se quebrar de forma catastrófica, onde seu Linux não boota mais, basta ir no menu extra do GRUB e bootar do snapshot anterior, que funcionava. E tudo volta igualzinho como estava antes.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_15-38-24.png" alt="Timeshift Snapshots"  loading="lazy" /></p>
<p>Não existe nada mais importante pro seu sistema do ter snapshots automáticos e que não ocupam quase nada de espaço extra. Só isso já torna o BTRFS superior a qualquer outra alternativa.</p>
<p><strong>Isso não substitui Backup externo!!</strong></p>
<p>Esse rollback e capacidade de recuperar coisas de forma fácil é bom pra acidentes do dia a dia. Mas digamos que seu NVME quebre de alguma forma, ou seu PC quebre de alguma forma. Pra isso servem backups externos (seja HD externo, seja NAS, seja Cloud). Você quer ter certeza que, numa situação catastrófica, ainda seja possível recuperar seus arquivos.</p>
<p>Eu tenho todas as camadas de proteção: snapshots locais via BTRFS e Timeshift, backups feitos remotamente pro meu NAS, e backup de partes mais importantes do meu NAS na <a href="https://aws.amazon.com/pt/s3/storage-classes/glacier/"target="_blank" rel="noopener">Amazon Glacier</a> que, diferente de Amazon S3 é pra guardar backup, onde o custo de armazenamento é ultra baixo mas o custo de transferência é mais alto (S3 o armazenamento é mais caro mas a transferência é barata, por isso serve pra servir assets de websites).</p>
<p>Eu gosto de estar preparado pra, caso minha casa pegue fogo, eu não perca nada importante.</p>
<h2>9 - NFS no NAS<span class="hx:absolute hx:-mt-20" id="9---nfs-no-nas"></span>
    <a href="#9---nfs-no-nas" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Falando em NAS, uma coisa que configurei diferente - já que uso primariamente Linux em vez de Windows - foi habilitar servidor de NFS.</p>
<p>Mas cuidado que alguns NAS tem uma característica que pode incomodar: o seu usuário no NAS vai ter UID e GID diferente de 1000!</p>
<p>Quando se cria um usuário em qualquer Linux, o padrão é atribuir o UID 1000 pro primeiro usuário, 1001 pro segundo e assim por diante. Mas como no NAS Synology o primeiro usuário recebe UID 1026, se eu montar com NFS (que transparece as permissões de UNIX), vou ter problemas de autorização.</p>
<p>Existem duas soluções: tentar mudar o UID no NAS de 1026 pra ser 1000. <a href="https://akitaonrails.com/2025/04/17/configurando-meu-nas-synology-com-nfs-no-linux/"target="_blank" rel="noopener">Eu tentei isso</a> e já adianto que é perda de tempo, você pode acabar quebrando as configurações do NAS de forma catastrófica.</p>
<p>É muito mais fácil mudar o usuário do seu novo Linux local pra ser 1026 e pronto. É bem fácil.</p>
<p>Primeiro, precisamos deslogar e sair do Hyprland e voltar pra tela de login do SDDM. Daí precisamos mudar pra outro TTY com <strong>CTRL + ALT + F3</strong> (pra ir pra tty3, por exemplo). De lá temos que fazer login como <strong>root</strong>.</p>
<p>Agora rodamos: <code>systemctl isolate multi-user.target</code> pra rodar em modo de recuperação isolado, onde nenhum outro usuário tem processos rodando. Já que vamos mexer no usuário, ele não pode estar ativo.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>usermod -u 1026 akitaonrails
groupmod -g 1026 akitaonrails
chown -R 1026:1026 /home/akitaonrails</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Com os comandos acima mudamos de 1000 pra 1026 e acertamos as permissões nos arquivos locais pra refletir essa mudança. Agora sim, podemos editar o <code>/etc/fstab</code> pra montar os diretórios compartilhados no NAS com NFS:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># NFS
192.168.0.x:/volume1/GIGACHAD /mnt/gigachad nfs4 _netdev,noauto,nofail,bg,x-systemd.automount,x-systemd.requires=network-online.target,x-systemd.after=network-online.target,x-systemd.idle-timeout=60s,noatime,nodiratime,async,rsize=65536,wsize=65536,actimeo=1  0 0
192.168.0.x:/volume1/TERACHAD /mnt/terachad nfs4 _netdev,noauto,nofail,bg,x-systemd.automount,x-systemd.requires=network-online.target,x-systemd.after=network-online.target,x-systemd.idle-timeout=60s,noatime,nodiratime,async,rsize=65536,wsize=65536,actimeo=1  0 0</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Não esquecer de criar os mount points:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mkdir /mnt/gigachad
mkdir /mnt/terachad</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto, só rebootar e tudo vai funcionar corretamente. As permissões dos arquivos no NAS - que estão pro UID 1026 e GID 1026 - vão ser acessíveis pro usuário local sem problemas.</p>
<h2>10 - Utilitários<span class="hx:absolute hx:-mt-20" id="10---utilitários"></span>
    <a href="#10---utilit%c3%a1rios" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui são as últimas dicas pequenas pra ficar tudo num lugar só. A primeira é substituir o comando <code>ls</code> pelo <code>eza</code> que oferece uma cara mais bonita, com ícones e tudo mais, assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_16-50-25.png" alt="eza"  loading="lazy" /></p>
<p>Só fazer <code>yay -S eza</code> e adicionar isto no seu <code>.zshrc</code> ou <code>.bashrc</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>alias ls=&#39;eza --icons --color=auto --group-directories-first&#39;
alias ll=&#39;eza -l --icons --color=auto --group-directories-first&#39;
alias la=&#39;eza -la --icons --color=auto --group-directories-first&#39;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Segunda dica é instalar <a href="https://atuin.sh/"target="_blank" rel="noopener">Atuin</a>. Pra quem mexe com infra, isso é extremamente importante: backup de toda o histórico de comandos que você usou no seu terminal até hoje.</p>
<p>Instale com <code>yay -S atuin</code> e faça:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>atuin login
atuin sync</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Leia o site oficial, mas primeiro precisa criar uma conta e uma chave de encriptação secreta - sim, você pode rodar localmente num servidor na sua casa, mas a opção cloud deles é bem cômoda e segura porque fica toda encriptada, então não tem problema se subir senhas do seu histórico.</p>
<p>Só precisa colocar isso no seu <code>.zshrc</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>export ATUIN_NOBIND=true
eval &#34;$(atuin init zsh)&#34;
bindkey &#34;^R&#34; atuin-search

# incremental history search with arrow keys
bindkey &#34;^[[A&#34; history-beginning-search-backward
bindkey &#34;^[[B&#34; history-beginning-search-forward]]</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se estiver usando ZSH, o auto-complete dele vai funcionar normalmente mas, se digitar CTRL+R, vai abrir o histórico do Atuin. Ele vai guardar todos os seus comandos num SQLite e sincronizar. Assim você pode sincronizar diversas máquinas e servidores que usa no dia-a-dia ou, como no meu caso, recuperar o histórico todo numa nova instalação.</p>
<p>E pra ficar melhor, podemos configurar ele pra auto-sincronizar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mkdir -p ~/.config/atuin
sed -i &#39;s/^#\?auto_sync.*/auto_sync = true/; s/^#\?sync_frequency.*/sync_frequency = &#34;30m&#34;/&#39; ~/.config/atuin/config.toml 2&gt;/dev/null || \
printf &#39;auto_sync = true\nsync_frequency = &#34;30m&#34;\n&#39; &gt;&gt; ~/.config/atuin/config.toml</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Terceira dica: como temos Docker já instalado e configurado, eu gosto de usar o <a href="https://github.com/tbckr/sgpt"target="_blank" rel="noopener"><strong>SGPT</strong></a> na linha de comando pra quando quero lembrar a sintaxe de algum comando que uso pouco, em vez de abrir um app ou navegador. Basta adicionar isto no meu <code>.zshrc</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>export OPENROUTER_API_KEY=&#34;sk-or-v1-8b8...17&#34;
export OPENAI_API_KEY=&#34;sk-or-v1-db...f3&#34;
export OPENAI_API_BASE=&#34;https://openrouter.ai/api/v1&#34;

alias sgpt=&#39;docker run --rm -e OPENAI_API_BASE=${OPENAI_API_BASE} -e OPENAI_API_KEY=${OPENROUTER_API_KEY} ghcr.io/tbckr/sgpt:latest txt &#39;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Eu uso <a href="https://openrouter.ai/"target="_blank" rel="noopener">OpenRouter</a> pra ter acesso a diferentes LLMs comerciais numa única API, mas você pode só usar sua chave da OpenAI. Feito isso eu usaria no terminal parecido com isto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>~ ❯ sgpt &#34;what is the pacman command in Arch to find out if a particular file came from an installed package?&#34;
To find out if a particular file came from an installed package in Arch Linux, you can use the following pacman command:

``bash
pacman -Qo /path/to/file
``

Replace &#34;/path/to/file&#34; with the actual path to the file you want to check. This command will show the package which owns the file, or report that the file does not belong to any package if that is the case.</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se quiser, ele suporta sessões, então vai lembrar da conversa a cada nova chamada. Leia o Github do projeto.</p>
<p>Como fiz backup do meu <code>~/.config</code> antigo, coisas como abas abertas do meu navegador Brave abriram normalmente nessa nova instalação de Omarchy e posso continuar fazendo minhas coisas exatamente do ponto onde parei. Não perdi nada. Mesma coisa vale pra todos os outros apps como emails que faço backup local via Thunderbird. Não preciso mandar baixar tudo de novo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/screenshot-2025-08-29_15-59-34.png" alt="Audio Output"  loading="lazy" /></p>
<p>Se como eu, você tem vários dispositivos de saída de áudio, é possível que logo que terminar de instalar note que parece que não tem som. Mas não é um problema porque pode ser só que a saída está apontando pro dispositivo errado ou no perfil errado. Use SUPER ALT SPACE pra abrir o menu do Omarchy, escolha SETUP e AUDIO pra abrir esse programa que é em modo texto (eu gosto de programas em modo texto).</p>
<p>No meu caso, uso um DAC Topping D70 pra processar meu áudio e o perfil &ldquo;Default&rdquo; não funciona mas mudando pra &ldquo;Pro Audio&rdquo; funcionou. Também cuidado que tem configuração de volume global e controle individual de volume por programa. No geral, graças ao Pipewire, tudo deve funcionar normalmente.</p>
<p>Eu testei apps como Discord, Blender, Bambu Studio, VLC e tudo funcionando perfeitamente bem. Só VLC que precisei instalar os codecs de um pacote separado:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S extra/vlc-plugin-ffmpeg</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Blender também, o melhor é instalar deste pacote:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S blender-bin</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se usar o pacote &ldquo;blender&rdquo; normal, alguns add-ons dele não instalam direito. Eu tive esse problema com MACHIN3Tools e MESHMachine, por exemplo.</p>
<p>Falando em Blender, ele é um app X11. Wayland roda aplicativos X11 usando uma camada adaptadora chamada <strong>XWayland</strong>. Eu tive vários problemas com posicionamento de menus e dialog boxes, mesmo adicionando <code>windowrule</code>. Uma coisa que sei lá porque funcionou foi instalar Blender e Bambu Studio via Flatpak:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>yay -S flatpak
flatpak install org.blender.Blender
flatpak install com.bambulab.BambuStudio</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Finalmente, se você é novo em LazyVim, não esqueça de rodar o comando <a href="https://www.lazyvim.org/extras"target="_blank" rel="noopener"><code>:LazyExtras</code></a> pra instalar os plugins extras pras suas linguagens favoritas, como LSP, Linter, syntax highlight, snippets e mais. O LazyVim puro já é completo mas sem suporte a muitas linguagens pra não ficar pesado desnecessariamente, você precisa instalar separado depois.</p>
<p>Também aprenda a usar <a href="https://mise.jdx.dev/dev-tools/"target="_blank" rel="noopener"><strong>Mise-en-place</strong></a>. No menu do Omarchy tem uma opção pra instalar suporte a várias linguagens e ele vai usar Mise, que é a forma correta de gerenciar suas linguagens.</p>
<p>Mise é muito fácil, no geral, de dentro do diretório do seu projeto, é só fazer algo como:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>mise use ruby@3.4.3</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Com isso, só dentro do seu projeto vai estar disponível Ruby 3.4.3, mas fora pode estar outra versão global. Não esquecer de ativar no seu <code>.zshrc</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>eval &#34;$(mise activate zsh)&#34;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h2>Impressões e Conclusão<span class="hx:absolute hx:-mt-20" id="impressões-e-conclusão"></span>
    <a href="#impress%c3%b5es-e-conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Comparado ao meu Manjaro antigo, muita coisa que não precisei configurar mais. Por exemplo, por causa do tanto de espaço que Docker e LLMs precisavam, eu tinha configurado um drive iSCSI no meu NAS só pra isso. Mas como eu liberei 2 TB de NVME local, não preciso mais lidar com isso, basta usar os novos sub-volumes de BTRFS que criei acima.</p>
<p>Também não preciso mais configurar QEMU/Libvirt porque não preciso mais usar Windows junto com Linux lado a lado. Mantive o NVME com as partições Windows e posso fazer dual boot pra ela se precisar muito de alguma coisa. No geral nunca preciso, então é menos uma configuração complicada.</p>
<p>Eu passei meses usando apps via Flatpak, com o intuito de ser mais seguro e isolado do sistema. É como rodar apps via Docker. Mas é chato demais. Por ser isolado significa que ele não obedece os temas do sistema, no final sou obrigado a ficar abrindo permissões pros apps. E se for pra ficar abrindo, é mais fácil instalar nativamente via <code>yay</code> e tudo funciona perfeitamente.</p>
<p>Acho que isso completa minhas anotações de tudo que precisei fazer pra deixar o Omarchy exatamente do jeito que eu gosto. Como falei repetidas vezes, o que funciona pra mim não quer dizer que vai funcionar pra você. Pra isso existe documentações como o <a href="https://wiki.archlinux.org/title/Main_page"target="_blank" rel="noopener">ArchWiki</a> que é &ldquo;O&rdquo; melhor lugar pra aprender tudo que sobre Linux. Use e abuse dessa documentação.</p>
<p>Como podem ver, não teve tanta coisa assim que eu customizei no Omarchy, por isso eu gosto dele: 95% do caminho ele já fez pra mim, só precisei mexer em poucos ajustes pra deixar do jeito que eu preciso. E agora sem o tanto de lixo que foi acumulando no meu Manjaro velho. Recomendo que todo mundo instale Omarchy como primeiro Linux e aprenda a usar de verdade.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>armazenamento-e-backup</category></item></channel></rss>