Skip to content

Концепции

Loadout

Слово «loadout» в AIM имеет два смысла — продуктовый и технический.

Loadout-метафора — полный патронташ разработчика, работающего с AI-инструментами. В него входят навыки, MCP-серверы и настройки, которые делают AI-среды готовыми к работе. Команда aiman sync — быстрая перезарядка этого патронташа на новой машине. Отсюда название продукта: AIM Loadout.

Технический loadout — именованное подмножество инвентаря для контекстной работы, например Documentation Work или Architecture Work. Хранится как loadouts/<name>.yaml и применяется командой aiman apply --loadout <name> декларативно: AI-среды приводятся ровно к набору loadout в пределах элементов, известных инвентарю. Элементы инвентаря вне loadout удаляются из сред; файлы, созданные вручную или другим инструментом, не затрагиваются.

СмыслЧто означаетКоманда
Loadout-метафоравесь инвентарь целикомaiman sync, aiman apply
Технический loadoutименованное подмножество инвентаряaiman apply --loadout <name>

aiman apply без флага --loadout работает в режиме виртуального loadout Default — это весь валидный инвентарь; его поведение аддитивно: устанавливает и обновляет элементы, но ничего не удаляет из сред. У aiman sync флага --loadout нет вовсе — это транспорт полного инвентаря, — но её поведение при применении зависит от пина: без пина она аддитивна, как apply без --loadout; с активным пином она декларативно приводит среды к набору пинованного loadout, как apply --loadout <name>.

Сценарий контекстного переключения — в Рабочих циклах, формат файла — в формате инвентаря.

Пин loadout

apply --loadout <name> — разовое действие: оно приводит AI-среды к набору loadout один раз и ничего не запоминает. Следующий aiman sync расширит среды обратно до полного инвентаря, потому что sync по умолчанию не знает о выборе, сделанном через apply.

Пин — это сохранённое состояние поверх того же loadout-механизма: имя закреплённого loadout хранится в глобальном конфиге пользователя (~/.config/aim/config.yaml, поле loadout) и остаётся активным между запусками CLI, пока его явно не снимут. Пока пин установлен, aiman sync вместо аддитивного применения полного инвентаря декларативно приводит среды к набору пинованного loadout — так же, как apply --loadout <name>, включая удаление элементов вне набора.

apply --loadout <name>apply --loadout <name> --pin
Что происходитприменяет набор один разприменяет набор и запоминает его как активный пин
Что видит следующий syncничего не знает о выборе — применяет полный инвентарьприменяет тот же loadout вместо полного инвентаря
Где хранитсянигде, эффект только в AI-средахв глобальном конфиге, loadout: <name>
Как снятьничего снимать не нужно — sync уже вернёт полный наборaiman apply --unpin или aiman apply --default

Пин управляется флагами apply:

  • apply --loadout <name> --pin — применить и закрепить;
  • apply --default — применить весь инвентарь и снять пин одним действием;
  • apply --unpin — снять пин, ничего не применяя.

aiman status показывает активный пин в поле Pinned loadout:. aiman switch на другой репозиторий инвентаря безусловно снимает пин, даже если в новом репозитории есть loadout с таким же именем — per-machine хранится только один глобальный указатель, а не набор пинов на репозиторий.

Если пин указывает на loadout, которого больше нет (переименовали, удалили, или switch привёл к репозиторию без такого имени), sync останавливается с ошибкой pinned loadout "X" not found in inventory вместо тихого отката к полному инвентарю — так рассинхронизация не остаётся незамеченной. Это отдельная проверка от loadout "X" not found in loadouts/, которую выдаёт apply --loadout без пина.

Полное описание флагов, конфликтов и вывода — в Справочнике CLI, сценарий использования — в Рабочих циклах.

Inventory

Inventory (инвентарь) — Git-репозиторий с файлами, которые AIM применяет в AI-среды пользователя.

В текущей модели инвентарь содержит:

  • skills/ — навыки;
  • mcp/ — MCP-серверы;
  • loadouts/ — именованные подмножества инвентаря (опционально);
  • aim.yaml — общий конфиг;
  • .gitignore — как минимум исключает aim.local.yaml;
  • aim.local.yaml — локальный файл на каждой машине, не хранится в Git.

Library Item

Library Item — единица инвентаря. В текущем MVP есть два типа: Skill Item и MCP Item.

Кандидатом на место в инвентаре становится сущность, которую AI-среды приняли как промышленный стандарт: у неё есть устоявшийся формат, её поддерживают несколько производителей, и её можно перенести между средами без существенных изменений. Такая сущность имеет смысл как переносимый актив — её стоит хранить централизованно и применять через адаптеры.

Skill Item

Skill Item — Markdown-инструкция для AI-среды.

Файл хранится как skills/<name>.md:

md
---
name: review-code
description: Проведи code review с фокусом на корректность
targets:
  - claude-code
  - cursor
---

# Role

...

После применения AIM устанавливает навык в формат, ожидаемый конкретной AI-средой.

