Agent Dev 101

Модуль 16 · Урок 16.15

Урок 16.15. Bundles: пакеты готового стека

На этой странице
  1. Зачем это нужно
  2. Основная идея
  3. First-party бандлы
  4. Поиск и информация
  5. Установка
  6. Обновление и удаление
  7. Инициализация проекта бандлом
  8. Валидация, сборка, публикация
  9. Каталоги
  10. Практика
  11. Краткое резюме
  12. Вопросы для самопроверки
  13. Что дальше
  14. Источники

Зачем это нужно

Расширения, пресеты, workflows и шаги - примитивы (уроки 16.12-16.14). Бандл решает следующую задачу: собрать курированный стек для команды или роли и развернуть его одним шагом - с пиновкой версий, проверкой конфликтов и трекингом происхождения для чистого удаления и обновления.

Примеры из репозитория - наборы для продакт-менеджера, бизнес-аналитика, security-исследователя и разработчика. First-party бандлы bugfix и assess мы уже встречали как строительный материал собственного SDLC проекта (урок 16.4).

Основная идея

Бандл - распределительный и композиционный слой поверх примитивов, без собственной рантайм-поведения. Он описывается манифестом bundle.yml, обнаруживается через стек каталогов и при установке резолвит объявленные компоненты против пинов, проверяет единственную точку межбандлового конфликта (активную интеграцию) и применяет каждый компонент идемпотентно, с полным provenance-трекингом.

First-party бандлы

Специфицируемый каталог bundles/catalog.json: курированные, verified: true, резолвятся через встроенный источник builtin://default.

Бандл Роль Компоненты Сценарий
bugfix developer расширение bug + workflow bugfix ведомый assess -> gate -> fix -> test
assess developer расширение assess + workflow assess триаж идей до SDD

add - алиас install:

bash
specify bundle install bugfix
specify bundle add assess

First-party каталог качается из репозитория онлайн и падает в офлайн-снапшот пакета wheel - обнаружение работает без сети. Локальный манифест может ставить bundled-расширения и workflows с --offline; каталогные манифесты резолвятся из своих download_url, поэтому bundle add <id> сегодня требует сеть - полностью офлайновая каталоговая установка в планах.

Поиск и информация

bash
specify bundle search [query]   # --offline, --json
specify bundle info <bundle_id>  # --offline, --json

Search выводит доступные бандлы с версией, ролью, источником и индикатором доверия (verified для курированных организацией записей, community для прочих) - чтобы оценивать доверие до установки.

Info показывает полные метаданные и полностью развернутый набор компонентов: каждое расширение, пресет, шаг и workflow с пином версии, приоритетом и стратегией пресета. Этот превью - тот же план, который применит install: видно ровно, что будет добавлено, включая предвидимые пересечения с компонентами уже установленных бандлов.

Установка

bash
specify bundle install <bundle_id | path>
Опция Описание
--integration интеграция при инициализации/установке
--offline без сети
--refresh обновить owned-компоненты из переданного источника бандла

Аргумент - ID каталога или локальный путь (собранный .zip, каталог бандла или bundle.yml); локальные источники ставятся напрямую, минуя стек каталогов. Если текущий каталог - еще не проект Spec Kit, install сначала инициализирует его: свежий checkout приходит в рабочее состояние одной командой.

Интеграции: --integration выбирает ее при инициализации нового проекта и подтверждает цель, когда бандл пинит конкретную интеграцию, а активная не определима (отсутствует/нечитаем .specify/integration.json). Активную интеграцию уже инициализированного проекта опция не перекрывает: бандл с другой целью - отказ без изменений. Интеграция-агностичные бандлы наследуют активную.

Идемпотентность и границы: без --refresh уже присутствующие компоненты пропускаются. Компоненты, установленные вне бандлов, пропускаются и никогда не усыновляются - их установленная версия обязана совпасть с пином манифеста; при несовпадении или нечитаемости install и refresh останавливаются до изменений, называя компонент (удалите его или поставьте пинованную версию сами). При сбое запись provenance не пишется, поставленное в этом прогоне удаляется best-effort (ошибки удаления глотаются - частичное состояние на диске возможно).

