Что такое repOx и какую проблему он решает
repOx - открытый CLI/TUI-инструмент на Rust, который собирает файлы репозитория в один текстовый промпт для языковой модели. Автор представил его в посте на r/LocalLLaMA, и задача сформулирована буднично: не тащить в контекст всё подряд.
Инструмент вырос из личного workflow автора. Он пишет, что регулярно подаёт кодовые базы в локальные модели (Qwen, DeepSeek R1) и в API-модели, и главной помехой называет «загрязнение промпта»: в окно модели попадает служебный мусор, который тратит токены и размывает внимание на реальном коде.
Потери измеримы: одни только lock-файлы Cargo.lock и package-lock.json могут сжигать более 30 000 токенов «за просто так». Рядом в тот же поток уходят SVG, бинарники и артефакты сборки. Код открыт под лицензиями MIT и Apache, а установка на macOS и Linux описана как одна команда curl.
Почему lock-файлы и бинарники портят контекст
Lock-файл создаёт пакетный менеджер, а не человек. Внутри лежат точные версии, контрольные суммы и десятки тысяч строк повторяющейся служебной разметки. Для сборки это критично, для понимания кода - ноль: модель не вынесет из Cargo.lock ни архитектуры проекта, ни логики модулей. При небольшим окне контекста такая утечка заметна сразу, потому что забирает заметную его долю.
С бинарниками и артефактами сборки другая беда: каталоги target/, dist/ и node_modules/ раздувают промпт в разы, а модель получает нечитаемый или бесполезный текст. SVG формально текстовый, но это разметка из тегов и координат, из которой LLM не вынесет ничего о поведении программы. Чем больше шума в промпте, тем меньше в нём остаётся места для файлов, которые действительно нужны.
Как repOx очищает контекст: эвристика Git по NUL-байтам
Фильтрация работает по умолчанию, отдельный флаг включать не нужно. Lock-файлы и бинарники отбрасываются эвристикой Git по NUL-байтам: Git считает файл бинарным, если внутри встречается нулевой байт (0x00), и repOx использует тот же признак.
Разница с проверкой по расширению существенная. Решение принимается по содержимому файла: бинарник без расширения, картинка с неожиданным суффиксом или собранный исполняемый файл со странным именем всё равно распознаются как бинарные и не попадут в промпт. Список масок вида *.png на такое не рассчитан, его пришлось бы вести вручную и обновлять под каждый проект.
SVG отбрасывается отдельно как формат, бесполезный именно для LLM.
Оговорка по механике: NUL-байт это признак, а не гарантия корректной классификации. Как и любая эвристика, метод может ошибаться на нестандартных файлах: текстовый файл, внутри которого встретится нулевой байт, рискует уехать в отброшенные. Поэтому проверка списка файлов в интерактивном режиме перед отправкой промпта в модель лишней не будет.
Скорость: 14 мс против 3-4 секунд у существующих упаковщиков
Заявленные цифры выглядят так: около 14 мс на репозиторий из 3 тысяч файлов, тогда как существующие упаковщики, по словам автора, тратят 3-4 секунды только на генерацию промпта.
Почему Rust даёт такой прирост
Rust компилируется в нативный машинный код, поэтому здесь нет ни интерпретатора, ни виртуальной машины, ни пауз сборщика мусора. Обход каталогов и чтение файлов упираются в системные вызовы и скорость диска, а накладные расходы рантайма почти не добавляются. Для задачи, где нужно прочитать тысячи мелких файлов и собрать их в один буфер, это тот случай, когда выбор языка заметен на глаз: операции простые, но их много.
Оговорка важнее самих цифр. ~14 мс и «3-4 секунды у существующих упаковщиков» - это слова автора инструмента, независимых замеров нет. В посте не сказано, на каких репозиториях, дисках и версиях сравниваемых утилит проводились измерения, а непрогретый кэш файловой системы способен изменить картину сильнее, чем язык реализации. Пока разница не проверена на вашей кодовой базе, считайте её заявленной, а не подтверждённой.
TUI в стиле lazygit: ручное управление тем, что попадёт в промпт
Интерактивный режим открывается командой repox -i. Интерфейс сделан в стиле lazygit, поэтому те, кто им пользовался, освоятся быстро: пробел снимает галочку с папки, «/» открывает поиск, файлы можно просматривать, а рядом обновляется счётчик токенов.
Смысл ручного режима в том, что фильтр по умолчанию не знает вашей задачи. Перед рефакторингом одного модуля тесты, миграции и генераторы только засоряют промпт, и их логично выключить одним пробелом, не правя конфигурацию и не пересобирая список исключений. Счётчик токенов при этом живой: видно, как каждая снятая галочка уменьшает итоговый пакет ещё до копирования.
Набор горячих клавиш в описании автора короткий: пробел и «/». Расширенную навигацию по интерфейсу пост не детализирует, так что рассчитывать на неё заранее не стоит.
Офлайн-токенизатор и бюджеты контекста Claude, GPT, Gemini, DeepSeek и Llama
Встроенный токенизатор считает промпт без обращения к сети и поддерживает бюджеты контекста для Claude, GPT, Gemini, DeepSeek и Llama. До копирования видно, влезает ли собранный пакет в окно выбранной модели, и если нет, понятно, что выключать.
Для локальных моделей с небольшим контекстом это самый ощутимый эффект: вместо отправки промпта и разбирательства с обрезанным ответом вы сразу видите, что репозиторий не помещается, и вырезаете лишние папки в TUI.
Про точность лучше помнить отдельно. Автор не заявляет совпадения до токена, поэтому цифру разумно воспринимать как оценку и оставлять запас, особенно когда пакет подходит к границе окна.
Установка и первый запуск: одна команда и флаг -c
Для macOS и Linux автор описывает установку одной строкой через curl: curl -fsSL <URL> | sh, где адрес скрипта берётся из README проекта.
Дальше сценарий минимальный. Переходите в корень репозитория, запускаете repox для обычной упаковки или repox -i для интерактивного режима. Флаг -c сразу отправляет готовый промпт в буфер обмена, и его можно вставить в чат с моделью или в файл без промежуточного сохранения.
Лицензии MIT и Apache относятся к разрешительным, так что использовать инструмент в рабочих и коммерческих проектах они не мешают.
Платформы в посте перечислены только две: macOS и Linux. Про Windows в описании ничего нет.
Ограничения и кому repOx может не подойти
Обе впечатляющие цифры принадлежат автору. ~14 мс на 3 тысячи файлов и «3-4 секунды у существующих упаковщиков» не подтверждены независимыми тестами, а условия замеров в посте не раскрыты: неизвестны ни репозитории, ни железо, ни версии сравниваемых утилит. Источник - пост на Reddit, поэтому к оценкам стоит относиться как к заявлению разработчика, а не к воспроизводимому бенчмарку.
Эвристика по NUL-байтам отбрасывает файлы по формальному признаку, а не по смыслу. Если вам действительно нужно передать в модель содержимое похожего на бинарник файла или текстового файла с нулевыми байтами, автоматика его вырежет, и обходить её придётся вручную.
Инструмент узкий по назначению: он собирает текст и не индексирует код, не строит граф вызовов и не отвечает на вопросы вида «кто вызывает эту функцию». Если агенту нужна навигация по коду, а не снимок репозитория, ближе по задаче будет другой подход: например, repopedia строит локальный граф кода в SQLite и отдаёт его через MCP-сервер.
Платформенное ограничение тоже стоит учитывать: macOS и Linux заявлены, про Windows данных нет.
Кому и когда repOx реально пригодится
Сценарии, где выигрыш очевиден:
- регулярная подача кодовой базы в локальные модели вроде Qwen или DeepSeek R1, где окно контекста ограничено и каждый вырезанный lock-файл продлевает жизнь промпту;
- code review и разбор архитектуры через API-модель, когда нужно отправить репозиторий целиком, но без артефактов сборки;
- рефакторинг больших проектов, где важно заранее прикинуть бюджет токенов и не упереться в лимит на середине;
- работа в терминале на macOS или Linux, где лишний GUI только мешает.
Для разового запроса к маленькому репозиторию на десяток файлов выигрыш будет незначительным: там и ручной обход каталога занимает секунды, а экономия токенов измеряется сотнями, а не десятками тысяч. Ставить repOx имеет смысл, если вы упирались в окно контекста больше одного раза. Инструмент узкий, но закрывает конкретную боль: он возвращает в промпт те токены, которые у вас молча забирали служебные файлы.