CLI for Project Amrita — scaffold, manage, and maintain Python projects with the Amrita ecosystem.
# From PyPI
uv tool install amctl
# By uv
uv tool install amctl
# From GitHub
uv tool install git+https://github.com/AmritaBot/Amctl.git# List available templates
amctl list
# Create a new project
amctl create -t amrita_core -n myapp
cd myapp
uv syncScaffold a new project from a template.
amctl create -t amrita_core -n myapp
amctl create -t amrita_core -n myapp --description="My awesome project"
amctl create -t amrita_core -n myapp -V 0.8.0 -o /tmp
# Bypass Python version resolution
amctl create -t amrita_core -n myapp --frozen
# Force a specific version not in the known list
amctl create -t amrita_core -n myapp --force-version 3.0-beta| Option | Description |
|---|---|
-t, --type |
Template type (e.g. amrita_core) |
-n, --name |
Project name |
-V, --version |
Template version (default: latest) |
-o, --output |
Output directory (default: .) |
-f, --force |
Overwrite existing directory |
--force-version |
Use any version string, bypassing validation |
--frozen |
Skip Python version selection and .python-version |
Template-specific fields (declared via __tmpl_fields__) are passed as
dynamic CLI flags:
amctl create -t amrita_core -n myapp --description="Hello" --port=8080After scaffolding, you are prompted to choose a license interactively:
[?] Choose a license for your project:
[1] MIT
[2] Apache-2.0
[3] GPL-3.0
[4] None (skip)
License [4]: _
A LICENSE file is written to the project root when a known license is
selected.
List all registered templates.
amctl list # compact (first 5 versions shown)
amctl list -v # verbose — full version listsShow detailed information about a template.
amctl info amrita_coreOutput includes description, available versions (with source labels), declared fields (name/type/default/required/description), and the expected template file tree.
Check for missing template files and restore them.
amctl fix --check # dry-run — report missing files only
amctl fix # interactive [Y/N/M] confirmation
amctl fix --force # restore all missing files without prompting
amctl fix --exclude '["README.md",".gitignore"]' # skip specific files| Option | Description |
|---|---|
--check |
Dry-run — show what would be restored |
--force, -f |
Skip confirmation, restore everything |
--exclude |
JSON array or single path to exclude |
Run project scripts defined in pyproject.toml under
[tool.amctl.scripts].
# pyproject.toml
[tool.amctl.scripts]
lint = "uv run ruff check ."
test = "uv run pytest -v"
start = "uv run uvicorn myapp.main:app --reload"amctl man lint
amctl man test -- --cov
amctl man startExtra arguments after -- are forwarded to the script.
Template-specific sub-commands. Each registered template is a sub-group.
amctl tmpl amrita_core # show field summary (if no commands registered)Templates can register custom commands via get_tmpl_commands().
Manage amctl itself.
amctl self cache show # display version cache contents
amctl self cache fresh # refresh cache from PyPI
amctl self cache clean # delete the cache file
amctl self tmpl-upd # check for template package updatesAmctl resolves available template versions through a cache-first fallback chain:
fresh cache (24h TTL) → PyPI → expired cache (warn) → hardcoded fallback
Cache location (in priority order):
$AMCTL_TMPL_CACHEPATH— explicit path.venv/.amctl/versions_cache.json— inside a virtualenv project~/.amctl/versions_cache.json— global
Environment variables:
| Variable | Description |
|---|---|
AMCTL_TMPL_CACHEPATH |
Custom cache directory |
AMCTL_TMPL_USECACHE=false |
Disable local cache (still uses PyPI) |
AMCTL_TMPL_NOPYPI=true |
Block all PyPI requests (air-gapped) |
AMCTL_LOG_LEVEL=debug |
Enable debug logging for network diagnostics |
Each version carries a requires_python constraint obtained from PyPI.
Amctl attempts to resolve a compatible Python interpreter using uv python list and writes a .python-version file to the project root.
Templates are auto-discovered from src/amctl/templ/<name>/. Define a
class with the required dunder attributes:
from amctl.templating import BaseTemplate, field
class MyTemplate(BaseTemplate):
__template_name__ = "my_template"
__template_description__ = "A custom project template"
__core_package__ = "my-core-lib" # PyPI package for version discovery
__python_requires__ = ">=3.11" # Python version constraint
__versions__ = ("1.0",) # hardcoded fallback
__tmpl_fields__ = {
"description": field(default="desc"),
"port": field(default=8000, type=int, required=True),
}
def on_create(self, project_dir, name, version=None, **fields):
super().on_create(project_dir, name, version=version, **fields)
__template_export__ = MyTemplateTemplate files go in the same directory and use the .tmpl extension
for Jinja2 rendering. Directory names containing {{ }} markers are
also rendered (e.g. src/{{ name }}/__init__.py.tmpl).
uv sync
uv run ruff check src/ # lint
uv run pyright src/ # type-check
uv run amctl --helpMIT — see LICENSE.