Skip to content
Apothem
アーキテクチャ

自己完結型ランタイム

Apothem のエンジンが任意のチェックアウトからどのように実行されるか — ベンダリングされた依存関係、PYTHONPATH=src による呼び出しモデル、プラグインツリーのブートストラップ。

自己完結型ランタイム

Apothem のエンジンは自己完結型ランタイムです。 サードパーティの依存関係がエンジンとともに移動するため、レジストリを必要とせず、任意のチェックアウトや配置されたソースツリーから直接実行されます。 これを実現するのは 2 つの要素です — ベンダリングされた依存関係ツリーと、インストール済みのコンソールスクリプトを必要としない python -m 呼び出しモデルです。

ベンダリングされた依存関係ツリー

検証とシリアライズのスタックは、純粋な Python ソースとして src/apothem/_vendor/ 配下にベンダリングされており、 各パッケージには上流のライセンスファイルが添えられています。

  • yaml(純粋 Python のパーサー / エミッター。任意の libyaml C 拡張は 含まれません)
  • jsonschema と、その依存チェーンである attrs(およびその attr エイリアス)、 referencing、jsonschema_specifications
  • rpds — jsonschema と referencing が使用する HashTrieMap、 HashTrieSet、List の面を組み込み型に基づいて再実装した純粋 Python のシムで、 これによりスタックはコンパイル済み拡張をひとつも使わずに実行されます
  • typing_extensions

ベンダリングされたコピーは、システムにインストールされたどのバージョンよりも優先されます。 プラグインのブートストラップ、npm シム、インストーラー、そして python -m apothem エントリーポイント自体が、 それぞれ vendor ディレクトリを site-packages より前に sys.path に置きます。 選定ポリシー — 何をベンダリングし、何をしないか、ベンダリングしたパッケージをどのように更新するか — は、 依存関係のベンダリング戦略に記載されています。

2 つの依存関係はツリーの外に置かれます。CLI がインポートするターミナル向けのライブラリである click と rich です。 これらは、エンジンを実行するインタープリターでインポート可能でなければなりません。 インストーラーは両方をチェックし、欠けているものがあればその名前を示し、あなたの確認を得て — または --yes / APOTHEM_AUTO_INSTALL_DEPS=1 を指定すると自動的に — インストールを提案します。 その他のすべてのチャネルでは、エントリーポイントが CLI をインポートする前に標準ライブラリで両方をチェックし、 欠けているものがあると、実行中のインタープリター向けの正確な pip コマンドを示すエラーで停止します (--json の下では、コード runtime.dependency_missing を持つ JSON エンベロープになります)。

python -m 呼び出しモデル

Apothem は意図的に pyproject.toml でコンソールスクリプトを宣言していません — コンソールスクリプトはパッケージマネージャーがそれを PATH に置いたときにのみ存在し、 自己完結型ランタイムはパッケージマネージャーの存在を決して前提としません。 代わりに、エンジンには 2 つの呼び出し面があります。

面呼び出しコンテキスト
エンジン CLIpython -m apothem <command>src/ を PYTHONPATH に含むソースツリー(チェックアウト、npx キャッシュ、プラグインツリー)
フックランタイム<resolved CPython> "<harness-root>/.apothem/support/hooks/dispatch.py" <event>Claude Code のマテリアライズ:ハーネスルートの共有 .apothem/support/ ツリー配下にあるコピーを、絶対パスで指定したもの
  • python -m apothem は src/apothem/__main__.py を実行します。これは src/apothem/_vendor を sys.path に置き、click と rich が インポート可能であることをチェックしてから、apothem.cli:main(Click のコマンドグループ)を呼び出します。
  • マテリアライズされた settings.json / hooks.json 内のフックエントリは、 ディスパッチャー(および Claude Code の場合は <harness-root>/.apothem/support/conformity/gate.py にあるコンフォーミティゲート)を絶対スクリプトパスで呼び出します。 どちらも自身の sys.path をブートストラップするスタンドアロンの標準ライブラリスクリプトで、 ゲートのスキーマフィクスチャは <harness-root>/.apothem/support/schemas/ にゲートと並んで置かれるため、 フックはホスト上にインポート可能な apothem パッケージがなくても実行されます。 テンプレートは ${HARNESS_ROOT} トークンを含み、apothem install がこれを スラッシュ区切り形式の実際のハーネスルートパスにレンダリングします。
  • ソースチェックアウトからは、モジュール形式の python -m apothem.hooks.dispatch と python -m apothem.conformity.gate が、開発用に同じコードを実行します。

