Перейти к содержанию

Claude Code

Toolog ведёт локальный журнал вызовов Claude Code

6 мин чтения

Текст написан ИИ-моделью по источникам, на которые ведут ссылки, и сверен с ними второй моделью. Как мы работаем

Всё о теме: Claude Code: версии и изменения →
Изображение: github.com

Автор Toolog прогнал через свои двенадцать правил риска всё, что Claude Code успел сделать на его машине, и выяснил, что 77% хранилища составляют команды Bash, с которыми не совпало ни одно правило. Журнал вызовов инструментов для macOS разработчик под ником zaghaghi показал на Show HN 6 сентября. Код, тринадцать архитектурных решений (ADR) и описание приватности лежат в репозитории на GitHub.

Эти 77% и объясняют, зачем в проекте вторая линия оценки. Отчёт по правилам показывал для таких команд пустоту, и автор формулирует проблему так: это выглядит как «с ними всё в порядке», а означает «их никто не проверял». Сам Toolog решает задачу поуже. Он отвечает на вопрос, что агент сделал, когда, в каком репозитории и кто это одобрил, без прокрутки терминала, который уже закрыт. Каждый вызов инструмента попадает во встроенную базу на машине, а смотреть её можно на трёх экранах: хронология, разбор разрешений и рисков, состояние самого захвата.

Две линии сбора

Вызовы приходят двумя путями, потому что ни один не полон в одиночку. Первый путь - транскрипты в ~/.claude/projects/**/*.jsonl, которые Toolog читает через fsevents, системные уведомления macOS об изменении файлов. В них лежит необрезанное содержимое: shell-команда целиком, полный дифф правки. Второй путь - OTLP-экспорт самого Claude Code, который приходит на 127.0.0.1:47318 запросом POST /v1/logs. OpenTelemetry обрезает вход инструмента на 512 знаках, «а это не доказательство», пишет автор. Зато только эта линия несёт то, чего в транскриптах нет: кто одобрил или отклонил вызов, по какому правилу и сколько он длился.

Встроенная телеметрия в Claude Code есть давно: CLI пишет структурированные события на каждый промпт, запрос к API и результат инструмента, а среди метрик есть счётчики решений по инструментам (так это описано в документации Claude Code). По умолчанию она выключена, пока не задан CLAUDE_CODE_ENABLE_TELEMETRY=1 и не выбран хотя бы один экспортёр, а логи по умолчанию уходят раз в 5 секунд. Включает её toolog doctor --fix: он пишет только в ~/.claude/settings.json, сливает настройки с существующими и сохраняет резервную копию с меткой времени. Если там уже прописан OTEL-эндпоинт не на loopback, команда отказывается работать: «ваш существующий конвейер телеметрии не нам перенаправлять».

Две записи склеиваются строго по tool_use_id, а расхождение считается находкой. Вызов, который видел только транскрипт, означает дыру в сборе. Вызов, который видел только OTEL, означает, что тело транскрипта так и не было записано. Так инструмент показывает собственную полноту, а не заявляет о ней. Ни одна из линий не стоит на критическом пути Claude Code: одна только читает файлы, другая отправляет данные без ожидания ответа, и её сбой ничего не стоит.

У схемы есть цена. Решения и задержки есть только у сессий, записанных вживую: OTEL-линию нельзя переиграть задним числом. Сессия, прошедшая без запущенного Toolog, получит из транскрипта команды и результаты, но слоя решений у неё не будет никогда. toolog backfill подтянет такую историю, а toolog verify перечислит, каких именно сессий это касается, вместо того чтобы усреднять статистику поверх пробела.

Правило или модель?

Хронология показывает вызовы от новых к старым под одной строкой запроса, и у каждого две колонки. В одной стоит серьёзность, которую выставило правило, в другой оценка локальной модели для вызовов, где правила промолчали. Фильтр @risk:high отбирает то, что пометило правило (какое именно, видно при наведении), @model-risk:>=4 отбирает оценки 4 и 5 вместе с однострочным пересказом модели. Колонки никогда не сливаются: серьёзность по правилу детерминирована, оценка модели нет. Экран разбора рисков показывает все правила от самых тяжёлых и для каждого объясняет, что оно ищет, даже если совпадений не было.

