feat: Add experimental uv workspace support
Extend the generic toolchain architecture introduced for Cargo to uv
(Python) workspaces, behind futureFlags.uvWorkspaces or
TURBO_EXPERIMENTAL_UV.
* Discovery (turborepo-repository/src/uv.rs): parse the root
pyproject.toml [tool.uv.workspace] globs and each member manifest;
PEP 503-normalized names, workspace = true source edges, dev
dependency-group cycle dropping. Packaged projects (build backend
present) get build -> uv build --package=<name> with dist/<name>-*
wheel/sdist outputs; virtual projects are graph-only; a synthetic uv
package maps sync -> uv sync --locked.
* Hashing: per-member external closures from uv.lock (identity =
version + source + artifact hashes) plus uv --version, workspace
manifest/interpreter input globs, UV_* env vars, and dependency-member
source globs with .venv/__pycache__ exclusions.
* Prune: copies the member closure, subsets uv.lock (rewriting
manifest.members), rewrites the root pyproject.toml, carries
.python-version/uv.toml, and canonicalizes via uv lock so
uv sync --locked passes in the pruned output.
* Watch: pyproject.toml/uv.lock changes trigger rediscovery;
.venv/__pycache__/dist write storms are suppressed. Toolchain flags
now travel as a WatchedToolchains struct.
* Covered by unit tests at every layer plus an end-to-end suite
(crates/turborepo/tests/uv_workspace_test.rs) that drives real uv:
build caching/restoration, cross-member invalidation, uv#sync, both
opt-in surfaces, and prune proven by uv sync --locked + uv run.