Eu gosto de Markdown justamente porque ele não tenta resolver o mundo. É texto, está no disco, funciona com Git, produz diffs legíveis, pode ser aberto no VS Code, Vim, terminal ou praticamente qualquer editor e, principalmente, não depende de uma plataforma para continuar existindo. Posso escrever hoje, mover a pasta de máquina daqui a alguns anos e continuar trabalhando sobre os mesmos arquivos. Essa simplicidade é uma das melhores propriedades do formato, mas existe um ponto em que ela começa a cobrar um preço: uma pasta cheia de .md continua sendo apenas uma coleção de arquivos, mesmo quando mentalmente já começamos a tratá-la como um conjunto relacionado de notas.

O exemplo mais óbvio são os wiki links. Escrever [[arquitetura]] em Markdown puro não significa absolutamente nada para o sistema de arquivos. É apenas uma sequência de caracteres que o autor decidiu interpretar como uma ligação entre duas coisas. Se arquitetura.md não existe, nada acontece; se existe, o editor normalmente não sabe disso; se outra nota aponta para ela, também não existe um índice reverso capaz de dizer quem referencia aquele documento. A relação existe na cabeça de quem escreve, mas ainda não existe no sistema. É justamente aí que, para mim, uma pasta deixa de ser suficiente.

A solução tradicional para esse problema é adotar alguma ferramenta de PKM. Obsidian é provavelmente o exemplo mais conhecido: resolve wiki links, backlinks, busca, grafo, plugins, sync e uma quantidade enorme de outras necessidades. Não há nada de errado nisso. O problema é que existe uma distância considerável entre “quero que meus arquivos Markdown saibam se relacionar” e “quero adotar um segundo cérebro completo”. Em determinado momento percebi que meu problema estava exatamente nesse intervalo. Eu não precisava substituir o filesystem por uma plataforma de conhecimento; precisava apenas fazer uma pasta Markdown deixar de ser burra.

Foi daí que nasceu o MD Studio.

A versão 0.1.0 é um editor Markdown desktop, Linux-first e local-first, construído com Tauri 2, React, TypeScript, Rust e CodeMirror 6. Os pacotes .deb e AppImage estão disponíveis na release v0.1.0. O projeto não nasceu da ideia de criar mais um editor Markdown, porque editor já existe aos montes. A questão era estabelecer algumas propriedades mínimas que transformassem uma pasta de documentos independentes em algo que pudesse efetivamente funcionar como um sistema de notas, sem obrigá-la a virar um vault, uma plataforma ou um ecossistema.

A primeira dessas propriedades é a resolução dos próprios links. No MD Studio, [[arquitetura]] e [[arquitetura|Arquitetura do sistema]] não são apenas elementos visuais reconhecidos pelo editor. Existe resolução para arquivo, autocomplete, possibilidade de criação da nota quando o alvo ainda não existe e, principalmente, um índice reverso que permite descobrir quais documentos apontam para a nota atualmente aberta. É isso que alimenta o painel de backlinks. E fiz questão de estabelecer uma regra simples: backlink é link resolvido. Se algum documento contém [[alguma-coisa]], mas alguma-coisa não pode ser resolvido dentro do workspace, aquilo não entra artificialmente no índice apenas para parecer que existe uma relação. É um link quebrado, e deve continuar sendo tratado como tal.

Esse detalhe parece pequeno, mas toca numa questão que considero importante na construção desse tipo de ferramenta: não basta reconhecer sintaxe, é preciso preservar semântica. Pintar [[nota]] com outra cor é trivial; estabelecer uma relação consistente entre documentos, mantê-la quando o filesystem muda e permitir navegar nos dois sentidos já transforma aquilo em uma propriedade do sistema.

A segunda decisão importante foi tratar o workspace como uma fronteira real. Quando uma pasta é aberta no MD Studio, é dentro dela que o programa deve operar. A camada Rust trabalha com paths canônicos e aplica um path fence, impedindo que operações de arquivo escapem do espaço autorizado por combinações de paths relativos ou outros caminhos inesperados. Se eu abri /home/elzo/notas, não existe razão para um editor de Markdown resolver explorar /home/elzo, /tmp ou qualquer outro lugar da máquina. Isso poderia ser tratado como detalhe interno de implementação, mas para mim é parte do contrato de um software local-first: o usuário escolheu um espaço de trabalho e essa escolha deve significar alguma coisa.

