Skip to content
Apothem
Архитектура

Самодостаточная среда выполнения

Как движок Apothem запускается из любого checkout — внутренние зависимости, модель вызова PYTHONPATH=src и bootstrap дерева плагина.

Самодостаточная среда выполнения

Движок Apothem — это самодостаточная среда выполнения: он работает без реестра, прямо из любого checkout или размещённого дерева исходников, потому что его сторонние зависимости путешествуют вместе с ним. Это обеспечивают две части — дерево внутренних зависимостей и модель вызова python -m, которой не нужны установленные консольные скрипты.

Дерево внутренних зависимостей

Стек валидации и сериализации внутренне встроен как чистый исходный код Python под src/apothem/_vendor/, каждый пакет — рядом со своим исходным файлом лицензии:

  • yaml (парсер/эмиттер на чистом Python; опциональное C-расширение libyaml не переносится)
  • jsonschema со своей цепочкой зависимостей attrs (и её псевдонимом attr), referencing и jsonschema_specifications
  • rpds — шим на чистом Python, переопределяющий поверхность HashTrieMap, HashTrieSet и List, которую используют jsonschema и referencing, опираясь на встроенные типы, так что стек работает с нулём скомпилированных расширений
  • typing_extensions

Внутренние копии имеют приоритет над любой версией, установленной в системе: bootstrap помещает каталог vendor в начало sys.path, перед site-packages. Политика отбора — что встраивается внутренне, что нет и как обновляются внутренние пакеты — задокументирована в стратегии внутреннего встраивания зависимостей.

Две зависимости остаются за пределами дерева: click и rich — библиотеки для терминала, которые импортирует CLI. Они должны быть импортируемы под интерпретатором, запускающим движок; установщики проверяют обе, называют любую отсутствующую и предлагают установить её за вас — с вашим подтверждением или автоматически с --yes / APOTHEM_AUTO_INSTALL_DEPS=1.

Модель вызова python -m

Apothem намеренно не объявляет консольных скриптов в pyproject.toml — консольные скрипты существуют, только когда менеджер пакетов помещает их в PATH, а самодостаточная среда выполнения никогда не предполагает его наличия. Вместо этого у движка две поверхности вызова:

ПоверхностьВызовКонтекст
CLI движкаpython -m apothem <command>Дерево исходников с src/ в PYTHONPATH (checkout, кеш npx, дерево плагина)
Среда выполнения хуковpython "<harness-root>/apothem/hooks/dispatch.py" <event>Материализованная копия под корнем окружения, по абсолютному пути
  • python -m apothem запускает src/apothem/__main__.py, который вызывает apothem.cli:main — группу команд Click.
  • Записи хуков в материализованном settings.json / hooks.json вызывают диспетчер (а для Claude Code — шлюз соответствия в <harness-root>/apothem/conformity/gate.py) по абсолютному пути скрипта. Оба — автономные скрипты stdlib, которые сами загружают свой sys.path, и схемные фикстуры шлюза путешествуют рядом с ним в <harness-root>/apothem/schemas/, так что хуки работают без импортируемого пакета apothem на хосте. Шаблоны несут токен ${HARNESS_ROOT}, который apothem install рендерит в реальный путь корня окружения в форме прямого слеша.
  • Из checkout исходников модульные формы python -m apothem.hooks.dispatch и python -m apothem.conformity.gate запускают тот же код для разработки.

Каталог пакета становится импортируемым, если поместить каталог src/ из checkout в начало PYTHONPATH:

PYTHONPATH="$HOME/.apothem/src" python -m apothem <command>

Это именно тот вызов, который установщик в один шаг печатает по завершении.

Bootstrap дерева плагина

Плагин Claude Code упаковывает движок под <plugin_root>/lib/apothem, а не полагается на PYTHONPATH. Модуль bootstrap apothem.lib.plugin_bootstrap предоставляет bootstrap_syspath, который идемпотентно помещает <plugin_root>/lib и каталог vendor в начало sys.path, чтобы import apothem и каждая внутренняя зависимость разрешались из дерева плагина. Некорректное дерево (отсутствует lib/) вызывает PluginBootstrapError, а не молча импортирует устаревшую системную копию.

Что установщик размещает на диске

Скриптовые установщики размещают git-клон дерева исходников в ~/.apothem (переопределяется через APOTHEM_HOME) и запускают движок из него — в site-packages не устанавливается ни одного пакета Python, кроме опционального предложения предусловия click / rich. Клон — это полный репозиторий, включая набор тестов и сайт документации, которые среда выполнения никогда не импортирует, по двум обдуманным причинам: движок материализует свои когорты — правила, навыки, команды и шаблоны — прямо из дерева в каждое окружение, так что дерево — живой источник истины, а не только среда выполнения; и каталог .git остаётся на месте, чтобы apothem update делал fast-forward существующего клона, а не скачивал заново.

Эта схема запуска из исходников — тот же паттерн, что используют инструменты вроде nvm, pyenv и oh-my-zsh — несколько мегабайт исходников плюс история, удаляемые в один шаг деинсталлятором (нет состояния системы, которое нужно откатывать). Более лёгкий след — мелкий или разреженный checkout, опускающий tests/ и site/, — возможен, но обменял бы на месте выполняемый, проверенный по подписи путь обновления на основе git; текущая схема предпочитает простое, проверяемое обновление минимальному диску.

Как среда выполнения находит Python

Установщики в один шаг и npx-шим находят интерпретатор одинаково: они зондируют python3, python, версионированные имена (от python3.14 до python3.10) и py -3 в Windows; отклоняют шимы лаунчера Microsoft Store; и принимают первого кандидата, сообщающего версию 3.10 или новее. При запуске из дерева исходников установщики повторно используют упакованный локатор hooks/lib/find-python, который применяет ту же нижнюю границу.

Рекомендуемый следующий шаг

Запустите python -m apothem --help с каталогом src/ из checkout в PYTHONPATH, чтобы подтвердить, что путь самодостаточного CLI разрешается на вашем хосте.

On this page