Visão geral
Conhecimento guardado em notas ligadas só é útil se as ligações puderem ser vistas e seguidas. O Parallelepiped abre qualquer pasta de arquivos Markdown como um cofre e mantém os próprios arquivos como a única fonte da verdade: não há formato proprietário nem etapa de importação. Sobre eles constrói um índice de ligações, tags e texto, usado para os backlinks, a busca e um grafo 3D que pode ser girado, aproximado e percorrido com o mouse para acender as conexões de uma nota. Também lê um repositório de código e gera um mapa ligado dos seus módulos, para que um projeto sem documentação possa ser explorado da mesma forma. É um projeto pessoal original, e não um fork de um aplicativo existente.
Minha contribuição
Sou o autor único. Desenhei as fronteiras entre os módulos e escrevi o backend em Go — cofre, notas, índice, watcher de arquivos e a importação estrutural — com o schema SQLite e as suas migrations; o frontend em TypeScript, com o editor, a coluna de contexto e o grafo 3D, incluindo a geometria dos neurônios e as otimizações de renderização; os temas claro e escuro e o ícone do aplicativo; e o Makefile, os testes e a documentação de arquitetura.
O projeto exercita duas coisas que valorizo: um monólito modular em camadas aplicado fora do mundo HTTP, e gráficos interativos que continuam rápidos sem abrir mão da aparência.
Arquitetura
Um único executável. O frontend roda no WebView2 do sistema e chama o backend em Go pelos bindings do Wails. O backend é um monólito modular: cinco módulos de negócio, cada um dividido em handler, service, model, repository e DTO, com as preocupações transversais numa camada de plataforma separada. Os módulos só conversam por interfaces pequenas definidas por quem as consome.
internal/modules,
internal/platform e frontend/src.
Organização do código
main.goé a composition root: monta repositórios, services e handlers e os liga ao Wails.internal/modulesreúne vault, notes, index, watcher e brain, cada um com handler, service, model, repository e DTO.internal/platformreúne o catálogo de erros, a validação por campo, o banco, o log e a ponte com o desktop.migrations/guarda o schema versionado do índice na raiz, embutido no binário.frontend/srcsepara as views (árvore, abas, editor, contexto, grafo) do cliente da API e dos módulos compartilhados de cores e tema.
Stack
- Backend: Go com Wails v2, um driver SQLite em Go puro com FTS5 e fsnotify para o watcher da pasta.
- Frontend: TypeScript e Vite, CodeMirror 6 no editor.
- Grafo: 3d-force-graph sobre three.js, com geometria própria de neurônio e bloom no tema escuro.
- Interface: layout original com tema claro e escuro e cores de pasta compartilhadas por todas as views.
- Entrega: um único executável gerado por Makefile, com instalador NSIS opcional.
Decisões de engenharia
Três decisões que moldaram o projeto, cada uma com a alternativa considerada e o que ela custa.
1. Os arquivos são a fonte da verdade; o banco é cache
- Decisão:
- as notas são arquivos
.mdcomuns, gravados de forma atômica (arquivo temporário e depois renomeação). O índice SQLite de ligações, tags e texto fica fora do cofre e pode ser apagado e reconstruído dos arquivos a qualquer momento; se a atualização do índice falhar depois de um salvamento, o salvamento vale e a falha vai para o log. - Alternativa:
- guardar as notas no banco e exportar Markdown quando pedido.
- Motivo:
- as notas do usuário continuam legíveis e editáveis com qualquer ferramenta e sob qualquer controle de versão, sem o app. Como o índice é derivado e de um único usuário, as suas migrations podem rodar com segurança na abertura — uma exceção deliberada à regra habitual, documentada nas notas de arquitetura.
- Limitação:
- o índice pode discordar do disco por um instante, e o que não está nos arquivos — como a disposição do grafo — não é guardado junto das notas.
2. Reconhecer as escritas do próprio app pelo hash do conteúdo, não por janela de tempo
- Decisão:
- o watcher espera cada caminho ficar 300 ms quieto e então o lê do disco. Ele guarda o hash do último conteúdo indexado; se o disco tem exatamente esse conteúdo, o evento veio do próprio app e é descartado.
- Alternativa:
- ignorar todos os eventos por um curto período depois de o app salvar uma nota.
- Motivo:
- uma janela de tempo ou engole uma edição externa real feita logo depois de um salvamento, ou deixa o salvamento do próprio app disparar uma reindexação. Comparar conteúdo não tem janela: a edição de fora é sempre percebida e os salvamentos do app nunca geram trabalho extra.
- Limitação:
- pastas removidas ou renomeadas, e eventos perdidos, ainda caem na reconstrução do índice do cofre inteiro.
3. Deixar o grafo mais rápido sem mudar um pixel
- Decisão:
- o grafo renderiza sob demanda — enquanto o layout se acomoda, a câmera se move ou o ponteiro está ativo — e pausa após 1,5 segundo de inatividade. Passar o mouse sobre um neurônio restiliza só as fibras ligadas a ele e ao neurônio anterior, atualizando as malhas no lugar.
- Alternativa:
- simplificar a cena — juntar as fibras em linhas planas ou abandonar a geometria tubular — para cortar o custo.
- Motivo:
- o estilo visual é a razão de ser do recurso, e uma versão simplificada foi rejeitada assim que foi vista. A biblioteca recriava todas as ligações a cada hover; restilizar só as afetadas levou o hover num cofre de cerca de 860 ligações de aproximadamente 150 ms para 7 ms, e o resultado foi conferido como idêntico ao da própria biblioteca.
- Limitação:
- a otimização depende de detalhes internos da biblioteca do grafo, então atualizá-la exige repetir essa verificação de equivalência.
Qualidade, segurança e custo
Tudo abaixo está no repositório público e pode ser conferido no código-fonte. Os números medidos vêm de uma única máquina de desenvolvimento e não são garantia para outro hardware.
Testes
- 13 arquivos de teste em Go com 49 funções de teste nos models, services e repositories de todos os módulos.
- Cobrem o parse das ligações, as consultas do índice, o debounce e o registro de escritas do watcher, e a análise e as regras de reimportação da importação estrutural.
make checkroda ogo vet, os testes em Go e a checagem de tipos do TypeScript.
Segurança das notas
- Apagar uma nota a move para a pasta
.trashdentro do cofre, com a data no nome; o app nunca exclui um arquivo permanentemente. - A importação estrutural só sobrescreve notas que ela mesma gerou, marcadas no front matter; a seção “Minhas anotações” de cada nota gerada sobrevive a toda reimportação.
- Os erros chegam ao frontend num único envelope, com código e mensagens por campo; os detalhes internos ficam no log.
Consumo
- Um único executável de cerca de 18 MB, sem runtime para instalar no Windows 11, que já traz o WebView2.
- O grafo para de desenhar quando está parado ou escondido, e desenha na resolução nativa da tela, sem supersampling.
- O hover sobre um neurônio custa cerca de 7 ms num cofre de cerca de 860 ligações.
Resultados e limitações
O que existe hoje é um aplicativo funcionando: abas e um editor com autocompletar de ligações; uma coluna de
contexto com mini-mapa 2D da vizinhança da nota, backlinks, ligações de saída e tags; busca de texto
completo; cores de pasta compartilhadas por todas as views; um grafo 3D com modo só-grafo; temas claro e
escuro; um índice que acompanha edições feitas fora do app; e uma importação estrutural que transforma um
repositório de código em notas ligadas dentro da sua própria pasta docs/.
Limitações declaradas
- Só o Windows 11 foi verificado. O Wails atende outros sistemas, mas nenhuma outra plataforma foi compilada ou testada.
- Renomear uma nota não reescreve as ligações que apontam para ela, e ainda não há pré-visualização renderizada; os dois são os próximos passos, seguidos de plugins isolados em WebAssembly.
- A importação estrutural é estática. Ela lê pacotes, símbolos exportados e imports em Go e imports relativos em TypeScript e JavaScript; não entende o que o código faz.
- O executável não é assinado, então o SmartScreen pode avisar na primeira execução.
- Não há dados de uso real. É um projeto pessoal; não declaro usuários, downloads nem adoção.
Explorar
O repositório é público e traz o README com as instruções de compilação, o documento de arquitetura, o guia de contribuição, o código de conduta e a política de segurança.
O vídeo e as imagens usam um cofre de demonstração fictício.
Galeria
Capturas do cofre de demonstração — selecione uma imagem para ampliá-la e navegar pela galeria.
O grafo 3D no modo só-grafo: cada nota é um neurônio, colorido pela pasta e dimensionado pelas ligações.
Uma nota com o seu contexto: mini-mapa da vizinhança, backlinks, ligações de saída e tags.
O mesmo grafo no tema claro.
O editor no tema claro, depois de uma ligação adicionada com autocompletar.