Skip to content

Справочник CLI

Все команды предоставляет бинарник aiman.

Формат вывода нестабилен до версии 1.0. Человекочитаемый вывод команд — не стабильный API. Для автоматизации ожидайте будущий флаг --json. Все изменения формата помечаются breaking: в changelog.

Глобальные флаги

ФлагОписание
--helpПоказать help для команды
--versionПоказать версию бинарника

aiman init

bash
aiman init <repo-url> [--path <dir>]

Подключает репозиторий инвентаря.

Аргументы:

  • <repo-url> — URL Git-репозитория инвентаря.

Флаги:

  • --path <dir> — локальный путь для clone или регистрации репозитория.

Поведение:

  • клонирует или регистрирует репозиторий инвентаря;
  • создаёт структуру для пустого репозитория;
  • создаёт локальный aim.local.yaml;
  • записывает активный репозиторий в глобальный конфиг;
  • классифицирует существующие файлы как adoptable, existing AIM или conflicting.

aiman switch

bash
aiman switch <path>

Переключает активный репозиторий инвентаря без clone.

Используйте, если у вас несколько локальных репозиториев инвентаря или нужно запустить команды из другой директории.

aiman apply

bash
aiman apply [--dry-run]

Применяет текущий локальный инвентарь в AI-среды без Git-операций.

Флаги:

  • --dry-run — показать sha256-дельту между локальным инвентарём и установленными AI-средами без записи файлов.

apply не делает commit, не выполняет push/fetch и не обновляет published_hash или synced_hash.

Пример вывода apply

При успехе apply выводит строку результата. Если в какой-либо AI-среде есть изменения, после строки результата печатается блок состава изменений с отступом в два пробела и маркерами A (новый артефакт) и M (изменённый):

text
applied: 21 skills, 1 MCP server → 3 environments
  A skills/refactor-helper.md   (new in all environments)
  M skills/commit-message.md    (updated in claude-code, cursor)

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

Если в средах ничего не изменилось, печатается только строка результата без блока:

text
applied: 21 skills, 1 MCP server → 3 environments

Пример вывода apply --dry-run

Инвентарь совпадает с установленными AI-средами:

text
[dry-run] nothing to apply — environments match local inventory

Есть изменения:

text
[dry-run] would apply 2 changes to 2 environments (claude-code, cursor):
  A skills/new-skill.md   (new in all environments)
  M skills/existing.md   (differs in cursor)
[dry-run] MCP context7 → claude-code, cursor

Для MCP-серверов apply --dry-run показывает только целевые AI-среды и не вычисляет дельту: AIM не сравнивает установленную в среде MCP-конфигурацию с дескриптором инвентаря. См. Известное ограничение: дельта MCP.

Если список изменений превышает 20 строк, он усекается:

text
  A skills/skill-1.md
  A skills/skill-2.md
  … and 15 more

Известное ограничение: дельта MCP-конфигов

Для навыков AIM вычисляет дельту: сравнивает содержимое инвентаря с установленным в каждой AI-среде файлом и помечает изменения маркерами A/M.

Для MCP-серверов дельта пока не вычисляется. AI-среды пишут MCP в разделяемые конфиги (~/.claude.json, mcp.json, config.toml), и сравнение установленного фрагмента с дескриптором требует парсинга и нормализации этих конфигов — это отложено. Поэтому в выводе MCP-строки показывают только целевые среды, без маркера A/M.

Отсутствие маркера у MCP-сервера не означает, что он не меняется. Оно означает, что AIM не проверяет его состояние в средах. Для навыков это утверждение проверено дельтой, для MCP — нет.

aiman push

bash
aiman push [--dry-run]

Валидирует инвентарь, создаёт commit и отправляет изменения в remote.

Флаги:

  • --dry-run — показать план публикации без commit/push.

push блокируется, если remote новее локального состояния или есть небезопасное состояние Git.

Валидация frontmatter: если поле frontmatter (кроме тела файла) содержит ошибку, push выводит warning: в stderr и продолжает работу. Ошибки в теле файла (body) остаются блокирующими: push выводит error: и прекращает публикацию.

Пример вывода push

