Настройка Nix и NixOS
Nix и NixOS — это платформы второго уровня. Описанные здесь flake и модуль NixOS поддерживаются лишь по мере возможности. Коммиты в ветку main могут в любой момент нарушить работу этих пакетов.
Для поддерживаемой установки используйте один из стандартных путей установки — Docker или окружение FHS.
VibeOS поставляется с Nix flake и модулем NixOS.
| Уровень | Для кого | Что вы получаете |
|---|---|---|
nix run / nix profile install | Любой пользователь Nix (macOS, Linux) | Предварительно собранный бинарник со всеми зависимостями — затем стандартный CLI-процесс |
| Модуль NixOS (нативный) | Серверные развёртывания NixOS | Декларативная конфигурация, защищённый systemd-сервис, управляемые секреты |
| Модуль NixOS (контейнер) | Агенты, которым нужна самомодификация | Всё вышеперечисленное, плюс постоянный контейнер Ubuntu, где агент может выполнять apt/pip/npm install |
Установщик curl | bash сам управляет Python, Node и зависимостями. Nix flake заменяет всё это — каждая зависимость Python является Nix-деривацией, собранной с помощью uv2nix, а инструменты времени выполнения (Node.js, git, ripgrep, ffmpeg) встроены в PATH бинарника. Никакого runtime pip, никакой активации venv, никакого npm install.
Для пользователей не-NixOS это меняет только шаг установки. Всё после (vibeos setup, vibeos gateway install, редактирование конфига) работает идентично стандартной установке.
Для пользователей модуля NixOS весь жизненный цикл другой: конфигурация живёт в configuration.nix, секреты проходят через sops-nix/agenix, сервис — это systemd-юнит, а CLI-команды конфигурации заблокированы. Вы управляете vibeos так же, как любым другим сервисом NixOS.
Предварительные требования
- Nix с включёнными flakes — рекомендуется Determinate Nix (включает flakes по умолчанию)
- API-ключи для сервисов, которые вы хотите использовать (как минимум: ключ OpenRouter или Anthropic)
Быстрый старт (любой пользователь Nix)
Клонирование не требуется. Nix сам загружает, собирает и запускает всё:
# Запуск десктопного приложения
nix run github:Linx72/VibeOS#desktop
# Или постоянная установка
nix profile install github:Linx72/VibeOS#desktop
# Запуск TUI
nix run github:Linx72/VibeOS -- setup
nix run github:Linx72/VibeOS -- --tui
# Или установка в профиль
nix profile install github:Linx72/VibeOS
vibeos setup
vibeos --tui
После nix profile install команды vibeos, vibeos-agent и vibeos-acp будут доступны в PATH. Дальнейший процесс идентичен стандартной установке — vibeos setup проведёт вас через выбор провайдера, vibeos gateway install настроит launchd (macOS) или systemd user-сервис, а конфиг будет находиться в ~/.vibeos/.
Пакет по умолчанию включает ВСЕ библиотеки, которые могут понадобиться vibeos-agent. Если вам нужен уменьшенный вариант, проверьте другие flake-выводы.
Пакет default добавляет ~700 МБ к замыканию. Если вам нужны только платформы обмена сообщениями, #messaging добавляет всего ~33 МБ.
Запуск из локального клона
git clone https://github.com/Linx72/VibeOS.git
cd vibeos
nix develop
vibeos setup
Модуль NixOS
Flake экспортирует nixosModules.default — полноценный сервисный модуль NixOS, который декларативно управляет созданием пользователя, директориями, генерацией конфига, секретами, документами и жизненным циклом сервиса.
Этот модуль требует NixOS. Для систем не-NixOS (macOS, другие дистрибутивы Linux) используйте nix profile install и стандартный CLI-процесс, описанный выше.
Добавление Flake-входа
# /etc/nixos/flake.nix (или ваш системный flake)
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
vibeos-agent.url = "github:Linx72/VibeOS";
};
outputs = { nixpkgs, vibeos-agent, ... }: {
nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
vibeos-agent.nixosModules.default
./configuration.nix
];
};
};
}
Минимальная конфигурация
# configuration.nix
{ config, ... }: {
services.vibeos-agent = {
enable = true;
settings.model.default = "anthropic/claude-sonnet-4";
environmentFiles = [ config.sops.secrets."vibeos-env".path ];
addToSystemPackages = true;
};
}
Вот и всё. nixos-rebuild switch создаёт пользователя vibeos, генерирует config.yaml, подключает секреты и запускает шлюз — долгоиграющий сервис, который соединяет агента с платформами обмена сообщениями (Telegram, Discord и т.д.) и слушает входящие сообщения.
Строка environmentFiles выше предполагает, что у вас настроен sops-nix или agenix. Файл должен содержать как минимум один ключ LLM-провайдера (например, OPENROUTER_API_KEY=sk-or-...). Полная настройка описана в разделе Управление секретами. Если у вас ещё нет менеджера секретов, вы можете использовать обычный файл в качестве отправной точки — просто убедитесь, что он не читается всеми:
echo "OPENROUTER_API_KEY=sk-or-your-key" | sudo install -m 0600 -o vibeos /dev/stdin /var/lib/vibeos/env
services.vibeos-agent.environmentFiles = [ "/var/lib/vibeos/env" ];
Установка addToSystemPackages = true делает две вещи: помещает CLI vibeos в системный PATH и устанавливает VIBEOS_HOME общесистемно, чтобы интерактивный CLI разделял состояние (сессии, навыки, cron) с сервисом шлюза. Без этого запуск vibeos в вашей оболочке создаст отдельную директорию ~/.vibeos/.
CLI с поддержкой контейнера
Когда container.enable = true и addToSystemPackages = true, каждая команда vibeos на хосте автоматически направляется в управляемый контейнер. Это означает, что ваш интерактивный CLI-сеанс выполняется в том же окружении, что и сервис шлюза — с доступом ко всем установленным в контейнере пакетам и инструментам.
- Маршрутизация прозрачна:
vibeos chat,vibeos sessions list,vibeos versionи т.д. все выполняются внутри контейнера «под капотом» - Все флаги CLI передаются как есть
- Если контейнер не запущен, CLI делает несколько попыток (5 с со спиннером для интерактивного использования, 10 с молча для скриптов), а затем завершается с понятной ошибкой — без молчаливого отката
- Для разработчиков, работающих над кодовой базой vibeos, установите
VIBEOS_DEV=1, чтобы обойти маршрутизацию контейнера и запускать локальную копию напрямую
Установите container.hostUsers, чтобы создать символическую ссылку ~/.vibeos на директорию состояния сервиса, чтобы CLI хоста и контейнер использовали общие сессии, конфиг и воспоминания:
services.vibeos-agent = {
container.enable = true;
container.hostUsers = [ "your-username" ];
addToSystemPackages = true;
};
Пользователи, перечисленные в hostUsers, автоматически добавляются в группу vibeos для доступа к файлам.
Пользователи Podman: Сервис NixOS запускает контейнер от root. Пользователи Docker получают доступ через сокет группы docker, но rootful-контейнеры Podman требуют sudo. Предоставьте sudo без пароля для вашей среды выполнения контейнеров:
security.sudo.extraRules = [{
users = [ "your-username" ];
commands = [{
command = "/run/current-system/sw/bin/podman";
options = [ "NOPASSWD" ];
}];
}];
CLI автоматически определяет, когда требуется sudo, и использует его прозрачно. Без этого вам придётся запускать sudo vibeos chat вручную.
Проверка работоспособности
После nixos-rebuild switch проверьте, что сервис запущен:
# Проверка статуса сервиса
systemctl status vibeos-agent
# Просмотр логов (Ctrl+C для остановки)
journalctl -u vibeos-agent -f
# Если addToSystemPackages = true, протестируйте CLI
vibeos version
vibeos config # показывает сгенерированный конфиг
Выбор режима развёртывания
Модуль поддерживает два режима, управляемых параметром container.enable:
| Нативный (по умолчанию) | Контейнер | |
|---|---|---|
| Как работает | Защищённый systemd-сервис на хосте | Постоянный контейнер Ubuntu с bind-mount /nix/store |
| Безопасность | NoNewPrivileges, ProtectSystem=strict, PrivateTmp | Изоляция контейнера, запуск от непривилегированного пользователя внутри |
| Агент может сам устанавливать пакеты | Нет — только инструменты из Nix-предоставленного PATH | Да — apt, pip, npm install сохраняются между перезапусками |
| Поверхность конфигурации | Та же | Та же |
| Когда выбирать | Стандартные развёртывания, максимальная безопасность, воспроизводимость | Агенту требуется установка пакетов во время выполнения, изменяемое окружение, экспериментальные инструменты |
Чтобы включить режим контейнера, добавьте одну строку:
{
services.vibeos-agent = {
enable = true;
container.enable = true;
# ... остальная конфигурация идентична
};
}
Режим контейнера автоматически включает virtualisation.docker.enable через mkDefault. Если вы используете Podman, установите container.backend = "podman" и virtualisation.docker.enable = false.
Конфигурация
Декларативные настройки
Параметр settings принимает произвольный attrset, который преобразуется в config.yaml. Он поддерживает глубокое слияние при нескольких определениях модуля (через lib.recursiveUpdate), поэтому вы можете разделять конфигурацию по файлам:
# base.nix
services.vibeos-agent.settings = {
model.default = "anthropic/claude-sonnet-4";
toolsets = [ "all" ];
terminal = { backend = "local"; timeout = 180; };
};
# personality.nix
services.vibeos-agent.settings = {
display = { compact = false; personality = "kawaii"; };
memory = { memory_enabled = true; user_profile_enabled = true; };
};
Оба объединяются на этапе вычисления. Ключи, объявленные в Nix, всегда побеждают ключи в существующем config.yaml на диске, но ключи, добавленные пользователем, которые Nix не трогает, сохраняются. Это означает, что если агент или ручное редактирование добавляет ключи вроде skills.disabled или streaming.enabled, они переживают nixos-rebuild switch.
settings.model.default использует идентификатор модели, ожидаемый вашим провайдером. С OpenRouter (по умолчанию) они выглядят как "anthropic/claude-sonnet-4" или "google/gemini-3-flash". Если вы используете провайдера напрямую (Anthropic, OpenAI), установите settings.model.base_url для указания на их API и используйте их собственные идентификаторы моделей (например, "claude-sonnet-4-20250514"). Если base_url не установлен, VibeOS по умолчанию использует OpenRouter.
Запустите nix build .#configKeys && cat result, чтобы увидеть каждый листовой ключ конфигурации, извлечённый из DEFAULT_CONFIG Python. Вы можете вставить ваш существующий config.yaml в attrset settings — структура отображается 1:1.
Полный пример: все часто настраиваемые параметры
{ config, ... }: {
services.vibeos-agent = {
enable = true;
container.enable = true;
# ── Модель ──────────────────────────────────────────────────────────
settings = {
model = {
base_url = "https://openrouter.ai/api/v1";
default = "anthropic/claude-opus-4.6";
};
toolsets = [ "all" ];
max_turns = 100;
terminal = { backend = "local"; cwd = "."; timeout = 180; };
compression = {
enabled = true;
threshold = 0.85;
summary_model = "google/gemini-3-flash-preview";
};
memory = { memory_enabled = true; user_profile_enabled = true; };
display = { compact = false; personality = "kawaii"; };
agent = { max_turns = 60; verbose = false; };
};
# ── Секреты ────────────────────────────────────────────────────────
environmentFiles = [ config.sops.secrets."vibeos-env".path ];
# ── Документы ──────────────────────────────────────────────────────
documents = {
"USER.md" = ./documents/USER.md;
};
# ── MCP-серверы ────────────────────────────────────────────────────
mcpServers.filesystem = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-filesystem" "/data/workspace" ];
};
# ── Параметры контейнера ──────────────────────────────────────────────
container = {
image = "ubuntu:24.04";
backend = "docker";
hostUsers = [ "your-username" ];
extraVolumes = [ "/home/user/projects:/projects:rw" ];
extraOptions = [ "--gpus" "all" ];
};
# ── Настройка сервиса ─────────────────────────────────────────────────
addToSystemPackages = true;
extraArgs = [ "--verbose" ];
restart = "always";
restartSec = 5;
};
}
Запасной вариант: свой конфиг
Если вы предпочитаете управлять config.yaml полностью вне Nix, используйте configFile:
services.vibeos-agent.configFile = /etc/vibeos/config.yaml;
Это полностью обходит settings — никакого слияния, никакой генерации. Файл копируется как есть в $VIBEOS_HOME/config.yaml при каждой активации.
Шпаргалка по настройке
Быстрый справочник по самым распространённым вещам, которые пользователи Nix хотят настроить:
| Я хочу... | Параметр | Пример |
|---|---|---|
| Изменить LLM-модель | settings.model.default | "anthropic/claude-sonnet-4" |
| Использовать другую конечную точку провайдера | settings.model.base_url | "https://openrouter.ai/api/v1" |
| Добавить API-ключи | environmentFiles | [ config.sops.secrets."vibeos-env".path ] |
| Дать агенту личность | ${services.vibeos-agent.stateDir}/.vibeos/SOUL.md | управляйте файлом напрямую |
| Добавить MCP-серверы инструментов | mcpServers.<name> | См. MCP-серверы |
| Включить Discord/Telegram/Slack | extraDependencyGroups | [ "messaging" ] |
| Смонтировать директории хоста в контейнер | container.extraVolumes | [ "/data:/data:rw" ] |
| Передать GPU в контейнер | container.extraOptions | [ "--gpus" "all" ] |
| Использовать Podman вместо Docker | container.backend | "podman" |
| Разделять состояние между CLI хоста и контейнером | container.hostUsers | [ "sidbin" ] |
| Сделать дополнительные инструменты доступными агенту | extraPackages | [ pkgs.pandoc pkgs.imagemagick ] |
| Использовать пользовательский базовый образ | container.image | "ubuntu:24.04" |
| Переопределить пакет vibeos | package | inputs.vibeos-agent.packages.${system}.default.override { ... } |
| Изменить директорию состояния | stateDir | "/opt/vibeos" |
| Установить рабочую директорию агента | workingDirectory | "/home/user/projects" |
Управление секретами
settings или environmentЗначения в Nix-выражениях попадают в /nix/store, который доступен для чтения всем. Всегда используйте environmentFiles с менеджером секретов.
Как environment (несекретные переменные), так и environmentFiles (файлы с секретами) объединяются в $VIBEOS_HOME/.env во время активации (nixos-rebuild switch). VibeOS читает этот файл при каждом запуске, поэтому изменения вступают в силу после systemctl restart vibeos-agent — пересоздание контейнера не требуется.
sops-nix
{
sops = {
defaultSopsFile = ./secrets/vibeos.yaml;
age.keyFile = "/home/user/.config/sops/age/keys.txt";
secrets."vibeos-env" = { format = "yaml"; };
};
services.vibeos-agent.environmentFiles = [
config.sops.secrets."vibeos-env".path
];
}
Файл секретов содержит пары ключ-значение:
# secrets/vibeos.yaml (зашифрован с помощью sops)
vibeos-env: |
OPENROUTER_API_KEY=sk-or-...
TELEGRAM_BOT_TOKEN=123456:ABC...
ANTHROPIC_API_KEY=sk-ant-...
agenix
{
age.secrets.vibeos-env.file = ./secrets/vibeos-env.age;
services.vibeos-agent.environmentFiles = [
config.age.secrets.vibeos-env.path
];
}
OAuth / Начальное заполнение аутентификации
Для платформ, требующих OAuth (например, Discord), используйте authFile для начального заполнения учётных данных при первом развёртывании:
{
services.vibeos-agent = {
authFile = config.sops.secrets."vibeos/auth.json".path;
# authFileForceOverwrite = true; # перезаписывать при каждой активации
};
}
Файл копируется только если auth.json ещё не существует (если только authFileForceOverwrite = true). Обновления OAuth-токенов во время выполнения записываются в директорию состояния и сохраняются между пересборками.
Документы
Параметр documents устанавливает файлы в рабочую директорию агента (workingDirectory, которую агент читает как своё рабочее пространство). VibeOS ищет определённые имена файлов по соглашению:
USER.md— контекст о пользователе, с которым взаимодействует агент.- Любые другие файлы, которые вы сюда поместите, видны агенту как файлы рабочего пространства.
Файл идентичности агента отдельный: VibeOS загружает свой основной SOUL.md из $VIBEOS_HOME/SOUL.md, который в модуле NixOS находится в ${services.vibeos-agent.stateDir}/.vibeos/SOUL.md. Помещение SOUL.md в documents создаст только файл рабочего пространства и не заменит основной файл личности.
{
services.vibeos-agent.documents = {
"USER.md" = ./documents/USER.md; # ссылка на путь, копируется из Nix store
};
}
Значения могут быть строками или ссылками на пути. Файлы устанавливаются при каждом nixos-rebuild switch.
MCP-серверы
Параметр mcpServers декларативно настраивает серверы MCP (Model Context Protocol). Каждый сервер использует либо stdio (локальная команда), либо HTTP (удалённый URL) транспорт.
Stdio-транспорт (локальные серверы)
{
services.vibeos-agent.mcpServers = {
filesystem = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-filesystem" "/data/workspace" ];
};
github = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-github" ];
env.GITHUB_PERSONAL_ACCESS_TOKEN = "\${GITHUB_TOKEN}"; # разрешается из .env
};
};
}
Переменные окружения в значениях env разрешаются из $VIBEOS_HOME/.env во время выполнения. Используйте environmentFiles для внедрения секретов — никогда не помещайте токены напрямую в Nix-конфигурацию.
HTTP-транспорт (удалённые серверы)
{
services.vibeos-agent.mcpServers.remote-api = {
url = "https://mcp.example.com/v1/mcp";
headers.Authorization = "Bearer \${MCP_REMOTE_API_KEY}";
timeout = 180;
};
}
HTTP-транспорт с OAuth
Установите auth = "oauth" для серверов, использующих OAuth 2.1. VibeOS реализует полный PKCE-процесс — обнаружение метаданных, динамическую регистрацию клиента, обмен токенами и автоматическое обновление.
{
services.vibeos-agent.mcpServers.my-oauth-server = {
url = "https://mcp.example.com/mcp";
auth = "oauth";
};
}
Токены хранятся в $VIBEOS_HOME/mcp-tokens/<server-name>.json и сохраняются между перезапусками и пересборками.
Первоначальная OAuth-авторизация на серверах без головы
Первая OAuth-авторизация требует процесса согласия через браузер. В развёртывании без головы VibeOS выводит URL авторизации в stdout/логи вместо открытия браузера.
Вариант A: Интерактивная начальная загрузка — выполните процесс один раз через docker exec (контейнер) или sudo -u vibeos (нативный):
# Режим контейнера
docker exec -it vibeos-agent \
vibeos mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth
# Нативный режим
sudo -u vibeos VIBEOS_HOME=/var/lib/vibeos/.vibeos \
vibeos mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth
Контейнер использует --network=host, поэтому слушатель OAuth-обратного вызова на 127.0.0.1 доступен из браузера хоста.
Вариант B: Предварительное заполнение токенов — выполните процесс на рабочей станции, затем скопируйте токены:
vibeos mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth
scp ~/.vibeos/mcp-tokens/my-oauth-server{,.client}.json \
server:/var/lib/vibeos/.vibeos/mcp-tokens/
# Убедитесь: chown vibeos:vibeos, chmod 0600
Сэмплинг (запросы LLM, инициированные сервером)
Некоторые MCP-серверы могут запрашивать завершения LLM у агента:
{
services.vibeos-agent.mcpServers.analysis = {
command = "npx";
args = [ "-y" "analysis-server" ];
sampling = {
enabled = true;
model = "google/gemini-3-flash";
max_tokens_cap = 4096;
timeout = 30;
max_rpm = 10;
};
};
}
Управляемый режим
Когда vibeos работает через модуль NixOS, следующие CLI-команды заблокированы с описательной ошибкой, указывающей на configuration.nix:
| Заблокированная команда | Почему |
|---|---|
vibeos setup | Конфигурация декларативна — редактируйте settings в вашей Nix-конфигурации |
vibeos config edit | Конфигурация генерируется из settings |
vibeos config set <key> <value> | Конфигурация генерируется из settings |
vibeos gateway install | systemd-сервис управляется NixOS |
vibeos gateway uninstall | systemd-сервис управляется NixOS |
Это предотвращает расхождение между тем, что объявляет Nix, и тем, что находится на диске. Обнаружение использует два сигнала:
- Переменная окружения
VIBEOS_MANAGED=true— устанавливается systemd-сервисом, видна процессу шлюза - Файл-маркер
.managedвVIBEOS_HOME— устанавливается скриптом активации, виден интерактивным оболочкам (например,docker exec -it vibeos-agent vibeos config set ...также заблокирован)
Чтобы изменить конфигурацию, отредактируйте вашу Nix-конфигурацию и выполните sudo nixos-rebuild switch.
Архитектура контейнера
Этот раздел актуален только если вы используете container.enable = true. Пропустите его для развёртываний в нативном режиме.
Когда режим контейнера включён, vibeos работает внутри постоянного контейнера Ubuntu с Nix-собранным бинарником, смонтированным только для чтения с хоста:
Хост Контейнер
──── ─────────
/nix/store/...-vibeos-agent-0.1.0 ──► /nix/store/... (ro)
~/.vibeos -> /var/lib/vibeos/.vibeos (символическая ссылка-мост, для каждого hostUsers)
/var/lib/vibeos/ ──► /data/ (rw)
├── current-package -> /nix/store/... (символическая ссылка, обновляется при каждой пересборке)
├── .gc-root -> /nix/store/... (предотвращает nix-collect-garbage)
├── .container-identity (sha256-хэш, инициирует пересоздание)
├── .vibeos/ (VIBEOS_HOME)
│ ├── .env (объединено из environment + environmentFiles)
│ ├── config.yaml (сгенерировано Nix, глубокое слияние при активации)
│ ├── .managed (файл-маркер)
│ ├── .container-mode (метаданные маршрутизации: backend, exec_user и т.д.)
│ ├── state.db, sessions/, memories/ (состояние времени выполнения)
│ └── mcp-tokens/ (OAuth-токены для MCP-серверов)
├── home/ ──► /home/vibeos (rw)
└── workspace/ (рабочая директория агента)
├── SOUL.md (из параметра documents)
└── (файлы, созданные агентом)
Записываемый слой контейнера (apt/pip/npm): /usr, /usr/local, /tmp
Nix-собранный бинарник работает внутри контейнера Ubuntu, потому что /nix/store смонтирован через bind-mount — он приносит свой собственный интерпретатор и все зависимости, поэтому нет зависимости от системных библиотек контейнера. Точка входа контейнера разрешается через символическую ссылку current-package: /data/current-package/bin/vibeos gateway run --replace. При nixos-rebuild switch обновляется только символическая ссылка — контейнер продолжает работать.
Что сохраняется при каких событиях
| Событие | Контейнер пересоздаётся? | /data (состояние) | /home/vibeos | Записываемый слой (apt/pip/npm) |
|---|---|---|---|---|
systemctl restart vibeos-agent | Нет | Сохраняется | Сохраняется | Сохраняется |
nixos-rebuild switch (изменение кода) | Нет (обновляется символическая ссылка) | Сохраняется | Сохраняется | Сохраняется |
| Перезагрузка хоста | Нет | Сохраняется | Сохраняется | Сохраняется |
nix-collect-garbage | Нет (GC root) | Сохраняется | Сохраняется | Сохраняется |
Изменение образа (container.image) | Да | Сохраняется | Сохраняется | Потерян |
| Изменение томов/параметров | Да | Сохраняется | Сохраняется | Потерян |
Изменение environment/environmentFiles | Нет | Сохраняется | Сохраняется | Сохраняется |
Контейнер пересоздаётся только при изменении его идентификационного хэша. Хэш покрывает: версию схемы, образ, extraVolumes, extraOptions и скрипт точки входа. Изменения переменных окружения, настроек, документов или самого пакета vibeos не инициируют пересоздание.
Когда идентификационный хэш изменяется (обновление образа, новые тома, новые параметры контейнера), контейнер уничтожается и пересоздаётся из свежего образа container.image. Любые пакеты, установленные через apt install, pip install или npm install в записываемом слое, теряются. Состояние в /data и /home/vibeos сохраняется (это bind-mount).
Если агент полагается на определённые пакеты, рассмотрите возможность включения их в пользовательский образ (container.image = "my-registry/vibeos-base:latest") или скриптовой установки в SOUL.md агента.
Защита GC Root
Скрипт preStart создаёт GC root в ${stateDir}/.gc-root, указывающий на текущий пакет vibeos. Это предотвращает удаление