diff --git a/CLAUDE.md b/CLAUDE.md index c421192..4a52540 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,44 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -`tensors` is a Python CLI tool (`tsr`) for reading safetensor file metadata and interacting with the CivitAI API (search, fetch, download models). Built with Typer, Rich, and httpx. +`tensors` is a Python CLI + FastAPI server for: +- Reading safetensor file metadata +- Searching CivitAI and HuggingFace models +- Managing a local model database (SQLModel ORM) +- Image gallery management +- Model downloads with resume support + +Built with: Typer, Rich, FastAPI, httpx, SQLModel. + +## Deployment + +### Production (junkpile server) + +| Service | Port | URL | Status | +|---------|------|-----|--------| +| tensors API | 51200 | https://tensors-api.saiden.dev | `systemctl status tensors` | +| ComfyUI | 8188 | internal only | `systemctl status comfyui` | + +**Note:** ComfyUI runs separately - no integration with tensors yet. + +```bash +# Deploy to junkpile +/deploy # or: ssh junkpile "cd /opt/tensors && git pull && pip install -e '.[server]' && systemctl restart tensors" + +# Check status +curl https://tensors-api.saiden.dev/status +ssh junkpile "systemctl status tensors" +ssh junkpile "journalctl -u tensors -f" # logs +``` + +### TypeScript Client + +Package: `@saiden/tensors` (GitHub: saiden-dev/tensors-typescript) + +```bash +# Regenerate client after API changes +ruby ~/.claude/scripts/commands/tensors/generate_client.rb +``` ## Commands @@ -21,29 +58,88 @@ just test # pytest with coverage just fix # auto-fix lint + format just types # mypy only +# Run server locally +uv run tsr serve --port 8000 + # Run a single test uv run pytest tests/test_tensors.py::TestClassName::test_name -v ``` ## Architecture -Five modules with clean separation: +### CLI (`tsr`) -- **`cli.py`** — Typer CLI with commands: `info`, `search`, `get`, `dl`, `config`. Legacy mode auto-converts bare `tsr file.safetensors` to `tsr info`. -- **`api.py`** — CivitAI REST API wrapper using httpx. Search, fetch model/version/by-hash, download with resume support and Rich progress bars. -- **`config.py`** — XDG-compliant paths (`~/.config/tensors/config.toml`, `~/.local/share/tensors/`). Enums with `to_api()` methods for CivitAI parameter mapping. API key resolution: env var → config file → legacy `~/.sftrc`. -- **`safetensor.py`** — Binary safetensor header parsing (8-byte u64 LE header size → JSON metadata). SHA256 streaming hash computation. -- **`display.py`** — Rich table formatting for all output types. All major commands support `--json` output. +Entry point: `tsr = "tensors:main"` (pyproject.toml) -Entry point: `tsr = "tensors:main"` (pyproject.toml `[project.scripts]`). +Commands: `info`, `search`, `get`, `dl`, `config`, `serve` + +### Modules + +| Module | Purpose | +|--------|---------| +| `cli.py` | Typer CLI commands | +| `api.py` | CivitAI REST API wrapper (httpx) | +| `hf.py` | HuggingFace Hub integration | +| `config.py` | XDG paths, enums, API key resolution | +| `safetensor.py` | Binary header parsing, SHA256 | +| `display.py` | Rich table formatting | +| `models.py` | SQLModel ORM (17 tables) | +| `db.py` | Database operations | + +### Server (`/api/*`) + +| Endpoint | Description | +|----------|-------------| +| `/api/search` | Unified CivitAI + HuggingFace search | +| `/api/civitai/model/{id}` | CivitAI model info | +| `/api/db/*` | Local database CRUD | +| `/api/images/*` | Gallery management | +| `/api/download/*` | Model downloads | + +Auth: `X-API-Key` header (configured via `TENSORS_API_KEY` env var) + +### Database + +SQLite with SQLModel ORM. Tables: +- Local files: `local_files`, `safetensor_metadata` +- CivitAI cache: `models`, `model_versions`, `creators`, `tags`, `version_files`, `file_hashes`, `trained_words`, `version_images`, `image_generation_params`, `image_resources` +- HuggingFace cache: `hf_models`, `hf_model_tags`, `hf_safetensor_files` ## Code Standards - Python 3.12+, strict mypy, line length 130 - Ruff with extended rule set (E, W, F, I, B, C4, UP, ARG, SIM, TCH, PTH, PL, RUF) - PLR0913 (too many arguments) is intentionally ignored for CLI commands -- Tests use respx for HTTP mocking and a `temp_safetensor` fixture from conftest.py +- Tests use respx for HTTP mocking and pytest fixtures from conftest.py + +## Testing + +```bash +# Full test suite +just test + +# Specific test file +uv run pytest tests/test_db.py -v + +# Test with coverage +uv run pytest --cov=tensors --cov-report=term-missing + +# Test API endpoints locally +uv run tsr serve --port 8000 & +curl http://localhost:8000/status +curl -H "X-API-Key: test" http://localhost:8000/api/db/stats +``` ## Release -Tags trigger PyPI publish: `git tag v0.1.x && git push origin v0.1.x`. See RELEASE.md for binary builds (Nuitka). +Tags trigger PyPI publish: `git tag v0.1.x && git push origin v0.1.x` + +## TODO: ComfyUI Integration + +ComfyUI is running on junkpile (port 8188) but NOT integrated with tensors. + +Needed: +- [ ] Add `/api/generate` endpoint that proxies to ComfyUI +- [ ] Workflow template management +- [ ] Queue job → poll for completion → return image +- [ ] Config: `[comfyui] url = "http://127.0.0.1:8188"`