При успехе push выводит строку результата с хэшем опубликованного commit. Если в инвентаре были изменения, после строки результата печатается блок состава: какие файлы опубликованы (A — новые, M — изменённые):

text
published: 96e091b · 19 skills, 1 MCP server
  M skills/commit-message.md
  A mcp/jira.yaml

Если изменений нет, печатается только строка результата без блока.

Пример вывода push --dry-run

Рабочее дерево чистое:

text
[dry-run] nothing to publish — working tree is clean

Есть изменения для публикации:

text
[dry-run] would publish managed changes:
  M skills/review-code.md
  A mcp/jira.yaml
  validated inventory: 5 skills, 1 MCP server

aiman sync

bash
aiman sync [--dry-run] [--force]

Получает опубликованное состояние из remote и применяет его в локальные AI-среды.

Флаги:

  • --dry-run — показать план без записи в репозиторий и AI-среды;
  • --force — удалить неотслеживаемые файлы, конфликтующие с remote, и применить опубликованное состояние. Файлы без конфликтов сохраняются в любом случае.

sync не выполняет merge. Если история разошлась, AIM останавливается и просит восстановить Git вручную.

Неотслеживаемые файлы в skills/ и mcp/ не блокируют sync, если они не конфликтуют по имени с файлами из remote. При конфликте sync останавливается и выводит список проблемных файлов.

Пример вывода sync

При успехе sync выводит строку результата с хэшем применённого состояния. Если из remote прилетели изменения, после строки результата печатается блок состава: что обновилось в инвентаре (A — новые, M — изменённые, D — удалённые):

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

Как и в apply, счётчики строки результата — это объём операции (всего применено), а блок — состав прилетевших изменений. 21 skills означает 21 навык всего, а не 21 изменение.

Если из remote ничего не прилетело (локальное состояние уже совпадало с origin/main), печатается только строка результата без блока:

text
synced: 67451fc · 21 skills, 1 MCP server → 3 environments

С флагом --force AIM перед применением удаляет конфликтующие неотслеживаемые файлы и сообщает, что именно удалено. Этот отчёт печатается до строки результата:

text
discarded untracked files (--force):
  skills/draft.md
  mcp/local-only.yaml
synced: 67451fc · 21 skills, 1 MCP server → 3 environments

Отчёт об удалении выводится всегда, без возможности отключения: --force удаляет файлы безвозвратно, и AIM не делает этого молча.

Пример вывода sync --dry-run

Из remote нечего применять (локальное состояние совпадает с origin/main):

text
[dry-run] nothing to sync — environments up to date with origin/main

Есть изменения для применения:

text
[dry-run] would sync 2 changes from origin/main → 3 environments:
  M skills/commit-message.md
  A skills/refactor-helper.md

aiman status

bash
aiman status

Показывает состояние активного репозитория инвентаря: позицию относительно origin/main, состояние AI-сред и список изменений в skills/ и mcp/, которые ещё не опубликованы.

aiman status обращается к remote. Перед расчётом позиции команда выполняет Git fetch — она отвечает на вопрос «что в инвентаре изменилось относительно опубликованного состояния», а этот вопрос по определению включает состояние remote. Без fetch ответ строился бы по устаревшему локальному ref и мог бы быть неверным (показывать up-to-date, когда remote уже ушёл вперёд).

Это осознанное отличие от локального git status. У git status нет сетевого обращения, потому что его вопрос — о локальном рабочем дереве. У aiman status вопрос другой и включает remote, поэтому короткая задержка на fetch — ожидаемое поведение, а не сбой.

TODO: добавить спиннер во время fetch

Fetch выполняется с жёстким таймаутом. Если remote недоступен, команда не зависает: поле Position: принимает значение unknown (remote unreachable), в stderr печатается warning: cannot reach remote repository, код возврата остаётся 0.

Поле Position: принимает значения: up-to-date with origin/main | N commits ahead of origin/main | N commits behind of origin/main | diverged from origin/main (N ahead, M behind) | unknown (remote unreachable).

Поле Environments: принимает значения: applied (synced <hash>) | unknown | needs sync (N commits not applied).

Если список изменений превышает 20 строк, он усекается с подписью … and N more.

Пример вывода

Репозиторий синхронизирован, инвентарь применён:

