Перейти к содержимому
Elemctl
Русский
Esc
↑↓navigate↵open⌘Jpreview
На этой странице

История изменений

Что менялось в elemctl от версии к версии, с разбивкой по дням.

Заметные изменения elemctl, свежие сверху. Записи сгруппированы по дням; версии, вышедшие в этот день, перечислены в заголовке. Формат основан на Keep a Changelog, проект следует семантическому версионированию.

Каждая запись заканчивается ссылкой на пул-реквест, из которого она пришла – ([#12](https://github.com/keyfire/elemctl/pull/12)). Поэтому изменения и приходят пул-реквестами: запись без такой ссылки не дописана – от строки журнала читателю некуда пойти за кодом и за причиной правки. Внутренним идентификаторам платформы в записи тоже не место: писать надо о поведении, а не о том, какой ид или какое поле ответа с чем сверялось. Ссылку пишет python scripts/changelog-link.py <номер> – он же тут же пересобирает сгенерированные страницы сайта: правка руками как раз и оставляет зеркала позади.

08.10.2026 – 0.52.0

Добавлено

  • Деплой проверяет ожидаемое приложение до сборки. Необязательные --expected-app-name и --expected-app-uri точно сверяют живую цель и останавливают работу при несовпадении до сборки и загрузки. Библиотека и MCP предоставляют ту же проверку. (#58)

30.09.2026 – 0.50.0, 0.51.0

Добавлено

  • Опцию команды плагина можно повторять: Argument(..., multiple=True). Команда получает все значения списком в порядке командной строки, а ее инструмент MCP принимает массив. Опция без этого поля оставляет только последнее значение – так команда, которой дали семь файлов, загрузила один. (#54)
  • Позиционный аргумент плагина тоже принимает несколько значений: multiple=True. Они идут подряд или через повторенный ключ cli_alias, который оставлял только последнее, а инструмент MCP принимает массив. Старое ядро это отвергает: проверьте plugins.POSITIONAL_MULTIPLE. (#56)

Изменено

  • Ключ, повторенный с другим значением, получает отказ. Раньше --output a --output b писал в b и молча терял a. Теперь вызов останавливается с кодом 2 и называет ключ и оба значения, у команд плагинов тоже. Повтор с тем же значением проходит, как и повторяемые ключи и флаги. (#57)

Исправлено

  • apps list --status running --status stopped показывает оба статуса. Справка обещала несколько статусов, но второй ключ молча заменял первый. Запятые работают, как раньше. (#54)
  • apps token-access --user и probe --cleanup принимают ключ несколько раз. Второй ключ молча заменял первый. Теперь у каждого пользователя и каждого пробника своя запись в ответе, сбой одного не останавливает остальных, а инструменты MCP принимают и список. (#55)

29.09.2026 – 0.47.0, 0.48.0, 0.49.0

Добавлено

  • builds upload без ид проекта называет проект, куда легла сборка. Ответ печатал project-id: null, хотя сервер проект называл. Теперь его несут project-id и поле project, а строка в stderr говорит, создала загрузка проект или нашла его по Ид из Проект.yaml. (#52)
  • CommandContext.surface показывает, откуда вызвана команда плагина. Он равен SURFACE_CLI у подкоманды, SURFACE_MCP у инструмента MCP и None в контексте, собранном вручную. Раньше плагин угадывал это по context.log. (#47)
  • --quiet принимается в любом месте команды. После команды плагина флаг вызывал отказ “unrecognized arguments”. Он скрывает в stderr ход работы и предупреждения, включая context.log плагина, но не ответ, ошибки и код возврата. (#47)
  • apps export-extension сохраняет сборку расширения, примененного в приложении. То же делает инструмент MCP export_extension. Если такого расширения в приложении нет, ошибка перечисляет те, что есть. Нужен Console API 2.1. (#48)
  • apps export сохраняет сборку, на которой работает приложение. То же делает инструмент MCP export_app. Сборка, загруженная в проект, приходит с номером от сервера. Примененные расширения сохраняет apps export-extension. (#49)

Изменено

  • apps create --version-id сам находит проект сборки. Если проект из ELEMENT_PROJECT_ID сборку не перечисляет, команда ищет ее в других проектах и берет тот, где она лежит. С явным --project-id команда отказывает и называет нужный проект. Инструменты MCP create_app и ensure_app делают то же. (#52)
  • builds list у проекта-расширения говорит, что уборки у него нет. Сборки такого проекта остаются, пока их не удалят, поэтому пропуск в его нумерации означает удаление вручную. (#52)
  • Ожидание прекращается после минуты в статусе UNKNOWN. Раньше оно тратило весь срок: пять минут у deploy и десять у нового приложения. Консоль дает UNKNOWN и проходящим состояниям, поэтому ожидание дает ему минуту, а потом останавливается с ошибкой, которая объясняет статус. (#47, #49)

Исправлено

  • self-update --stop-holders больше не снимает команды других сессий. Команда, которая ждала конвейер, обрывалась с кодом 1 без вердикта. Теперь флаг снимает только MCP-серверы, а идущие команды называет по pid и командной строке. Если такая команда держит файлы, self-update отказывает и просит дождаться ее конца. --stop-holders=all снимает и команды, как раньше. (#53)
  • Загрузка без ид проекта больше не переименовывает проект молча. Если сервер кладет сборку в проект с тем же Ид и другим именем, builds upload и probe предупреждают об этом и называют прежнее имя в ответе. Имя берется из представления в Проект.yaml, а не из Name манифеста, как писала документация. (#52)
  • ROUTE_NAME вернулась в elemctl.registry. Прошлый выпуск переименовал константу в ROUTE_NO_PROJECT_ID, и код, который импортировал старое имя, ломался. Теперь старое имя – синоним нового. (#52)
  • Плагин больше не может занять имя, которое использует ядро. --timeout самого плагина не получал значения, его --env-file не давал запустить сервер MCP, а аргумент handler, --help или -h ломал вызов или весь CLI. Теперь elemctl отбрасывает такой плагин и называет его. (#48, #49)
  • deploy не отстает от нумерации сервера, даже когда последнюю сборку удалили. Сервер считает и удаленные сборки, а перечень их не показывает, поэтому deploy сверяется и с локальным реестром загрузок. Удаленную сборку, загруженную с другой машины, по-прежнему не видно, и тогда deploy просто сообщает номер сервера. (#48)
  • build собирает проект расширения как расширение. Теперь в манифесте ProjectKind: Extension и ManifestVersion: 1.1, как у консоли, а build --kind принимает extension. Раньше сервер отвергал даже исправленный вручную архив с ошибкой “Неизвестный вид проекта”. (#49)
  • Путь, которого старый сервер не знает, больше не ведет к повторному входу. Ответ 401 “Handler of HTTP request … not found” клиент считал отказом в токене и входил заново. Теперь он читает текст и сообщает, что метод неизвестен. (#49)
  • builds list точнее описывает нумерацию. Для пустого перечня команда пишет, что сборок у проекта нет, а для сборок без номеров сообщает, что судить не по чему. Пропуск, который и скачок, и удаление, называется и тем и другим. (#49)
  • Предупреждение об отключенной проверке сертификата больше не ссылается на незаданную настройку. Оно называло ELEMENT_TLS_VERIFY=false, даже если проверку отключили в коде. Теперь UrllibTransport принимает причину параметром tls_off_reason. (#49)
  • Примененное расширение больше не выглядит откатом. Карточка приложения по-прежнему называет сборку приложения, и apps apply, deploy и verify-deploy называли откатом любое применение расширения. Теперь сборку расширения проверяют по расширениям приложения, а сервер без Console API 2.1 получает ответ “проверить нельзя”. (#50)
  • apps ensure узнает расширение, которое уже работает на сборке. Команда сверяла сборку с карточкой приложения и отвечала applied: false. Теперь она сверяет по расширениям приложения, как apps apply и verify-deploy, и так же работает ensure_app. (#51)

Документация

  • Спецификация правильно называет флаги, которые принимаются после подкоманды. В перечне был --version, который там не принимается, и не было --lang, который принимается. (#48)
  • Документация объясняет, когда платформа удаляет неиспользуемые сборки. Это бывает, когда приложение проекта применило сборку. Тогда она просматривает до десяти сборок этой базы и оставляет используемые сборки, сборку с наибольшим номером, релизные и защищенные. Загрузки по поставщику и имени защищены сразу. (#49)
  • Проект находится по Ид из описания, а не по поставщику и имени. Загрузка с тем же Ид и другим именем ложится в прежний проект и переименовывает его, а новый Ид с уже занятой парой получает 409. (#50)
  • Уборка никогда не трогает сборки проекта-расширения. Она начинается со сборки приложения, поэтому проект расширения хранит все сборки, пока их не удалят вручную. (#51)
  • Загрузка, которая не называет проект, называется загрузкой без ид проекта. Проект сервер находит по Ид, а не по поставщику и имени. Реестр пишет путь как no-project-id, а vendor-name в старых строках читает по-прежнему. (#51)

27.09.2026 – 0.46.0

Добавлено

  • deploy не даёт молча снять справочник целиком. Сторож схемы читал только файлы на диске, и справочник, документ или регистр, убранные из исходников, уходили со всей таблицей незамеченными. Теперь он берёт перечень файлов применённого коммита и отклоняет такое снятие, как сужение, если не указан --allow-data-loss. (#45)
  • Инструмент MCP deploy принимает allow_data_loss. Сужение, отклонённое сторожем схемы, можно было пропустить только из CLI, а клиенту MCP-сервера сказать “потеря данных допустима” было нечем. Отказ теперь называет и параметр, и ключ. (#45)
  • deploy говорит, когда сервер нумерует сборку по-своему. Загрузка в проект получает от сервера следующий номер базы проекта, какую бы версию ни нёс архив, а отчёт отвечал ok, и расходились только version и applied-version. Теперь версию, которую сервер не сохранит, деплой называет до сборки, перенумерованную сборку – сразу после загрузки, а в отчёте есть assembly-version и renumbered. (#45)
  • apps users показывает, кто подключён к приложению. Перечень был виден только в отказе apps token-access. Команда и инструмент MCP list_app_users печатают его так, как отдаёт платформа, и считают администраторов и пользователей с доступом по токену. (#46)
  • deploy отклоняет справочник, описанный заново с новым Ид. Описание, сделанное заново в своём файле, для платформы – новый элемент: проверено живьём, справочник вышел из применения пустым, а сторож называл только его поля. Теперь деплой отклоняет такое как снятие, а отказ называет прежний Ид, который нужно вернуть. (#46)

Изменено

  • Сторож схемы deploy берёт недостающий коммит из реестра загрузок. У сборки, создавшей свой проект, коммита в карточке нет, и сторож отступал, хотя эта машина коммит помнила. Теперь сверка идёт с ним, а отчёт называет, откуда он взят. (#45)
  • Реестр загрузок хранит тысячу последних загрузок. Он прирастал строкой с каждой загрузкой, пока машина выкатывала сборки. Когда файл перерастёт предел на десятую часть, следующая загрузка его обрежет; другое число задаёт ELEMCTL_REGISTRY_LIMIT, а 0 – хранить все. (#45)
  • Спецификация называет статусы Deleting и UNKNOWN. Справочник описывает статус приложения простой строкой, и в перечне спецификации не хватало двух статусов, встреченных вживую: Deleting, пока приложение удаляется, и UNKNOWN у приложения, у которого пропала база. Ожидание стабильного статуса UNKNOWN за такой статус не принимает. (#46)

Исправлено

  • probe --cleanup убирает пробник, которому дали своё имя и версию. Ни одной приметы пробника у него не было, уборка отказывала, и приложение, сборки и проект снимали руками. Теперь реестр загрузок помнит приложение, которое создал пробник, поэтому уборка его узнаёт и заодно забирает сборки, выкаченные в него. (#46)
  • Загрузка кладёт сборку в названное пространство. Клиент передавал пространство параметром SpaceId, которого сервер не читает, поэтому пространство нового проекта до сервера не доходило, а ошибка в нём оставалась незамеченной. Теперь загрузка в проект передаёт space-id, а новый проект заводится в своём пространстве через POST /spaces/{space-id}/projects. (#46)
  • builds list отличает скачок нумерации от уборки платформы. Сборка, загруженная по поставщику и имени, сохраняет номер архива, и счёт проекта идёт от него, а строка итога списывала пропуск под ней на удалённые сборки. Теперь реестр загрузок помнит, каким путём ушла каждая сборка, и такой пропуск строка называет скачком. (#46)

25.09.2026 – 0.45.0

Добавлено

  • Сборку можно связать с кодом, из которого она собрана. Загрузка в проект теперь передаёт коммит так, как параметр пишет справочник, и сервер хранит его в карточке сборки. Ветку, состояние дерева и каталог платформа не хранит – их помнит локальный реестр загрузок, а builds list --brief и apps get называют источник каждого значения. (#42)
  • apps token-access открывает HTTP-сервисы приложения для токена. Вызов сервиса токеном пользователя получал 500 “Token access is denied”, пока признак не включали в панели управления. Команда и инструмент MCP token_access показывают признак, переключают его и перечитывают, а пользователя, не подключённого к приложению, называют сами. (#43)
  • probe --cleanup убирает оставленный пробник одной командой. Руками уборка срывалась: голый builds delete искал сборку в проекте окружения, а не пробника. Новая команда начинает с приложения, удаляет его, сборку и опустевший проект в порядке платформы и отказывает приложению, которое оставил не пробник; отчёт probe --keep называет эту команду и шаги вручную. (#43)

Исправлено

  • Сервер, который ещё стартует, назван прямо. Пока поднималась его консоль, все команды отвечали голым 404, а deploy падал на перечне сборок. Теперь такой ответ говорит, что сервер стартует и повторить нужно, когда /console ответит 302, а deploy ждёт консоль сам, не дольше --server-start-timeout секунд. (#42)
  • Сторож схемы deploy видит табличные части. Сборка без табличной части уносила её строки, а сторож молчал. Теперь снятие табличной части, реквизита или ресурса называется до сборки и выкат не останавливает, сужение внутри табличной части отклоняется как любое другое, а пропущенная сверка называет настоящую причину, а не всегда отсутствие коммита. (#42)
  • self-update видит выпуск, опубликованный несколько минут назад. После выпуска оба списка PyPI ещё какое-то время называют прежнюю версию, и команда отвечала “уже актуально”. Теперь она читает оба списка и страницы следующих версий, говорит, когда источники расходятся, и не заменяет установку более старым выпуском. (#43)

24.09.2026 – 0.44.0

Добавлено

  • probe проверяет манифест до сборки. Проект пробника без Представление консоль отклоняла ответом 500 без объяснения, без ЯзыкРазработки приложение не создавалось, а ЯзыкПоУмолчанию без ЯзыкиЛокализации сервер отклонял, не называя причины. Теперь пробник останавливается до сборки и называет каждый недостающий ключ вместе со строкой, которую нужно добавить. (#41)

23.09.2026 – 0.43.2

Изменено

  • В комментариях и документирующих строках Python используется обычный дефис. Остальные строковые литералы сохранены. (#40)

22.09.2026 – 0.43.1

Исправлено

  • self-update сообщает об оборванном ответе PyPI и не затрагивает установленный пакет. Чтение индекса Simple, метаданных и колеса не ловило ошибки синтаксического анализатора HTTP, поэтому оборванный ответ мог закончиться трассировкой. (#38)
  • Настройка подключения отказывает базовому URL без схемы HTTP. Адрес без http:// или https:// доходил до urllib и заканчивался необработанным ValueError. (#38)

19.09.2026 – 0.43.0

Добавлено

  • probe и deploy называют журнал сервера, когда сервер отказал без ошибки компиляции. Платформа может ответить на неудачное создание или применение одним “Contact administrator for details”, и отчёту нечего было предложить. Новое поле hint говорит искать последнюю строку Caused by в server.log сервера, где строка SrcPath: рядом называет файл. (#36)

Исправлено

  • deploy, apps apply и уборка в probe больше не заканчиваются ошибкой на первом оборванном чтении карточки приложения. Пропущенным опросом такое чтение считало только ожидание нового приложения, и один обрыв соединения ронял весь деплой или оставлял сборку probe на стенде. Теперь все три ожидания опрашивают карточку одинаково и заканчиваются ошибкой, только когда вышел срок. (#37)
  • Оборванный на середине ответ больше не заканчивает команду трассировкой. Транспорт ловил только OSError, а http.client сообщает о таком обрыве и об искажённой строке статуса своими исключениями. Теперь оба случая считаются сетевой ошибкой: команда пишет обычный JSON ошибки, а чтение, которое повторяется после обрыва соединения, повторяется и после них. (#37)
  • apps create и apps ensure отказывают до создания, если сборки из --version-id нет в перечне проекта. Платформа удаляет сборки, которыми никто не пользуется, и на создание из такой сборки отвечала голым 400 “Can’t create application”, похожим на предел числа приложений. Теперь отказ называет причину и сборку работающего приложения проекта, а инструменты MCP create_app и ensure_app отказывают так же. (#36)
  • Оборванное ожидание в apps create --wait и apps ensure --wait больше не теряет созданное приложение. Обрыв соединения при чтении перечня задач заканчивал команду голой сетевой ошибкой, и ид приложения, поднявшегося через несколько минут, приходилось искать по имени. Теперь ответ сохраняет ид рядом с полем wait-error и кодом возврата 1, а оборванное чтение перечня задач повторяется. (#36)
  • Плагин, который не загрузился, больше не роняет CLI. Плагин под более новое ядро падал в вызове своей фабрики, который ничем не был защищён, и любая команда, даже команда ядра, заканчивалась трассировкой Python. Теперь такой плагин остаётся за бортом и называется в stderr и в elemctl plugins, вызов его пропавшей команды получает обычный отказ JSON, а MCP-сервер запускается с остальными. (#36)

18.09.2026 – 0.42.0

Добавлено

  • Позиционный аргумент команды плагина принимает синоним-ключ cli_alias. Команда плагина объявляла такой аргумент только позиционным, поэтому wiki-get --page 123 падал на “unrecognized arguments”, хотя тот же ключ принимает wiki-publish. Второй Argument("--page") тоже не годился: тогда у инструмента MCP было бы два параметра page. Синоним действует только в CLI – схема инструмента MCP по-прежнему несёт тот же один параметр, – позиционная форма продолжает работать, а ключ и позиция одновременно, как и ни один из них у обязательного аргумента, – отказ разборщика. Плагин, не объявивший cli_alias, ведёт себя как раньше. (#34)

Исправлено

  • ELEMCTL_NO_PROXY теперь читается и из .env самого стенда. Вызов инструмента MCP несёт только env_file, а задать переменную окружения для одного стенда среди нескольких, которые обслуживает тот же серверный процесс, было нечем – вызов к локальному стенду падал за прокси, который до него не дотягивается, а обход ELEMCTL_NO_PROXY=1, работающий в CLI, оставался недоступен. Переменная окружения по-прежнему сильнее, если она задана, а значение из файла одного стенда не доходит до вызова к другому стенду, обслуживаемому тем же процессом. (#32)
  • builds list теперь печатает счётчик и отметку об усечении после ответа, а не до него – в том же порядке, что и apps list. Вызывающая сторона, захватывающая оба потока одним (2>&1 или stderr=STDOUT – обычный способ поймать всё, что напечатала команда), у builds list видела эти пояснения раньше ответа JSON. Теперь обе команды печатают в одном порядке, хотя целиком разобрать объединённый захват по-прежнему не гарантируется – безопасен только stdout, прочитанный отдельно, как документ. (#32)
  • Кэш клиентов MCP-сервера теперь подхватывает правку .env. Раньше кэш держал клиента по одному env_file на весь процесс, поэтому правка файла стенда после старта сервера – скажем, добавление ELEMCTL_NO_PROXY=1 – оставалась невидимой до перезапуска; файл по умолчанию (без env_file) работал так же. Теперь кэш следит за временем изменения и размером файла, так что правка входит в силу на следующем же вызове к этому стенду, а env_file (или стартовый --env-file), пропавший уже после кэширования, даёт ту же понятную ошибку, что и всегда давал – вместо тихой работы на клиенте, который сработал в прошлый раз. Явный --env-file по-прежнему проверяется сразу при старте elemctl mcp (выход 1 до запуска сервера), а прочие ошибки настройки стенда по умолчанию всплывают на самом вызове. (#33)
  • Config.from_env(no_proxy=...) больше не бросает TypeError. Каждое поле принимает явный аргумент раньше окружения и файла, как и обещает докстринг; no_proxy было единственным исключением – переопределение не забиралось из **overrides и попадало в проверку “неизвестные параметры конфигурации”. Теперь явный аргумент сильнее ELEMCTL_NO_PROXY и его же копии в файле, как и у остальных полей. Вызовов с этим параметром сегодня ещё нет – тем и объясняется, что пробел оставался незамеченным. (#35)
  • Четыре мелочи вокруг кеша клиентов MCP-сервера. create_app и ensure_app разрешали client(env_file) по нескольку раз за вызов – до четырёх внутри общего _create_app плюс собственная проверка самого инструмента – так что один вызов в принципе мог провести свои шаги на двух разных клиентах, если файл стенда менялся посреди вызова; теперь каждый инструмент разрешает клиента один раз и передаёт его дальше. Клиента, которого заменяет правка, раньше освобождали до того, как записан новый – исключение из его close() оставляло кеш на прежней записи, том самом клиенте, чьё закрытие только что провалилось, вместо нового, рабочего; теперь запись идёт первой. Вокруг словаря кеша теперь блокировка – сегодня каждый вызов проходит до конца, прежде чем начнётся следующий, так что гонка ничем не проявляется, но будущий поточный или асинхронный диспетчер сделает её настоящей. Отпечаток (время изменения и размер) по-прежнему не отличает файл, ставший нечитаемым без правки, от неизменившегося: закрыть это означало бы читать файл при каждом обращении, а не только при правке, а более лёгкий вариант на битах доступа POSIX всё равно не заметил бы того же на Windows – эта граница теперь явно описана там же, где строится отпечаток. (#35)

13.09.2026 – 0.41.0

Добавлено

  • Команда плагина сама задаёт код возврата. CLI завершается тем целым от 0 до 255, которое результат кладёт в поле exit-code, и конвейер отличает “нашлись различия” от “сбоя шага” по одному коду. Без поля "ok": false по-прежнему означает 1. (#31)
  • Сторож документации ловит фразу, которая объясняет правку ссылкой на человека. У репозитория один автор, и такая фраза ничего не говорит читателю о самой правке. Сторож читает оба издания документов, комментарии и описания src, scripts, tests и tools. (#30)
  • Сторож соглашений требует называть stdin при запуске процесса из src. Проверка читает только поставляемый пакет. Скрипт, инструмент и тест работают из консоли, а консольный stdin дочернему процессу отдать можно. (#29)
  • tests/test_conventions.py ловит тест, затенённый однофамильцем. Из двух определений с одним именем Python оставляет последнее, и старый тест перестаёт выполняться, хотя число тестов растёт. Проверка называет строку новичка, которую надо переименовать. (#28)

Исправлено

  • Дочерний процесс не наследует stdin сервера MCP. На Windows процесс с каналом клиента не может завершиться: git status --porcelain выстаивал весь пятнадцатисекундный срок, и сборка считала git недоступным. Запуски процессов в src теперь передают stdin=subprocess.DEVNULL, и тот же вызов инструмента занимает 0,8 секунды вместо 47. (#29)
  • .gitattributes держит перевод строки за весь репозиторий. Строка * text=auto eol=lf хранит текстовые файлы с переводом строки на любой машине. README, которые собирает scripts/sync-docs.mjs, раньше выходили со смешанными окончаниями. (#28)

Документация

  • Общий сторож закреплён на docsguard@v0.7.1. В выпуске появился словарь заимствованных слов: пин, прогон, билд, дефолт и ещё одиннадцать. Закреплённую версию подняли отдельной правкой, раньше всего, что ею пользуется. (#26)
  • Сторож документации читает русские тексты по этому словарю. Страницы docs/*.ru.md он находит сам, корневые документы названы в scripts/check_docs.py: README.ru.md, CHANGELOG.ru.md и CLAUDE.md. Слово в обратных кавычках или в блоке кода находкой не считается. (#26)
  • Слова, названные в журнале, взяты в обратные кавычки. Запись от 12.09.2026 перечисляет слова, которые ушли из текста, и сторож читал их как жаргон. Так же записана подпись кнопки XBSL: деплой на стенд – это имя команды. (#26)
  • Общий сторож закреплён на docsguard@v0.8.0. Словарь заимствованных слов вырос на шесть: дашборд, бэкенд, лаунчер, мейнтейнер, топ-объект, легаси. (#27)
  • Сторож проверяет по словарю и русские строки исходников. Справка команды и текст ошибки доходят до читателя так же, как страница на сайт: он видит их в терминале, едва запустив инструмент. Названы два файла: каталог сообщений src/elemctl/i18n.py и src/elemctl/mcp_server.py, подсказки инструментов которого клиент MCP показывает списком. (#27)
  • Слово лаунчер ушло из записи про self-update --stop-holders. Речь там о программе запуска, потомком которой работает команда. То же слово поправлено в tests/test_selfupdate.py. (#27)
  • Общий сторож закреплён на docsguard@v0.9.0. В выпуске проверки исходников перестали падать на файле с меткой порядка байтов. Редакторы на Windows ставят её сами, а разбор через ast отвечал на неё SyntaxError и уносил с собой находки по всем остальным файлам. Оттуда же приехал сторож затенённых тестов. (#28)

12.09.2026 – 0.40.1

Добавлено

  • tests/test_conventions.py ловит текстовый файл, записанный без явного newline. Проверка смотрит на src/, scripts/ и tools/, разбирает исходники через ast и считает записью write_text или open в текстовом режиме. Сама она пришла из общего пакета docsguard. (#22)

Изменено

  • Строки --help перестали кричать капсом и говорить чужими словами. “Таймаут” стал сроком ожидания, “деплой” – развёртыванием, а выделение капсом ушло из verify-deploy, --project-id, --force-rename и пояснения к tasks. Справочник команд пересобран из тех же строк. (#25)
  • Три проверки покрытия у сторожа документации считают разность множеств одним кодом. Инструменты, переменные окружения и расширения архива сверялись с документами тремя копиями, и копия, переставшая что-либо находить, молча проходила. Теперь все три судят через coverage_problems из пакета docsguard. (#20)

Исправлено

  • scripts/changelog-link.py больше не переписывает журнал переводом строки платформы. Одна дописанная ссылка отдавала четыре файла, в которых изменилась каждая строка. Тот же пропуск исправлен у render-diagrams.py, кэша токена, метаданных pipx и индекса адаптера. (#22)

Документация

  • Документация переписана живым языком. Длинные предложения разрезаны, ИИ-обороты, вставки в скобках посреди фразы и слова капсом убраны, а английская редакция написана английским, а не калькой с русского. Из журнала ушли слова из словаря: пин, прогон, джоба, раннер, таймаут и деплой. (#24)
  • Общий сторож закреплён на docsguard@v0.5.0. В выпуске появилось второе соглашение исходников: текстовый файл без явного newline забирает перевод строки платформы. Закреплённую версию подняли отдельной правкой, раньше всего, что ею пользуется. (#21)

11.09.2026 – 0.39.0, 0.40.0

Добавлено

  • get_build отдаёт карточку одной сборки на поверхности MCP. Перечень был, а карточки не было, и за именем из манифеста, поставщиком или комментарием агент уходил в CLI. Инструмент адресуется версией сборки, ид тоже принимается. (#14)
  • apps create и apps ensure проверяют применение сборки сами – флагом --verify, а на поверхности MCP параметром verify. Раньше проверка жила только в deploy, apps apply и verify-deploy, и поднятый стенд приходилось проверять вторым вызовом. Отчёт приходит в поле verify. (#5)

Изменено

  • Строка итога под перечнем сборок судит по дырам в нумерации, а не по порогу в тридцать сборок. Номера одной базовой версии платформа выдаёт подряд, поэтому пропущенный номер – это снятая сборка. Константа ASSEMBLY_STORE_LIMIT ушла вместе с порогом. (#13)
  • build и inspect отказываются принимать ключи подключения. Раньше --env-file, --base-url и реквизиты молча выбрасывались, и вызов выглядел сборкой, привязанной к стенду. Изменение поведения: теперь это отказ с кодом возврата 1. (#7)
  • Перечень сборок описан так, как платформа работает на самом деле. Мы считали, что она держит предел сборок на проект и вытесняет старые; на деле она удаляет те, которыми никто не пользуется. Подсказка перечня и страницы про Console API переписаны. (#6)
  • --wait заканчивается проверкой, а не карточкой на веру. Неудачное применение откатывается на прежнюю сборку, и приложение поднимается работающим, а по карточке этого не видно. Изменение поведения: непройденная проверка даёт код возврата 1, --no-verify возвращает простое ожидание. (#5)

Исправлено

  • Правка про автоудаление сборок дошла до остальных страниц и подсказок. Требования к CLI, страницы MCP-сервера, подсказка list_builds и комментарии в коде рассказывали про предел хранения. Теперь везде одна модель. (#9)
  • builds get заработала: карточка сборки адресуется версией. Наши страницы утверждали, что метод принимает только UUID, поэтому команда переводила версию в ид и получала 404. Живые вызовы на двух установках показали обратное, и теперь принимаются обе формы. (#8)

Документация

  • Проверку кодировки процессов взял на себя общий пакет docsguard. Написана она была здесь, хотя движок и мост запускают процессы так же и ждут того же молчаливого отказа. Здесь остался перечень каталогов, а закреплённая версия поднята до v0.4.0. (#19)
  • Общий сторож ставится по тегу, а подъём версии стал отдельной правкой. Раньше docsguard брался из главной ветки, и любая правка в нём сразу попадала в наши проверки: они могли покраснеть без единого изменения у нас, а такую красноту никто не читает. tests/test_workflows.py падает, когда процессы называют разные теги. (#18)
  • Процесс, который читают как текст, обязан называть кодировку, и это проверяет тест. Новый скрипт её не назвал, и отказ вышел молчаливым: имена русских страниц вернулись символами замены, а код возврата говорил, что всё прошло хорошо. Соглашение записано в CLAUDE.md. (#17)
  • Механика утверждений переехала в общий сторож. Один факт, рассказанный разом в нескольких документах, – беда не одного elemctl: у движка и у моста документация устроена так же. Claim, claim_texts и claim_problems берутся из пакета docsguard. (#16)
  • python scripts/rebuild-docs.py пересобирает все сгенерированные страницы разом. Генераторов два, страниц четыре, и каждый приходилось помнить отдельно; первыми забывали зеркала. Команда отвечает кодом возврата, и упавший генератор не прячет соседний. (#15)
  • Сторож ловит одно утверждение, рассказанное по-разному. Факт о платформе живёт разом в требованиях, на страницах Console API и MCP, в README и в комментариях кода, а правится в одном месте. Такие факты собраны в CLAIMS в scripts/check_docs.py. (#12)
  • Ссылка на пул-реквест и пересборка зеркал стали одним шагом. Ссылку можно писать только после того, как пул-реквест заведён, поэтому она приходит отдельным коммитом, а зеркала при этом забывали. Обе половины делает python scripts/changelog-link.py <номер>. (#11)

10.09.2026 – 0.37.0, 0.38.0

Добавлено

  • Команда verify-deploy – проверка применения отдельно от деплоя. Механизм был у библиотеки и у инструмента MCP, а в CLI его не было, и скрипты CI собирали ту же проверку руками из apps get и tasks list. Теперь она отвечает тем же отчётом, что и deploy, и кодом возврата 1 при неудаче; сама ничего не деплоит.
  • Флаг --json: в stdout только ответ. Скрипты разбирали вывод приёмом “найти первую скобку”, и лишняя строка перед JSON ломала разбор. Теперь на время работы команды stdout подменяется на stderr – ни строка плагина, ни предупреждение библиотеки в поток не пролезут. Флаг глобальный и принимается в любой позиции.

Изменено

  • builds list называет, что за перечень перед читателем. “Показаны 30 из 30” читалось как вся история проекта, хотя платформа держит на проект ограниченное число сборок. Строка итога теперь говорит, полный это перечень или упёршийся в предел хранения. Изменение поведения: инструмент MCP list_builds отвечает объектом {total, shown, summary, builds}, а не массивом.
  • Группа, вызванная сразу с ключом, получает подсказку про действие. elemctl tasks --app-id ... argparse отвергал словами “invalid choice”, и читатель искал ошибку в значении, а не хватало слова list. После отказа печатается форма вызова с перечнем действий группы, а tasks --help называет обе формы целиком.
  • --latest-build берёт самую свежую сборку по отметке создания, а не по наибольшему счётчику: после смены базовой версии старая база хранит большие номера, и приложение “из последней сборки” создавалось бы из старой.

Исправлено

  • Справочник команд не рвёт слово, перенесённое по дефису. argparse переносит длинное слово по дефису, и склейка строк через пробел ломала само имя: в справочнике стояло elemctl tasks get- group TASK_ID. Правило склейки стало общим – оно работает и для описания парсера, и для его эпилога.
  • Счётчик сборок начинается заново при смене базовой версии проекта. Автоинкремент брал наибольший счётчик по всем сборкам проекта: одна случайная 1.0.1-19001 увела все последующие сборки в 19xxx, а поднятие проекта до 1.0.2 продолжило бы счёт с 19024. Теперь счётчик берётся среди сборок собственной базовой версии проекта, и поднятый проект начинает с 1.0.2-1.

09.09.2026 – 0.36.0

Изменено

  • apps list скрывает удалённые приложения и говорит, сколько скрыл. Платформа держит удалённые приложения в перечне со статусом Deleted и прежним ид: стенд, живущий не первый месяц, отвечал тремя сотнями карточек, из которых живых единицы, а --brief их не убирал – ответ приходилось фильтровать своим кодом. Теперь удалённые скрыты, --include-deleted возвращает их, а --status deleted снимает скрытие сам: отбор, который ответил бы пустотой, хуже отсутствия отбора. Молчаливое сокрытие – ловушка, поэтому команда заканчивается строкой итога в stderr (“живых 7 из 324”, а при дополнительном отборе – ещё и числом показанных); в stdout остаётся тот же массив JSON, который разбирают скрипты.
  • Инструмент MCP list_apps принимает include_deleted и отвечает объектом. Рядом с карточками (applications) идут счётчики total, live, shown и готовая строка summary: агент видит только JSON, и срезанные карточки должны быть названы, иначе перечень читается как “на стенде семь приложений”. Прежний ответ – голый массив – заменён; find_app и разрешение имени в ид по-прежнему видят удалённые приложения и отсеивают их сами.

06.09.2026 – 0.35.0

Добавлено

  • projects list --name и --include-deleted; те же фильтры принимает инструмент MCP list_projects. Платформа держит удалённые проекты в перечне с признаком, и стенд, живущий не первый месяц, отвечал на проверку имени проекта сотней с лишним карточек, почти сплошь удалённых. Теперь удалённые скрыты, пока их не попросят, а name сужает перечень по подстроке без учёта регистра на клиенте – так, как это давно делает apps list.

05.09.2026 – 0.34.0

Исправлено

  • Приложение адресуется и позиционно, и ключом --app-id. Команды apps get, apply, delete, start, stop и debug принимали только позицию, а deploy и apps ensure – только ключ, и вызов, написанный не в той форме, отвечал справкой вместо работы. Две РАЗНЫЕ ссылки в одной команде отвергаются: молчаливое предпочтение одной отправило бы команду в чужое приложение.

31.08.2026 – 0.33.0

Добавлено

  • Сторож схемы видит измерения регистра. По ним ключуются записи, поэтому смена типа измерения – или его удаление – заставляет платформу конвертировать записи, значения схлопываются, и применение падает на неуникальности ключей, а следом идёт тихий откат. Пробник этого не предскажет: в пустом приложении конвертировать нечего.
  • Описание клиента SOAP-сервиса попадает в сборку. <ИмяКлиента>.Wsdl.<n> и <ИмяКлиента>.Xsd лежат рядом с элементом проекта, а не в Ресурсы, и их расширения вне списка разрешённых – архив терял их молча. Клиент, у которого описания нет, называется до загрузки.
  • apps list --status running (несколько статусов через запятую). На стенде, живущем не первый месяц, приложений сотни, а живых единицы, и вопрос “что здесь работает” не должен стоить полного перечня.
  • Отчёт деплоя несёт отказ построчно. В problems-lines лежит текст платформы, разобранный на строки: JSON экранирует многострочный отказ в и ровно там, где его надо читать, – какой объект, какие ключи стали неуникальными.

Исправлено

  • Применение пережидает занятое приложение вместо отказа. Развёртывание сразу после предыдущего падало с “приложение занято” уже ПОСЛЕ загрузки сборки; ожидание короткое и включается только на этой формулировке, так что несуществующее приложение по-прежнему отказывает сразу.
  • Пробник обрывается на непринятом режиме совместимости. Стенд старше проекта отказывает проекту целиком, а следом жалуется на типы и свойства этого режима в файлах, которых правка не касалась, – сотни строк, читающихся как приговор коду. Теперь отказ назван тем, чем он является, а производное от него считается, а не разбирается.

30.08.2026 – 0.32.3

Изменено

  • Описание пакета называет пробник. Сводка на карточке PyPI и описания сайта перечисляли приложения, сборки и развёртывание, но молчали про проверку компиляции на сервере без риска для рабочего приложения – а это отдельная причина ставить elemctl.

27.08.2026 – 0.32.2

Добавлено

  • Релиз оставляет карточку на GitHub. После успешной публикации на PyPI конвейер создаёт GitHub-релиз, телом которого становится раздел этой истории изменений за выпущенные версии, – подписчики репозитория видят в ленте, что нового, а не голый тег.

26.08.2026 – 0.32.1

Изменено

  • Пример локального облака в документации указывает на домен-плацедержатель в зарезервированной зоне .example: пример конфигурации не должен называть настоящий сервер.
  • Журнал изменений сокращён до двух-четырёх строк на запись: что изменилось и почему это важно; история находок остаётся в коммитах и документации.

24.08.2026 – 0.32.0

Добавлено

  • apps apply [APP_ID] VERSION_ID – применить загруженную сборку и проверить результат. Прежде применение было доступно только инструментом MCP, а долгие операции просят запускать CLI фоном. При сбое платформа молча откатывает приложение на прежнюю сборку и запускает его, поэтому команда сверяет применённое и отвечает кодом возврата 1, если сборка не встала.
  • apps ensure отвечает и про сборку. Флаги создания действуют только при создании, поэтому --version-id существующему приложению не применялся – молча. Теперь в ответе есть applied и applied-version-id, stderr называет команду, доводящую приложение до нужной сборки, а флаг --apply делает это сразу; то же поле получил MCP-инструмент ensure_app.

Исправлено

  • builds upload больше не отвергает сборку своего проекта. Сверялись разные вещи: техническое Имя из манифеста и Представление, под которым проект показан в панели, – совпасть они могли только случайно, и правильная загрузка выглядела переименованием. Теперь сравнивается представление проекта из дескриптора внутри архива; чужая сборка отвергается по-прежнему.
  • Отказ загрузки объясняет --new-project. Формулировка “заведёт отдельный проект” отпугивала от рабочего пути: платформа опознаёт проект по паре поставщик плюс имя из манифеста, поэтому сборка своего проекта попадает в существующий проект.

18.08.2026 – 0.31.0, 0.31.1

Добавлено

  • Подключение с отключённой проверкой TLS предупреждает о себе на каждом запуске. ELEMENT_TLS_VERIFY=false прописывают в .env однажды, а вызов без проверки выглядит ровно как прошедший её. Предупреждение идёт в stderr, поэтому вывод JSON по конвейеру не портится.
  • TLS настраивается: частный CA и строгость проверок. Строгий профиль RFC 5280, включённый в Python 3.13, отверг внутренний CA частного облака. ELEMENT_CA_FILE добавляет PEM-файл к хранилищу доверия, ELEMENT_TLS_STRICT=false снимает только строгий профиль, а ELEMENT_TLS_VERIFY=false остаётся крайней мерой; опечатка в значении даёт ошибку конфигурации, а не молча ослабленный TLS. Вклад @dvkuchin (запрос на слияние #4).

14.08.2026 – 0.30.0

Изменено

  • builds list отвечает десятью свежими сборками. У давнего проекта их накапливаются тысячи, и вопрос “из какого коммита применённая сборка” решался усечением полного списка. Срез задаёт --limit (0 – все), stderr называет, сколько из скольких показано, а --brief оставляет ид, версии, дату, ветку и коммит; те же параметры получил MCP-инструмент list_builds.

Исправлено

  • Сборка пробника больше не может победить в выборе последней. Случайный токен её версии примерно раз в сорок розыгрышей выпадает целиком числовым, и такая версия читается огромным счётчиком – --latest-build выбрал бы пробную сборку вместо настоящей. Числовой токен теперь перевыбирается; поймано вживую в CI.

11.08.2026 – 0.29.0

Изменено

  • Отсутствующий .env-файл называется абсолютным путём и текущим каталогом. Относительный --env-file разрешается от текущего каталога, а не от --project-dir, и в фоновом запуске отказ читался как недоступный стенд.
  • probe описывает требование к раскладке проекта. Каталог обязан лежать по схеме {репозиторий}/{Поставщик}/{Имя}/Проект.yaml – прежде об этом узнавали из ошибки постфактум.

10.08.2026 – 0.28.0

Документация

  • Перечень инструментов MCP полон. Семь из двадцати четырёх не были названы нигде, кроме исходников: страница обходилась фразой “и другие”.
  • Переменные окружения описаны полностью – вместе с ELEMCTL_NO_PLUGINS, переменными CI, из которых сборка берёт номер запуска, и системными LC_ALL/LANG.
  • Устаревшие утверждения исправлены: общие флаги принимаются в любой позиции, .htm входит в расширения архива, а внутри каталога Ресурсы отбора по расширению нет вовсе.
  • Один источник на текст. Разделы README, повторяющие страницы сайта, разошлись в обе стороны; теперь источник – страница, а scripts/sync-docs.mjs вставляет её раздел в README между маркерами.
  • Схема устройства docs/architecture.svg – поверхности, движок, цикл развёртывания с молчаливым откатом и пробник; палитра следует теме читателя.
  • Сторож scripts/docsguard.py и задача docs в конвейере CI. Он судит проверяемое механически: инструмент без строки в таблице, переменную окружения, которую код читает и никто не описал, протухшее зеркало чейнджлога. Каждый класс находки провоцируется тестом.

Добавлено

  • deploy принимает имя приложения наравне с ид – как это давно делают apps get, apps start, apps stop и apps debug.

Изменено

  • Расширение VS Code уехало из этого репозитория. Отладка приложений 1С:Элемент – часть расширения XBSL с его версии 0.57.0, вместе с кнопкой деплоя: из-за разделения путь к elemctl и ид приложения приходилось задавать дважды. Здесь осталась сторона elemctl – apps debug, debug-adapter и точка расширения elemctl.debug_adapter.

07.08.2026 – 0.26.0, 0.27.0

Добавлено

  • Проекты с английскими артефактами собираются и деплоятся. build, deploy и probe находят дескриптор Project.yaml наравне с Проект.yaml, разбор архива читает английские ключи и значения, а страж схемы знает, что два написания имени примитивного типа – один тип: перевод описания не выглядит изменением, разрушающим данные.

Изменено

  • Загрузка сборки не отправляет коммит и ветку. Документированный метод их не принимает, а отправленные сервер игнорирует: коммит в карточке сборки проставляется только связью проекта с репозиторием. Внутри архива ветка и коммит едут по-прежнему – сборка пишет их в манифест.
  • Пропущенная сверка схемы названа в отчёте. Поле schema-check отвечает clean, allowed или skipped:<причина>: пропущенная проверка не должна читаться как пройденная.

03.08.2026 – 0.25.0

Изменено

  • Сборка с чужим именем отвергается, а не сопровождается предупреждением. Панель показывает проект под именем последней залитой сборки, и удаление сборки прежнее имя не возвращает. Выходы названы в самом сообщении: --force-rename, если так и задумано, --new-project, если сборка чужая.

31.07.2026 – 0.23.0, 0.24.0

Исправлено

  • self-update сразу после релиза больше не пропускает его. Список файлов брался из JSON-метаданных PyPI, а они догоняют публикацию минутами: в этом окне команда отвечала “уже актуально”. Теперь список берётся из simple-индекса (PEP 691), а версии ранжируются численно.

Изменено

  • MCP-сервер работает с обоими мажорами пакета mcp, закрепление версии снято. В mcp 2.0.0 класс сервера переехал, не оставив псевдонима, и свежая установка не поднималась вовсе. Импорт пробует оба расположения, разницу в чтении ответов прячут две функции, а CI запускает набор тестов на обоих мажорах.
  • serverInfo называет версию самого elemctl, а не версию пакета mcp.

30.07.2026 – 0.22.0

Добавлено

  • Сборка приложения забирает библиотечные проекты, лежащие рядом, включая транзитивные зависимости; объявленная библиотека без локального проекта остаётся внешней зависимостью платформы. Вклад @dvkuchin (запрос на слияние #3).

Исправлено

  • Прокси в окружении больше не выдаёт живой стенд за мёртвый. Прокси, которому до стенда не дотянуться, отказывает ровно так же, как отказал бы лежащий стенд. Заведомо бесполезный прокси теперь обходится, ELEMCTL_NO_PROXY=1 обходит его везде, а неудавшийся вызов через прокси называет его.
  • self-update --stop-holders больше не снимает собственное дерево процессов. Команда работает потомком программы запуска, по имени неотличимой от держателя, и предлагала снять саму себя, обрывая обновление на полпути.

28.07.2026 – 0.20.0, 0.21.1

Добавлено

  • Создание приложения заканчивается способом в него войти. У apps create и apps ensure (и у их двойников в MCP) появилось поле sign-in. Новое приложение получает свой пустой список пользователей, поэтому учётные записи, которыми входят в другие приложения, здесь не работают: войти можно учётной записью панели управления. Перебирать нельзя – у пользователя есть счётчик неудачных попыток входа.

Изменено

  • self-update больше не меняет рабочую установку на пустое место. pip install --upgrade упёрся в занятый живой сессией файл, удалил пакет, не распаковал новый и промолчал. Теперь установленный пакет сначала переименовывается, держатели называются по имени и pid, а прежняя установка возвращается на место, пока новая не докажет, что импортируется.

27.07.2026 – 0.19.0

Добавлено

  • user-lists calculation-rules – переприменить правила, по которым из ответа провайдера собирается пользователь. Пересоздание сервиса входа их сбрасывает, а чтение не возвращает, поэтому отчёт говорит прямо: что отправлено, что запрос принят и что подтвердить значение через API нельзя – это отвечает панель управления или живой вход.

Исправлено

  • Сборка, сделанная исполнителем CI, записывала ветку HEAD. Исполнитель выкладывает коммит, а не ветку. Имя теперь берётся из окружения CI, а если ветку не называет никто, поле остаётся пустым: честный пробел лучше слова, похожего на имя ветки.

26.07.2026 – 0.15.0, 0.16.0, 0.17.0, 0.18.0

Добавлено

  • deploy называет цель и то, откуда она взялась. В отчёте появились app-name, app-id-source и project-id-source, а цель объявляется первой строкой прогресса – до сборки, пока развёртывание не в то приложение ещё можно прервать.
  • Сборка называет файлы, которые в неё не вошли (skipped-files и предупреждение). Файл с расширением вне списка разрешённых попадает в архив, только если лежит в каталоге Ресурсы; в любом другом месте он теряется молча, и платформа сообщает об этом лишь на применении.
  • Страж разрушающих изменений схемы. Сужение длины реквизита и смена его типа пересоздают данные объекта, поэтому deploy сверяет исходники с состоянием на коммите применённой сборки и отказывается работать до сборки; пропустить – флагом --allow-data-loss. Сравнить нечем – страж говорит об этом и деплою не мешает: невозможность сравнить не есть доказательство опасности.
  • user-lists – настройки входа списка пользователей, за которыми обычно ходят в панель: list, get, self-registration и password-login. Без флага обе команды-настройки только читают состояние; со стороны MCP – list_user_lists и configure_user_list.
  • Точки расширения elemctl.commands – пакет-плагин приносит собственные команды, и одно объявление становится сразу подкомандой CLI и инструментом MCP. Там место команде, которая знает про чужое окружение и потому в публичном ядре жить не может.
  • elemctl probe – изолированная проверка компиляции. Компиляция у платформы серверная и происходит на применении сборки, поэтому пробник собирает архив, создаёт из него одноразовое приложение и убирает созданное за собой. Ошибки приходят разобранными: файл, строка, колонка, окружение и текст.

Исправлено

  • Глобальная опция принимается и после подкоманды – elemctl deploy --env-file .env больше не падает argparse-фразой “unrecognized arguments”.
  • Отвергнутый сервером токен больше не живёт в кэше. Негодный токен этот сервер отвергает 400, а не 401, называя причину в error_description; такой отказ теперь сбрасывает файл кэша и повторяет запрос один раз.
  • Сборка удаляется после того, как исчезло приложение. Платформа отклоняет удаление, пока живо созданное из этой сборки приложение, поэтому пробник сначала дожидается его исчезновения.

Документация

  • Контракт Console API пополнился списками пользователей (п. 4.7) и тем, чего в API нет вовсе: состава форм аутентификации и настройки автоматического подключения пользователей.
  • Проект платформы опознаётся парой Vendor плюс Name манифеста, а не Ид из Проект.yaml: второй проект под ту же пару отклоняется с 409 ALREADY_EXISTS.

25.07.2026 – 0.14.0

Добавлено

  • Суффикс версии берётся из номера запуска CI (CI_PIPELINE_IID, GITHUB_RUN_NUMBER, BUILD_NUMBER), когда нет ни явной версии, ни прежней сборки: чистый рабочий каталог CI больше не даёт -1 при каждом запуске.
  • build и deploy --dry-run выводят состав сборки – name, vendor, version, version-source, kind, branch, commit и dirty, – и CI больше не выковыривает версию из имени файла.
  • apps get/delete/start/stop/debug принимают точное имя приложения наравне с ид (в MCP тоже); несколько совпадений – ошибка с перечнем ид, разрушающие команды не угадывают.
  • apps list --brief – краткие карточки: вопрос “жив ли acme-crm-dev” решается парой сотен байт вместо десятков килобайт.
  • Незакоммиченные изменения каталога проекта видны в отчёте (dirty, dirty-files), а флаг --require-clean прерывает работу до сборки.

Изменено

  • apps list --name фильтрует на клиенте: платформа query-параметр игнорирует, поэтому прежний сквозной фильтр не фильтровал ничего.
  • Ключи дескриптора Проект.yaml читаются в обоих написаниях – двуязычие исходников заявлено платформой, и раньше такой проект отвергался.
  • Ожидания статусов считают Error терминальным: развёртывание падает сразу с ошибками компиляции, а не ждёт весь отведённый срок.

Исправлено

  • --lang en теперь английский везде. Около сорока строк, обращённых к пользователю, были зашиты русскими литералами мимо каталога сообщений; тест обходит модули и не даёт им появиться снова.

24.07.2026 – 0.12.0, 0.13.0, 0.13.1

Исправлено

  • Файлы каталогов Ресурсы попадают в архив независимо от расширения. Прежде на них действовал общий список разрешённых расширений, файлы молча выпадали из сборки, и применение падало с ошибкой “Неизвестный ресурс”. Вне каталогов ресурсов список действует по-прежнему и пополнился .htm.

Изменено

  • MCP: list_projects по умолчанию отдаёт краткие карточки – как list_apps; полные карточки возвращает brief=false.

Добавлено

  • builds upload сообщает цель загрузки (project-id и project-id-source): раньше сборка молча ложилась в проект из окружения, когда задумывался новый.
  • builds upload --new-project загружает сборку новым проектом, игнорируя ELEMENT_PROJECT_ID.
  • builds upload предупреждает о чужом имени сборки: панель показывает проект под именем последней залитой сборки.
  • Справочник команд и его генератор под тестами (tests/test_cli_docs.py): каждая команда отвечает на --help и покрыта разделом справочника, а две языковые версии действительно различаются.

22.07.2026 – 0.11.0

Добавлено

  • Сайт документации (docs.keyfire.ru/elemctl), полный справочник команд и справка – целиком на русском и английском.

21.07.2026 – 0.10.0

Изменено

  • MCP: окружение задаётся на вызов, apps list по умолчанию краткий.
  • Ошибка “нет источника приложения” подсказывает, как завести проект.

Исправлено

  • Справка CLI переводится: язык определяется до построения парсера аргументов.
  • apps create показывает собственные ошибки задачи компиляции вместо обобщённого “Неизвестная ошибка. Обратитесь к администратору”.

19.07.2026 – 0.9.1

Изменено

  • Раздел команд в справке назван “команды”, а версия читается из одного источника.

17.07.2026 – 0.9.0

Добавлено

  • inspect – разбор готового архива сборки.
  • builds get и builds delete принимают версию сборки и резолвят её в id.

15.07.2026 – 0.5.0, 0.6.0, 0.7.0, 0.8.0

Добавлено

  • self-update – обновление распаковкой колеса, безопасно даже когда запущенный исполняемый файл занят (0.7.0).
  • Система плагинов: адаптер отладки платформы подключается через точки расширения (0.5.0).

Изменено

  • verify подтверждает развёртывание по id применённой сборки, а не по строке версии (0.8.0).
  • Подсказка MCP отмечает, что долгие операции асинхронны: запускать CLI в фоне (0.5.0).
  • Ссылки проекта на PyPI (Homepage / Repository / Issues) в метаданных пакета (0.6.0).

Исправлено

  • MCP-сервер учитывает глобальные аргументы конфигурации (--env-file и прочие) (0.7.0).

12.07.2026 – 0.4.0, 0.4.1

Добавлено

  • Полное двуязычие ru/en: i18n рантайма (--lang / ELEMCTL_LANG), README и спецификация на двух языках.
  • apps debug – данные для сессии отладки платформы (POST /actions/debug).

Изменено

  • Релизы публикуются на PyPI по тегу v* через Trusted Publishing, с подписанными аттестациями происхождения; теги vscode-v* при этом не задеваются.

10.07.2026 – 0.2.0, 0.2.1, 0.3.0

Добавлено

  • Первый релиз: клиент документированного Console API v2, сборка .xasm/.xlib из исходников, развёртывание одной командой с проверкой, что изменение применилось, CLI и MCP-сервер – написано clean-room, по спецификации в docs/SPEC.md (0.2.0).
  • apps ensure – создать приложение только если его нет (0.3.0).

Изменено

  • apps find пропускает удалённые приложения; --include-deleted возвращает прежнее поведение (0.3.0).

Исправлено

  • apps find возвращает 0, когда приложение отсутствует, вместо ошибки (0.2.1).

Последнее обновление 8 октября 2026 г.

Эта страница была полезной?