Central de carreira local para quem procura emprego em tecnologia.
Coleta vagas remotas em portais públicos, pontua cada uma contra o seu perfil, acompanha as candidaturas, monta currículos direcionados e calcula o que estudar em seguida. Sem conta, sem nuvem, sem assinatura.
Português · English
- Visão geral
- Instalação
- Primeiro uso
- Funcionalidades
- Fontes de vagas
- Política de coleta
- Alertas de vaga nova
- Leituras
- Assistente por inteligência artificial
- Linha de comando
- Dados e backup
- Execução em contêiner
- Arquitetura
- Desenvolvimento
- Privacidade e segurança
- Licença
O Farol é um aplicativo de desktop que roda inteiramente na máquina do usuário.
O servidor escuta apenas em 127.0.0.1, os dados ficam em um arquivo SQLite no
diretório do usuário e nenhuma informação é enviada para serviços externos —
exceto as requisições de leitura aos portais de vagas, aos feeds de leitura que
você ligar e, quando explicitamente habilitado, ao assistente por inteligência
artificial. O assistente pode ser um modelo rodando na sua própria máquina,
e aí nem esse tráfego sai da sua rede.
| Tela | Finalidade |
|---|---|
| Painel | Funil de candidaturas, meta semanal, próximas ações atrasadas e as vagas de maior aderência no momento. |
| Vagas | Vagas coletadas de seis portais mais os feeds RSS cadastrados, com pontuação de 0 a 100 explicada item a item e filtros combináveis. |
| Alertas | Buscas guardadas que avisam quando a coleta traz vaga nova compatível, com resumo dentro do app e aviso opcional no desktop. |
| Leituras | Índice de artigos técnicos dos feeds RSS que você ligar, etiquetado com as mesmas competências do fit score. Opt-in e sem republicar texto de ninguém. |
| Métricas | Conversão entre etapas, tempo mediano de cada passo, ritmo semanal, candidaturas esquecidas, retorno por fonte e faixa salarial das vagas coletadas. |
| Pipeline | Quadro das candidaturas por etapa, com histórico e próximo passo. O cartão muda de coluna por arraste ou pelo seletor de etapa, que funciona no teclado e no celular. |
| Currículos | Currículo base e versões direcionadas a uma vaga, em português ou inglês, montados numa oficina com a folha redesenhada enquanto se digita, em sete modelos (Harvard, FAANG e Designer entre eles), com verificador ATS que dá nota de 0 a 100 sem IA, carta de apresentação e geração de PDF. Um currículo pronto serve de ponto de partida para o da próxima vaga. Com assistente configurado, a versão direcionada sai pronta em um clique a partir da tela da vaga. Também armazena PDFs prontos. |
| Roadmap | Lacunas de competência calculadas sobre as vagas que as suas buscas trouxeram, com projetos e certificações recomendados. |
| Perfil | Fonte única de verdade: alimenta a pontuação, os currículos e o roadmap. |
| Ajustes | Termos de busca, fontes com diagnóstico de erro, preferências de região, notificação no desktop e o assistente de IA opcional — chave da API ou modelo local. |
O aplicativo requer Python 3.10 ou superior. As distribuições Linux recentes e o macOS já o incluem; no Windows, o instalador indica como obtê-lo caso não esteja presente.
git clone https://github.com/Bappoz/farol.git
cd farol
./install.shO script cria um ambiente Python isolado, instala o aplicativo, prepara o banco
de dados e registra o atalho no sistema: uma entrada .desktop no menu, no
Linux, e um pacote Farol.app em ~/Applications, no macOS. O comando farol
fica disponível no terminal.
git clone https://github.com/Bappoz/farol.git
cd farol
powershell -ExecutionPolicy Bypass -File .\install.ps1O script cria o ambiente, instala o aplicativo, adiciona o atalho no Menu
Iniciar e registra o comando farol no PATH do usuário. Use
-ComAreaDeTrabalho para criar também um atalho na área de trabalho.
As páginas de Releases trazem um executável por sistema, com o interpretador Python embutido. Baixe, extraia e execute — não há instalação nem dependências.
Esses arquivos não são assinados digitalmente. No macOS, libere o executável com
xattr -d com.apple.quarantine farol antes do primeiro uso; no Windows, o
SmartScreen pede confirmação em Mais informações → Executar assim mesmo.
pipx install farol-carreira
farolEsta forma instala apenas o comando, sem atalho no menu do sistema.
./uninstall.sh # Linux e macOS
powershell -ExecutionPolicy Bypass -File .\uninstall.ps1 # WindowsOs dados não são apagados. Para removê-los também, acrescente --com-dados
(ou -ComDados no Windows); a confirmação é solicitada.
- Perfil. Preencha antes de qualquer outra coisa: a pontuação, o currículo
e o roadmap derivam dele. Competências são separadas por vírgula e o
aplicativo reconhece abreviações comuns (
js,k8s,postgres). - Ajustes. Cadastre de dois a quatro termos de busca. Termos em inglês
produzem muito mais resultado nestes portais:
junior backend,entry level data,trainee software. - Vagas → Atualizar vagas. A coleta busca, remove duplicatas e pontua.
- Salvar uma vaga cria o cartão no pipeline com um próximo passo sugerido.
- Gerar currículo direcionado na página da vaga, revisar a verificação e usar Ver / gerar PDF → Salvar como PDF no diálogo de impressão.
- Roadmap. O que aparece com frequência nas suas vagas e falta no seu perfil se converte em projeto ou certificação recomendada.
- Alertas, quando a busca já estiver afinada: guarde-a como alerta e o app passa a avisar sozinho quando entrar vaga nova compatível.
Cada vaga recebe uma nota de 0 a 100, soma de cinco componentes. A tela exibe a conta completa, componente por componente, com a frase que justifica cada nota.
| Componente | Faixa | Critério |
|---|---|---|
| Competências | 0–55 | Quanto do que a vaga pede já consta no seu perfil. |
| Senioridade | 0–20 | Vaga de entrada pontua; vaga sênior reduz a nota. |
| Região | 0–10 | Aceita candidatos no Brasil ou na América Latina. |
| Recência | 0–10 | Vaga publicada hoje vale mais que vaga de três semanas. |
| Preferências | 0–5 | Suas palavras-chave; termo excluído no título derruba a vaga. |
O cálculo é determinístico e local. Não há modelo estatístico, chamada de rede nem caixa-preta: a mesma vaga com o mesmo perfil produz sempre a mesma nota, e a nota é auditável na própria interface.
Todos os filtros combinam entre si e com a busca textual.
| Filtro | Comportamento |
|---|---|
| Região | Agrupa a localização em Brasil, América Latina, Mundial ou Outra, resolvendo a fragmentação dos rótulos: Brazil e Brazil, Latin America caem no mesmo grupo. |
| Localização exata | Lista apenas os valores presentes na sua base, com a contagem de cada um. É um campo de seleção justamente para evitar erro de digitação. Aplica-se também a vagas remotas: é nesse campo que os portais informam de onde aceitam candidatos. |
| Modelo | Remoto, híbrido, presencial ou todos. |
| Salário mínimo | Compara com o topo da faixa anunciada e apenas entre vagas da mesma moeda. Valor mensal é normalizado para anual (multiplicado por doze). |
Duas restrições são deliberadas no filtro de salário. O aplicativo não infere a moeda quando o anúncio não a declara — a vaga fica fora do filtro em vez de ser tratada como dólar — e não estima faixa para quem não publicou nenhuma. Como a maioria dos anúncios não publica salário, limpar o campo devolve essas vagas à lista.
Quando o resultado é vazio, a tela informa a causa em vez de sugerir afrouxar a pontuação. As cinco fontes embutidas são portais de trabalho remoto, de modo que filtrar por presencial tende a produzir lista vazia; para vagas presenciais, cadastre em Ajustes o feed RSS de um portal que as anuncie.
Idioma. Cada currículo tem o seu. Em inglês, o aplicativo troca os títulos
das seções (SUMMARY, SKILLS, EXPERIENCE) e o nome das competências de
rótulo português — testes automatizados passa a Automated testing. O modelo
da carta de apresentação também muda.
O que o aplicativo não faz é traduzir o seu texto: o currículo nasce com o conteúdo do Perfil e a tradução é feita ali dentro. Cada currículo é um documento próprio — cargo, empresa, período, marcadores, formação e idiomas são editáveis campo a campo, e nada disso retorna ao Perfil. Assim é possível manter um Perfil único, em português, e quantas versões em inglês forem necessárias. O botão Remontar a partir do perfil refaz o documento do zero e, com isso, descarta as traduções.
A pontuação das vagas independe do idioma: unit tests e testes automatizados
resolvem para a mesma competência canônica, assim como junior, entry level,
trainee e estágio para o mesmo nível de senioridade.
Oficina. O editor e a folha A4 ficam lado a lado, e a folha se redesenha a cada pausa na digitação — sem salvar e sem recarregar a página. Quem desenha é o servidor, com o mesmo template da impressão: o navegador só troca a folha dentro da pré-visualização, então não existe uma segunda versão do currículo que possa divergir da que vira PDF. Salvar continua sendo um ato explícito; a tela marca quando há edição não salva e pede confirmação antes de sair. Experiência, projeto, formação e idioma podem ser acrescentados ali mesmo, sem passar pelo Perfil.
Modelos de apresentação. Sete, escolhidos na criação e trocáveis a qualquer momento na oficina, vendo a folha mudar.
| Modelo | Quando usar |
|---|---|
| Sóbrio (recomendado, padrão) | Uma coluna, sem ornamento. É o que passa limpo por filtro automático de currículos. |
| Harvard | O padrão acadêmico americano: serifado, nome centralizado, formação antes da experiência. |
| FAANG | O formato denso das big techs: experiência e projetos primeiro, competências no fim, uma página. |
| Compacto | Mesma estrutura em espaçamento menor, para caber em uma página. |
| Com destaque | Nome e títulos de seção em cor de acento. |
| Moderno | Sem serifa, nome em corpo maior, barra no título da seção. |
| Designer | Duas colunas com barra lateral colorida. O único que o verificador ATS reprova no formato. |
O modelo sóbrio é o recomendado por uma razão concreta: quando o anúncio pede o envio do currículo por formulário, é quase certo que um filtro automático o leia antes de qualquer pessoa, e coluna lateral, cor de fundo e ícone são o que mais o confunde. Os demais valem quando se sabe que uma pessoa abrirá o PDF diretamente — indicação, feira, portfólio.
Os modelos alteram a apresentação e a ordem das seções, nunca o conteúdo. Trocar de modelo não altera nem perde nada do que foi escrito.
Criar a partir de um currículo pronto. Personalizar para uma vaga não exige recomeçar do Perfil. Criar a partir deste (na oficina) e Duplicar (na lista) geram um documento próprio com o texto, o modelo e o idioma do original — que não muda. Apontando a cópia para outra vaga do pipeline, as competências e os projetos se reordenam pelo que ela pede e a carta volta a ser rascunho; o texto lapidado fica intacto. A lista mostra de qual currículo cada um saiu.
Verificador ATS. Cada currículo recebe uma nota de 0 a 100 calculada por regras fixas, na máquina, sem IA e sem rede — a mesma entrada produz sempre a mesma nota. Ela aparece na lista, na oficina (atualizada junto com a folha) e na tela do PDF enviado.
| Categoria | Peso | O que mede |
|---|---|---|
| Leitura pelo robô | 25 | Modelo de uma coluna, símbolos que quebram parser, períodos com ano, links por extenso. No PDF: camada de texto e títulos de seção reconhecíveis. |
| Contato | 15 | Nome, e-mail válido, telefone, cidade, LinkedIn, GitHub. |
| Estrutura | 20 | Resumo, experiência ou projetos, formação, quantidade de competências, tamanho, [preencher] esquecido. |
| Conteúdo | 40 | Marcadores com verbo de ação e com número, tamanho dos marcadores, clichês, primeira pessoa, verbo repetido, texto no idioma do currículo. |
| Aderência à vaga | 30 | Termos técnicos do anúncio presentes no currículo e usados em frase, cargo no cabeçalho. Só existe quando há vaga; sem ela os outros pesos são renormalizados. |
Cada verificação devolve o motivo e uma correção concreta, citando o trecho. As
pendências vêm ordenadas pelo que mais devolve ponto. Cinco falhas travam a nota
em 64 por melhor que seja o resto — [preencher] esquecido, e-mail ausente,
currículo sem experiência nem projeto, texto em idioma diferente do declarado e
PDF sem camada de texto.
Duas ressalvas que a própria tela faz. Nenhum ATS publica a nota que atribui: o verificador mede as causas conhecidas de um currículo ser mal lido ou mal ranqueado, não reproduz o Gupy nem o Greenhouse. E ele nunca sugere incluir competência que você não tem — termo da vaga ausente vira "cite onde usou, se usou", com o caminho para o Roadmap.
Verificação com IA (opcional). Com um assistente configurado em Ajustes —
modelo local ou API —, um botão pede uma segunda leitura: marcadores fracos com
proposta de reescrita, o que um recrutador não encontraria em dez segundos e
incoerências. O modelo recebe o que as regras já apontaram, para não repetir, e é
instruído a não dar nota: a nota continua sendo a determinística. Sem assistente
o botão não existe, nenhuma requisição é feita e o verificador segue completo.
Decisão registrada em docs/decisoes/0004.
PDF pronto. É possível enviar um currículo que já existe em PDF (até 15 MB), pela tela de Currículos ou diretamente na página da vaga. Ele aparece na lista junto dos montados no editor, vinculado à vaga, e o arquivo é guardado no diretório de dados. O aplicativo não modifica o PDF.
O texto é extraído de volta — via pypdf, com pdftotext como alternativa —
para três finalidades: mostrar o que um filtro automático enxerga, comparar com a
vaga (o que ela pede e aparece no seu PDF × o que falta) e sugerir ao Perfil
as competências presentes no arquivo que ainda não foram cadastradas. Se o PDF
for uma imagem digitalizada, o aplicativo informa que não há camada de texto em
vez de simular a leitura, e avisa: é assim que filtros automáticos costumam
reprovar currículos.
Descrição da vaga. Cada portal entrega a descrição em um HTML diferente. Na
ingestão, o aplicativo reduz o conteúdo a texto marcando a estrutura (## para
título de seção, - e 1. para listas) e, na exibição, farol.markup
remonta títulos, listas e parágrafos, convertendo URLs em links. O texto do
anúncio é escapado antes de qualquer marcação: ele vem de terceiros e nunca pode
injetar HTML na página.
Sem invenção. O gerador de currículo reordena e destaca o que consta no seu
perfil, e nada além disso. Onde falta informação, escreve [preencher] e diz o
que falta. A revisão opcional por inteligência artificial recebe a mesma regra na
instrução de sistema.
As lacunas são calculadas sobre as vagas que as suas buscas trouxeram, e não sobre uma lista genérica de tecnologias em alta. Cada competência ausente do perfil aparece com a frequência real na sua base, e o catálogo de projetos e certificações é ordenado pelo quanto cobre essas lacunas.
Itens marcados formam um quadro de acompanhamento em três estados: planejado, fazendo e concluído.
A tela responde à pergunta que o funil sozinho não responde: onde a busca está travando. Quarenta candidaturas sem nenhuma triagem é um problema de currículo; quarenta candidaturas com doze triagens e nenhuma entrevista é um problema de conversa técnica. São diagnósticos opostos, e sem os números não há como distingui-los.
| Bloco | O que mostra |
|---|---|
| Funil | Quantas candidaturas chegaram a cada etapa, com a conversão de uma para a seguinte. Conta a etapa mais avançada alcançada, não a atual: uma recusa após a entrevista conta na entrevista. |
| Ritmo | Envios e respostas por semana, nas últimas oito. |
| Tempo entre etapas | Mediana de dias de cada passo, com o tamanho da amostra ao lado. Serve para saber quando cobrar retorno. |
| Paradas | Candidaturas ativas sem movimento há mais de dez dias. |
| O fit prevê resposta? | Pontuação média das vagas que responderam contra as que não responderam — uma checagem da própria pontuação contra o resultado real. |
| Retorno por fonte | De qual portal saem as candidaturas que avançam. |
| Faixa salarial | Média das faixas publicadas nas vagas coletadas, por moeda. |
Todos os números são descritivos: não há previsão, modelo nem recomendação automática. Percentual só aparece a partir de cinco candidaturas na amostra, e etapa sem dado exibe "sem dado" em vez de um número inventado.
Seis fontes embutidas, todas APIs ou feeds públicos, sem necessidade de chave: Remotive, RemoteOK, Arbeitnow, Himalayas, We Work Remotely e Vagas BR.
Vagas BR reúne os murais que a comunidade brasileira mantém no GitHub —
backend-br/vagas, frontendbr/vagas, react-brasil/vagas, androiddevbr/vagas,
phpdevbr/vagas e datascience-br/vagas. É a única fonte embutida em português,
e a única que traz vaga híbrida e presencial em quantidade. Ela não recebe termo
de busca: cada repositório já é a seleção, e filtrar anúncio em português por
termo escrito para portal em inglês devolveria lista vazia.
Vaga que sai do ar. Nenhum portal avisa quando remove um anúncio; o único
sinal é ele parar de aparecer nas coletas. Depois de três semanas sem reaparecer
(FAROL_STALE_DAYS ajusta), a vaga é marcada como fora do ar: some da lista e
deixa de contar no roadmap e nas métricas, mas continua no banco, porque pode
estar ligada a uma candidatura em andamento. O filtro Estado → fora do ar traz
essas vagas de volta à tela. A marcação só acontece depois de uma rodada que
trouxe resultado — se todas as fontes falharam, o sumiço é da rede, não do
anúncio.
Um portal fora do ar ou uma API que mudou de formato não derruba a coleta: a fonte é marcada como erro em Ajustes, com a mensagem original, e o botão testar executa apenas aquela fonte.
Para acrescentar um portal que publique RSS ou Atom, basta colar a URL do feed em Ajustes → Adicionar feed. Para um portal com API própria, o procedimento está descrito em CONTRIBUTING.md.
Feeds abertos que valem cadastrar, todos verificados:
| Feed | URL |
|---|---|
| Jobicy | https://jobicy.com/?feed=job_feed |
| Hacker News — Who is hiring | https://hnrss.org/whoishiring/jobs |
| Hacker News — vagas de startups YC | https://hnrss.org/jobs |
| Python.org Jobs | https://www.python.org/jobs/feed/rss/ |
| We Work Remotely — programação | https://weworkremotely.com/categories/remote-programming-jobs.rss |
E o LinkedIn? Fica de fora, por decisão registrada. O robots.txt do site
proíbe acesso automatizado sem permissão expressa (User-agent: * / Disallow: /),
e as únicas permissões autosserviço da API oficial são login e publicação — nenhuma
lê anúncio de vaga. O raciocínio completo, as evidências e as alternativas estão em
docs/decisoes/0001-linkedin-como-fonte.md.
O critério que ficou valendo para as próximas fontes: o Farol só coleta de portal
cujo robots.txt permita, ou que ofereça API ou feed público para este uso.
O termo de busca casa todas as palavras informadas, em qualquer posição do
anúncio. junior backend python encontra vagas que mencionem as três palavras,
ainda que separadas — não a frase literal.
O Farol consulta portais de terceiros e trata isso com as restrições que a situação exige.
Identificação honesta. O cabeçalho User-Agent declara o nome, a versão e o
endereço do projeto. O aplicativo não se faz passar por navegador.
Uma coleta por abertura. Abrir o aplicativo dispara uma rodada e apenas uma. A janela abre imediatamente e o indicador coletando vagas nos portais fica na barra superior; ao terminar, o Painel e a lista de Vagas se atualizam sozinhos.
Janela de descanso. Entre uma abertura e outra vale o intervalo mínimo configurado em Ajustes, de 45 minutos por padrão. Reabrir o aplicativo cinco vezes em dez minutos não gera nenhuma requisição adicional. É o que evita a rajada — e o CAPTCHA e o bloqueio por endereço que costumam vir depois dela.
Pausa entre requisições. Dentro de uma rodada, requisições consecutivas ao
mesmo portal são espaçadas em 1,5 segundo (FAROL_REQUEST_DELAY ajusta).
Portais distintos são consultados em paralelo, por serem servidores diferentes.
Escape manual. O botão Atualizar vagas, no Painel e em Vagas, ignora a janela de descanso e executa a coleta imediatamente.
O uso é pessoal. Respeite os termos de cada portal.
Um alerta é uma busca guardada: termos, nível, região, modelo de trabalho e fit mínimo. No fim de cada coleta, as vagas que acabaram de entrar são comparadas com os alertas ativos, e o que casa aparece em Alertas e no topo do Painel. O aviso no desktop é opcional, por alerta.
O que o alerta não faz é buscar por conta própria. Ele trabalha sobre o que a coleta normal já trouxe, então ligar cinco alertas não gera nenhuma requisição a mais nos portais — a janela de descanso continua sendo o único regulador de tráfego.
Cada vaga casa com cada alerta uma única vez. O mesmo anúncio reaparece em toda coleta enquanto estiver no ar; avisar de novo transformaria o alerta em ruído em dois dias. Um alerta recém-criado começa com o acervo já marcado como lido — a tela diz quantas vagas antigas casam, sem despejar trinta avisos.
Pausar interrompe o casamento; desmarcar Avisar no desktop mantém o resumo na tela e cala só o sistema; remover apaga o alerta e o histórico dele.
Um índice de artigos técnicos, ligado por RSS/Atom e etiquetado com as mesmas competências que alimentam o fit score — o Roadmap diz o que estudar, e esta tela ajuda a achar por onde começar.
Quatro limites deliberados, detalhados em
docs/decisoes/0002-agregador-de-leituras.md:
- Só feed. Nada de raspar HTML de blog: feed é o canal que o autor abriu de propósito para ser lido por programa.
- Índice, não cópia. Ficam gravados título, link, data, feed e o resumo curto que o próprio feed publica (até 400 caracteres). O texto do artigo continua no site de quem escreveu, e é para lá que o link leva.
- Opt-in. Os dez feeds do catálogo embutido nascem desligados, e a busca só roda quando você clica em Buscar artigos. Quem nunca abrir a tela não gera uma requisição sequer.
- Poda e validade. Artigo publicado há mais de um ano ganha a marca pode estar desatualizado; o acervo é podado pela janela definida em Ajustes (padrão: 60 dias).
A deduplicação é feita no banco, em duas camadas: o par (feed, identificador) para
o mesmo item reaparecendo no próprio feed, e a URL normalizada — sem www., sem
barra final e sem parâmetros de campanha — para o mesmo artigo chegando por dois
feeds diferentes.
Opcional e desligado por padrão. Sem assistente, o app funciona inteiro: a pontuação, o roadmap e o currículo são calculados na máquina, sem acesso à rede. Em Ajustes você escolhe quem escreve:
| Provedor | O que é | Onde o texto vai |
|---|---|---|
| Nenhum | o padrão | a lugar nenhum |
| API Anthropic | sua chave, seu modelo | sai da máquina |
| Modelo local | um servidor que você mesmo subiu | não sai da sua rede |
Com um provedor configurado aparecem os botões de revisar resumo, reescrever marcadores e revisar a carta — e, na tela da vaga, Gerar e revisar, que monta o currículo direcionado e o passa pelo modelo em um clique.
A instrução de sistema é a mesma nos dois provedores, e proíbe inventar
experiência, empresa, número, diploma ou tecnologia que não esteja no seu perfil.
Quando falta informação, o modelo escreve [preencher]. Confira cada linha
antes de enviar: a revisão é sugestão, não verdade.
O Farol não instala, não baixa e não sobe modelo nenhum. A integração é sua: você sobe o servidor que preferir e diz o endereço aqui.
| Servidor | Como subir | Porta padrão |
|---|---|---|
| Ollama | ollama serve |
11434 |
| LM Studio | Developer → Start Server | 1234 |
| llama.cpp | llama-server -m modelo.gguf |
8080 |
| Jan | Local API Server | 1337 |
Qualquer um serve: o app fala a API compatível com a da OpenAI
(/v1/chat/completions), que os quatro implementam.
Segurança. O endereço só é aceito se resolver inteiramente para loopback ou rede privada, e a checagem roda antes de cada requisição, não só ao salvar. O que sai daqui é o seu currículo e a descrição da vaga: um endereço digitado errado que apontasse para fora seria um vazamento sem nenhum aviso na tela. O cliente HTTP também ignora proxy do ambiente, pela mesma razão.
Qual modelo usar. Ajustes mede a RAM e a VRAM da máquina e marca, no catálogo abaixo, o que cabe. Os tamanhos são os dos manifestos publicados pela biblioteca do Ollama, não estimativas; quando a memória não pode ser medida, nada é marcado como "cabe" e a tela diz isso.
| Modelo | Baixa | Pede | Para quê |
|---|---|---|---|
qwen2.5:3b |
1,9 GB | 6 GB | o mais leve que ainda escreve português aceitável |
llama3.2:3b |
2,0 GB | 6 GB | alternativa de 3B, texto mais solto |
qwen3:4b |
2,5 GB | 8 GB | raciocina antes de responder; melhor carta, mais lento |
phi4-mini |
2,5 GB | 8 GB | obediente a instrução curta, português seco |
gemma3:4b |
3,3 GB | 8 GB | português do Brasil mais natural entre os pequenos |
mistral:7b |
4,4 GB | 12 GB | veterano estável |
qwen2.5:7b |
4,7 GB | 12 GB | melhor equilíbrio em máquina de 16 GB |
llama3.1:8b |
4,9 GB | 12 GB | texto longo com boa coesão |
qwen3:8b |
5,2 GB | 16 GB | a melhor escrita da lista, e a mais lenta |
gemma3:12b |
8,1 GB | 24 GB | só com GPU de 12 GB ou mais |
O botão Ver modelos instalados pergunta ao seu servidor o que ele tem — o app lista o que existe, não adivinha.
Sobre a espera. Em CPU, sem GPU dedicada, um modelo de 3B escreve alguns
tokens por segundo: as três etapas da geração dirigida levam minutos, não
segundos. O tempo limite padrão é de 300 segundos por etapa
(FAROL_LOCAL_AI_TIMEOUT). Uma etapa que falha não leva as outras junto — o
currículo fica com o que deu certo, e a tela diz o que faltou.
O raciocínio dos modelos que pensam em voz alta (<think>…</think>, como Qwen3 e
DeepSeek-R1) é removido antes de o texto entrar no documento.
As decisões de projeto desta integração estão em
docs/decisoes/0003-ia-local.md.
farol abre o aplicativo (sobe o servidor e abre a janela)
farol servir apenas o servidor, no primeiro plano
farol atualizar apenas a coleta de vagas
farol caminho mostra onde ficam o banco e os arquivos
farol versao mostra a versão instalada
farol update verifica se há uma versão nova do app e atualiza
Opções: --port, --host, --reload e --sem-navegador. Use farol --help
para a descrição completa.
O comando farol atualizar imprime uma linha por fonte com o que foi encontrado
ou o erro exato, e ignora a janela de descanso. Ao agendá-lo em cron ou no
Agendador de Tarefas, escolha um intervalo folgado — uma ou duas vezes ao dia —
pela mesma razão descrita em Política de coleta.
O comando farol update só funciona quando o app foi instalado a partir de um
clone git (o caminho descrito em Instalação): ele busca o
repositório remoto, compara com o commit instalado e, se houver algo novo, faz
git pull --ff-only e reinstala as dependências no mesmo ambiente. Com mudanças
locais não commitadas ele se recusa a mexer — resolva-as primeiro. Ele também só
atualiza a partir da branch principal: numa branch de trabalho, avisa e não mexe
em nada. E se o Farol já estiver aberto, o servidor em execução continua com o
código antigo até ser fechado — o comando diz isso ao final.
Tudo fica em um único diretório, por convenção de cada sistema:
| Sistema | Diretório |
|---|---|
| Linux | $XDG_DATA_HOME/farol (por padrão ~/.local/share/farol) |
| macOS | ~/Library/Application Support/Farol |
| Windows | %LOCALAPPDATA%\Farol |
A variável FAROL_HOME sobrescreve essa escolha. O comando farol caminho
mostra os caminhos em uso.
O diretório contém farol.db (o banco SQLite), a pasta curriculos/ com os PDFs
enviados e server.log. Fica fora da pasta do projeto de propósito: para
atualizar o aplicativo, basta extrair a versão nova sobre a antiga — colunas
novas são aplicadas na abertura seguinte, sem apagar nada.
Backup e restauração. Ajustes → Backup completo gera um ZIP com perfil, candidaturas e todo o histórico de etapas, currículos (inclusive os PDFs enviados), plano de estudo e ajustes. Restaurar lê o mesmo arquivo de volta — ou um JSON solto de versões anteriores — e substitui os dados atuais, o que exige digitar a confirmação.
As vagas coletadas ficam de fora do backup de propósito: elas se refazem sozinhas na próxima coleta e ocupariam a maior parte do arquivo. A chave da API também nunca entra: backup que carrega credencial vira credencial espalhada.
Agenda. /agenda.ics devolve as próximas ações com data marcada em formato
iCalendar, uma tarefa de dia inteiro por candidatura, com alarme na véspera.
Baixe o arquivo ou assine a URL no calendário do celular para vê-la sempre
atual. Um follow-up anotado num aplicativo que só abre quando a pessoa lembra de
abrir não lembra ninguém de nada.
Para manter o Farol disponível em um servidor doméstico:
docker compose up -d # http://127.0.0.1:7788O compose.yaml publica a porta apenas em 127.0.0.1, de propósito. O Farol não
possui autenticação, e a base contém dados pessoais: para alcançá-lo de outra
máquina, coloque um proxy reverso com autenticação à frente em vez de expor a
porta na rede. Consulte SECURITY.md.
farol/
app.py rotas e renderização (FastAPI + Jinja, tudo no servidor)
db.py SQLite sem ORM, schema.sql e migrações de coluna
collect.py ingestão: busca, deduplicação, gravação e pontuação
scoring.py pontuação explicável, modelo de trabalho, região e faixa salarial
skills.py taxonomia de competências e extração de texto
alerts.py buscas guardadas e casamento com as vagas da rodada
reading.py feeds de artigo, ingestão como índice e poda
markup.py descrição da vaga em HTML legível (escapa antes de marcar)
resume.py montagem de currículo, modelos e carta
ats.py verificador ATS determinístico (nota e sugestões, sem IA)
ai.py assistente opcional: escolhe o provedor e guarda as instruções
localai.py servidor de modelo local: endereço privado, catálogo e hardware
insights.py métricas do funil a partir do histórico de eventos
pdfs.py PDFs enviados: armazenar, servir e extrair texto
roadmap.py lacunas, projetos e certificações
agenda.py próximas ações em iCalendar
backup.py exportar, ler e restaurar o trabalho da pessoa
selfupdate.py `farol update` sobre um clone git
launcher.py abertura do aplicativo em Linux, macOS e Windows
sources/ um módulo por portal, leitor RSS genérico e casamento de termos
data/ catálogo de projetos e certificações (JSON editável)
templates/ páginas
static/ app.css, app.js e ícone
docs/decisoes/ decisões registradas (o que foi decidido não fazer, e por quê)
packaging/ especificação do executável único (PyInstaller)
assets/ ícones nos formatos de cada sistema
Sem etapa de build, sem npm, sem framework de front-end. O CSS é uma folha
única, com tokens no topo e tema claro e escuro que segue o sistema; o botão
Tema, na barra lateral, força um dos dois.
O banco é SQLite em modo WAL, com a conexão reaproveitada por thread. As competências de cada vaga são extraídas uma vez, na ingestão, e gravadas na linha — é o que mantém o Painel e o Roadmap na casa dos milissegundos independentemente do tamanho da base.
./install.sh --sem-atalho # ambiente e instalação editável
.venv/bin/python -m farol servir --reload
.venv/bin/python -m pytest # 257 testes, sem acesso à rede
.venv/bin/ruff check farol testsCom just: just setup, just dev,
just check, just binary, just docker. O justfile é a referência canônica
dos comandos do projeto.
As escolhas de projeto que uma pessoa reabriria sem o registro — principalmente
as que terminaram em não fazer — ficam em
docs/decisoes/.
A suíte de testes não acessa a rede: os coletores são exercitados contra
respostas HTTP gravadas em tests/fixtures/.
Consulte CONTRIBUTING.md antes de abrir um pull request.
O servidor escuta em 127.0.0.1 e não possui autenticação, porque assume que o
único cliente é a pessoa sentada na máquina. Os dados não são cifrados em
repouso. O modelo de ameaça completo, as superfícies consideradas no projeto e o
canal para relatar vulnerabilidades estão em SECURITY.md.
Todo tráfego de saída é deliberado e listável:
| Quando | Para onde |
|---|---|
| coleta de vagas | os portais ativos em Ajustes |
| busca de artigos | os feeds que você ligou em Leituras, e só quando você pede |
| assistente Anthropic | api.anthropic.com, se e quando você escolher esse provedor |
| assistente local | o endereço que você configurou, sempre dentro da sua rede |
farol update |
o repositório git de onde o app foi clonado |
A chave da API fica só no banco local e nunca entra no backup. O endereço do modelo local é validado contra loopback e rede privada a cada requisição, e o cliente HTTP do assistente local ignora proxy herdado do ambiente.
MIT. O histórico de mudanças está em CHANGELOG.md.