Handbooks
Справочник

Справочник CLI

Каждая подкоманда, каждый флаг, его переменная окружения и значение по умолчанию — а также то, что каждая команда записывает и с каким кодом возврата завершается.

handbook [global options] <command> [command options]

Каждая команда пишет результат в stdout в виде JSON, а логи — в stderr, поэтому конвейеры работают ровно так, как вы и рассчитываете:

handbook analyze --source ~/code/api --work work/api | jq .functions

`--help` генерируется, а не пишется руками

Каждый флаг ниже выводится из одного реестра настроек, поэтому handbook <cmd> --help всегда показывает флаг, его переменную окружения, её вариант с областью видимости команды и значение по умолчанию. Если эта страница и --help когда-нибудь разойдутся, прав --help — а тест на расхождение уронит сборку.

Глобальные опции

ФлагДействие
-V, --versionВывести версию
-v, --verboseОтладочное логирование
-q, --quietТолько ошибки — приоритетнее -v
--env <name>Выбрать окружение: загружает .env.<name>.local и .env.<name> перед .env.local и .env, а также предпочитает handbook.config.<name>.yaml. То же, что HANDBOOK_ENV
--env-file <path>Загрузить именно этот файл, минуя каскад .env. Отсутствующий файл — это громкая ошибка, а не откат к умолчанию. Предпочитайте HANDBOOK_ENV_FILE — см. предупреждение ниже
--config <path>Использовать этот файл конфигурации вместо поиска ближайшего handbook.config.yaml

Глобальные опции идут перед подкомандой:

handbook --env prod -v generate --source ~/code/api --work work/api

`--env-file` конфликтует с флагом Node

У Node >= 20.6 есть собственный --env-file, и он предварительно сканирует всю командную строку в его поисках — включая часть после пути к скрипту, где на самом деле файл не применяется. Существующий путь проходит в Handbooks нетронутым, а вот путь, которого не существует, убивает процесс раньше:

$ handbook --env-file /gone.env config
node: /gone.env: not found        # node, exit 9, before Handbooks ever runs

Так что единственный случай, о котором флаг обещает сообщить громко, — это как раз тот, о котором он сообщить не может. HANDBOOK_ENV_FILE делает ровно то же самое, и его нельзя перехватить:

$ HANDBOOK_ENV_FILE=/gone.env handbook config
handbook: error: ENOENT: no such file or directory, open '/gone.env'

Флаг по-прежнему работает всегда, когда файл действительно на месте, и он приоритетнее переменной окружения, когда заданы оба.


analyze

Только Phase 1: построение статического графа вызовов. Без LLM, без ключа, бесплатно.

handbook analyze --source <dir> --work <dir> [--lang <lang>]
ФлагПо умолчаниюEnv
--source <dir>обязателенHANDBOOK_SOURCE / HANDBOOK_ANALYZE_SOURCE
--work <dir>обязателенHANDBOOK_WORK / HANDBOOK_ANALYZE_WORK
--lang <lang>autoHANDBOOK_LANG / HANDBOOK_ANALYZE_LANG

--lang принимает auto или одно из: cpp csharp dart go java kotlin objc ocaml php python ruby rust scala shell solidity swift typescript zig. auto определяет и объединяет все языки за один проход и почти всегда является тем, что вам нужно.

Записывает phase1/graph.json, functions.csv, graph.dot, dropped-calls.json, scan-coverage.json.

files считает то, что действительно прочитано и разобрано; filesUnparsed — то, что нет, и каждый такой файл поимённо назван с причиной в scan-coverage.json. См. Форматы артефактов.

stdout
{
  "language": "multi",
  "files": 412,
  "functions": 3187,
  "edgesKept": 9042,
  "edgesDropped": 611,
  "filesUnparsed": 3
}

generate

Полный pipeline. Нужна конечная точка LLM для всего, что идёт после phase 1.

handbook generate --source <dir> --work <dir> [options]

Опции конвейера