Модель подключается вручную и только советует. Toolog собран с llama.cpp, но загрузчика не получил: файл .gguf вы скачиваете сами и указываете путь через toolog model set PATH. Оценка модели никогда не становится правилом, не превращается в серьёзность и не попадает в итоговые цифры. У неё своя колонка, свой раздел и свой блок в карточке вызова.

Цифры по ней автор приводит без прикрас. Это квантизованная модель на 4,6 млрд параметров весом 3,1 ГБ, и на его машине она почти в 19 раз тяжелее всей базы, которая занимает 166 МБ. На его же хранилище модель поставила безобидному cargo test оценку 2, а запись dd на сырое устройство признала опасной только после того, как ей расписали критерии. Ту самую dd на сырой диск защитный хук из Claude Code Field Kit блокирует обычным шаблоном. Сам автор считает, что полезнее оценки может оказаться однострочное описание того, что команда делала, даже там, где балл ошибочен.

Как проверяется «ничего не уходит»

В Toolog нет аналитики, отчётов о падениях, удалённого конфига, аккаунта и проверки обновлений, а обновляется он через brew upgrade --cask toolog. Обещание закреплено тестом в CI: он прогоняет полный импорт и все запросы, которые делает окно, потом спрашивает у операционной системы, какие сокеты держит процесс. Любой адрес не из loopback валит сборку. Второй тест проверяет, что проверка вообще умеет падать: открывает сокет наружу и убеждается, что перепись его видит.

С моделью понадобилась ещё одна страховка. У llama.cpp есть свой загрузчик --hf-repo, которого не видно при проверке Cargo.toml, поэтому релиз дополнительно проверяет через otool -L, что в собранном бинарнике нет ни libcurl, ни TLS-библиотек. «Опция в конфиге - не гарантия, гарантия - бинарник», - пишет автор.

Обратная сторона тоже названа. Если вы ставили .dmg напрямую, о новой версии вам никто не сообщит. Записи api_request сохраняются и учитываются, но ни расходы, ни токены Toolog не показывает: в ADR-0010 это записано как сознательное ограничение рамок проекта.

Установка и откат

Ставится Toolog командой brew install --cask zaghaghi/tap/toolog или из .dmg в релизах. Это универсальная сборка, подписанная Developer ID и нотаризованная Apple, так что Gatekeeper не ругается. Один бинарник служит и приложением в строке меню, и CLI. После doctor --fix и backfill команда toolog запускает приёмник и слежку за транскриптами, а toolog agent install добавляет агент входа, чтобы запись переживала перезагрузку. Выход из приложения через строку меню останавливает захват намеренно: пропущенное потом подтянет backfill, без слоя решений.

toolog uninstall --apply снимает агент и возвращает ~/.claude/settings.json байт в байт из копии, снятой до первой записи. Если вы правили файл после этого, удаляются только шесть собственных ключей Toolog, и команда объясняет, почему не стала восстанавливать файл. История остаётся, пока не добавлен --delete-data, а у brew uninstall --cask toolog для этого есть --zap.

Работает всё это только на macOS 11 и новее. Привязана к системе лишь LaunchAgent, так что для порта на Linux понадобится пользовательский юнит systemd и для установки, и для удаления. Ещё одна мелочь касается имён проектов: Claude Code кодирует / как -, и /a/b/my-app с /a/b/my/app превращаются в одно и то же имя каталога. Поэтому принадлежность к проекту Toolog берёт из cwd в записях, а по закодированному имени работает только исключение проектов.

Сама база - обычный файл SQLite, и прочитать его может любой, у кого есть доступ к диску. Так сделано намеренно, чтобы заявления из PRIVACY.md можно было проверить, не доверяя программе. Шифрование хранилища автор рассматривал и отказался от него в пользу FileVault.

Пока никто не написал. Будьте первым.

Присоединяйтесь к разговору

Войдите, чтобы оставить комментарий. Он появится после модерации.