Контракт упаковки групп
Стабильный контракт для упаковки групп и манифестов плагинов, предназначенный для внешних потребителей: перечислить группы и разрешить их нативные цели по окружениям без повторного выведения сопоставления.
Контракт упаковки групп
Этот документ задаёт стабильный контракт для упаковки групп и манифестов плагинов, предназначенный для внешних потребителей. Потребитель читает этот контракт, чтобы перечислить группы и разрешить их нативные цели по окружениям без повторного выведения сопоставления.
Артефакты
| Артефакт | Роль |
|---|---|
src/apothem/schemas/cohort.schema.json | JSON Schema для документа манифеста групп. |
src/apothem/schemas/cohort-manifest.yaml | Экземпляр манифеста групп — все шесть групп (core, developer, security, research, ai-engineering, full), заполненные своими наборами участников; full — объединение остальных пяти. |
src/apothem/schemas/plugin.schema.json | JSON Schema для манифеста плагина отдельного пакета (plugin.json). |
src/apothem/lib/propagation-manifest.yaml | Источник истины для нативных целей по окружениям. |
Форма манифеста групп
Манифест групп — это объект верхнего уровня с тремя ключами:
version— строка SemVer манифеста.cohorts[]— одна запись на группу. Каждая запись содержитid(из закрытого набораcore | developer | security | research | ai-engineering | full),name,descriptionиmembers(объект, группирующий идентификаторы участников по типу каталога:skills/agents/commands/rules/hooks).per_harness_targets— контракт разрешения (см. ниже).
Каждый идентификатор участника — это стабильное имя в kebab-case, которое
соответствует реальному артефакту под src/apothem/ (skills/<name>/,
agents/<name>.md, commands/<name>.md, rules/<name>.md или запись хука —
либо исполняемый hooks/<name>.py, либо рекомендательный контекст сообщения в
hooks/messages/<name>.md, доставляемый через диспетчер).
Перечисление групп
Потребитель загружает cohort-manifest.yaml, проверяет его по
cohort.schema.json, затем перебирает cohorts[]. Для каждой группы он читает
members.<type>, чтобы получить идентификаторы участников каждого типа каталога.
Разрешение нативных целей по окружениям (без повторного выведения)
Манифест групп не повторяет сопоставление окружений. Вместо этого
per_harness_targets.source указывает на lib/propagation-manifest.yaml —
единственный источник истины. Правило разрешения:
Для участника группы с типом каталога
T(одним изskills,agents,commands,rules,hooks) и целевого окруженияH(одного из перечисленных вper_harness_targets.harnesses) нативная цель плагина — это полеtargetтой записи вlib/propagation-manifest.yamlподharnesses.H.install, чейsourceсовпадает сT/.
Например, навык группы core, устанавливаемый для claude_code, разрешается
через запись harnesses.claude_code.install с source: "skills/" в
target: "${HARNESS_ROOT}/skills/". Тот же навык для opencode разрешается в
${HARNESS_ROOT}/skills/; для gemini_cli — в ${PROJECT_ROOT}/.gemini/skills/.
Потребители никогда не выдумывают цели окружений — они их ищут.
Заполнители ${HARNESS_ROOT} / ${PROJECT_ROOT} разрешаются во время установки
каждым адаптером окружения; потребители групп используют разрешённый target
дословно.
Роль манифеста плагина
plugin.schema.json описывает plugin.json — самоописывающий пакет участников
каталога (skills / commands / agents / hooks / rules) с обязательными
name, version в формате SemVer и description. Необязательные метаданные
охватывают displayName (имя, показываемое вместо name) и поля для листинга
в каталоге плагинов: documentationUrl, supportUrl, privacyPolicyUrl и
termsOfServiceUrl, каждое из которых является URL с https://, а также путь
icon внутри плагина. Сгенерированный пакет Claude Code задаёт displayName,
documentationUrl и supportUrl. Каталог Anthropic читает поля для
каталога, а Claude Code игнорирует их при загрузке. Синхронизация маркетплейса
claude.ai сообщает об этих двух ссылках как о нераспознанных ключах и удаляет
их, поэтому маркетплейс там показывает «1 with warnings». Это предупреждение
ожидаемо, и плагин загружается без изменений. Манифест плагина — это единица, которую
адаптер окружения материализует в свою нативную поверхность плагинов; группы
выбирают, каких участников несёт плагин, а манифест распространения
разрешает, куда эти участники попадают в каждом окружении.
Решение об упаковке — один зонтичный пакет, логические группы
Группы — это логический слой выбора (данный манифест), а не набор отдельных, независимо устанавливаемых пакетов. Apothem поставляет один зонтичный пакет, несущий полный каталог; манифест групп позволяет потребителю выбрать согласованное подмножество, а манифест распространения разрешает, куда попадает каждый выбранный участник в каждом окружении.
Разделение каталога на отдельные пакеты по группам (например, по одному пакету
на семейство developer / security / research) достижимо без
дублирования на уровне репозитория с помощью задокументированного основной
поверхностью распространения паттерна символических ссылок мета-плагина:
один каталог маркетплейса перечисляет несколько плагинов групп, и каталог
каждого плагина группы содержит символические ссылки на единый общий
каталог-источник, а не копии. Когда группа устанавливается, окружение
разыменовывает каждую символическую ссылку внутри маркетплейса, копируя
содержимое цели в кэш этой группы, поэтому установленная группа
самодостаточна, тогда как репозиторий сохраняет единый источник истины,
связанный символическими ссылками (связывание вместо избыточности, ровно как
предпочитает дисциплина дедупликации). Прежнее толкование, согласно которому
пакеты групп «механически дублируют» каталог, смешивало дублирование кэша во
время установки (обычную копию каждого плагина, которую делает окружение) с
дублированием в репозитории; паттерн символических ссылок избегает последнего.
Apothem сейчас поставляет один зонтичный пакет, потому что это самая простая поверхность распространения, а не потому, что группы механически невозможны. Переход к форме с пакетами по группам — это настоящий компромисс между UX и сопровождением, а не нарушение дедупликации: выигрыш — более точечный сценарий «установить только это семейство»; затраты — сопровождение N каталогов символических ссылок групп и их записей в маркетплейсе, более крупная поверхность соответствия / тестов / эталонных снимков и копии кэша во время установки для каждой группы. Описанный выше логический слой групп уже обеспечивает результат выбора «установить только то, что нужно» из единого пакета; упаковка по группам — это следующий шаг, когда понадобится более точечный UX установки.