Перейти к тексту

Claude Code: работа с coding-агентом3. Знакомство с Claude Code

Permissions: что агенту можно без спроса

Засчитывается, когда отвечены все вопросы квиза

Зачем это нужно

Агент с неограниченными правами однажды выполнит что-то опасное — не со зла, а по ошибке: удалит не тот каталог, сделает git push в чужую ветку, применит миграцию к базе. Агент, который спрашивает разрешения на каждую команду, превращает работу в бесконечное нажатие «да». Permissions в Claude Code — это настройка баланса между риском и скоростью: что разрешено всегда, что запрещено всегда, о чём агент спрашивает.

Как это устроено

Запрос разрешения. Новая session в терминале или VS Code обычно стартует в режиме auto, где вопросов почти нет (о нём ниже). В режиме Manual Claude Code спрашивает перед Bash-командами, кроме встроенного набора read-only команд, перед правкой файлов и перед запросами в веб. Чтение файлов в рабочем каталоге разрешения не требует. Запрос показывает, что агент собирается сделать, и варианты ответа:

  • Yes — разрешить один раз;
  • Yes, and don’t ask again — разрешить и запомнить. Для Bash-команды и домена WebFetch правило сохраняется навсегда в .claude/settings.local.json в корне git-репозитория. Разрешение на правку файлов действует только до конца session;
  • No — отказать. Клавиша Tab открывает поле для комментария: с ним агент получит причину отказа, например «используй npx tsc», и продолжит работу.

Правила в settings. Правила лежат в объекте permissions файла настроек, в трёх массивах: allow — без вопросов, ask — всегда спрашивать, deny — запретить. Порядок проверки — deny, затем ask, затем allow: первое совпадение решает, а специфичность правила порядок не меняет. Поэтому allow-правило не может пробить дыру в deny-правиле.

{
  "permissions": {
    "allow": ["Bash(pnpm typecheck)", "Bash(pnpm test *)"],
    "deny": ["Bash(git push *)"]
  }
}

Bash(pnpm typecheck) разрешает ровно эту команду, а * заменяет любой текст, включая пробелы: Bash(pnpm test *) покрывает pnpm test --watch. Ставьте * после подкоманды. Для веба правило выглядит как WebFetch(domain:example.com).

Чьи это правила — решает файл:

Файл Для кого
~/.claude/settings.json Для вас во всех проектах на этой машине
.claude/settings.json Для всех, кто работает в проекте, если файл закоммичен
.claude/settings.local.json Для вас в одном проекте; Claude Code держит его вне git

Permission modes. Shift+Tab переключает режимы по кругу. Из auto первое нажатие ведёт в default (в интерфейсе — Manual), дальше идут acceptEdits — без вопросов принимает правки файлов и простые файловые команды вроде mkdir и mv в рабочем каталоге, plan — агент исследует код, но не правит исходники. Затем круг возвращается к auto; bypassPermissions входит в него, только если включён. В auto вопросов почти нет: перед shell-командами и сетевыми запросами фоновый classifier проверяет, соответствует ли действие вашей просьбе. Режим, в котором стартует session, задают флаг --permission-mode или настройка permissions.defaultMode; без них терминальная session стартует в auto, если он доступен, иначе в Manual. Активный режим виден в строке статуса, например ⏸ manual mode on.

Практика

Запустите Claude Code в Cadence и нажимайте Shift+Tab, пока в строке статуса не появится ⏸ manual mode on: в auto запроса не будет. Попросите агента запустить type check. Когда появится запрос, выберите No, нажмите Tab и напишите «запусти npx tsc --noEmit». Агент предложит новую команду — посмотрите, как изменился запрос. Затем выполните:

/permissions

Откроется диалог с правилами по областям. Добавьте deny-правило Bash(git push *) и попросите агента сделать git push: команда будет отклонена без вопроса.

Подводные камни

  • Deny по шаблону ловит не всё. Bash(git push *) не совпадёт с git -C . push: правило сравнивает текст команды как написано. Для жёстких запретов это стоит помнить.
  • auto и bypassPermissions нельзя включить по умолчанию из проектного файла. В .claude/settings.json и settings.local.json такой defaultMode не действует: задайте его в пользовательских или управляемых настройках либо передайте --permission-mode на одну session.
  • settings.local.json, созданный руками, а не самим Claude Code, в .gitignore сам не попадёт — добавьте его туда.

Вывод: правила команды храните в закоммиченном .claude/settings.json, личное — в settings.local.json, а то, что нельзя никогда, — в deny.

Проверь себя

Источники

Текст подготовлен с помощью LLM и может содержать неточности.