チェックアウトの src/ ディレクトリを PYTHONPATH の先頭に追加すると、 パッケージディレクトリがインポート可能になります。

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

apothem ランチャーが PATH 上にない場合、install.sh は完了時にこの形式を表示します。その際、ベンダリングされたディレクトリを src/ より前に置き、python の代わりに解決された CPython を使います。install.ps1 は、同じ 2 つの設定を PowerShell の形式で表示します。すなわち、ベンダリングされたディレクトリと src/ ディレクトリを ; で連結する $env:PYTHONPATH の代入と、続けて & '<CPython>' -m apothem <command> です。

プラグインツリーのブートストラップ

Claude Code プラグインは、PYTHONPATH に頼るのではなく、エンジンを <plugin_root>/lib/apothem 配下にバンドルします。 ブートストラップモジュール apothem.lib.plugin_bootstrap は bootstrap_syspath を公開します。 これは <plugin_root>/lib と vendor ディレクトリを冪等に sys.path の先頭へ追加し、 import apothem とすべてのベンダリングされた依存関係がプラグインツリーから解決されるようにします。 不正な形式のツリー(lib/ が欠けている)は、古いシステムのコピーを暗黙にインポートするのではなく、 PluginBootstrapError を送出します。

インストーラーがディスクに配置するもの

スクリプトインストーラーは、ソースツリーの git クローンを ~/.apothem(APOTHEM_HOME で上書き可能)に配置し、 そこからエンジンを実行します — 任意の click / rich 前提条件のインストール提案を除き、 site-packages に Python パッケージがインストールされることはありません。 クローンは完全なリポジトリであり、ランタイムが決してインポートしないテストスイートとドキュメントサイトも含みます。 これには 2 つの意図的な理由があります。 エンジンはツリーから各ハーネスへ直接コホートをマテリアライズする(ルール、スキル、コマンド、テンプレート)ため、 ツリーは単なるランタイムではなく、現に使われる信頼できる情報源であること。 そして、.git ディレクトリがその場に残るため、apothem update が再ダウンロードする代わりに 既存のクローンでリリースタグをチェックアウトすること、です。

このソースから実行するレイアウトは、nvm、pyenv、oh-my-zsh などのツールが使用するのと同じパターンです — 数メガバイトのソースと履歴で、アンインストーラーで 1 ステップで削除できます(巻き戻すべきシステム状態はありません)。 よりスリムなフットプリント — tests/ と site/ を省いたシャローチェックアウトまたはスパースチェックアウト — も可能ですが、 その場で行う、署名検証済みの git ベースの更新パスを手放すことになります。 現在のレイアウトは、最小限のディスク使用量よりも、シンプルで検証可能な更新を優先しています。

ランタイムが Python を見つける方法

ワンショットインストーラーと npx シムは、探索する名前は異なりますが、適用する規則は同じです。 インストーラーは python3、python、およびバージョン付きの名前(python3.14 から python3.10 まで)を探索します。 npx シムは、APOTHEM_PYTHON が設定されている場合はまずそれを探索し、続いて python3、python、py -3 を探索します。 バージョン付きの名前は探索しません。 どちらも Microsoft Store のランチャーシムを除外し、バージョン 3.10 以降を報告する最初の候補を受け入れます。 ソースツリーから実行される場合、インストーラーはバンドルされた hooks/lib/find-python ロケーターを再利用し、これは同じ下限を適用します。

推奨される次のステップ

チェックアウトの src/ ディレクトリを PYTHONPATH に含めた状態で python -m apothem --help を実行し、 自己完結型 CLI のパスがあなたのホストで解決されることを確認してください。

On this page