Руководство
Как ketch хранит, отслеживает и линкует то, что устанавливает. Каждая команда с примером — в COMMANDS.md.
Хранилище и откат
Всё лежит в ~/.ketch: версионированные данные в store/, ссылки в bin/, state.json с
записью того, что установлено, и stats.db с записью того, что происходило. За пределами этого
дерева ничего не пишется, кроме .app-бандлов, которым место в /Applications, пользовательских
каталогов man-страниц и автодополнений, о которых сообщает ketch doctor, файла запуска оболочки,
который ketch path install правит по вашей просьбе, ./ketch.lock и ./ketch.toml, когда вы их
запрашиваете, и самого запущенного бинарника, когда ketch self upgrade заменяет его на месте вне
хранилища.
Обновление оставляет предыдущий префикс на диске и записывает его в retained в state.json
вместе с политикой retention (keep, по умолчанию 1). ketch rollback <pkg> перелинковывает
этот префикс — он никогда не скачивает заново. ketch prune — единственная команда, которая
удаляет сохранённые префиксы; она оставляет keep предыдущих версий. ketch list и ketch info
показывают, что ещё сохранено. Файлы состояния, записанные до появления этого поля, по-прежнему
загружаются: отсутствующий retention означает keep 1, отсутствующий retained — ничего.
Установка с диска
ketch install --path PATH (или ketch install local:PATH) устанавливает то, что уже есть на
этой машине: голый бинарник, символическую ссылку на него, архив или .app-бандл. Путь
записывается в абсолютной форме, оригинал никогда не трогается, а удаление убирает только копию
ketch. Одиночный файл линкуется под именем пакета, которое берётся из имени файла, если --name
не говорит иначе:
ketch install --path ./target/release/mytool --name mytool
У локального пакета нет релизов: он записывает версию 0.0.0-local, outdated и upgrade его
пропускают, а повторная установка того же пути с --force подхватывает пересобранный файл.
Опубликованной контрольной суммы нет, поэтому require_checksums к нему не применяется.
ketch lock записывает хеш того, что там было, и sync отказывается от пути, если его
содержимое с тех пор изменилось.
--name работает для любого одиночного пакета, не только локального, а upgrade и sync
сохраняют выбранное им имя.
Что у вас было и когда
ketch history # каждая установка, обновление и удаление, новые сверху
ketch history rg # только версии этого пакета, включая старые
ketch stats # сколько установок и сколько они длятся
state.json говорит, что установлено сейчас, и переписывается при каждом изменении, поэтому не
может ответить, какая версия была у вас в марте. stats.db — вторая половина: журнал только на
дозапись, который переживает сами пакеты, поэтому ketch history rg работает и после
ketch uninstall rg. Удалите файл — потеряете историю, но не пакеты.
Что изменилось
ketch changelog rg # запись для вашей версии
ketch changelog rg --latest # релиз, который вы получите при обновлении
ketch changelog rg --release # заметки к релизу, а не поставляемый файл
Большинство релизов несут историю дважды: CHANGELOG.md внутри архива и заметки, прикреплённые
к релизу. ketch предпочитает файл — он уже на диске, так что это работает без сети — и
переходит к заметкам, когда в файле нет записи для этой версии; так бывает каждый раз, когда
проект ставит тег раньше, чем пишет заголовок.
Changelog идёт в stdout, а всё остальное в stderr, поэтому ketch changelog rg > NOTES.md
оставляет только markdown.
Установка нескольких сразу
ketch install rg fd bat jq # четыре загрузки одновременно, четыре индикатора
ketch install rg fd --jobs 1 # по одной
Загрузки по умолчанию идут параллельно и большую часть времени ждут, поэтому пакет из нескольких утилит занимает примерно столько, сколько самая медленная, а не сумму всех. Пересекаются только загрузка и распаковка: пакеты помещаются в хранилище по одному, в том порядке, в каком завершаются загрузки, — не обязательно в том, в каком вы их просили. Код выхода и выведенные результаты всё равно следуют порядку запроса.
upgrade и sync работают так же. --jobs N задаёт ширину для любой из них; jobs в файле
конфигурации задаёт значение по умолчанию.
Журнал
Каждый запуск пишется в ~/.ketch/logs/ketch.log — включая строки, которые проглотил --quiet,
и отладочные подробности, которые показал бы --verbose. Неудачная команда сообщает, где его
найти.
2026-08-27T09:12:33Z [4218] INFO ketch 0.1.0 · install rg fd
2026-08-27T09:12:34Z [4218] ERROR HTTP 404 from https://api.github.com/...
Установите log_format = "json" для JSON Lines, log_level в debug для всего или off для
ничего. Файл ротируется в ketch.log.1 при 5 МиБ, поэтому чистить его вручную не нужно.
ketch doctor показывает, где он лежит и насколько вырос.
Воспроизведение машины
ketch lock # записать ./ketch.lock из того, что установлено
ketch lock --check # что-нибудь разошлось?
ketch sync # привести эту машину к lock-файлу
Закоммитьте ketch.lock рядом с dotfiles, и новая машина отстаёт от старой на одну команду.
Везде воспроизводится тег; записанная контрольная сумма проверяется на машине той же цели, а
в остальных случаях ketch выбирает подходящий ассет и проверяет его по источнику. --prune
удаляет то, чего нет в lock-файле, --dry-run сначала показывает план. См.
LOCKFILE.md.
Добавление в PATH
ketch path # показать настройку PATH (то же, что `path status`)
ketch path status # какие оболочки настроены и где
ketch path install # отредактировать те, которыми вы пользуетесь
ketch path uninstall # убрать блок обратно
В Unix он находит bash, zsh и fish — оболочку из $SHELL и любую, чей файл запуска у вас уже
есть, — и пишет один блок между маркерами, чтобы переписать его, если корень переедет, и чисто
удалить позже. В Windows он пишет пользовательский PATH, который читает каждый новый терминал.
--shell <name> выбирает Unix-оболочку, --all берёт все известные ketch цели, --dry-run
показывает правку без её применения, а --print даёт строку, чтобы вставить её туда, о чём
ketch не знает.
Строку, добавленную вами самостоятельно, ketch не трогает и не дублирует. ketch doctor
сообщает о PATH как об ошибке, когда ни одна оболочка о нём не знает, как о предупреждении,
когда файл запуска его содержит, но текущая оболочка запущена до правки, а ketch doctor --fix
выполняет настройку за вас.
Как находится пакет
Имя разрешается по четырём уровням по порядку:
- ваши собственные манифесты в
~/.ketch/manifests/ - скачанный реестр пакетов — см. REGISTRY.md
- реестр, встроенный в бинарник, чтобы распространённые утилиты работали офлайн
- вывод из
owner/repo— именно он позволяет установить некурируемый репозиторий вообще без манифеста
Вывод выбирает ассет релиза, подходящий вашей машине — архитектуре, ОС и libc, — и объясняет
выбор в ketch info --assets.
Если он ошибается, манифест говорит, что делать вместо этого: какой ассет, какие бинарники и под какими именами. См. MANIFESTS.md.
Источники помимо GitHub добавляются плагинами — один исполняемый файл, без нового релиза ketch. См. PLUGINS.md.
Поддержка платформ
macOS, Linux и Windows. У каждой ОС есть бэкенд Platform, который выбирает ассет релиза,
распаковывает его и размещает бинарники; всё, что выше этого трейта, общее. cargo test
запускает набор для ОС хоста; CI делает это на macOS, Linux и Windows. Способы установки:
curl | bash через install.sh на macOS и Linux, irm | iex через install.ps1 на Windows
или brew install --cask pyrlyn/tap/ketch на macOS. ketch path install добавляет
~/.ketch/bin в PATH (файлы запуска оболочки в Unix; пользовательский PATH в Windows). Релизы
публикуют архив для каждой цели; install.sh и install.ps1 скачивают тот, что подходит машине,
на которой они запущены. Homebrew tap — pyrlyn/homebrew-tap;
реестр пакетов — pyrlyn/ketch-registry.