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 antigo MOVIE_ADE_CONFIG_DIR també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. id pode ser qualquer string única.
  • agents.customAgents: qualquer CLI ou script wrapper. startupAgents lista, em ordem, as abas de agentes abertas com um projeto.
  • capture.sttEndpoints.compatible: qualquer servidor que implemente o /v1/audio/transcriptions da OpenAI (speaches, vLLM, LocalAI…). costLimitUsd: null desativa 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/completions compatível com OpenAI (aqui, o Ollama). Use "runner": "claude-code" ou "codex" para usar o seu próprio login da CLI, e organizer.cliModels para 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. preset também pode ser cloudflare, vercel, typesafe ou custom.
  • Todo bloco de provedor (sttEndpoints.*, organizer.endpoints.*) também aceita timeoutMs, headers e, 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.

CampoSignificado
baseUrl, modelQualquer URL http(s) e nome de modelo. {account_id} na URL é substituído por accountId ou pela variável de ambiente CLOUDFLARE_ACCOUNT_ID
authSchemebearer (Authorization: Bearer <key>), header (a chave no cabeçalho indicado por authHeader) ou none. Omita para manter o padrão do provedor
headersCabeç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 / apiKeyEnvA 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:

  1. "apiKey": "…": a chave em texto puro no settings.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.
  2. "apiKeyEnv": "OPENAI_API_KEY": o nome de uma variável de ambiente. O Ferret procura no próprio ambiente, depois no .env do 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.
  3. 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

Editando o settings.json: o app aplica a alteração enquanto está em execução.

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)