Навык может храниться в виде папки (skills/<name>/SKILL.md) с дополнительными справочными файлами — например agent-patterns.md или examples.md. В этом случае AIM копирует всю папку целиком. Подробнее — в Справочнике формата инвентаря.

MCP Item

MCP Item — YAML-описание MCP-сервера:

yaml
name: context7
description: Документация библиотек через MCP
command: npx
args:
  - -y
  - "@upstash/context7-mcp"
targets:
  - claude-code
  - cursor
  - codex
env:
  - name: API_KEY
    description: API key
    required: true

Значения env-переменных не хранятся в Git. AIM запрашивает их локально и сохраняет в aim.local.yaml.

Потенциальные будущие типы

По мере того как AI-среды договариваются о новых стандартах, в инвентарь могут войти дополнительные типы.

Инструкция субагента. Claude Code уже поддерживает инструкции для субагентов. Когда этот формат примут Codex CLI и Cursor, он может стать самостоятельным Library Item.

Системная инструкция проекта / директории. Claude Code хранит её в CLAUDE.md, Codex — в AGENTS.md, Cursor читает оба файла. Эти инструкции уже де-факто конвергируют к схожему формату. В перспективе AIM сможет хранить такую инструкцию как единый актив и при sync распределять её по средам через адаптеры.

В текущем MVP ни один из этих типов не реализован. Library Item — это только Skill Item или MCP Item.

Сбор инвентаря

Прежде чем управлять инвентарём, его нужно наполнить. AIM поддерживает два способа добавления элементов.

aiman add — из локального файла или stdin:

bash
aiman add skill cool-skill.md
cat prompt.md | aiman add skill -

aiman add mcp jira.yaml
cat jira.yaml | aiman add mcp -

aiman add skill принимает и путь к папочному скиллу (или его SKILL.md) — в этом случае в инвентарь копируется вся папка: SKILL.md и все файлы-references рядом с ним.

При добавлении MCP-сервера AIM автоматически извлекает реальные значения env-переменных из файла и сохраняет их в aim.local.yaml — в инвентарь (и в Git) попадают только дескрипторы без секретов.

aiman import — из установленной AI-среды:

bash
aiman import skill review-code --from claude-code
aiman import skill my-prompt --from codex

aiman import mcp context7 --from claude-code
aiman import mcp jira --from cursor --print

aiman import пишет только в активный репозиторий инвентаря: без подключённого репозитория команда завершается ошибкой и просит выполнить aiman init, а не создаёт файлы в текущей директории.

При импорте навыка, который хранится в среде папкой (<name>/SKILL.md с ресурсными файлами), в инвентарь переносится вся папка — так же, как при aiman add skill <dir>.

При импорте MCP-сервера AIM читает живую конфигурацию AI-среды, применяет env-strip и записывает дескриптор в mcp/<name>.yaml. Реальные значения env-переменных при этом попадают в aim.local.yaml, но не в Git. Импортируются только stdio-серверы (с полем command); серверы с HTTP/SSE-транспортом AIM не переносит.

После добавления элемент появляется в локальном инвентаре (skills/<name>.md или mcp/<name>.yaml). Для публикации используйте aiman push.

Подробнее о конкретных командах и флагах — в Справочнике CLI.

Discovery: occurrence, unique item и три слоя кандидата

aiman import без имени — отдельный режим (discovery): вместо переноса одного заранее известного элемента он сканирует все поддерживаемые AI-среды сразу и строит план того, что из уже установленного ещё не попало в инвентарь. Команды не изменились; discovery — дополнительный вход поверх той же модели add/import.

Два термина, которые discovery вводит в вывод:

  • occurrence (вхождение) — один элемент в одном источнике. Скилл review-code, найденный в Claude Code, — одно occurrence.
  • unique item (уникальный элемент) — группа occurrences с одинаковым ключом <kind>:<name> (например, mcp:context7). Один и тот же MCP-сервер, найденный в трёх средах, — три occurrences, один unique item. Разные имена никогда не схлопываются в один unique item только из-за одинакового содержимого.

У каждого кандидата — три независимых слоя, которые discovery никогда не смешивает:

  1. Payload — переносимое содержимое: для скилла это SKILL.md, все ресурсные файлы и исполняемый бит; для MCP-сервера — команда, аргументы и набор имён env-переменных (без значений).
  2. Delivery policy (targets) — куда AIM должен доставлять элемент. Для нового MCP-элемента это отсортированное объединение сред, где нашёлся тот же payload. Для нового скилла — явно заданный targets из frontmatter сохраняется как есть; если поля нет, оно и остаётся отсутствующим (это по-прежнему значит «все обнаруженные среды»). У уже существующего элемента инвентаря targets всегда авторитетны: находка того же payload в ещё одной среде — просто наблюдение, оно никогда не расширяет политику доставки молча.
  3. Local values — реальные значения MCP env-переменных для текущей машины. Они никогда не путешествуют через Git и обрабатываются отдельно от первых двух слоёв.

