раздел 10 · подстраница 4

Headless mode для скриптов

Claude Code умеет работать без интерактивного TUI. Передаёте промпт ключом -p, получаете ответ в stdout. Можно встраивать в bash-скрипты, CI/CD пайплайны, cron, githooks - куда угодно.

Концепция

Обычно claude запускает интерактивный режим - TUI с историей. С флагом -p (или --prompt) - однократный запуск: промпт на вход, ответ на выход, выход.

claude -p "что такое worktree в git, в двух предложениях"

Никакого TUI, никакого подтверждения - получаете ответ в stdout и команда завершается.

Базовые формы

Промпт строкой

claude -p "сгенерируй короткий changelog по последним 10 коммитам"

Промпт из файла

claude -p < prompt.txt

Или через cat:

cat prompt.txt | claude -p

Промпт + stdin как контекст

git diff | claude -p "сделай ревью этого diff"

Stdin превращается в контекст. Очень удобно для линтеров и diff-based проверок.

Output форматы

По умолчанию выход - человекочитаемый текст. Можно переключить на JSON для скриптов:

claude -p --output-format json "найди все TODO в src/"

Получите JSON примерно такого вида:

{
  "response": "...",
  "model": "claude-sonnet-4-6",
  "usage": { "input_tokens": 1234, "output_tokens": 567 },
  "session_id": "..."
}

Парсите через jq:

claude -p --output-format json "вопрос" | jq -r .response

Примеры в CI/CD

Авто-генерация changelog

#!/bin/bash
# generate-changelog.sh

LAST_TAG=$(git describe --tags --abbrev=0)
COMMITS=$(git log $LAST_TAG..HEAD --pretty=format:"%h %s")

echo "$COMMITS" | claude -p "Сгенерируй changelog в формате Keep a Changelog. Сгруппируй по Added/Changed/Fixed/Removed. Игнорируй коммиты типа 'merge', 'wip'." > CHANGELOG.next.md

cat CHANGELOG.next.md CHANGELOG.md > CHANGELOG.new.md
mv CHANGELOG.new.md CHANGELOG.md
git add CHANGELOG.md
git commit -m "chore: update changelog"

Запускаете при создании релиз-тега.

Авто-fix линтерных ошибок

#!/bin/bash
# auto-fix-eslint.sh

# Получить отчёт линтера
ERRORS=$(npx eslint src/ --format=json 2>/dev/null)

if [ -z "$ERRORS" ] || [ "$ERRORS" == "[]" ]; then
  echo "Нет ошибок"
  exit 0
fi

echo "$ERRORS" | claude -p "Вот отчёт eslint в JSON. Для каждой ошибки - открой файл, исправь, сохрани. Не меняй логику, только то, что требует линтер."

Cтавите на pre-commit hook.

Авто-ответ на issue в GitHub

ISSUE_BODY=$(gh issue view $ISSUE_NUMBER --json body -q .body)

echo "$ISSUE_BODY" | claude -p "Это GitHub issue. Прочитай README репозитория и предположи: это баг, фича-реквест, или вопрос? Если вопрос - дай ответ. Если баг - попроси шаги воспроизведения. Ответ - в markdown, не больше 200 слов." | gh issue comment $ISSUE_NUMBER --body-file -

Ограничения headless

  • Нет интерактивности - Claude не может задать уточняющий вопрос. Промпт должен быть полным.
  • Подтверждения bash-команд автоматически блокируют скрипт. Используйте --dangerously-skip-permissions (осторожно) или ограничьте --allowed-tools только нужным.
  • Лимиты по подписке учитываются. Скрипт на cron, который дёргается каждую минуту, быстро упрётся в потолок.

Безопасность

claude -p \
  --allowed-tools "Read,Grep,Bash(git log:*,git diff:*)" \
  "сделай ревью последнего коммита"

Параметр --allowed-tools ограничивает, что Claude может делать. Полезно в CI - не давайте больше прав, чем нужно для конкретной задачи.

Антипаттерны

  • Дёргать claude -p в цикле без задержек - упретесь в rate limit и сожжёте бюджет.
  • Передавать в stdin мегабайты файлов "на всякий случай". Платите за каждый input-токен.
  • Использовать headless для интерактивных задач. Если нужен диалог - TUI быстрее.
  • Хранить вывод headless в файл и парсить регексом, когда есть --output-format json.

Полезные ссылки