--- title: Navegador Híbrido Smallweb date: 2026-07-02 summary: Documentação de ideia para construir um navegador híbrido para Gemini, Gopher, Nex, Spartan e outros protocolos da smallweb. tags: [smallweb, gemini, gopher, nex, spartan, navegador, permacomputação, tui, go, rust] flowerColor: "#c7f7e8" --- # Navegador Híbrido Smallweb Um navegador híbrido para **Gemini**, **Gopher**, **Nex**, **Spartan** e outros protocolos pequenos não deve tentar competir com Chrome, Firefox ou Safari. Essa seria a primeira ideia errada. Ele deve competir com outra coisa: a dependência da web moderna como único modo aceitável de acessar, publicar e preservar conteúdo. A ideia aqui é construir um navegador leve, modular, textual, seguro e extensível para explorar a smallweb: cápsulas Gemini, buracos Gopher, espaços Nex, servidores Spartan, arquivos, páginas simples, logs pessoais, diretórios, feeds e documentos. Ele deve ser pequeno o bastante para rodar em hardware velho, mas organizado o bastante para não virar brinquedo abandonado depois da primeira versão. --- ## Diagnóstico A web moderna virou pesada demais para uma parte enorme do que as pessoas realmente precisam fazer. Muitas páginas que poderiam ser documentos simples viraram aplicações gigantescas, cheias de JavaScript, rastreadores, fontes externas, frameworks, banners, métricas, cookies e dependências. Enquanto isso, protocolos como **Gopher**, **Gemini**, **Nex** e **Spartan** mantêm uma proposta radicalmente simples: - conectar; - pedir um recurso; - receber texto, menu ou arquivo; - navegar; - fechar a conexão. Não há DOM monstruoso. Não há JavaScript obrigatório. Não há publicidade embutida por padrão. Não há modelo de atenção baseado em vício. Isso torna esses protocolos interessantes para: - smallweb; - indieweb; - permacomputação; - publicação pessoal; - servidores pequenos; - hardware antigo; - arquivos comunitários; - educação técnica; - cyberativismo; - preservação digital. --- ## Nome provisório ### `Moth` Nome sugerido: **Moth**. A mariposa combina com a ideia de navegar por luzes pequenas na escuridão. Mas o nome é secundário. O mais importante é a arquitetura. Outras opções: - `Lantern` - `Burrow` - `Capsule` - `Smallgate` - `Gloom` - `Murmur` - `Nighthost` - `Wayfarer` - `Peregrine` - `Hollow` --- ## Objetivo do projeto Criar um navegador híbrido, modular e leve para protocolos da smallweb. O navegador deve abrir, navegar, exibir, baixar, arquivar e favoritar conteúdos de múltiplos protocolos, usando uma interface simples e uma arquitetura interna comum. ### Objetivo principal Construir primeiro um **MVP TUI**. Ou seja: um navegador em terminal, bonito e funcional, com suporte inicial a Gemini e Gopher. Depois disso, adicionar Nex, Spartan e uma interface desktop. ### O que ele não deve ser no começo Ele não deve começar como: - navegador web completo; - substituto de Firefox; - cliente mobile; - engine HTML; - leitor universal de tudo; - plataforma social; - aplicativo Electron pesado; - software com 40 preferências antes de abrir a primeira página. Isso mataria o projeto. --- ## Princípio central > O protocolo muda. O documento interno permanece. Cada protocolo deve ser convertido para uma estrutura interna comum chamada, por exemplo, `Document`. A interface não deve se importar se o conteúdo veio de Gemini, Gopher, Nex ou Spartan. Ela deve receber um documento já normalizado. ```go type Document struct { URL string Title string MimeType string Protocol string Blocks []Block Links []Link RawBytes []byte StatusCode string Meta string } ``` Essa separação é o que impede o projeto de virar uma bagunça. --- ## Protocolos-alvo | Protocolo | Prioridade | Dificuldade | Observação | | --------- | ---------- | ----------- | ---------- | | Gemini | Alta | Média | Começar por ele. Precisa de TLS e TOFU. | | Gopher | Alta | Baixa | Simples, antigo, ótimo para MVP. | | Nex | Média | Baixa | Muito simples; bom para adicionar cedo. | | Spartan | Média | Média | Tratar como experimental até confirmar a spec final usada. | | Finger | Baixa | Baixa | Pode ser um módulo futuro divertido. | | HTTP | Baixa | Alta | Não implementar render web. Abrir externamente. | | File | Média | Baixa | Permitir abrir arquivos locais `.gmi`, `.txt`, `.md`. | --- ## Gemini Gemini é um protocolo de aplicação para acesso a documentos remotos, parecido em espírito com HTTP e Gopher, mas com simplicidade deliberada. Características importantes: - usa URLs `gemini://`; - normalmente usa a porta `1965`; - usa TLS; - funciona em modelo request-response; - o cliente envia uma URL terminada por CRLF; - o servidor responde com status, meta e corpo; - o formato nativo é `text/gemini`, também chamado de Gemtext; - Gemtext é line-oriented, com links, títulos, listas, citações e blocos preformatados. ### Pontos críticos em Gemini O maior detalhe não é renderizar texto. Isso é fácil. O ponto crítico é segurança: - validação TLS; - TOFU, ou trust on first use; - persistência de certificados conhecidos; - alerta quando certificado muda; - suporte opcional a certificados de cliente; - redirects limitados; - tratamento de input status; - downloads seguros. ### Tipos de status Gemini O cliente deve tratar famílias de status: | Classe | Significado geral | | ------ | ----------------- | | `1x` | Input necessário | | `2x` | Sucesso | | `3x` | Redirect | | `4x` | Falha temporária | | `5x` | Falha permanente | | `6x` | Certificado de cliente necessário | ### Parser Gemtext Blocos principais: | Sintaxe | Bloco | | ------- | ----- | | `#` | Heading 1 | | `##` | Heading 2 | | `###` | Heading 3 | | `=>` | Link | | `*` | Lista | | `>` | Citação | | ``` | Bloco preformatado | | texto | Parágrafo | --- ## Gopher Gopher é mais antigo e ainda mais simples. Ele funciona como um sistema de documentos e menus distribuídos. Características importantes: - usa URLs `gopher://`; - normalmente usa a porta `70`; - o cliente envia um selector; - o servidor responde com texto ou menu; - menus têm linhas com tipo, nome, selector, host e porta; - é extremamente fácil de depurar manualmente; - a resposta de diretório termina com um ponto em uma linha isolada. ### Tipos Gopher básicos | Tipo | Significado | | ---- | ----------- | | `0` | Arquivo de texto | | `1` | Diretório/menu | | `3` | Erro | | `7` | Busca | | `9` | Arquivo binário | | `g` | GIF | | `I` | Imagem | | `h` | HTML ou link externo | | `i` | Linha informativa | ### Parser Gopher Cada linha de menu pode virar um `Block`. Exemplo interno: ```go type GopherItem struct { Type rune Label string Selector string Host string Port int } ``` O navegador deve exibir menus como listas navegáveis. --- ## Nex Nex é um protocolo simples de recuperação distribuída de documentos, inspirado por Gopher e Gemini. Características importantes: - usa porta `1900`; - o cliente conecta e envia um caminho, que pode ser vazio; - o servidor responde com texto ou binário; - a conexão é fechada após a resposta; - não mantém estado; - diretórios podem usar linhas começando com `=>` como links; - se não houver extensão, o cliente pode assumir texto puro. ### Por que Nex é interessante Nex é quase brutal na simplicidade. Isso é ótimo para um navegador pequeno. Ele pode ser implementado depois de Gemini e Gopher com pouco esforço, desde que o core esteja bem separado. --- ## Spartan Spartan deve ser tratado como protocolo experimental no projeto. Não coloque Spartan como base do MVP. A regra prática: 1. criar interface `Fetcher`; 2. implementar Gemini; 3. implementar Gopher; 4. implementar Nex; 5. só então adicionar Spartan; 6. manter Spartan isolado atrás de feature flag. ### Política para Spartan Como o ecossistema é menor e mais difícil de pesquisar em fontes HTTP comuns, o projeto deve guardar a spec usada dentro de `docs/specs/spartan.md`, com data e origem. Isso evita o erro clássico: implementar uma interpretação pessoal do protocolo e depois descobrir que os servidores reais falam outra variação. --- ## Stack recomendada A recomendação principal é: > **Go no core + Bubble Tea na TUI + SQLite/JSON para estado.** Isso dá velocidade de desenvolvimento, binários simples, boa rede, boa portabilidade e manutenção razoável. ### Stack principal | Camada | Escolha recomendada | | ------ | ------------------- | | Linguagem | Go | | TUI | Bubble Tea | | Componentes TUI | Bubbles | | Estilo terminal | Lip Gloss | | Configuração | TOML | | Estado simples | SQLite ou JSON | | Logs | slog | | Testes | testing nativo do Go | | Build | GoReleaser | | Desktop futuro | Tauri ou Fyne | | Documentação | Markdown | | CI | GitHub Actions ou Forgejo Actions | --- ## Por que Go? Go é uma escolha pragmática. Vantagens: - rede excelente; - TLS nativo; - binário único; - compilação cruzada simples; - consumo razoável; - código legível; - biblioteca padrão forte; - curva menor que Rust; - ótimo para ferramentas CLI/TUI. Desvantagens: - menos garantias que Rust; - UI desktop nativa não é seu ponto forte; - gerenciamento de erros pode ficar repetitivo; - bibliotecas Gemini/Gopher podem ser menos maduras que implementar você mesmo. Mesmo assim, para este projeto, Go é provavelmente o caminho mais rápido para sair do papel. --- ## Alternativa em Rust Rust é excelente para segurança, performance e binários pequenos. Stack possível: | Camada | Escolha | | ------ | ------- | | Linguagem | Rust | | TUI | Ratatui | | Terminal backend | Crossterm | | TLS | rustls | | Config | serde + toml | | Storage | rusqlite | | CLI | clap | | Logs | tracing | | Desktop | Tauri | ### Quando escolher Rust Escolha Rust se o objetivo for: - máxima robustez; - segurança de memória; - projeto de longo prazo; - integração futura com Tauri; - distribuição como software mais sério. ### Quando não escolher Rust Não escolha Rust se você quer MVP rápido e pouca fricção. Rust é ótimo, mas ele cobra pedágio. --- ## Alternativa em Python Python pode servir para protótipo, mas eu não faria o produto final nele. Vantagens: - rápido de escrever; - ótimo para testar parsers; - bom para protótipos; - muitas bibliotecas. Desvantagens: - distribuição pior; - dependências mais frágeis; - performance menor; - empacotamento multiplataforma mais chato; - menos coerente com a ideia de navegador leve e permanente. Python pode ser usado para scripts auxiliares, testes de crawler e conversores. --- ## Interface inicial A primeira interface deve ser TUI. Nada de abrir com GUI antes de provar o core. ### Tela sugerida ```txt ┌────────────────────────────────────────────────────────────────────┐ │ Moth gemini://example.org/ │ ├────────────────────────────────────────────────────────────────────┤ │ # Example Capsule │ │ │ │ Welcome to a small place on the network. │ │ │ │ [1] About this capsule │ │ [2] Recent notes │ │ [3] Archive │ │ │ ├────────────────────────────────────────────────────────────────────┤ │ ↑/↓ scroll enter open b back f forward / search q quit │ └────────────────────────────────────────────────────────────────────┘ ``` ### Atalhos essenciais | Tecla | Ação | | ----- | ---- | | `q` | sair | | `g` | abrir URL | | `enter` | abrir link selecionado | | `b` | voltar | | `f` | avançar | | `r` | recarregar | | `/` | buscar na página | | `s` | salvar/download | | `a` | adicionar favorito | | `B` | abrir favoritos | | `h` | histórico | | `y` | copiar URL | | `?` | ajuda | | `o` | abrir link HTTP externamente | --- ## Arquitetura A arquitetura deve ter separação radical entre: - protocolos; - documento interno; - renderização; - interface; - storage; - segurança. ### Estrutura de pastas sugerida ```txt moth/ cmd/ moth/ main.go internal/ app/ app.go commands.go state.go protocol/ fetcher.go gemini/ client.go parser.go certs.go gopher/ client.go parser.go nex/ client.go parser.go spartan/ client.go parser.go document/ document.go blocks.go links.go normalize.go render/ text.go terminal.go download.go storage/ bookmarks.go history.go certstore.go cache.go security/ url.go redirects.go downloads.go external.go config/ config.go defaults.go ui/ tui/ model.go update.go view.go keymap.go styles.go docs/ specs/ gemini.md gopher.md nex.md spartan.md architecture.md security.md testdata/ gemini/ gopher/ nex/ go.mod README.md LICENSE ``` --- ## Interface comum de protocolo ```go type Fetcher interface { Schemes() []string Fetch(ctx context.Context, req Request) (*Response, error) } ``` ```go type Request struct { URL string Method string Input string Headers map[string]string } ``` ```go type Response struct { FinalURL string Status string Meta string MimeType string Body []byte Links []Link } ``` ### Registro de protocolos ```go type Registry struct { fetchers map[string]Fetcher } func (r *Registry) Register(fetcher Fetcher) { for _, scheme := range fetcher.Schemes() { r.fetchers[scheme] = fetcher } } ``` --- ## Documento interno ```go type BlockType string const ( BlockParagraph BlockType = "paragraph" BlockHeading1 BlockType = "heading1" BlockHeading2 BlockType = "heading2" BlockHeading3 BlockType = "heading3" BlockQuote BlockType = "quote" BlockListItem BlockType = "list_item" BlockLink BlockType = "link" BlockPre BlockType = "pre" BlockInfo BlockType = "info" BlockError BlockType = "error" ) ``` ```go type Block struct { Type BlockType Text string URL string } ``` ```go type Link struct { Index int Text string URL string } ``` Esse formato permite transformar Gemini, Gopher, Nex e Spartan em uma mesma linguagem visual. --- ## Renderização A renderização deve ser simples. Nada de tentar simular HTML. ### Regras - títulos devem se destacar; - links devem ser numerados; - texto deve quebrar de acordo com a largura do terminal; - blocos preformatados devem preservar espaçamento; - downloads devem ser claramente marcados; - links externos devem pedir confirmação; - imagens devem ser baixadas ou abertas externamente; - binários nunca devem ser executados. ### Política para imagens No MVP: - detectar imagem por MIME ou extensão; - perguntar se deseja baixar ou abrir externamente; - não renderizar imagem no terminal. Futuro: - preview via sixel/kitty graphics; - thumbnails opcionais; - modo texto puro sempre disponível. --- ## Storage O navegador precisa persistir: - histórico; - favoritos; - certificados TOFU; - cache opcional; - downloads; - configurações; - sessões; - identidade/certificados de cliente. ### Opção simples: JSON Boa para MVP: ```txt ~/.config/moth/config.toml ~/.local/share/moth/bookmarks.json ~/.local/share/moth/history.json ~/.local/share/moth/certs.json ``` ### Opção mais robusta: SQLite Melhor para evolução: ```txt ~/.local/share/moth/moth.db ``` Tabelas: ```sql CREATE TABLE history ( id INTEGER PRIMARY KEY, url TEXT NOT NULL, title TEXT, protocol TEXT, visited_at TEXT NOT NULL ); ``` ```sql CREATE TABLE bookmarks ( id INTEGER PRIMARY KEY, url TEXT NOT NULL UNIQUE, title TEXT, tags TEXT, created_at TEXT NOT NULL ); ``` ```sql CREATE TABLE certificates ( host TEXT NOT NULL, port INTEGER NOT NULL, fingerprint TEXT NOT NULL, first_seen TEXT NOT NULL, last_seen TEXT NOT NULL, PRIMARY KEY (host, port) ); ``` --- ## Segurança Este projeto parece simples, mas segurança ainda importa. Não por causa de “exploit hollywoodiano”. Por causa de erro besta. ### Riscos reais | Risco | Mitigação | | ---- | --------- | | Certificado Gemini mudou | Alertar e bloquear por padrão | | Redirect infinito | Limite de 5 redirects | | URL malformada | Parser rígido | | Download perigoso | Nunca executar automaticamente | | Link externo | Pedir confirmação | | `file://` indevido | Desabilitado por padrão | | Path traversal | Normalizar paths | | Conteúdo binário disfarçado | Detectar e tratar como download | | Resposta gigante | Limite configurável | | Host travado | Timeout obrigatório | ### Política de downloads Downloads devem ir para: ```txt ~/Downloads/moth/ ``` Ou diretório definido no config. Nunca abrir automaticamente. Nunca marcar como executável. Nunca sobrescrever sem confirmação. ### Política de links HTTP/HTTPS O navegador não deve renderizar HTTP. Ele deve: - detectar link HTTP/HTTPS; - mostrar aviso; - abrir no navegador padrão se o usuário confirmar. --- ## Certificados Gemini e TOFU TOFU significa **trust on first use**. Na primeira conexão com um host Gemini, o navegador guarda a fingerprint do certificado. Em conexões futuras: - se a fingerprint for igual, segue; - se mudou, alerta; - se o usuário aceitar, atualiza; - se o usuário recusar, aborta. ### Exemplo de alerta ```txt Certificado alterado para gemini://example.org Fingerprint anterior: SHA256: abc123... Fingerprint nova: SHA256: def456... Isso pode ser renovação legítima ou ataque man-in-the-middle. [aceitar uma vez] [atualizar] [cancelar] ``` --- ## Configuração Arquivo: ```toml [general] home = "gemini://geminiprotocol.net/" downloads_dir = "~/Downloads/moth" open_external_http = "ask" max_response_size_mb = 20 redirect_limit = 5 timeout_seconds = 15 [ui] theme = "dark" show_line_numbers = false link_style = "numbered" mouse = true [protocols.gemini] enabled = true verify_mode = "tofu" client_cert_dir = "~/.config/moth/certs" [protocols.gopher] enabled = true [protocols.nex] enabled = true [protocols.spartan] enabled = false [privacy] save_history = true cache_pages = false ``` --- ## Dependências recomendadas em Go ### Core | Dependência | Uso | | ----------- | --- | | `net` | TCP | | `net/url` | parsing de URL | | `crypto/tls` | TLS para Gemini | | `crypto/x509` | certificados | | `context` | timeouts/cancelamento | | `log/slog` | logs | | `os/exec` | abrir navegador externo | | `database/sql` | SQLite | | `encoding/json` | storage simples | | `errors` | erros tipados | ### Bibliotecas externas | Biblioteca | Uso | | ---------- | --- | | `charmbracelet/bubbletea` | TUI | | `charmbracelet/bubbles` | componentes TUI | | `charmbracelet/lipgloss` | estilos no terminal | | `spf13/cobra` | CLI | | `spf13/viper` | configuração | | `BurntSushi/toml` | TOML simples | | `mattn/go-sqlite3` | SQLite com CGO | | `modernc.org/sqlite` | SQLite sem CGO | | `atotto/clipboard` | copiar URL | | `skratchdot/open-golang` | abrir links externos | | `goreleaser/goreleaser` | builds | ### Nota brutal sobre dependências Não exagere. Para o MVP, use poucas dependências: ```txt bubbletea bubbles lipgloss toml sqlite ou json ``` O resto entra depois. --- ## Dependências recomendadas em Rust | Crate | Uso | | ----- | --- | | `ratatui` | TUI | | `crossterm` | backend terminal | | `rustls` | TLS | | `webpki-roots` | raízes TLS, se necessário | | `serde` | serialização | | `toml` | configuração | | `rusqlite` | SQLite | | `clap` | CLI | | `url` | parsing de URL | | `tracing` | logs | | `directories` | caminhos padrão | | `open` | abrir links externos | --- ## Desktop futuro Depois do MVP TUI, há três caminhos. ### Caminho 1: Tauri Melhor se você quiser: - desktop bonito; - frontend web local; - core em Rust; - app multiplataforma; - possível mobile futuro. Problema: - se o core estiver em Go, integrar com Tauri exige bridge; - pode ficar pesado conceitualmente para um navegador smallweb; - ainda depende de WebView. ### Caminho 2: Fyne Melhor se você quiser: - continuar em Go; - GUI multiplataforma; - empacotamento simples; - menos peças. Problema: - UI pode ficar com cara genérica; - controle visual menor. ### Caminho 3: GTK Melhor se você quiser: - estética Linux/Unix; - app mais nativo; - integração com desktop livre. Problema: - multiplataforma mais chato; - empacotamento mais trabalhoso. ### Recomendação Comece com TUI. Só faça desktop quando o core estiver bom. --- ## MVP v0.1 O MVP deve ser pequeno e realista. ### Escopo - abrir URL Gemini; - abrir URL Gopher; - renderizar Gemtext; - renderizar Gopher menus; - navegar por links; - voltar/avançar; - abrir URL manualmente; - salvar favoritos; - histórico básico; - downloads simples; - TOFU para Gemini; - abrir HTTP externamente; - config mínima. ### Fora do escopo - abas; - imagens inline; - Spartan; - Nex; - busca global; - sincronização; - contas; - plugins; - mobile; - temas avançados; - proxy; - indexador; - crawler. --- ## MVP v0.2 Adicionar: - Nex; - busca na página; - tags em favoritos; - export/import bookmarks; - cache opcional; - modo offline para páginas salvas; - melhor tela de erro; - suporte a certificados de cliente Gemini; - página inicial configurável; - comando `moth gemini://...`; - comando `moth --download URL`. --- ## MVP v0.3 Adicionar: - Spartan; - abas ou buffers; - bookmarks por pasta/tag; - leitor de feeds; - coleção de cápsulas; - painel de descoberta; - modo arquivo local; - render Markdown local; - suporte inicial a plugins simples; - tema Catppuccin/monocromático; - pacote `.deb`, `.rpm`, AppImage e Windows portable. --- ## Roadmap sugerido | Versão | Meta | | ------ | ---- | | `0.0.1` | Abrir uma URL Gemini e imprimir no terminal | | `0.0.2` | Parser Gemtext | | `0.0.3` | UI Bubble Tea básica | | `0.0.4` | Links navegáveis | | `0.0.5` | Histórico e voltar | | `0.0.6` | Gopher | | `0.0.7` | Favoritos | | `0.0.8` | Downloads | | `0.0.9` | TOFU Gemini | | `0.1.0` | Primeiro MVP usável | | `0.2.0` | Nex | | `0.3.0` | Spartan experimental | | `0.4.0` | Pacotes e releases | | `1.0.0` | Estável para uso diário | --- ## Comandos CLI ```bash moth gemini://geminiprotocol.net/ ``` ```bash moth gopher://gopher.floodgap.com/ ``` ```bash moth --no-history gemini://example.org/ ``` ```bash moth bookmark add gemini://example.org/ --tag smallweb ``` ```bash moth history ``` ```bash moth certs list ``` ```bash moth certs forget gemini://example.org/ ``` --- ## UX A UX deve ser calma. Nada de tentar imitar navegador moderno. ### Princípios de UX - texto legível; - links claros; - atalhos previsíveis; - erros humanos; - downloads explícitos; - nenhuma surpresa; - nenhuma execução automática; - tudo exportável; - tudo compreensível. ### Mensagem de erro ruim ```txt ERR_TLS_CERT_MISMATCH ``` ### Mensagem de erro boa ```txt O certificado deste servidor Gemini mudou. Isso pode ser normal, mas também pode indicar interceptação. Host: gemini://example.org Use: [a] aceitar nova fingerprint [c] cancelar [?] entender este aviso ``` --- ## Página inicial A página inicial pode mostrar: - URL configurada; - favoritos recentes; - histórico recente; - cápsulas sugeridas; - ajuda rápida; - últimos downloads. Exemplo: ```txt Moth Home: gemini://geminiprotocol.net/ Favorites: 1. Project Gemini 2. Floodgap Gopher 3. Nightfall Nex Commands: g open URL B bookmarks h history ? help ``` --- ## Sistema de plugins Não implementar plugins no começo. Mas deixar a arquitetura pronta. Futuro: - protocolo novo; - conversor de formato; - exportador; - tema; - comando; - filtro de conteúdo. ### Interface futura ```go type Plugin interface { Name() string Register(registry *Registry) error } ``` --- ## Testes Testar protocolos com fixtures locais. ### Testes mínimos - parse de URL Gemini; - parse de resposta Gemini; - parse de Gemtext; - parse de Gopher menu; - parse de Nex links; - normalização de links relativos; - redirect limit; - certificado mudou; - download com nome repetido; - resposta maior que limite; - timeout. ### Testdata ```txt testdata/ gemini/ simple.gmi links.gmi preformatted.gmi redirects.txt gopher/ menu.txt text.txt nex/ index.txt ``` --- ## Crawler opcional Não coloque crawler no MVP. Mas um crawler pequeno pode virar ferramenta separada: ```bash moth-crawl gemini://example.org/ --depth 2 --output archive/ ``` Uso: - espelhar cápsulas; - arquivar smallweb; - gerar índice; - encontrar links quebrados; - criar coleção offline. Isso combina muito com preservação digital. Mas se entrar cedo, vai bagunçar o navegador. --- ## Integração com permacomputação Este projeto deve ter compromisso explícito com hardware modesto. ### Metas técnicas - rodar bem em 512 MB de RAM; - funcionar em terminal simples; - não depender de GPU; - binário pequeno; - sem Electron no MVP; - sem telemetria; - sem conta; - sem cloud obrigatória; - sem atualização forçada; - configuração em arquivos legíveis. --- ## Licença Sugestão: - **AGPLv3**, se você quer forçar compartilhamento de modificações em versões de rede; - **GPLv3**, se quer manter copyleft forte; - **MIT**, se quer máxima adoção e menos controle; - **Apache-2.0**, se quer permissiva com proteção de patente. Minha recomendação brutal: Use **GPLv3** ou **AGPLv3**. Se o projeto é cyberativista e smallweb, MIT pode ser permissivo demais para empresas pegarem, embrulharem e devolverem nada. --- ## README inicial ```md # Moth A small hybrid browser for Gemini, Gopher, Nex, Spartan and other quiet protocols. Moth is not a web browser. It is a lantern for the small internet. ## Goals - Lightweight - Text-first - Protocol-oriented - Offline-friendly - Privacy-respecting - Useful on old machines ## Supported protocols - Gemini - Gopher - Nex - Spartan experimental ## Status Pre-alpha. ``` --- ## Manifesto curto do projeto > A web não precisa ser pesada para ser viva. > > Um documento não precisa de um império para existir. > > Um computador velho não é lixo quando ainda pode carregar uma ideia. > > Moth é uma lanterna para redes pequenas. --- ## Tabela de decisão | Decisão | Escolha | | ------- | ------- | | MVP | TUI | | Linguagem | Go | | UI | Bubble Tea | | Estilo | Lip Gloss | | Protocolos iniciais | Gemini + Gopher | | Storage inicial | JSON | | Storage futuro | SQLite | | Desktop futuro | Tauri ou Fyne | | Segurança Gemini | TOFU obrigatório | | HTTP | abrir externamente | | Imagens | baixar/abrir externamente | | Plugins | só depois | | Licença | GPLv3 ou AGPLv3 | --- ## Plano de execução em 14 passos 1. Criar repositório. 2. Criar CLI mínima. 3. Criar interface `Fetcher`. 4. Implementar Gemini básico. 5. Implementar parser Gemtext. 6. Imprimir documento no terminal. 7. Criar UI Bubble Tea. 8. Adicionar navegação por links. 9. Adicionar histórico. 10. Implementar Gopher. 11. Adicionar favoritos. 12. Implementar downloads. 13. Implementar TOFU. 14. Lançar `v0.1.0`. --- ## Primeira tarefa real Não comece desenhando interface. Comece assim: ```bash moth gemini://geminiprotocol.net/ ``` O programa deve: 1. conectar; 2. validar TLS de forma mínima; 3. enviar URL + CRLF; 4. ler status; 5. ler corpo; 6. imprimir no terminal. Só depois disso existe projeto. Antes disso existe fantasia. --- ## Fontes e referências - Gemini Protocol: https://geminiprotocol.net/ - Gemini / Gemtext overview: https://en.wikipedia.org/wiki/Gemini_%28protocol%29 - RFC 1436 — The Internet Gopher Protocol: https://datatracker.ietf.org/doc/html/rfc1436 - Nex Protocol Specification: https://nightfall.city/nex/info/specification.txt - Bubble Tea: https://github.com/charmbracelet/bubbletea - Lip Gloss: https://github.com/charmbracelet/lipgloss - Ratatui: https://ratatui.rs/ - Tauri: https://tauri.app/ - Permacomputing: https://permacomputing.net/ --- ## Detalhes recolhíveis
Notas de escopo para não destruir o projeto O perigo deste projeto não é protocolo. O perigo é vaidade. Se você tentar fazer Gemini, Gopher, Nex, Spartan, HTTP, Markdown, RSS, imagens, abas, plugins, crawler, sincronização e desktop ao mesmo tempo, o projeto morre. Faça um cliente Gemini feio. Depois faça ele bonito. Depois adicione Gopher. Depois adicione Nex. Depois pense em Spartan. Depois pense em desktop. Essa ordem salva o projeto.
--- ### Dicas finais - **Não implemente HTTP renderizado.** Isso abre um inferno técnico desnecessário. - **Não comece por mobile.** Mobile mata projeto pequeno com detalhe idiota. - **Não invente parser universal.** Normalize cada protocolo para `Document`. - **Não confie em certificados silenciosamente.** TOFU precisa ser explícito. - **Não execute downloads.** Baixar é uma coisa; executar é outra. - **Não use Electron no MVP.** Seria contraditório com a proposta. - **Não coloque Spartan no centro.** Comece por Gemini e Gopher. - **Não confunda simples com malfeito.** Smallweb pede cuidado, não gambiarra relaxada.