This repository is the public discovery registry for independently published Vane dynamic extension provider packages. It plays the same narrow role as an extension directory: it tells clients which provider package owns an extension name and where that provider is maintained.
The machine-readable catalog is published by GitHub Pages at:
https://astrovela.github.io/vane-extensions/v1/index.json
That endpoint is the small, stable discovery contract consumed by Vane. Rich metadata is published separately so documentation and operational fields can evolve without requiring a Vane release:
https://astrovela.github.io/vane-extensions/v1/extensions/index.json
https://astrovela.github.io/vane-extensions/v1/extensions/<name>.json
https://astrovela.github.io/vane-extensions/v1/metrics/downloads-last-week.json
https://astrovela.github.io/vane-extensions/extensions/<name>/
The stable catalog is discovery metadata only. The separate website enriches that metadata and publishes exact pip installation recipes generated by PDM. It does not distribute native artifacts or grant trust to an artifact. Vane validates each installed provider's embedded metadata and native descriptor when it is explicitly loaded.
-
Publish a Python distribution named
vane-extension-<name>that exposes avane.dynamic_extension_providersentry point named<name>. Names use lowercase ASCII letters and digits with single, non-trailing underscores so every extension maps to exactly one normalized Python distribution name. The nameindexis reserved for the aggregate detail document. -
Add
extensions/<name>/extension.json, followingschema/extension.schema.json. Selectpypiortestpypiexplicitly; metadata generation never searches or falls back to a different package index. Include at least one GitHub maintainer plus a documentation URL, a representative first query, and a concise extended description. Provider source bindings come from these manifests automatically; adding an extension does not require Vane code changes. -
Run the deterministic checks used by CI:
python -m pip install -r requirements.txt check-jsonschema --schemafile schema/extension.schema.json extensions/*/extension.json python -m scripts.build_catalog --check index.json python -m unittest discover -s tests -v -
Optionally build the complete site against live metadata.
GITHUB_TOKENincreases the GitHub API rate limit but is not required for public repos:GITHUB_TOKEN=$(gh auth token) python -m scripts.build_site --output _site
Dependency resolution belongs to PDM, not the registry.
The builder creates a temporary virtual project with the exact provider version
and its declared Requires-Python, then runs pdm lock for each declared CI
target and pdm export. PDM's native --append mode merges target locks and
their conditional pins; the registry does not construct those conditions.
PDM resolves the complete dependency graph, including versions, extras, and
environment markers. The registry does not walk that graph, infer ABI/libc
compatibility, or translate wheel architecture tags into runtime marker values.
packaging parses requirements, versions, and wheel
filenames; tomli-w writes the temporary project.
The registry consumes PDM's requirements export, not its dependency graph.
Index ownership remains a small, explicit registry policy:
- Vane-owned packages use the provider's selected channel,
pypiortestpypi. - PDM's per-package source filters
bind
vane-aiandvane-extension-*to that channel, including transitive packages. Ordinary third-party dependencies use PyPI. An unavailable package in its designated index fails resolution; there is no cross-index fallback or--extra-index-url. - A small PDM repository policy rejects URL/Git/path requirements before preparing their metadata. It does not implement dependency resolution. Exported entries must be exact named pins; source directives are removed before constructing separate pip commands. Artifact URLs and credentials never appear in public details.
- PDM runs with an explicit temporary configuration, cleaned package-manager variables, isolated Python imports, no ambient plugins, wheel-only candidates, a bounded export, and timeouts. Identical requests share a result; distinct requests resolve concurrently.
PDM is used because uv's named sources do not cover transitive requirements in this configuration; a regression test with same-name packages on both indexes exposed that distinction. Index routing is delegated to PDM rather than worked around with another handwritten dependency walker.
Users still use pip; PDM is only registry build tooling. Generated recipes install
the exact exported pins from separate indexes with --no-deps,
--only-binary=:all:, and --force-reinstall, then run pip check.
Markers exported by PDM are preserved for pip to evaluate on the real interpreter.
Use a fresh virtual environment: recipes are not a migration tool for an
existing environment.
POSIX commands use PIP_CONFIG_FILE=/dev/null and && guards. PowerShell
uses nul, checks each command's status, and restores the caller's environment
in finally. Every pip invocation also uses --isolated.
Published wheel tags and Requires-Python are upstream metadata, not a
guarantee that all matching machines can install or load the extension.
A dependency lock is not a native compatibility proof. Recipes target the
declared CI matrix only; the service does not attempt a universal installation
proof across every platform described by upstream wheel metadata.
The shared validation workflow builds one site snapshot. It then tests the
snapshot's exact generated recipes in fresh virtual environments on
Ubuntu 24.04 x86-64, CPython 3.10, 3.11, 3.12, 3.13, and 3.14.
The resolver targets that runner's manylinux_2_39_x86_64 environment. The CI
Python matrix comes from the same PYTHON_TARGETS used to produce the locks.
For each published provider it requires wheel-only installation, pip check,
and vane.load_installed_extension() with automatic extension downloads disabled.
These are local load smoke checks, not query, performance, or distributed-Ray
coverage. They do not certify an older glibc baseline, Windows, macOS, other
architectures, or other Python implementations.
The Pages workflow deploys that same artifact only after all matrix jobs pass. It does not rebuild or re-resolve between validation and deployment. Check the deployment run logs for exact versions and runner details; the JSON metadata does not invent a per-platform verified-support list. Refreshes repeat the installation checks.
To exercise a generated snapshot locally with a target Python:
python -m scripts.smoke_install --site _siteThis downloads prebuilt wheels into temporary environments; it never builds Vane or runs the Vane test suite.
index.json is generated deterministically from the discovery subset of the
individual manifests and must be updated in the same pull request. Package
versions and wheel/Python platform availability are derived from the manifest's
explicit Python package index while GitHub stars come from the repository API.
PyPI download estimates from pypistats.org are published in a separate
metrics document; TestPyPI does not expose meaningful download counts, so those
values are null. Unavailable or invalid PyPIStats responses also produce
null metrics instead of blocking publication. Fetch and response-validation
errors emit a build warning; GitHub identity and package/dependency validation
errors still fail the build.
No direct artifact URL, hash, or trust identity is published
by the registry: those values belong to immutable provider packages and their
Vane descriptors.
extensions/*/extension.json: one reviewed discovery manifest per extensionschema/extension.schema.json: the strict manifest schemaschema/*detail*.schema.json: public enriched-detail service contractsschema/download-metrics.schema.json: public metrics service contractscripts/build_catalog.py: deterministic catalog generator and validatorscripts/build_site.py: live-metadata enrichment and Pages assemblerscripts/installation.py: thin PDM invocation and requirements-export boundaryscripts/pdm_runner.py: named-index-only PDM repository policyscripts/smoke_install.py: actual target-interpreter install/check/load smoke testindex.json: the reviewed aggregate consumed by Vanesite/: the human-readable GitHub Pages landing page source
The Pages build produces one detail page and JSON document per extension. Each
contains the reviewed documentation, install/load examples, package publication
state, latest package version and upload time, Requires-Python, available
Python/ABI/platform wheel tags, validated package requirements with direct-URL
entries omitted, GitHub stars, and download metrics when the selected index
supports them. These values are informational and never participate in artifact
resolution or trust.
The repository is licensed under the Apache License 2.0. Each manifest records the license declared by its provider project; that field does not change the license of this registry.