Настройка
Настройка через settings.json
Все настройки Ferret хранятся в одном JSON-файле, рядом с которым лежит JSON Schema, поэтому вы или ваш собственный агент для написания кода (например, Claude Code, Codex или Gemini CLI) можете настраивать приложение, редактируя файл. Изменения применяются, пока приложение работает.
#Где находится файл
Путь одинаков во всех ОС:
~/.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
- Чтобы использовать другую папку, например внутри репозитория dotfiles, задайте
FERRET_CONFIG_DIR(старое имяMOVIE_ADE_CONFIG_DIRтоже работает).~раскрывается. - Сборки для разработки (
pnpm dev) используют~/.ferret/dev/, поэтому работа над самим Ferret никогда не перезаписывает ваши настоящие настройки. - Обновление с 0.1.0: при первом запуске старый
<userData>/settings.jsonкопируется в новые файлы. Старый файл остаётся на месте как резервная копия и никогда не изменяется.
Обновление с MOVIE-ADE: при первом запуске settings.json, state.json, usage/ и .env копируются из ~/.movie-ade/ в ~/.ferret/. Старая папка остаётся на месте и не изменяется.
В приложении путь показан вверху страницы Настройки, вместе с кнопками Открыть settings.json (редактирование во встроенном редакторе с автодополнением по схеме) и Показать в папке.
#Схема и проверка
Первая строка settings.json — "$schema": "./settings.schema.json". Редакторы, такие как VS Code, и агенты, такие как Claude Code, используют её для автодополнения, проверки и описания каждого поля. Схема поставляется внутри приложения и записывается рядом с файлом при каждом запуске, поэтому всегда соответствует установленной версии.
Ключи, которые Ferret не знает, при сохранении остаются как есть. Открытые вкладки, последний URL и другое состояние сеанса хранятся в state.json, а не здесь.
#Пример с пояснениями
В JSON нет комментариев, поэтому пояснения даны под примером. Все поля необязательны; опускайте то, что вам не нужно.
{
"$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: цели ревью для меню URL. Первая открывается при открытии проекта.idможет быть любой уникальной строкой.agents.customAgents: любой CLI или скрипт-обёртка.startupAgentsперечисляет вкладки агентов, открываемые вместе с проектом, по порядку.capture.sttEndpoints.compatible: любой сервер, реализующий/v1/audio/transcriptionsOpenAI (speaches, vLLM, LocalAI…).costLimitUsd: nullотключает лимит расходов, что разумно для собственного GPU. См. Распознавание речи и расходы.organizer: Обработать замечания с отправкой напрямую на OpenAI-совместимый сервер/v1/chat/completions(здесь Ollama). Чтобы вместо этого использовать собственный вход в CLI, укажите"runner": "claude-code"или"codex", а модель для них выберите вorganizer.cliModels.decision: модель, которая проверяет, исправлено ли каждое замечание. Clef Flash на локальном Ollama бесплатна и читает скриншоты.presetтакже может бытьcloudflare,vercel,typesafeилиcustom.- Каждый блок провайдера (
sttEndpoints.*,organizer.endpoints.*) также принимаетtimeoutMs,headersи, для Azure,apiVersion.
Ferret никогда не платит за ИИ от вашего имени. Встроенного ключа и релея нет: каждый запрос идёт с вашего компьютера на настроенный вами эндпоинт с вашим ключом.
#Любой провайдер: свои эндпоинты
Пресеты лишь заранее заполняют URL и модель. Каждое подключение (распознавание, обработка замечаний, модель решений) также принимает любой URL, модель, заголовки и способ аутентификации, поэтому можно использовать любого провайдера: Cloudflare, шлюз, корпоративный прокси или собственный сервер. Поля ниже называются и устроены одинаково во всех трёх.
| Поле | Значение |
|---|---|
baseUrl, model | Любой URL http(s) и имя модели. {account_id} в URL заменяется на accountId или на переменную окружения CLOUDFLARE_ACCOUNT_ID |
authScheme | bearer (Authorization: Bearer <key>), header (ключ в заголовке, имя которого задано в authHeader) или none. Не указывайте, чтобы оставить значение провайдера по умолчанию |
headers | Дополнительные заголовки. Значение — обычная строка или {"env": "VAR"}, чтобы взять его из переменной окружения (поиск как у apiKeyEnv). Секретные заголовки, такие как Authorization или токен шлюза, принимаются только в виде {"env": …}. На странице настроек пишите Name: ${VAR} |
apiKey / apiKeyEnv | Ключ, см. API-ключи |
Распознавание на любом OpenAI-совместимом сервере /v1/audio/transcriptions, который ожидает ключ в заголовке 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" }
}
}
}
Обработка замечаний через Cloudflare Workers AI (OpenAI-совместимые chat completions), при желании через 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" } }
}
}
}
Модель решений на Cloudflare Workers AI (Clef Flash) или, с "preset": "custom", на любом сервере, поддерживающем System One API. Модель решений принимает полный URL запроса в endpoint (с подставленными {account_id} и {model}); остальные поля называются и устроены так же, как выше:
"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" } }
}
Поместите CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN и другие переменные в ~/.ferret/.env. Имена моделей выше — примеры. Сверьтесь со списком моделей вашего провайдера.
#API-ключи
Каждый блок провайдера принимает ключ одним из трёх способов. Используется первый найденный:
"apiKey": "…": ключ открытым текстом вsettings.json. Любой, кто может прочитать файл, может прочитать ключ, и пока такой ключ есть, Настройки показывают предупреждение. Избегайте этого, особенно если файл лежит в репозитории dotfiles."apiKeyEnv": "OPENAI_API_KEY": имя переменной окружения. Ferret ищет её в своём окружении, затем в.envоткрытого проекта, затем в~/.ferret/.env. Приложения, открытые из Finder или меню «Пуск», не видят переменных, экспортированных в профиле оболочки, поэтому надёжнее всего~/.ferret/.env.- Ключ, сохранённый в Настройки: шифруется хранилищем ключей ОС в
<userData>/stt-keys.bin(см. Где хранятся ключи).
Ferret читает переменную окружения, только если вы указали её имя в apiKeyEnv. Ключи никогда не пишутся в журнал, не показываются в интерфейсе и не включаются в отчёты о сбоях.
#Применение на лету
Ferret следит за settings.json. Когда файл меняется, приложение перечитывает его, проверяет по схеме и применяет: тема, язык, раскладка, агенты, проекты и эндпоинты ИИ обновляются без перезапуска, а страница настроек обновляется.
- Если в файле синтаксическая ошибка JSON или значение неверного типа, ничего из этой правки не применяется. Приложение сохраняет последние корректные настройки, показывает ошибку с номером строки и не перезаписывает ваш файл, пока вы её не исправите.
- Когда сохраняет само приложение (вы что-то изменили в Настройки), оно пишет во временный файл и переименовывает его поверх
settings.json, поэтому сбой никогда не оставит наполовину записанный файл.
#Пусть агент настроит Ferret
Вставьте это в Claude Code, Codex или любого агента, который умеет редактировать файлы:
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">
Тот же промпт с подставленными реальными путями находится в Настройки → Пусть агент настроит Ferret вместе с кнопкой Копировать промпт.
Помочь с переводом этой страницы на GitHub (откроется в новой вкладке)