Смешивание слоёв даёт ложные выводы: наличие MCP-сервера в Cursor — это наблюдение (payload), а не решение о доставке (policy); заполнение пропущенного значения env — это про local values, а не про payload или policy.

Три типа конфликта, которые план различает по смыслу, а не по одному общему «conflict»:

  • source conflict — один и тот же ключ найден с разным payload в разных средах (пример: jira MCP-сервер с разной командой в Codex и Cursor). У скилла отдельно выделяется policy conflict — payload идентичен, но targets в frontmatter отличаются между источниками.
  • inventory conflict — payload кандидата отличается от уже существующего элемента инвентаря с тем же ключом, либо в инвентаре одновременно есть skills/<name>.md и skills/<name>/SKILL.md — discovery не полагается на то, какой из двух форматов сейчас применяется.
  • local-value conflict — два и более источника расходятся в значении одной и той же MCP env-переменной. Такое значение не заполняется автоматически, даже если сам payload элемента однозначен — при конфликте payload значения вообще не импортируются, они могут относиться к другому серверу с тем же именем.

Discovery никогда не выбирает «первый попавшийся» вариант при конфликте и не переписывает уже эквивалентный элемент инвентаря — совпадающий payload становится no-op, форматирование и mtime существующего файла не меняются. Разрешение конфликта — точечное, тем же aiman import skill|mcp <name> --from <env> (при необходимости с --overwrite), что и раньше.

Подробный контракт команды, флаги и обе осознанные асимметрии с точечным импортом — в Справочнике CLI.

Adapter

Adapter — часть AIM, которая знает формат конкретной AI-среды.

Адаптер отвечает за:

  • обнаружение базовой директории AI-среды;
  • сканирование навыков при aiman import skill — адаптер знает, где AI-среда хранит навыки;
  • сканирование MCP-конфигурации при aiman import mcp — адаптер читает живой конфиг среды;
  • установку Skill Item;
  • запись MCP-сервера в нужный JSON или TOML-конфиг.

Поддерживаемые среды:

  • Claude Code;
  • Cursor;
  • Codex CLI.

apply, push и sync

aiman apply применяет текущее локальное рабочее дерево без Git-операций. Это внутренний цикл разработки навыка.

aiman apply --loadout <name> — контекстный вариант apply: приводит AI-среды ровно к именованному подмножеству инвентаря, включая удаление элементов инвентаря вне loadout (см. Loadout).

aiman push валидирует инвентарь, делает commit и отправляет изменения в удалённый репозиторий. Это публикация.

aiman sync получает опубликованное состояние из Git и применяет его в локальные AI-среды. Это перенос на другую машину или обновление текущей. Без пина sync применяет весь инвентарь аддитивно; с активным пином — декларативно приводит среды к набору пинованного loadout, как apply --loadout <name>.

Состав изменений в результате

Все три команды после строки результата показывают состав изменений — что именно добавлено (A), изменено (M) или удалено (D). У push маркер D всегда означает файл, удалённый из инвентаря. У apply он появляется только при --loadout и означает удаление элемента из AI-среды. У sync смысл D зависит от контекста: в git-дельте (что изменилось в опубликованном инвентаре) он означает удалённый файл, а в pinned-режиме дополнительно печатается второй, отдельный блок — состав применения к средам, где D означает то же, что у apply --loadout (см. Справочник CLI):

text
synced: 67451fc · 21 skills, 1 MCP server → 3 environments
  M skills/commit-message.md
  A skills/refactor-helper.md

Здесь важно различать два числа. Счётчики в строке результата (21 skills) — это объём операции: сколько всего применено. Блок ниже — состав изменений: что нового или изменённого. 21 skills означает 21 навык всего, а не 21 изменение. Если ничего не изменилось, блок не печатается — остаётся только строка результата.

Для навыков состав изменений вычисляется сравнением содержимого. Для MCP-серверов он пока не вычисляется (см. Известное ограничение в справочнике).

Почему aiman status обращается к remote

aiman status отвечает на вопрос «что в моём инвентаре изменилось относительно опубликованного состояния». Этот вопрос по определению включает состояние remote, поэтому перед расчётом позиции команда выполняет Git fetch.

Это осознанное отличие от локального git status, который к сети не обращается: его вопрос — только о локальном рабочем дереве. У aiman status нет «честного» локального ответа — без fetch позиция строилась бы по устаревшему ref и могла бы вводить в заблуждение. Поэтому короткая задержка на fetch — ожидаемое поведение, а не сбой. Если remote недоступен, status не зависает: позиция показывается как unknown (remote unreachable), а команда завершается успешно.

aim.local.yaml

aim.local.yaml создаётся на каждой машине отдельно и не попадает в Git.

В нём хранятся:

  • пути к AI-средам;
  • hash-метки последнего успешного push и sync;
  • локальные значения env-переменных MCP-серверов.

Hash-метки информационные: они помогают объяснить состояние, но безопасность push и sync опирается на состояние Git.


Дальше

Released under the Apache 2.0 License.