ФлагПо умолчаниюЧто делает
--phase <spec>allall · 1 · 2 (=2a+2b+2c) · 2a · 2b · 2c · 3 или список через запятую
--strategy <s>(записанная в рабочем каталоге, иначе file)file или member
--skeleton <path>Ваш собственный skeleton.yaml. Обязателен для --strategy member
--detail <d>briefГлубина карточек: brief или deep
--synth-mode <m>oneshotoneshot или doctor для цикла ремонта «актёр — критик»
--narrate-lang <l>enen или zh
--max-doctor-rounds <n>6Раунды сходимости доктора
--resumefalseПропускать файлы, у которых уже есть готовая карточка
--refreshfalseИгнорировать кеши phase 3
--llm-cachefalseКешировать сырые ответы LLM в <work>/phase3/cache

Опции пропускной способности

ФлагПо умолчаниюЧто делает
--read-workers <n>12Параллельные пакеты карточек
--read-batch-size <n>(1 для deep, 8 для brief)Файлов на пакет карточек
--max-chars-per-file <n>0Обрезать каждый файл до n символов; 0 — без предела
--assign-batch-size <n>25Карточек на пакет назначения
--assign-workers <n>12Параллельные пакеты назначения
--organize-workers <n>8Параллельные вызовы организации этапов
--narrate-workers <n>8Параллельные вызовы повествования

Опции LLM (общие для generate, plan, resync, studio)

ФлагПо умолчаниюПсевдоним env
--provider <name>openaiOPENAI_PROVIDER
--model <id>gpt-4o-miniOPENAI_MODEL
--base-url <url>https://api.openai.com/v1OPENAI_BASE_URL
--max-tokens <n>16000OPENAI_MAX_TOKENS
--timeout <sec>300OPENAI_TIMEOUT
--llm-retries <n>6
--llm-retry-backoff <sec>3
--llm-concurrency <n>16

Ключ API никогда не является флагом. Задайте OPENAI_API_KEY (или HANDBOOK_LLM_API_KEY) в окружении или в файле .env. В файле конфигурации он отклоняется, потому что файлы конфигурации попадают в коммиты.

Дополнительное тело запроса тоже никогда не является флагом и по той же причине отклоняется в файле конфигурации. Задавайте его через OPENAI_EXTRA_BODY (или HANDBOOK_LLM_EXTRA_BODY) в окружении: оно подмешивает вендорские поля в тело каждого запроса — например, {"thinking":{"type":"disabled"}}, — а форма у него произвольная, так что отличить в нём поле тонкой настройки от поля аутентификации невозможно. Поля модели, сообщений и токенов переопределить через него нельзя.

