Spaces:
Running on Zero
Running on Zero
chore: project scaffolding (pyproject, requirements, license, claude.md, tests)
Browse files- CLAUDE.md +44 -0
- LICENSE +21 -0
- README.md +3 -0
- pyproject.toml +18 -0
- requirements.txt +25 -0
- setup.sh +12 -0
- tests/__init__.py +0 -0
- tests/conftest.py +5 -0
- tests/test_scaffold.py +27 -0
CLAUDE.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Project Guidelines — z-image-studio
|
| 2 |
+
|
| 3 |
+
Working notes for AI assistants implementing this project.
|
| 4 |
+
|
| 5 |
+
## Sole-author rule (non-negotiable)
|
| 6 |
+
|
| 7 |
+
Mayank Gupta is the sole author on every commit. NO `Co-Authored-By: Claude...`, NO "Generated with Claude Code" footer, NO `--author=...` flag. Treat any tooling suggesting a Claude trailer as a bug.
|
| 8 |
+
|
| 9 |
+
## Architecture facts (locked — see spec)
|
| 10 |
+
|
| 11 |
+
Spec: `docs/superpowers/specs/2026-05-13-z-image-studio-design.md`
|
| 12 |
+
Plan: `docs/superpowers/plans/2026-05-13-z-image-studio.md`
|
| 13 |
+
|
| 14 |
+
1. Backend is DiffSynth-Studio's `ZImagePipeline` — not ComfyUI.
|
| 15 |
+
2. Three tabs (T2I dual-model, ControlNet turbo-only, Upscale turbo-only).
|
| 16 |
+
3. One pipeline instance, shared across modes; transformer swap is the only model-pool change.
|
| 17 |
+
4. `@spaces.GPU` applied module-level; identity off-Spaces.
|
| 18 |
+
5. DiffSynth handles VRAM management — do not sprinkle `empty_cache()` calls.
|
| 19 |
+
6. Models live in HF cache; on Spaces mirrored into `~/hf-cache-rw/` (build-vs-runtime user permissions).
|
| 20 |
+
|
| 21 |
+
## Coding conventions
|
| 22 |
+
|
| 23 |
+
- Python 3.11 (HF Spaces base image is 3.11)
|
| 24 |
+
- Flat top-level layout — no `src/`, no nested packages.
|
| 25 |
+
- No conda — `python3.11 -m venv .venv` + brew for system binaries.
|
| 26 |
+
- No emojis in code or commits unless explicitly asked.
|
| 27 |
+
- Type hints on public functions.
|
| 28 |
+
- Imports at top of file unless breaking circular deps.
|
| 29 |
+
- `ruff format` + `ruff check` must pass in CI.
|
| 30 |
+
|
| 31 |
+
## Commits
|
| 32 |
+
|
| 33 |
+
- Conventional Commits: `<type>(<scope>): <subject>` — types: `feat`, `fix`, `chore`, `docs`, `test`, `refactor`, `ci`, `perf`.
|
| 34 |
+
- Subject is imperative, lowercase, no trailing period.
|
| 35 |
+
- Body explains WHY when non-obvious. Reference plan task if relevant.
|
| 36 |
+
- Frequent small commits — one logical change per commit.
|
| 37 |
+
- NO Claude trailer (see above).
|
| 38 |
+
|
| 39 |
+
## Testing
|
| 40 |
+
|
| 41 |
+
- TDD per the plan — failing test first, then implementation.
|
| 42 |
+
- L1 + L2 run in CI without GPU. L3 + L4 require GPU/HF Space and are manual.
|
| 43 |
+
- No mocks for DiffSynth internals — mock only the `pipe(...)` call boundary.
|
| 44 |
+
- Use `pytest --gpu` to opt into L3 smoke tests.
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Mayank Gupta
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# z-image-studio
|
| 2 |
+
|
| 3 |
+
Placeholder — will be replaced by Task 16.
|
pyproject.toml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[tool.ruff]
|
| 2 |
+
target-version = "py311"
|
| 3 |
+
line-length = 120
|
| 4 |
+
extend-exclude = [".venv", "build", "dist", ".superpowers"]
|
| 5 |
+
|
| 6 |
+
[tool.ruff.lint]
|
| 7 |
+
select = ["E", "F", "I", "B", "UP", "RUF"]
|
| 8 |
+
ignore = ["E501"] # handled by formatter
|
| 9 |
+
|
| 10 |
+
[tool.ruff.format]
|
| 11 |
+
quote-style = "double"
|
| 12 |
+
|
| 13 |
+
[tool.pytest.ini_options]
|
| 14 |
+
testpaths = ["tests"]
|
| 15 |
+
python_files = "test_*.py"
|
| 16 |
+
markers = [
|
| 17 |
+
"gpu: requires a GPU (CUDA or MPS); skipped by default",
|
| 18 |
+
]
|
requirements.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core
|
| 2 |
+
gradio==5.50.0
|
| 3 |
+
spaces==0.30.0
|
| 4 |
+
diffsynth-studio>=0.5.0
|
| 5 |
+
torch>=2.4
|
| 6 |
+
safetensors>=0.4.5
|
| 7 |
+
huggingface-hub>=0.27
|
| 8 |
+
|
| 9 |
+
# ControlNet preprocessors
|
| 10 |
+
controlnet-aux>=0.0.9
|
| 11 |
+
opencv-python-headless>=4.9.0
|
| 12 |
+
einops>=0.8.0
|
| 13 |
+
|
| 14 |
+
# Upscaler
|
| 15 |
+
realesrgan>=0.3.0
|
| 16 |
+
basicsr>=1.4.2
|
| 17 |
+
|
| 18 |
+
# Imaging
|
| 19 |
+
pillow>=10.4.0
|
| 20 |
+
numpy>=1.26
|
| 21 |
+
|
| 22 |
+
# Dev
|
| 23 |
+
ruff>=0.6.0
|
| 24 |
+
pytest>=8.0
|
| 25 |
+
pytest-mock>=3.14
|
setup.sh
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
cd "$(dirname "$0")"
|
| 4 |
+
|
| 5 |
+
if [ ! -d .venv ]; then
|
| 6 |
+
python3.11 -m venv .venv
|
| 7 |
+
fi
|
| 8 |
+
# shellcheck source=/dev/null
|
| 9 |
+
source .venv/bin/activate
|
| 10 |
+
python -m pip install -U pip
|
| 11 |
+
python -m pip install -r requirements.txt
|
| 12 |
+
echo "Done. Activate with: source .venv/bin/activate"
|
tests/__init__.py
ADDED
|
File without changes
|
tests/conftest.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
|
| 4 |
+
# Make top-level modules importable in tests
|
| 5 |
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
tests/test_scaffold.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
import re
|
| 3 |
+
|
| 4 |
+
REPO = Path(__file__).resolve().parents[1]
|
| 5 |
+
|
| 6 |
+
def test_required_files_exist():
|
| 7 |
+
for rel in [
|
| 8 |
+
"pyproject.toml", "requirements.txt", "setup.sh",
|
| 9 |
+
"LICENSE", "CLAUDE.md", "README.md", ".gitignore",
|
| 10 |
+
"tests/__init__.py", "tests/conftest.py",
|
| 11 |
+
]:
|
| 12 |
+
assert (REPO / rel).exists(), f"missing {rel}"
|
| 13 |
+
|
| 14 |
+
def test_pyproject_targets_py311():
|
| 15 |
+
text = (REPO / "pyproject.toml").read_text()
|
| 16 |
+
assert "python = " not in text # not poetry
|
| 17 |
+
assert "py311" in text # ruff target-version
|
| 18 |
+
|
| 19 |
+
def test_requirements_has_core_deps():
|
| 20 |
+
text = (REPO / "requirements.txt").read_text().lower()
|
| 21 |
+
for dep in ["diffsynth-studio", "gradio", "spaces", "controlnet-aux", "torch", "safetensors", "ruff", "pytest"]:
|
| 22 |
+
assert dep in text, f"missing dep: {dep}"
|
| 23 |
+
|
| 24 |
+
def test_license_is_mit():
|
| 25 |
+
text = (REPO / "LICENSE").read_text()
|
| 26 |
+
assert "MIT License" in text
|
| 27 |
+
assert "Mayank Gupta" in text
|