kraa

Contribuir

Arquitetura

Como o código está organizado e as regras que mantêm os pacotes independentes.

O app é um binário Go com Wails v3: o backend cuida da bandeja, do atalho global, da captura/colagem e do cliente LLM; o modal é um frontend React embutido no binário.

 atalho global ──► main.go ──► internal/app (ImproveService) ──► internal/improver ──► internal/llm ──► LLM
                     │                 │  ▲                                                   (SSE)
                     │                 │  └─ eventos de stream ──► frontend (React, modal)
                     │                 └─► internal/platform (Capture/Paste, teclas por SO)
                     └─► bandeja, janela, single-instance, internal/autostart

Mapa de pacotes

PacoteResponsabilidade
main.goBootstrap do Wails: app, bandeja, janela, atalho global, single-instance.
internal/configTipos, Load/Default/ApplyEnv, validação e ações padrão.
internal/llmCliente OpenAI-compatível com streaming SSE e ListModels.
internal/improverMonta as mensagens (system + user) e roda o stream.
internal/platformClipboard/KeySender, Capture/Paste, detecção de sessão e teclas por SO.
internal/appImproveService exposto ao frontend (bindings) e adapters do Wails.
internal/autostart“Iniciar com o sistema”: LaunchAgent, chave Run, .desktop.
frontend/srcModal em React: App.tsx, components/*, hooks/useImprove.ts.
npm/Pacote npm: instalador (postinstall) e CLI kraa.
site/Este site (Astro + MDX + shadcn/ui).

Regras do projeto

  • internal/config, internal/llm, internal/improver e internal/platform/capture.go não importam o Wails. Só main.go, main_server.go (só E2E, -tags server) e internal/app dependem de github.com/wailsapp/wails/v3, o que mantém o núcleo testável sem interface gráfica.
  • Código específico de SO usa build tags (keys_darwin.go, keys_windows.go, keys_linux.go, session_linux.go), nunca if runtime.GOOS espalhado.
  • Textos da UI em PT-BR; identificadores e código em inglês.
  • internal/autostart gera artefatos idênticos aos da CLI npm (npm/src/autostart.ts): mudar um exige mudar o outro.

Como a captura funciona

  1. Guarda o conteúdo atual da área de transferência e grava um valor sentinela.
  2. Simula “Copiar” no app de origem (Cmd+C via CoreGraphics, SendInput, xdotool).
  3. Espera até 400 ms a área de transferência mudar; o novo valor é a seleção.
  4. Restaura o conteúdo original (se era texto).

“Substituir” faz o caminho inverso: grava o resultado, devolve o foco ao app de origem, simula “Colar” e restaura a área de transferência.

O design completo está em docs/superpowers/specs.