Обновление записанного бандла: обычный install отвергает изменение версии или метаданных owned-компонентов (версия, источник, приоритет пресета, стратегия), включая удаление owned-компонента - даже при неизменной версии локального манифеста. Перестановка неизменных компонентов и добавление новых refresh не требуют. Применить изменения локального бандла без добавления в каталог:

bash
specify bundle install ./new-release/bundle.yml --refresh

Источник может быть и каталогом, и .zip. Refresh идет тем же путем обновления примитивов, что и bundle update, повторно применяет owned-компоненты и удаляет исключенные из нового манифеста (если они не нужны другому бандлу); независимо установленные компоненты не трогаются и не усыновляются. Запись бандла продвигается только после успеха; измененные при неудачном refresh компоненты не откатываются.

Офлайн: локальный источник дает манифест, не payload-ы компонентов - каталогные компоненты требуют сети даже установленными. --offline добавляйте, только когда компоненты шипятся со Spec Kit; иначе команда назовет компонент, требующий сети, - перезапустите без флага.

Step-payload-ы резолвятся только через step-каталог. provides.steps бандла резолвятся исключительно через активные step-каталоги; bundle-local steps/<id>/ и относительные provides.steps[].source-оверрайды в этом релизе не резолвятся - так объявленный шаг офлайн не поставить. Чтобы доставить шаг с бандлом сегодня - опубликуйте его в step-каталоге, достижимом для пользователей бандла.

Обновление и удаление

bash
specify bundle update [<bundle_id>]   # --all, --integration, --offline
specify bundle remove <bundle_id>
specify bundle list [--json]

update перерезолвит бандл и refresh-ит компоненты через путь обновления каждого примитива, поднимая установленные до новых пинов с сохранением примитивных оверрайдов (например, приоритета пресета). Без ID - один бандл, с --all - все установленные.

Важно: контроль пинов - только на установке. Идемпотентные проверки - по id, не по версии: owned-компонент, уже присутствующий, пропускается без сравнения версии на диске с пином манифеста. Гарантия пинов - только при первой установке или refresh. Для принудительного приведения к пинам: specify bundle update <bundle_id> (каталоговые) или specify bundle install <path> --refresh (локальные).

remove удаляет только компоненты, внесенные этим бандлом; нужные другому установленному бандлу остаются (сопутствующих удалений нет). list выводит версии, счетчики компонентов и таймстемпы установки.

Инициализация проекта бандлом

bash
specify bundle init [<bundle_id>]   # --integration, --offline

Гарантирует, что текущий каталог - проект Spec Kit (идемпотентно инициализирует при необходимости), затем опционально ставит бандл. Явный one-step bootstrap для нового checkout.

Валидация, сборка, публикация

bash
specify bundle validate    # --path (каталог или bundle.yml; дефолт - текущий), --offline
specify bundle build       # --path, --output

Validate проверяет корректность bundle.yml и резолвимость каждой ссылки против bundled-компонентов, установленных в проекте и - онлайн - активных каталогов. Отказ - только при доказанном отсутствии везде, где можно проверить (каталог достижим и подтверждает отсутствие); непроверяемые ссылки (офлайн или недостижимый каталог) понижаются до предупреждений, чтобы авторинг продолжался.

Build собирает единственный версионируемый дистрибутив .zip из каталога бандла; артефакт встраивает манифест и ставится напрямую specify bundle install <artifact.zip>.

Публикация: авторы валидируют и пакуют бандл локально, затем хостят артефакт и метаданные каталога там, где пользователи их достанут. Запись каталога указывает на артефакт, но компоненты внутри bundle.yml резолвятся через bundled/установленные компоненты или активные каталоги расширений, пресетов, workflows и шагов. Если бандл ссылается на компоненты не-дефолтных каталогов - документируйте их URL и тестируйте установку из чистого проекта с подключенными каталогами; сабмишены сообщества прикладывают это доказательство резолюции зависимостей в issue Bundle Submission.