text
Repository:   git@github.com:you/aim-loadout.git
Position:     up-to-date with origin/main
Environments: applied (synced a1b2c3d)

Working tree matches origin/main · nothing to publish

Есть неопубликованные изменения:

text
Repository:   git@github.com:you/aim-loadout.git
Position:     2 commits ahead of origin/main
Environments: needs sync (2 commits not applied)

Changes not yet published (origin/main → working tree):
  A skills/new-skill.md
  M skills/existing.md

  run aiman push to publish
  run aiman sync to apply

Remote недоступен (нет сети или нет доступа к репозиторию):

text
Repository:   git@github.com:you/aim-loadout.git
Position:     unknown (remote unreachable)
Environments: applied (synced a1b2c3d)

Working tree matches origin/main · nothing to publish

aiman doctor

bash
aiman doctor

Диагностирует локальную установку:

  • активный репозиторий;
  • найденные AI-среды;
  • пути адаптеров;
  • валидность элементов инвентаря;
  • обязательные MCP env-переменные;
  • доступность remote и состояние синхронизации.

Пример вывода

Всё в порядке, все среды найдены:

text
Active Repo: /home/user/.aim/aim-loadout (from /home/user/.config/aim/config.yaml)

=== AI Environments ===
✓ claude-code   /home/user/.claude   found
✓ cursor        /home/user/.cursor   found
✗ codex         /home/user/.codex    not found

=== Skills ===
Found: 4 valid, 0 invalid

=== Sync State ===
synced_hash:    a1b2c3d
published_hash: a1b2c3d
remote HEAD:    a1b2c3d
status:         up-to-date

=== MCP Environment Variables ===
✓ context7 › UPSTASH_REDIS_REST_URL   — set

=== Issues ===
• codex: not installed or not found at /home/user/.codex

Есть проблемы — AI-среда не найдена, обязательная переменная не задана:

text
Active Repo: /home/user/.aim/aim-loadout (from /home/user/.config/aim/config.yaml)

=== AI Environments ===
✓ claude-code   /home/user/.claude   found
✗ cursor        /home/user/.cursor   not found
✗ codex         /home/user/.codex    not found

=== Skills ===
Found: 2 valid, 1 invalid

=== Sync State ===
synced_hash:    not set
published_hash: not set
remote HEAD:    a1b2c3d
status:         not yet synced

=== MCP Environment Variables ===
✗ context7 › UPSTASH_REDIS_REST_URL   — missing (required)

=== Issues ===
• cursor: not installed or not found at /home/user/.cursor
• codex: not installed or not found at /home/user/.codex
• my-skill.md: invalid: name does not match filename
• context7 › UPSTASH_REDIS_REST_URL — missing (required)

aiman add

bash
aiman add skill <file|dir|-> [--name <string>] [--overwrite]
aiman add mcp <file|-> [--name <string>] [--overwrite]

Добавляет элемент инвентаря (навык или MCP-сервер) в локальный репозиторий из файла, директории или stdin.

aiman add skill

bash
aiman add skill <file|dir|->
aiman add skill ~/Downloads/my-skill.md
aiman add skill -

Читает скилл из файла, директории или stdin (-), валидирует frontmatter, определяет имя и записывает результат в активный репозиторий инвентаря.

Аргументы:

  • <file|dir|-> — путь к файлу скилла, путь к папочному скиллу (или его SKILL.md), либо - для чтения из stdin.

Флаги:

  • --name <string> — переопределить имя скилла; если не указан, имя берётся из frontmatter файла (для плоского скилла) или из имени директории (для папочного скилла).
  • --overwrite — перезаписать существующий скилл при конфликте содержимого.

Поведение:

  • одиночный файл (не названный SKILL.md) или stdin — записывается как плоский skills/<name>.md;
  • путь к директории, либо путь к файлу SKILL.md внутри неё — распознаётся как папочный скилл и копируется целиком в skills/<name>/ (SKILL.md + все файлы-references рядом с ним). Оба варианта пути дают одинаковый результат;
  • если директория не содержит SKILL.md — возвращается понятная ошибка, а не системная "is a directory";
  • если skills/<name>.md (плоский скилл) или skills/<name>/SKILL.md (папочный скилл) уже существует с тем же содержимым — команда завершается успешно без изменений; для папочного скилла сравнивается только содержимое SKILL.md, файлы-references в сравнении не участвуют;
  • если назначение уже существует с другим содержимым и --overwrite не указан — возвращает ошибку с подсказкой использовать --overwrite.