--base-url, наоборот, флагом остаётся, и в файле конфигурации ему самое место: один общий шлюз, на который вся команда направляет каждый свой клон, — это ровно тот случай, ради которого такой файл и нужен. Там — и только там — отклоняется URL со встроенными учётными данными (https://user:pass@gw.internal/v1); держите их в окружении.

--provider выбирает формат протокола, а не поставщика: openai (по умолчанию) работает с любым OpenAI-совместимым эндпоинтом, а таких большинство; anthropic и gemini — для двух оставшихся.

stdout
{
  "phasesRun": ["1", "2a", "2b", "2c", "3"],
  "nCards": 412,
  "nStages": 9,
  "nUnassignedFiles": 0,
  "nRegisters": 6,
  "usage": { "promptTokens": 1840221, "completionTokens": 214880, "totalTokens": 2055101 }
}

render

Рабочий каталог → markdown и, по желанию, кое-что ещё. Без LLM.

handbook render --work <dir> [--title <t>] [--html] [--html-single] [--agent-site] [--llms-txt]
ФлагПо умолчаниюЧто делает
--work <dir>обязателенРабочий каталог для рендеринга
--title <title>System HandbookЗаголовок руководства в результате
--out <dir><work>/handbookКуда записывать
--htmlfalseДополнительно многостраничный HTML-сайт в <out>/html
--html-singlefalseДополнительно один самодостаточный <out>/handbook.html
--agent-sitefalseДополнительно индекс для агента и таблицы фактов в <out>/agent
--llms-txtfalseДополнительно llms.txt и llms-full.txt
--source-base-url <url>Связать каждую карточку файла с <url>/<relative path>

Без --source-base-url результат не содержит вообще никаких внешних URL, что важно, если вы поставляете руководство для закрытой кодовой базы.

--out имеет только ограниченную область видимости: его переменная окружения — HANDBOOK_RENDER_OUT, а не плоская HANDBOOK_OUT, потому что --out означает разное в plan и skill.


skill

Отрендеренное руководство → SKILL-пакет для агента. Без LLM.

handbook skill --handbook <dir> --out <dir> --name <slug> [options]
ФлагПо умолчаниюЧто делает
--handbook <dir>обязателенКаталог отрендеренного руководства
--out <dir>обязателенКуда попадёт SKILL-пакет
--name <slug>обязателенSlug из строчных букв и дефисов; даёт <slug>-handbook
--project <name>(--name)Человекочитаемое имя проекта, используемое в тексте
--work <dir>Добавляет coverage.json из назначения phase 2
--source <dir>Вместе с --work добавляет хеш содержимого на каждый файл
--agent-dir <dir>Кладёт индекс для агента и его таблицы фактов в references/agent/
--lang <l>enЯзык тела SKILL.md. Фронтматтер остаётся английским

Два отказа, о которых стоит знать

--out не должен быть каталогом руководства или его предком: сборка начинается с очистки --out, что удалило бы ровно то, что упаковывается. А --lang zh даёт вам китайское тело с английским фронтматтером — среды выполнения агентов маршрутизируют по тексту описания, поэтому его перевод молча сломал бы выбор скилла.


validate

Проверить SKILL-пакет. Без LLM. Возвращает 2 при неудаче.

handbook validate --skill <dir> [--source <dir>]
ФлагПо умолчаниюЧто делает
--skill <dir>обязателенКаталог скилла для проверки
--source <dir>Перехешировать живой исходник, чтобы выявить расхождение

Проверяет структуру, контракт фронтматтера, согласованность индекса и страниц этапов, схему coverage.json и свежесть хешей. Ошибки и предупреждения идут в stderr.


plan

Локализация изменений с опорой на руководство. Нужна конечная точка LLM. Только чтение.

handbook plan --source <dir> --request "<text>" [--handbook <dir>] [--out <file>]
ФлагПо умолчаниюЧто делает
--source <dir>обязателенКодовая база, для которой строится план (запись в неё никогда не ведётся)
--request <text>обязателенЗапрос на изменение на естественном языке
--handbook <dir>Отрендеренное руководство или skills/<x>/references. Настоятельно рекомендуется
--out <file>(stdout)Записать план сюда
--max-turns <n>30Бюджет ходов агента

Плюс общие опции LLM.

Завершается с ненулевым кодом, если планировщик сдался — выдумал результаты инструментов, исчерпал ходы или закончил ничем пригодным — вместо того чтобы записать извинение, которое скрипт скормит в apply.


apply

Применить EDIT-блоки плана. Без LLM. Возвращает 2, если что-то не легло.

handbook apply --source <dir> --plan <file> [--dry-run] [--backup-root <dir>]
ФлагПо умолчаниюЧто делает
--source <dir>обязателенДерево для редактирования
--plan <file>обязателенПлан от handbook plan
--dry-runfalseТолько проверка — никогда не пишет
--backup-root <dir><source>/.handbook-patchesКуда попадают резервные копии
stdout
{
  "ok": true,
  "dryRun": false,
  "outcomes": [
    { "index": 1, "file": "src/upload.py", "where": "Uploader.send (~88)", "status": "applied", "line": 88 }
  ],
  "changedFiles": ["src/upload.py"],
  "backupDir": "/repo/.handbook-patches/2026-08-08T14-05-11-204Z",
  "problems": []
}

Статусы: applied · created · no-match · ambiguous · file-missing · not-a-file · unsafe-path · undecodable · skipped.


rollback

Восстановить дерево исходников из резервной копии патча. Без LLM.

handbook rollback --backup <dir> [--source <dir>] [--force]
ФлагПо умолчаниюЧто делает
--backup <dir>обязателенКаталог резервной копии, содержащий manifest.json
--source <dir>Отклонить резервную копию, принадлежащую другому дереву
--forcefalseВосстанавливать даже файлы, изменённые после патча

Без --force файл, текущий хеш которого не совпадает с хешем после патча, отклоняется — восстановление молча уничтожило бы всё, что было сделано с тех пор.


resync

Перекатить руководство вперёд после изменения кода.

handbook resync --case <dir> --work <dir> [options]
ФлагПо умолчаниюЧто делает
--case <dir>обязателенКаталог кейса: edited/ + необязательный plan.md + необязательный change.diff
--work <dir>обязателенРабочий каталог для перекатывания вперёд
--title <title>System HandbookЗаголовок, используемый при повторном рендеринге
--no-llm(LLM включён)Только структурное обновление; проза помечается устаревшей
--no-render(рендеринг включён)Не обновлять уже отрендеренные результаты
--corrections <file>corrections.jsonl; его файлы расширяют набор для обновления
--detail <d>(как в существующем руководстве)brief или deep для перегенерированных карточек
--narrate-lang <l>(как в существующем руководстве)en или zh

Плюс общие опции LLM.

Оставить --detail и --narrate-lang незаданными — правильное умолчание: незаданное значит «соответствовать тому, чем это руководство уже является», поэтому resync никогда молча не понижает глубокое руководство до краткого.


studio

Локальный веб-интерфейс. Работает до Ctrl-C.

handbook studio [--port <n>] [--host <addr>] [--state-dir <dir>]
ФлагПо умолчаниюЧто делает
--port <n>4860Порт для прослушивания
--host <addr>127.0.0.1Адрес привязки. Контейнерам нужен 0.0.0.0
--state-dir <dir>$HOME/.handbook-studioРеестр и управляемые рабочие каталоги

Плюс общие опции LLM — Studio разрешает их через те же слои, что и любая другая команда, поэтому и --model, и блок llm: в файле конфигурации доходят до его задач.

Установка --host 0.0.0.0 не делает Studio удалённо доступной в сколько-нибудь полезном смысле: защита от CSRF проверяет заголовок Host, поэтому запрос, называющий IP из локальной сети, отклоняется с 403. См. Studio.


config

Вывести разрешённую конфигурацию и то, откуда взялось каждое значение. Без LLM.

handbook config [--command <name>] [--json] [--check]
ФлагПо умолчаниюЧто делает
--command <name>generateПоказать только настройки, применимые к этой подкоманде
--jsonfalseМашиночитаемый вывод
--checkfalseТолько проверка; код возврата 2, если что-то неверно или отсутствует
handbook config --command generate      # a table, with provenance per row
handbook config --json | jq '.settings[] | select(.source.kind == "env")'
handbook config --check                 # put this one in CI

Она показывает сломанную конфигурацию намеренно

В отличие от всех остальных команд, config не прерывается на неверном значении. Отсутствующий --source отображается видимой строкой — unset (required), а не роняет тот единственный инструмент, которым вы стали бы отлаживать ровно эту проблему.


Коды возврата

КодЗначение
0Успех
1Ошибка — неверная конфигурация, отсутствующий артефакт, сорвавшийся запуск. Сообщение в stderr с префиксом handbook: error:
2Проверка не прошла: validate нашла проблемы, apply легло не полностью или config --check нашла что-то неверное

2 означает «инструмент отработал, и ответ — нет». Скрипты должны обрабатывать его иначе, чем 1.

Сокращения pnpm

Из клона каждое из них сначала собирает проект и пробрасывает флаги напрямую:

pnpm analyze  --source ~/code/proj --work work/proj
pnpm generate --source ~/code/proj --work work/proj
pnpm render   --work work/proj --html --agent-site --llms-txt
pnpm skill    --handbook work/proj/handbook --out skills/proj --name proj
pnpm validate --skill skills/proj --source ~/code/proj
pnpm plan     --source ~/code/proj --request "…" --out plan.md
pnpm apply    --source ~/code/proj --plan plan.md --dry-run
pnpm rollback --backup ~/code/proj/.handbook-patches/<stamp>
pnpm resync   --case cases/mycase --work work/proj
pnpm studio
pnpm config:show --command generate
pnpm handbook --help

На этой странице