Каталоги

Бандлы обнаруживаются через приоритизированный стек источников (проект, пользователь, встроенные):

  • builtin://default - first-party бандлы из bundles/catalog.json (bugfix, assess, ...), install-allowed;
  • builtin://community - сабмишены сообщества из bundles/catalog.community.json, discovery-only.

Политики: install-allowed разрешает установку; discovery-only виден в search/info, установку отвергает.

bash
specify bundle catalog list                        # стек с политиками
specify bundle catalog add <url>                   # --policy, --priority (меньше=выше; дефолт 10), --id
specify bundle catalog remove <id_or_url>          # встроенные удалить нельзя

Повторное добавление источника с теми же ID, URL, политикой и приоритетом - no-op; с другими настройками - отказ.

Предупреждение документации: вэттьте и источник бандла, и каталоги его компонентов. Проект может нести собственный каталог бандлов и install-allowed каталоги компонентов под .specify/ - наличие этой конфигурации не доказывает, что в ней что-то ревьюилось. В незнакомом проекте перед установкой: specify bundle catalog list, плюс extension/preset/workflow catalog list и specify workflow step catalog list для тянущихся компонентов; источник, который добавляли не вы, считайте непроверенным до ревью.

Область действия команд: search и info работают где угодно (без проекта - fallback на встроенный/пользовательский стек); меняющие состояние (list, update, remove, catalog) требуют проект; install и init инициализируют проект по требованию в неинициализированном каталоге.

Практика

  1. В чистом каталоге выполните specify bundle init bugfix --integration copilot - одной командой получите проект с расширением bug и его workflow; проверьте specify bundle list и provenance.
  2. Прогоните specify bundle info assess до установки и сверьте развернутый набор компонентов с тем, что реально появится после install.
  3. Соберите собственный минимальный бандл: bundle.yml с одним пресетом и одним расширением; validate, build, затем установка артефакта из .zip в другом проекте.

Краткое резюме

Бандлы - версионируемые пакеты поверх примитивов: bundle.yml пинит компоненты, установка идемпотентна и отслеживает происхождение каждого компонента, удаление убирает только вклад бандла. First-party каталог (bugfix, assess) верифицирован и работает офлайн через wheel-снапшот. Обновление - refresh через механизмы примитивов; контроль пинов гарантируется только при установке/refresh, не при пропуске идемпотентности.

Главное из урока:

  • конфликтная точка между бандлами одна - активная интеграция; --integration не перекрывает активную существующего проекта;
  • независимо установленные компоненты не усыновляются: версия обязана совпасть с пином, иначе стоп;
  • --offline реален только для bundled-компонентов; step-payload-ы бандла сегодня требуют step-каталога;
  • info показывает точный план установки - превью до обязательства;
  • доверие: verified против community, вэттинг каталогов проекта и компонентов.

Вопросы для самопроверки

  1. Что добавляет бандл поверх примитивов и чего он не добавляет? Почему он называется распределительным слоем?
  2. Что произойдет, если бандл пинит интеграцию, отличную от активной в проекте? А если активная нечитаема?
  3. Почему независимо установленный компонент с несовпадающей версией останавливает установку? Какие варианты действия называет команда?
  4. В чем ограничение идемпотентности установки по отношению к пинам версий? Когда пины гарантируются?
  5. Что удаляет bundle remove и почему «сопутствующих удалений» нет?
  6. Какие источники каталогов бандлов встроены и каковы их политики? Что нужно вэттить перед установкой бандла в незнакомом проекте?

Что дальше

Все слои кастомизации замкнуты в один вопрос: что фактически лежит в проекте и какой слой победил? Урок 16.16 разбирает specify artifact - read-only интроспекцию полного инвентаря команд, шаблонов и скриптов.

Источники

Обновлено 03.10.2026