estudo de caso · desde 2026-08
Anotadinho
"Eu gosto assim."
Editor de notas Markdown nativo, offline-first, inspirado no Obsidian e no Logseq. Projeto pessoal que uso para aprender Rust de verdade: arquitetura em crates, testes, CLI, TUI e um servidor MCP para agentes de IA.
- linhas de Rust
- 55.328
- testes automatizados
- 851
- commits
- 345
- crates
- 6
Decisões
Por que Rust?
Eu queria sair da zona de conforto do Python/TypeScript e entender memória, ownership e concorrência de verdade. Um editor de notas tem parser, I/O, índice e UI — cobre quase tudo.
Por que Tauri + Yew?
Bundle de ~1 MB contra ~100 MB de um Electron, e a UI também em Rust (compilada para WASM), com componentes e hooks parecidos com React. Avaliei Dioxus, Leptos e Svelte antes de decidir.
Por que arquivos .md?
Offline-first sem lock-in: o vault é uma pasta comum, sincronizável por pendrive ou qualquer cópia, legível em outro editor daqui a 10 anos.
Arquitetura
Workspace Cargo com crates isoladas. A UI Yew só conversa com o núcleo por comandos IPC do Tauri; CLI e TUI reutilizam o mesmo núcleo.
↓ tauri::command / chamadas diretas ↓
↓
core
modelo de blocos, parser Markdown, embeds, índice, consultas
vault
I/O de arquivos, watcher, locks
search
busca full-text com FTS5
Embeds que continuam sendo Markdown
Tudo fica em .md com frontmatter YAML. Os 9 tipos de embed interativo usam uma sintaxe {{ type: "X" }} que nunca colide com CommonMark, então o arquivo continua legível em qualquer editor.
- kanban
- calendar
- table
- callout
- columns
- gallery
- query
- timeline
- actions
{{ type: "kanban" }}
columns:
- name: A fazer
cards:
- title: Revisar parser de embeds
checklist: [testes, docs]
- name: Feito
cards:
- title: Servidor MCP
{{ /kanban }}IA que propõe, humano que decide
O servidor MCP (JSON-RPC sobre stdio) dá a agentes como o Claude Code leitura direta do vault — mas a única ferramenta de escrita é "propor". A mudança vai para uma tela de revisão e só vira arquivo após um clique humano.
//! As ferramentas de LEITURA são diretas. A de ESCRITA é `propor`,
//! não `escrever`: o agente não tem como gravar uma página, só
//! sugerir. O que ele propõe aparece na tela de revisão e só vira
//! arquivo depois de um clique humano.
//!
//! JSON-RPC 2.0 em linhas, sobre stdin/stdout: uma requisição por
//! linha, uma resposta por linha. É o transporte stdio do MCP.
use serde_json::{json, Value};
use std::io::{BufRead, Write};
/// Versão do protocolo que este servidor fala.
const VERSAO_PROTOCOLO: &str = "2024-11-05";crates/cli/src/mcp.rs
Desenvolvimento em ciclos
O projeto evolui por ciclos, não commits avulsos: cada ciclo lê uma tarefa, implementa, roda testes, valida critérios e registra status. Isso mantém mais de 800 testes verdes num código de 55 mil linhas.
Um núcleo, três interfaces
O mesmo núcleo em Rust alimenta o app desktop (Tauri + Yew/WASM, ~1 MB contra ~100 MB de um Electron), a CLI e a TUI no terminal.