Skip to content
Apothem
Arquitectura

Tiempo de ejecución autónomo

Cómo el motor de Apothem se ejecuta desde cualquier checkout — dependencias incorporadas, el modelo de invocación PYTHONPATH=src y el arranque del árbol del plugin.

Tiempo de ejecución autónomo

El motor de Apothem es un tiempo de ejecución autónomo: se ejecuta sin depender de un registro de paquetes, directamente desde cualquier checkout o árbol de código fuente colocado, porque sus dependencias de terceros viajan con él. Dos piezas lo hacen posible: un árbol de dependencias incorporadas y un modelo de invocación python -m que no necesita scripts de consola instalados.

Árbol de dependencias incorporadas

La pila de validación y serialización está incorporada como código fuente en Python puro bajo src/apothem/_vendor/, cada paquete junto al archivo de licencia de su proyecto de origen:

  • yaml (el analizador/emisor en Python puro; la extensión C opcional libyaml no se incluye)
  • jsonschema, con su cadena de dependencias attrs (y su alias attr), referencing y jsonschema_specifications
  • rpds — un shim en Python puro que reimplementa la superficie de HashTrieMap, HashTrieSet y List que usan jsonschema y referencing, respaldado por tipos integrados, de modo que la pila se ejecuta sin ninguna extensión compilada
  • typing_extensions

Las copias incorporadas tienen prioridad sobre cualquier versión instalada en el sistema: el arranque del plugin, el shim de npm, los instaladores y el propio punto de entrada python -m apothem colocan cada uno el directorio de dependencias incorporadas en sys.path por delante de site-packages. La política de selección — qué se incorpora, qué no y cómo se actualizan los paquetes incorporados — está documentada en la estrategia de incorporación de dependencias.

Dos dependencias quedan fuera del árbol: click y rich, las bibliotecas orientadas a la terminal que importa la CLI. Deben poder importarse con el intérprete que ejecuta el motor; los instaladores comprueban ambas, nombran la que falte y ofrecen instalarla por ti — con tu confirmación, o automáticamente con --yes / APOTHEM_AUTO_INSTALL_DEPS=1. En todos los demás canales, el punto de entrada comprueba ambas con la biblioteca estándar antes de importar la CLI, y si falta una se detiene con un error que nombra el comando pip exacto para el intérprete en ejecución (un sobre JSON con el código runtime.dependency_missing bajo --json).

El modelo de invocación python -m

Apothem, de forma intencionada, no declara ningún script de consola en pyproject.toml: los scripts de consola solo existen cuando un gestor de paquetes los coloca en PATH, y el tiempo de ejecución autónomo nunca da por supuesto ninguno. En su lugar, el motor tiene dos superficies de invocación:

SuperficieInvocaciónContexto
CLI del motorpython -m apothem <command>Un árbol de código fuente con src/ en PYTHONPATH (checkout, caché de npx, árbol del plugin)
Tiempo de ejecución de hooks<resolved CPython> "<harness-root>/.apothem/support/hooks/dispatch.py" <event>La materialización de Claude Code: la copia bajo el árbol compartido .apothem/support/ de la raíz del entorno, por ruta absoluta
  • python -m apothem ejecuta src/apothem/__main__.py, que coloca src/apothem/_vendor en sys.path, comprueba que click y rich se puedan importar y luego llama a apothem.cli:main, el grupo de comandos de Click.
  • Las entradas de hooks del settings.json / hooks.json materializado invocan el despachador (y, para Claude Code, la puerta de conformidad en <harness-root>/.apothem/support/conformity/gate.py) por ruta absoluta del script. Ambos son scripts independientes que solo usan la biblioteca estándar y que preparan su propio sys.path, y los fixtures de esquema de la puerta viajan junto a ella en <harness-root>/.apothem/support/schemas/, de modo que los hooks se ejecutan sin ningún paquete apothem importable en el host. Las plantillas llevan un token ${HARNESS_ROOT} que apothem install renderiza como la ruta real de la raíz del entorno, escrita con barras inclinadas hacia delante.
  • Desde un checkout del código fuente, las formas de módulo python -m apothem.hooks.dispatch y python -m apothem.conformity.gate ejecutan el mismo código para el desarrollo.

El directorio del paquete se vuelve importable al anteponer el directorio src/ del checkout a PYTHONPATH:

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

Cuando el lanzador apothem no está en PATH, install.sh imprime esta forma al terminar, con el directorio de dependencias incluidas antes de src/ y el CPython que resolvió en lugar de python. install.ps1 imprime los mismos dos ajustes en forma de PowerShell: una asignación de $env:PYTHONPATH que une el directorio de dependencias incluidas y src/ con ;, y después & '<CPython>' -m apothem <command>.

Arranque del árbol del plugin

El plugin de Claude Code empaqueta el motor bajo <plugin_root>/lib/apothem en lugar de depender de PYTHONPATH. El módulo de arranque apothem.lib.plugin_bootstrap expone bootstrap_syspath, que antepone de forma idempotente <plugin_root>/lib y el directorio de dependencias incorporadas a sys.path, de modo que import apothem y cada dependencia incorporada se resuelven desde el árbol del plugin. Un árbol mal formado (sin lib/) lanza PluginBootstrapError en lugar de importar en silencio una copia obsoleta del sistema.

Qué coloca el instalador en el disco

Los instaladores de script colocan un clon git del árbol de código fuente en ~/.apothem (se puede cambiar con APOTHEM_HOME) y ejecutan el motor desde él: no se instala ningún paquete de Python en site-packages más allá de la oferta opcional de los requisitos previos click / rich. El clon es el repositorio completo, incluidos la suite de pruebas y el sitio de documentación que el tiempo de ejecución nunca importa, por dos razones deliberadas: el motor materializa sus cohortes — reglas, skills, comandos y plantillas — directamente desde el árbol en cada entorno, de modo que el árbol es la fuente de verdad viva y no solo un tiempo de ejecución; y el directorio .git permanece en su sitio para que apothem update extraiga la etiqueta de la versión en el clon existente en lugar de volver a descargarlo.

Esta disposición de ejecución desde el código fuente es el mismo patrón que usan herramientas como nvm, pyenv y oh-my-zsh: unos pocos megabytes de código fuente más el historial, que se eliminan en un solo paso con el desinstalador (no hay ningún estado del sistema que deshacer). Una huella más reducida — un checkout superficial o disperso que omita tests/ y site/ — es posible, pero sacrificaría la ruta de actualización in situ basada en git y verificada por firma; la disposición actual prioriza una actualización sencilla y verificable frente a un uso mínimo del disco.

Cómo encuentra Python el tiempo de ejecución

Los instaladores de un solo paso y el shim de npx prueban nombres distintos y aplican las mismas reglas. Los instaladores prueban python3, python y los nombres con versión (python3.14 hasta python3.10). El shim de npx prueba APOTHEM_PYTHON cuando está definida, luego python3, python y py -3; no tiene nombres con versión. Ambos rechazan los shims del lanzador de Microsoft Store y aceptan el primer candidato que informe la versión 3.10 o posterior. Cuando se ejecutan desde un árbol de código fuente, los instaladores reutilizan el localizador incluido hooks/lib/find-python, que aplica la misma versión mínima.

Próximo paso recomendado

Ejecuta python -m apothem --help con el directorio src/ del checkout en PYTHONPATH para confirmar que la ruta de la CLI autónoma se resuelve en tu host.

On this page