Пример добавления из файла:

bash
aiman add skill ~/Downloads/create-spec.md

Пример добавления из stdin:

bash
cat ~/Downloads/create-spec.md | aiman add skill -

Пример добавления папочного скилла (оба варианта равнозначны):

bash
aiman add skill ~/Downloads/get-team-tasks
aiman add skill ~/Downloads/get-team-tasks/SKILL.md

Вывод при успешном добавлении:

text
added: skill create-spec

Вывод, если скилл уже есть в инвентаре с тем же содержимым (операция не требуется):

text
up to date: skill create-spec · already identical

aiman add mcp

bash
aiman add mcp <file|->
aiman add mcp jira.yaml
aiman add mcp -

Читает описание MCP-сервера из YAML-файла или из stdin (-), применяет env-strip и записывает результат в активный репозиторий инвентаря.

Аргументы:

  • <file|-> — путь к YAML-файлу MCP-сервера или - для чтения из stdin.

Флаги:

  • --name <string> — переопределить имя сервера; если не указан, имя берётся из поля name файла.
  • --overwrite — перезаписать существующий MCP-сервер при конфликте содержимого.

Поведение:

  • если mcp/<name>.yaml уже существует с тем же содержимым — команда завершается успешно без изменений;
  • если mcp/<name>.yaml уже существует с другим содержимым и --overwrite не указан — возвращает ошибку с подсказкой использовать --overwrite.

Env-strip: поля env с заполненным value не сохраняются в mcp/<name>.yaml. Вместо этого реальные значения записываются в aim.local.yaml под ключом mcp_env: {<name>.<VAR>: value}. В инвентаре хранятся только дескрипторы: name, description, required, example. Файл aim.local.yaml исключён из Git, поэтому секреты не попадают в репозиторий.

Пример входного файла:

yaml
name: jira
description: Jira MCP server
command: npx
args: [-y, mcp-jira]
targets: [claude_code]
env:
  - name: JIRA_API_KEY
    description: Jira API key
    required: true
    value: "secret123"

После выполнения команды:

  • mcp/jira.yaml содержит дескриптор без поля value;
  • aim.local.yaml содержит mcp_env: {jira.JIRA_API_KEY: "secret123"}.

Пример добавления из файла:

bash
aiman add mcp jira.yaml

Пример добавления из stdin:

bash
cat jira.yaml | aiman add mcp -

Переопределить имя сервера:

bash
aiman add mcp jira.yaml --name jira-work

Перезаписать при конфликте:

bash
aiman add mcp jira.yaml --overwrite

Вывод при успешном добавлении:

text
added: mcp jira

Вывод, если MCP-сервер уже есть в инвентаре с тем же содержимым (операция не требуется):

text
up to date: mcp jira · already identical

aiman import

bash
aiman import skill <name> --from <env> [--print] [--overwrite]
aiman import mcp <name> --from <env> [--print] [--overwrite] [--targets all]

Импортирует элемент инвентаря (навык или MCP-сервер) из установленной AI-среды в локальный репозиторий.

aiman import skill

bash
aiman import skill <name> --from <env>
aiman import skill create-spec --from claude-code
aiman import skill create-spec --from claude-code --print

Читает скилл по имени из указанной AI-среды, нормализует его и записывает как skills/<name>.md в активном репозитории инвентаря.

Аргументы:

  • <name> — имя скилла, который нужно импортировать.

Флаги:

  • --from <env> — источник импорта (обязательный). Доступные значения: claude-code, cursor, codex.
  • --print — вывести содержимое скилла в stdout без записи на диск.
  • --overwrite — перезаписать существующий скилл при конфликте содержимого.

Источники скиллов по AI-средам:

