Configuração
Configurar com o settings.json
Todas as configurações do Ferret ficam em um único arquivo JSON com um JSON Schema ao lado, então você ou o seu próprio agente de programação (por exemplo Claude Code, Codex ou Gemini CLI) podem configurar o app editando um arquivo. As alterações são aplicadas com o app em execução.
#Onde fica o arquivo
O caminho é o mesmo em todos os sistemas:
~/.ferret/settings.json # your settings (edit this)
~/.ferret/settings.schema.json # JSON Schema, rewritten by the app on launch
~/.ferret/state.json # open folder, last URL, open tabs (managed by the app)
~/.ferret/.env # optional: API keys referenced by apiKeyEnv
- Defina
FERRET_CONFIG_DIR(o nome antigoMOVIE_ADE_CONFIG_DIRtambém funciona) para usar outra pasta, por exemplo uma dentro de um repositório de dotfiles. O~é expandido. - As versões de desenvolvimento (
pnpm dev) usam~/.ferret/dev/, então mexer no código do Ferret nunca reescreve as suas configurações reais. - Atualizando a partir da 0.1.0: na primeira execução, o antigo
<userData>/settings.jsoné copiado para os novos arquivos. O arquivo antigo fica no lugar como backup e nunca é modificado.
Atualizando a partir do MOVIE-ADE: na primeira execução, settings.json, state.json, usage/ e .env são copiados de ~/.movie-ade/ para ~/.ferret/. A pasta antiga fica no lugar e não é modificada.
No app, as Configurações mostram o caminho no topo, com Abrir settings.json (edita o arquivo no editor integrado com autocompletar pelo schema) e Mostrar na pasta.
#Schema e validação
A primeira linha do settings.json é "$schema": "./settings.schema.json". Editores como o VS Code e agentes como o Claude Code o usam para autocompletar, validar e descrever cada campo. O schema vem dentro do app e é gravado ao lado do arquivo a cada execução, então sempre corresponde à versão instalada.
Chaves que o Ferret não conhece são mantidas como estão quando o app salva. Abas abertas, a última URL e outros estados da sessão ficam no state.json, não aqui.
#Exemplo comentado
JSON não tem comentários, então as observações ficam abaixo do exemplo. Todos os campos são opcionais; deixe de fora o que você não precisa.
{
"$schema": "./settings.schema.json",
"theme": "dark",
"locale": "en",
"projects": [
{
"id": "shop",
"name": "shop",
"folderPath": "/Users/you/src/shop",
"kind": "web",
"urls": [
{ "id": "local", "label": "local", "url": "http://localhost:3000" },
{ "id": "prd", "label": "prd", "url": "https://shop.example.com" }
]
}
],
"agents": {
"customAgents": [
{ "id": "custom:my-agent", "name": "My agent", "command": "my-agent", "args": "--yes" }
],
"startupAgents": ["claude", "custom:my-agent"]
},
"capture": {
"transcription": "compatible",
"language": "auto",
"costLimitUsd": null,
"sttEndpoints": {
"compatible": {
"baseUrl": "http://gpu-box.local:8000/v1",
"model": "Systran/faster-whisper-large-v3",
"apiKeyEnv": "WHISPER_SERVER_TOKEN"
}
}
},
"organizer": {
"runner": "api:compatible",
"endpoints": {
"compatible": { "baseUrl": "http://localhost:11434/v1", "model": "qwen3:14b" }
}
},
"decision": {
"enabled": true,
"preset": "ollama",
"endpoint": "http://localhost:11434/v1/systemone",
"model": "clef-flash"
},
"layout": {
"panels": {
"projects": { "dock": "left", "visible": true },
"terminal": { "dock": "bottom", "visible": true },
"files": { "dock": "right", "visible": false }
}
}
}
projects[].urls: alvos de revisão para o menu de URLs. O primeiro abre quando o projeto abre.idpode ser qualquer string única.agents.customAgents: qualquer CLI ou script wrapper.startupAgentslista, em ordem, as abas de agentes abertas com um projeto.capture.sttEndpoints.compatible: qualquer servidor que implemente o/v1/audio/transcriptionsda OpenAI (speaches, vLLM, LocalAI…).costLimitUsd: nulldesativa o limite de custo, o que faz sentido para a sua própria GPU. Veja Transcrição e custos.organizer: Organizar apontamentos enviado direto a um servidor/v1/chat/completionscompatível com OpenAI (aqui, o Ollama). Use"runner": "claude-code"ou"codex"para usar o seu próprio login da CLI, eorganizer.cliModelspara escolher o modelo deles.decision: o modelo que verifica se cada apontamento foi corrigido. O Clef Flash em um Ollama local é gratuito e lê capturas de tela.presettambém pode sercloudflare,vercel,typesafeoucustom.- Todo bloco de provedor (
sttEndpoints.*,organizer.endpoints.*) também aceitatimeoutMs,headerse, para o Azure,apiVersion.
O Ferret nunca paga por IA em seu nome. Não há chave embutida nem servidor relay: cada requisição vai da sua máquina para o endpoint que você configurar, com a sua chave.
#Qualquer provedor: endpoints personalizados
As predefinições só preenchem a URL e o modelo. Toda conexão (transcrição, Organizar apontamentos, modelo de decisão) também aceita qualquer URL, modelo, cabeçalhos e autenticação, então você pode usar qualquer provedor: Cloudflare, um gateway, um proxy corporativo ou o seu próprio servidor. Os campos abaixo têm os mesmos nomes e o mesmo formato nos três.
| Campo | Significado |
|---|---|
baseUrl, model | Qualquer URL http(s) e nome de modelo. {account_id} na URL é substituído por accountId ou pela variável de ambiente CLOUDFLARE_ACCOUNT_ID |
authScheme | bearer (Authorization: Bearer <key>), header (a chave no cabeçalho indicado por authHeader) ou none. Omita para manter o padrão do provedor |
headers | Cabeçalhos extras. Um valor é uma string simples ou {"env": "VAR"} para lê-lo de uma variável de ambiente (procurada como em apiKeyEnv). Cabeçalhos secretos, como Authorization ou um token de gateway, só são aceitos como {"env": …}. Na página de Configurações, escreva Name: ${VAR} |
apiKey / apiKeyEnv | A chave; veja Chaves de API |
Transcrição com qualquer servidor /v1/audio/transcriptions compatível com OpenAI que espera a chave em um cabeçalho api-key:
"capture": {
"transcription": "compatible",
"sttEndpoints": {
"compatible": {
"baseUrl": "https://stt.internal.example.com/v1",
"model": "whisper-large-v3",
"authScheme": "header",
"authHeader": "api-key",
"apiKeyEnv": "INTERNAL_STT_KEY",
"headers": { "X-Team": "design" }
}
}
}
Organizar apontamentos com o Cloudflare Workers AI (chat completions compatível com OpenAI), opcionalmente pelo AI Gateway:
"organizer": {
"runner": "api:compatible",
"endpoints": {
"compatible": {
"baseUrl": "https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1",
"model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
"apiKeyEnv": "CLOUDFLARE_API_TOKEN",
"headers": { "cf-aig-authorization": { "env": "CF_AIG_TOKEN" } }
}
}
}
Modelo de decisão no Cloudflare Workers AI (Clef Flash) ou, com "preset": "custom", em qualquer servidor que fale a API System One. O modelo de decisão recebe uma URL de requisição completa em endpoint (com {account_id} e {model} preenchidos); todos os outros campos têm o mesmo nome e formato que acima:
"decision": {
"enabled": true,
"preset": "cloudflare",
"endpoint": "https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/run/@cf/cloudflare/{model}",
"model": "clef-flash",
"authScheme": "bearer",
"apiKeyEnv": "CLOUDFLARE_API_TOKEN",
"headers": { "cf-aig-authorization": { "env": "CF_AIG_TOKEN" } }
}
Coloque CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN e as outras variáveis em ~/.ferret/.env. Os nomes de modelos acima são exemplos. Confira a lista de modelos do seu provedor.
#Chaves de API
Cada bloco de provedor aceita uma chave de uma de três formas. A primeira encontrada vale:
"apiKey": "…": a chave em texto puro nosettings.json. Qualquer pessoa que consiga ler o arquivo consegue ler a chave, e as Configurações mostram um aviso enquanto houver uma. Evite isso, principalmente se o arquivo estiver em um repositório de dotfiles."apiKeyEnv": "OPENAI_API_KEY": o nome de uma variável de ambiente. O Ferret procura no próprio ambiente, depois no.envdo projeto aberto e depois em~/.ferret/.env. Apps abertos pelo Finder ou pelo menu Iniciar não veem variáveis exportadas no perfil do seu shell, então~/.ferret/.envé o lugar confiável.- A chave salva nas Configurações: criptografada com o chaveiro do sistema em
<userData>/stt-keys.bin(veja Onde as chaves são armazenadas).
O Ferret só lê uma variável de ambiente quando você a indica em apiKeyEnv. As chaves nunca são registradas em log, nunca aparecem na interface e nunca são incluídas nos relatórios de falhas.
#Recarregamento ao vivo
O Ferret observa o settings.json. Quando ele muda, o app o relê, valida com o schema e aplica: tema, idioma, layout, agentes, projetos e endpoints de IA são atualizados sem reiniciar, e a página de Configurações é atualizada.
- Se o arquivo tiver um erro de sintaxe JSON ou um valor do tipo errado, nada dessa edição é aplicado. O app mantém as últimas configurações válidas, mostra o erro com o número da linha e não sobrescreve o seu arquivo até que você o corrija.
- Quando o próprio app salva (você mudou algo nas Configurações), ele grava em um arquivo temporário e o renomeia por cima do
settings.json, então uma falha nunca deixa um arquivo gravado pela metade.
#Deixe seu agente de programação configurar o Ferret
Cole isto no Claude Code, no Codex ou em qualquer agente que consiga editar arquivos:
Edit ~/.ferret/settings.json following the JSON Schema in
~/.ferret/settings.schema.json (read the field descriptions first).
Keep unknown keys and keep the file valid JSON. Never write API keys in
plaintext: set "apiKeyEnv" to an environment variable name instead and
tell me which variable to put in ~/.ferret/.env.
Ferret applies the change as soon as the file is saved.
Task: <what you want, e.g. "use my Ollama at http://localhost:11434 with
qwen3:14b for Organize findings and add a prd URL for the shop project">
O mesmo prompt, com os seus caminhos reais preenchidos, está em Configurações → Deixe seu agent de código configurar o Ferret, com um botão Copiar prompt.
Ajude a traduzir esta página no GitHub (abre em uma nova aba)