[project] name = "atlas-bootstrapper" # Tracks the tagged product version (BRAND_VERSION in .env / AppState). Atlas # remains pre-1.0; post-v0.1.0 changes stay under CHANGELOG's [Unreleased] # section until the next semantic-version tag is cut. version = "0.1.0" description = "Atlas bootstrapper - cross-platform startup and management scripts" requires-python = ">=3.11" dependencies = [ "pyyaml>=6.0", # YAML parsing (replaces yq) "markdown-it-py>=3,<4", # CommonMark block scanner used by docs regeneration "rich>=14.2.0,<16", # Terminal colors, tables, formatting; Textual 8.x depends on # rich>=14.2.0, so uv resolves this floor upward regardless (#535 Pass 0). # Capped to the tested major (#535 followups review, finding R9): # this floor previously read `rich>=13.0.0` and had silently drifted — # nobody was tracking that it let uv resolve an undisclosed major jump # to rich 15.0.0, the exact defect this entry's own history names. # Reproducing the same shape (an unbounded floor) after raising the # number doesn't fix that; `<16` pins the ceiling to the major actually # locked and tested (15.0.0), mirroring textual-image's own # `>=0.12,<0.13` convention below. Bump deliberately, not by drift. "click>=8.3.3", # CLI argument parsing; clears click.edit command injection advisory "requests>=2.33.0", # HF + civitai catalog HTTP scraping "urllib3>=2.8.0", # Explicit floor (transitive via requests) — clears CVE-2026-44431/44432 and CVE-2026-97687/97688/97689 "textual>=8.2.8", # TUI framework — owns the wizard, launch, and streaming-logs flows. # Floor raised from 0.85 for selection auto-scroll, cross-container # selection, and the TextSelected event (#535 Pass 0). Left unbounded # (#535 followups review, finding R9, considered and declined): unlike # rich's floor above, this one was JUST deliberately raised and reviewed # this same pass, not left to silently drift — and capping the framework # that owns the entire wizard surface is a bigger, separate call than a # narrow dependency-hygiene fix. Revisit if this floor goes as long # without a deliberate look as rich's did. "jsonschema>=4.0.0", # Validates services//service.yml against bootstrapper/schemas/* "textual-image>=0.12,<0.13", # Smooth splash poster via the terminal's image protocol (Kitty/Sixel/iTerm); <0.13 keeps Python 3.11 support. Block-art fallback where unsupported. # The supported Python floor admits the security-fixed Pillow 13. # textual-image 0.12 still uses getdata(), which Pillow 14 removes. "pillow>=13.0.0,<14", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["."] [dependency-groups] # PEP 735 dependency groups (replaces the deprecated `[tool.uv] # dev-dependencies` table; uv warns on every invocation otherwise). # CI invokes `uv sync --group dev`. dev = [ "cairosvg>=2.7,<3", "fastapi==0.141.1", "httpx2>=2.12.0", "mkdocs>=1.6,<2", "mkdocs-material>=9.6,<10", "packaging>=23.0", # Version parsing for tests/test_textual_floor.py; only ever # resolved transitively (via pytest) before, declare it directly. "python-dotenv==1.2.2", "python-multipart==0.0.32", "pytest>=7.0.0", "pytest-cov>=7.1,<8", "radon==6.0.1", # Recomputes the committed maintenance complexity ceiling in CI. "asyncpg>=0.31.0", ] [tool.pytest.ini_options] testpaths = ["tests"] python_files = "test_*.py" markers = [ "live: optional test requiring a running external service or special hardware", ] # Bootstrapper modules import as bare names (e.g. `from core.config_parser import ConfigParser`); # adding the package root keeps that style working under pytest. pythonpath = [".", ".."] [tool.coverage.run] branch = true source = ["."] omit = ["tests/*"]