O mesmo raciocínio aparece no preview. Sempre me incomodou a ideia de um editor apresentar uma interpretação do Markdown durante a escrita e usar outro pipeline quando chega a hora de exportar. O resultado previsível é aquele documento que parecia correto dentro do programa e se comporta de outra maneira quando sai dele. No MD Studio, preview e export HTML passam pelo mesmo pipeline. GFM, matemática, syntax highlighting e Mermaid seguem a mesma interpretação, e o HTML produzido passa por rehype-sanitize. Não existe execução arbitrária de JavaScript vindo das notas e não há backend envolvido nesse processo. O documento está no disco antes de ser aberto, continua no disco enquanto está sendo editado e permanece um arquivo comum depois que o programa fecha. A exportação HTML também utiliza escrita atômica, porque gerar uma saída válida e depois destruí-la parcialmente no meio de uma falha não me parece uma característica aceitável só porque estamos falando de um editor pequeno.

Outro problema que aparece rapidamente quando se trabalha dessa forma é o conflito entre o buffer do editor e o filesystem. Quem usa Git, terminal, scripts, ferramentas de automação ou simplesmente outro editor pode modificar o mesmo arquivo enquanto ele está aberto. Se o buffer local está limpo, recarregar a versão do disco é relativamente simples. A situação muda quando existem alterações ainda não salvas. Nesse caso, sobrescrever silenciosamente uma das versões seria a solução mais fácil e provavelmente a pior. O watcher de filesystem do MD Studio usa debounce e, quando detecta esse conflito, a decisão volta para o usuário: recarregar o arquivo vindo do disco, manter a versão que está no editor ou salvar o conteúdo atual em outro arquivo. Não considero isso uma grande funcionalidade; considero apenas uma forma de não destruir trabalho.

É também por isso que tentei manter a versão 0.1 bastante explícita sobre aquilo que ela não faz. Não há grafo de notas, sync em nuvem, sistema de plugins JavaScript ou backend. Abrir diretamente um .md pelo associador de arquivos do sistema operacional ainda é um follow-up relacionado ao PR #2. A exportação atual é HTML; não PDF. Se o README diz HTML, então a funcionalidade publicada é HTML. Parece uma observação banal, mas existe uma tendência curiosa em projetos de software de apresentar roadmap, intenção e implementação como se fossem a mesma coisa. Prefiro separar as três.

Isso também ajuda a explicar por que não vejo o MD Studio como um concorrente direto do Obsidian. Se alguém precisa de grafo, sincronização entre vários dispositivos, plugins, aplicações móveis e um ecossistema grande em torno das notas, existem ferramentas maduras cuja finalidade é exatamente essa. Construir uma versão pequena das mesmas coisas seria apenas produzir um Obsidian pior. O problema que tentei resolver é outro: descobrir qual é a quantidade mínima de infraestrutura necessária para que uma pasta Markdown comece a se comportar como um sistema de notas sem deixar de ser, fundamentalmente, uma pasta Markdown.

Minha resposta atual é relativamente simples: arquivos locais, links que realmente resolvem, índice reverso, navegação e uma representação consistente do documento. Depois disso acontece uma mudança interessante. Os arquivos continuam independentes e continuam podendo ser abertos com cat, Vim ou VS Code, mas deixam de depender exclusivamente da memória do autor para saber como se relacionam. Se amanhã o MD Studio desaparecer, nada precisa ser migrado para recuperar as notas, porque não existe um formato proprietário escondido por baixo delas. O programa adiciona comportamento à pasta, não substitui a pasta.

Talvez seja isso que eu queira dizer quando chamo o projeto de um PKM mínimo, embora até essa expressão possa carregar mais bagagem do que o necessário. Entre uma coleção de arquivos Markdown e uma plataforma completa de gestão do conhecimento existe uma camada intermediária que raramente recebe muita atenção: resolução, navegação, backlinks, integridade de arquivos e um preview que represente honestamente aquilo que será exportado. Era essa camada que eu queria usar no dia a dia.

Então escrevi.