Уже доступен
Одна директория. Одни ворота для каждого действия.
Kvist — терминальная кодовая помощница, которая работает в одной директории проекта. Она работает через tool calling: прочитать, поправить, запустить, проверить — и получает результаты обратно прежде, чем выбрать следующий шаг. Модели без tool calling переходят на запасной JSON. Каждое действие проходит через один исполнитель, который может его не пропустить.
Kvist вышел, исходники открыты под лицензией MIT. Прогон и двенадцать гайдов ниже показывают настоящий интерфейс. Linux и Windows · macOS без гарантий
Запись прогона
Настоящий прогон, а не репетиция
Это терминальная запись того, как Kvist чинит функцию slug: она читает оба файла, планирует и останавливается на подтверждении, показав диф в одну строку, — записать она сможет только после ответа. Дальше запускает проверку и отчитывается: 4/4. Ничего не вырезано и не переснято. Ниже запись разобрана в текст — её можно выделить, и её прочитает скринридер.
╭────────────────────────────────────────────────────────────────────────────────────────────────╮│ │ ││ ╭────────────────────────────────────────────╮ │ ││ │ │ │ Provider: [DeepSeek] ││ │ │ │ ││ │ │ │ Fast: [deepseek-v4-flash] ││ │ ▀▀▀▀▀▀▀▀▀▀▀▀ │ │ ││ │ ▀▀▀▀▀▀▀▀▀▀▀▀ │ │ Smart: […seek-v4-flash-vision-exp]││ │ ▀▀▀▀▀▀▀▀▀▀▀▀ │ │ ││ │ ▀▀▀▀▀▀▀▀▀▀▀▀ │ │ Planner: [deepseek-v4-pro] ││ │ │ │ ││ │ │ │ Role: [coder] ││ │ │ │ ││ │ │ │ Effort: [medium] ││ ╰────────────────────────────────────────────╯ │ ││ │ │╰────────────────────────────────────────────────────────────────────────────────────────────────╯❯ check.py падает. Прочитай slugify.py и check.py, почини slugify: подряд идущие не-буквенно-цифровые символы должны схлопываться в один дефис, а дефисы по краям убираться. Потом запусти python3 check.py.⚡ Role: coder (manual)╭─ Final Answer ───────────────────────────────────────────────────────────────────────────────────╮│ ││ Исправил slugify.py: добавил .strip('-') после подстановки в slugify, чтобы убрать дефисы по ││ краям. Теперь подряд идущие не-буквенно-цифровые символы схлопываются в один дефис, а дефисы ││ по краям удаляются. python3 check.py прошёл: 4/4 passed. ││ │╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ❯
Ползунок перематывает прогон. Когда воспроизведение остановлено, показан финальный кадр.
Записано скриптом web/assets/demo/record.fish — каждый раз одним и тем же.
Цикл
Tool calling, несколько изменений за раз
Запрос уходит в роль и выполняется по шагам через tool calling; модель или провайдер без него переходят на запасной JSON. За один ответ модель может запросить любое число чтений и поисков — они идут параллельно, по четыре одновременно. Правки и команды ограничены восемью на ответ и идут по порядку, а упавшая останавливает остальные. Набор действий закрыт: модель не может придумать себе новую возможность посреди прогона.
-
21 тип действий
read_file, write_file, replace_in_file, search_code, run_shell, git_diff, fetch_url, delegate_task, refuse, final_answer и ещё одиннадцать. Список — это Literal в protocol.py, а тест роняет сборку, если промпты, парсер и исполнитель разъехались.
-
Пять ролей и auto
coder правит, reader разбирается и ничего не пишет, devops занимается сервисами и деплоем, chat отвечает, не трогая файлы, universal и говорит, и действует по запросу — он же роль по умолчанию, когда ничего не подошло. Маршрутизация сначала пробует явные правила, потом маленькую модель, потом ключевые слова — именно в таком порядке и на двух языках.
-
Чужой вывод остаётся чужим
Всё, что может повлиять на модель — содержимое файлов, результаты поиска, вывод команд, скачанные страницы — оборачивается в размеченный блок, а поддельный закрывающий тег внутри полезной нагрузки обезвреживается до того, как попадёт в промпт.
-
Прогресс вычисляется, а не объявляется
Модель не сообщает проценты. Прогресс выводится из фазы, в которой находится каждый ответ — изучение, план, правка, проверка — и только растёт. Когда лимит шагов кончается, Kvist спрашивает, продолжать ли, вместо того чтобы молча остановиться.
Граница
Чего она не сделает
Держат те части, которые не читают промпт. Враждебный файл, отравленная страница и запутавшаяся модель упираются в одни и те же ворота.
-
.env закрыт наглухо
Чтение и запись .env блокируются на проверке пути, до того как файл будет открыт, и блокируются отдельно для команд оболочки. Отказ прямо называет нарушение, а не падает молча.
-
Секреты маскируются, а не доверяются
Под Bubblewrap песочница закрывает .ssh, .aws, .gnupg, .kube и .azure, id_rsa / id_ed25519 / id_ecdsa, .netrc, .npmrc, .git-credentials и любые .pem, .key, .p12, .pfx и .crt. Файлы становятся /dev/null, директории — пустым tmpfs, так что собранный на лету путь тоже ничего не найдёт.
-
Из оболочки нет сети по умолчанию
Песочница отсоединяет сетевое пространство имён, пока AGENT_SANDBOX_NET не выставлен в allow. PID, IPC и UTS тоже отсоединяются, хостовые /home и /root спрятаны, а корень хоста не монтируется никогда.
-
Опасные команды подтверждаются каждый раз
git push, git reset, git clean, docker rm, docker prune, systemctl start/stop/enable и install/remove пакетных менеджеров подтверждаются на каждый запуск. Политика проекта может запретить больше, но не меньше: deny и встроенные жёсткие блокировки всегда бьют allow.
-
Подтверждение привязано к конкретной команде
Вы подтверждаете argv вместе с разрешённым cwd, ролью, слепком политики, профилем песочницы, окружением потомка, идентичностью и содержимым целевого исполняемого файла и заверенным интерпретатором из shebang. Изменится что-то одно до запуска — подтверждение недействительно.
-
Ничто не отцепится и не переживёт прогон
Потомок, вызвавший setsid(), уходит из группы процессов, поэтому всё поддерево живёт в cgroup v2 и сносится через cgroup.kill и по таймауту, и по завершении. Вывод сливается в буферы фиксированного размера, так что шумный потомок не раздует родителя.
Kvist — подконтрольный инструмент, а не средство защиты. Транзитивные импорты по отдельности не заверяются, инструменты, знающие историю репозитория, могут вытащить содержимое, которого нет в argv, и между последней проверкой и запуском остаётся узкое окно. Смотрите диф.
Откат
Прервите её, не потеряв работу
Прогон записывает, что собирается сделать, прежде чем это сделать. Именно поэтому прерванный прогон продолжается, а изменение откатывается.
-
/resume возвращается в нужный разговор
Чекпойнт пишется перед каждым действием, видимым снаружи. Продолжение идёт по чекпойнту в ту сессию, которой он принадлежит, а не подставляет его в ту, что случайно открыта.
-
/revert трогает только доказанное
Журнал отделяет запись, авторство которой он может доказать, от содержимого, которое просто похоже на нужное. Первое перезаписывается, второе остаётся нетронутым. Испорченный журнал останавливает изменение, а не читается как пустой.
-
Сессии — документы, а не черновик
/new начинает сессию, а не стирает предыдущую. У каждой своя история, свой чекпойнт и свой стиль, причём стиль фиксируется на старте — чтобы план и следующие за ним шаги исходили из одних и тех же убеждений.
Контроль
Ваши модели, ваши правила
Провайдеры, глубина рассуждения и тон — это настройки, а не допущения, зашитые в Kvist.
-
Шесть провайдеров и свой эндпоинт
OpenAI, Anthropic, DeepSeek, OpenRouter, OmniRoute и FreeFlow — либо любой OpenAI-совместимый или Anthropic-совместимый эндпоинт, добавленный через /provider. Стриминг и JSON-режим — это факт про конкретного провайдера, а не одно допущение на всех.
-
Два уровня моделей на прогон
fast и smart. Прогон стартует на fast и переключается на smart при сложной задаче, ошибке разбора, серии ошибок или застревании — если вы сами не закрепили модель.
-
Шесть уровней глубины рассуждения
false, low, medium, high, xhigh, max — одна команда /effort, переведённая под каждого провайдера. Если провайдер откажется от настройки, Kvist повторит запрос без неё и предупредит вас — каждый раз.
-
Четырнадцать рабочих стилей
Девять для цикла действий — minimalist, paranoid, architect, perfectionist, senior-dev и другие — и пять для чата. Одна сессия держит один стиль, чтобы исполнитель не расходился молча с полученным планом.
-
Проект сам заявляет свои правила
KVIST.md и KVIST-CHAT.md в корне рабочей директории несут ваши команды сборки, раскладку и соглашения в каждый вызов. Это содержимое проекта, поэтому оно цитируется как данные внутри границ, которые исключают смену роли, правил безопасности и протокола действий.
-
Без интерфейса, когда так нужно
Фронтенд на построчном JSON запускает Kvist из другого процесса, а операции с сессиями и журналом доступны одиночными командами. Electron-интерфейс использует ровно этот же протокол и ничего больше.
Установка
Начните работу с Kvist
Запустите установщик релиза: он установит команду kvist и нужный для терминального интерфейса Node.js. Python и права администратора не нужны. Выберите компоненты и подтвердите установку.
-
01
Установить релиз
Linux / macOS: curl -fsSL https://github.com/davud-d/Kvist/releases/download/latest-plugin-build/install.sh | bash
-
02
Windows (PowerShell)
irm https://github.com/davud-d/Kvist/releases/download/latest-plugin-build/install.ps1 | iex
-
03
Запустить в проекте
Зайдите в проект и наберите kvist. Лаунчер берёт текущую директорию как рабочую. Первый запуск спросит провайдера, модели и ключ и сохранит их в ~/.kvist/config.json.
-
04
Дать задачу
Наберите задачу или / для списка команд. Подтверждения появляются по ходу; ответите — прогон продолжится. /changes покажет, что записано, /revert вернёт как было.
Что понадобится
- Ключ провайдера или вход через подписку ChatGPT Plus/Pro
- Терминал для настройки и подтверждений
- Linux и Windows; macOS без гарантий
Для запуска из исходников нужен Python 3.11+: клонируйте репозиторий, установите requirements.txt в venv и запустите main.py --workspace <путь>. Подробности — в README репозитория.