AI-средаИдентификаторПуть к скиллам
Claude Codeclaude-code~/.claude/skills/*.md и ~/.claude/skills/<name>/SKILL.md
Codex CLIcodex~/.codex/skills/<name>/SKILL.md
CursorcursorНет нативного понятия скиллов — всегда возвращает пустой список

Поведение:

  • если скилл не найден в указанной среде — возвращает ошибку;
  • если skills/<name>.md уже существует с тем же содержимым — завершается успешно без изменений;
  • если skills/<name>.md уже существует с другим содержимым и --overwrite не указан — возвращает ошибку с подсказкой использовать --overwrite.

Пример импорта из Claude Code:

bash
aiman import skill create-spec --from claude-code

Вывод при успешном импорте:

text
imported: skill create-spec · from claude-code

Вывод, если скилл уже есть в инвентаре с тем же содержимым (операция не требуется):

text
up to date: skill create-spec · already identical

Просмотр содержимого без записи:

bash
aiman import skill create-spec --from claude-code --print

aiman import mcp

bash
aiman import mcp <name> --from <env> [--print] [--overwrite] [--targets all]
aiman import mcp context7 --from claude-code
aiman import mcp jira --from cursor --print
aiman import mcp context7 --from claude-code --targets all

Сканирует живую конфигурацию указанной AI-среды, находит MCP-серверы, применяет env-strip и записывает дескриптор в активный репозиторий инвентаря.

Аргументы:

  • <name> — имя MCP-сервера для импорта.

Флаги:

  • --from <env> — источник импорта (обязательный). Доступные значения: claude-code, cursor, codex.
  • --print — вывести YAML-дескриптор в stdout без записи файлов.
  • --overwrite — перезаписать существующий файл, если содержимое отличается.
  • --targets all — задать все три адаптера (claude-code, cursor, codex) как целевые среды в дескрипторе. По умолчанию используется только среда-источник.

Поведение:

  • Env-strip: реальные значения env-переменных не сохраняются в mcp/<name>.yaml. Вместо этого они записываются в aim.local.yaml под ключом mcp_env: {<name>.<VAR>: value}. В инвентарь попадают только дескрипторы: name, required. Файл aim.local.yaml исключён из Git, поэтому секреты не попадают в репозиторий.
  • Дедупликация: если одно имя сервера встречается несколько раз с одинаковой командой и аргументами, берётся первая запись.
  • Неоднозначность (AmbiguousError): если одно имя сервера встречается с разными командами или аргументами, команда завершается с ошибкой — нужно явно указать источник через --from.
  • Сервер не найден: если сервер с указанным именем отсутствует в конфигурации среды, команда завершается с ошибкой MCP server "<name>" not found in <env>.
  • Неизвестная среда: если значение --from не распознано, команда завершается с ошибкой unknown environment: X; available: claude-code, cursor, codex.
  • если mcp/<name>.yaml уже существует с тем же содержимым — команда завершается успешно без изменений;
  • если mcp/<name>.yaml уже существует с другим содержимым и --overwrite не указан — возвращает ошибку с подсказкой использовать --overwrite.

Источники MCP-конфигурации по AI-средам:

AI-средаИдентификаторФайл конфигурации
Claude Codeclaude-code~/.claude.json (ключ mcpServers)
Cursorcursor~/.cursor/mcp.json (ключ mcpServers)
Codex CLIcodex~/.codex/config.toml (секция mcp_servers)

Пример импорта из Claude Code:

bash
aiman import mcp context7 --from claude-code

Вывод при успешном импорте:

text
imported: mcp context7 · from claude-code

Если MCP-сервер содержал env-переменные с заполненными значениями, они записываются в aim.local.yaml:

text
imported: mcp context7 · from claude-code · secrets stored in aim.local.yaml

Вывод, если MCP-сервер уже есть в инвентаре с тем же содержимым (операция не требуется):

text
up to date: mcp context7 · already identical

Просмотр YAML-дескриптора без записи:

bash
aiman import mcp context7 --from claude-code --print

Импорт с установкой всех адаптеров как целевых сред:

bash
aiman import mcp context7 --from claude-code --targets all

Перезаписать, если файл уже существует:

bash
aiman import mcp context7 --from claude-code --overwrite

Команды вне текущего публичного scope

aiman list может присутствовать в кодовой базе как историческая команда, но полноценный публичный контракт отложен до реализации loadouts и полного inventory view.

Released under the Apache 2.0 License.