diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..969ba1e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI + +on: + push: + branches: [master, main] + pull_request: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + + - name: Sync workspace + run: uv sync --group dev + + - name: Ruff + run: uv run ruff check . + + - name: Typecheck + run: uv run ty check + + - name: Pytest + run: uv run pytest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c037cb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Python +__pycache__/ +*.py[cod] +*.egg-info/ +.eggs/ +dist/ +build/ +.venv/ +venv/ + +# Tooling / coverage +.pytest_cache/ +.ruff_cache/ +.mypy_cache/ +.ty_cache/ +.coverage +htmlcov/ +.cache/ + +# Editors / OS +.DS_Store +.idea/ +.vscode/ +*.swp + +# Local agent scratch +.scratch/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..b478c41 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# pi-python + +Python implementation aligned with [earendil-works/pi](https://github.com/earendil-works/pi) semantics: thin LLM adapter, agent runtime, Textual TUI, and interactive coding CLI (`piy`). + +## Workspace + +```text +packages/ + pi_llm/ # Thin LiteLLM adapter + pi_agent/ # Agent loop + Agent SDK + pi_tui/ # Textual widgets/layouts + pi_coding_agent/ # Coding CLI (piy) wiring +``` + +## Develop + +```bash +# Optional: faster installs in CN (do not commit as default — CI uses public PyPI) +export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple + +uv sync --group dev +uv run pytest +uv run ruff check . +uv run ty check +``` + +## CLI + +```bash +uv run piy +``` diff --git a/packages/pi_agent/pyproject.toml b/packages/pi_agent/pyproject.toml new file mode 100644 index 0000000..ce3a878 --- /dev/null +++ b/packages/pi_agent/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "pi_agent" +version = "0.1.0" +description = "Agent loop and stateful Agent SDK for pi-python" +requires-python = ">=3.11" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/pi_agent"] diff --git a/packages/pi_agent/src/pi_agent/__init__.py b/packages/pi_agent/src/pi_agent/__init__.py new file mode 100644 index 0000000..1ff3895 --- /dev/null +++ b/packages/pi_agent/src/pi_agent/__init__.py @@ -0,0 +1,3 @@ +"""Agent runtime: pure loop + stateful Agent SDK.""" + +__all__: list[str] = [] diff --git a/packages/pi_coding_agent/pyproject.toml b/packages/pi_coding_agent/pyproject.toml new file mode 100644 index 0000000..b0c1d32 --- /dev/null +++ b/packages/pi_coding_agent/pyproject.toml @@ -0,0 +1,25 @@ +[project] +name = "pi_coding_agent" +version = "0.1.0" +description = "Interactive coding CLI (piy) for pi-python" +requires-python = ">=3.11" +dependencies = [ + "pi_llm", + "pi_agent", + "pi_tui", +] + +[project.scripts] +piy = "pi_coding_agent.cli:main" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/pi_coding_agent"] + +[tool.uv.sources] +pi_llm = { workspace = true } +pi_agent = { workspace = true } +pi_tui = { workspace = true } diff --git a/packages/pi_coding_agent/src/pi_coding_agent/__init__.py b/packages/pi_coding_agent/src/pi_coding_agent/__init__.py new file mode 100644 index 0000000..6a73651 --- /dev/null +++ b/packages/pi_coding_agent/src/pi_coding_agent/__init__.py @@ -0,0 +1,3 @@ +"""Interactive coding CLI package (piy).""" + +__all__: list[str] = [] diff --git a/packages/pi_coding_agent/src/pi_coding_agent/cli.py b/packages/pi_coding_agent/src/pi_coding_agent/cli.py new file mode 100644 index 0000000..475ef6f --- /dev/null +++ b/packages/pi_coding_agent/src/pi_coding_agent/cli.py @@ -0,0 +1,8 @@ +"""Console entrypoint for `piy`.""" + +from __future__ import annotations + + +def main() -> None: + """Stub entrypoint; interactive wiring lands in a later ticket.""" + raise SystemExit("piy: not implemented yet (scaffold stub)") diff --git a/packages/pi_llm/pyproject.toml b/packages/pi_llm/pyproject.toml new file mode 100644 index 0000000..5342d02 --- /dev/null +++ b/packages/pi_llm/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "pi_llm" +version = "0.1.0" +description = "Thin LiteLLM adapter for the pi-python agent runtime" +requires-python = ">=3.11" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/pi_llm"] diff --git a/packages/pi_llm/src/pi_llm/__init__.py b/packages/pi_llm/src/pi_llm/__init__.py new file mode 100644 index 0000000..52d9114 --- /dev/null +++ b/packages/pi_llm/src/pi_llm/__init__.py @@ -0,0 +1,3 @@ +"""Thin LLM adapter (LiteLLM-backed).""" + +__all__: list[str] = [] diff --git a/packages/pi_tui/pyproject.toml b/packages/pi_tui/pyproject.toml new file mode 100644 index 0000000..61a4916 --- /dev/null +++ b/packages/pi_tui/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "pi_tui" +version = "0.1.0" +description = "Textual widgets and layouts for the pi-python coding CLI" +requires-python = ">=3.11" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/pi_tui"] diff --git a/packages/pi_tui/src/pi_tui/__init__.py b/packages/pi_tui/src/pi_tui/__init__.py new file mode 100644 index 0000000..cf5e885 --- /dev/null +++ b/packages/pi_tui/src/pi_tui/__init__.py @@ -0,0 +1,3 @@ +"""Textual UI widgets and layouts.""" + +__all__: list[str] = [] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..65f5ef2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,48 @@ +[project] +name = "pi-python" +version = "0.1.0" +description = "Python implementation aligned with earendil-works/pi semantics" +readme = "README.md" +requires-python = ">=3.11" +dependencies = [ + "pi_llm", + "pi_agent", + "pi_tui", + "pi_coding_agent", +] + +[tool.uv.workspace] +members = [ + "packages/pi_llm", + "packages/pi_agent", + "packages/pi_tui", + "packages/pi_coding_agent", +] + +[tool.uv.sources] +pi_llm = { workspace = true } +pi_agent = { workspace = true } +pi_tui = { workspace = true } +pi_coding_agent = { workspace = true } + +[dependency-groups] +dev = [ + "pytest>=8.0", + "ruff>=0.9", + "ty>=0.0.1a16", +] + +[tool.pytest.ini_options] +testpaths = ["tests", "packages"] +pythonpath = ["."] + +[tool.ruff] +target-version = "py311" +line-length = 100 +src = ["packages", "tests"] + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "B"] + +[tool.ty.environment] +python-version = "3.11" diff --git a/tests/test_workspace_smoke.py b/tests/test_workspace_smoke.py new file mode 100644 index 0000000..4192673 --- /dev/null +++ b/tests/test_workspace_smoke.py @@ -0,0 +1,25 @@ +"""Smoke tests for the uv workspace scaffold (#19).""" + +from __future__ import annotations + +import importlib +import shutil +from importlib import metadata + + +def test_four_packages_are_importable() -> None: + for name in ("pi_llm", "pi_agent", "pi_tui", "pi_coding_agent"): + module = importlib.import_module(name) + assert module.__name__ == name + + +def test_piy_console_entrypoint_is_declared() -> None: + # Console script name must be `piy` (stub body is fine for scaffold). + eps = metadata.entry_points() + scripts = eps.select(group="console_scripts") + names = {ep.name for ep in scripts} + assert "piy" in names + + +def test_piy_executable_resolves_on_path() -> None: + assert shutil.which("piy") is not None diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..ceaae9e --- /dev/null +++ b/uv.lock @@ -0,0 +1,188 @@ +version = 1 +revision = 2 +requires-python = ">=3.11" + +[manifest] +members = [ + "pi-agent", + "pi-coding-agent", + "pi-llm", + "pi-python", + "pi-tui", +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pi-agent" +version = "0.1.0" +source = { editable = "packages/pi_agent" } + +[[package]] +name = "pi-coding-agent" +version = "0.1.0" +source = { editable = "packages/pi_coding_agent" } +dependencies = [ + { name = "pi-agent" }, + { name = "pi-llm" }, + { name = "pi-tui" }, +] + +[package.metadata] +requires-dist = [ + { name = "pi-agent", editable = "packages/pi_agent" }, + { name = "pi-llm", editable = "packages/pi_llm" }, + { name = "pi-tui", editable = "packages/pi_tui" }, +] + +[[package]] +name = "pi-llm" +version = "0.1.0" +source = { editable = "packages/pi_llm" } + +[[package]] +name = "pi-python" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pi-agent" }, + { name = "pi-coding-agent" }, + { name = "pi-llm" }, + { name = "pi-tui" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, + { name = "ruff" }, + { name = "ty" }, +] + +[package.metadata] +requires-dist = [ + { name = "pi-agent", editable = "packages/pi_agent" }, + { name = "pi-coding-agent", editable = "packages/pi_coding_agent" }, + { name = "pi-llm", editable = "packages/pi_llm" }, + { name = "pi-tui", editable = "packages/pi_tui" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pytest", specifier = ">=8.0" }, + { name = "ruff", specifier = ">=0.9" }, + { name = "ty", specifier = ">=0.0.1a16" }, +] + +[[package]] +name = "pi-tui" +version = "0.1.0" +source = { editable = "packages/pi_tui" } + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.22" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, +] + +[[package]] +name = "ty" +version = "0.0.61" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/63/6944925d0fe9a4bb9cc744e6c045a42bbd2ee4654c103190674577a36c3f/ty-0.0.61.tar.gz", hash = "sha256:acbf0d914cc7e2e57ccc440036af36114819e2a604a5ffb554e72e4ca7dd65a2", size = 6234957, upload-time = "2026-07-18T01:39:54.696Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/cf/044f31523e2768e3e64b0ca2ec32f70b3a731d4a2caa6ea110baf26e251c/ty-0.0.61-py3-none-linux_armv6l.whl", hash = "sha256:148779b8675eac93f40ec58bd70037fe67537117f20a23272264f8f136d41336", size = 11891448, upload-time = "2026-07-18T01:39:18.449Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/55/558cfe76b65d91d1854bbfac336020bd42fd887caa632d845d13c0c539eb/ty-0.0.61-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:08217382b3385808ee7288501ea3214b32631b08d1fd091ece6799b0c95264c5", size = 11602442, upload-time = "2026-07-18T01:39:20.914Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/be/78c0ae6634cd606a68e5b46b338db427a48a1800c96a749b2d2f7a702e03/ty-0.0.61-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d99c729011b47dec20e78a32ac9c8f6defd4cf62f7bb851bbccf70dde6cee50", size = 11125286, upload-time = "2026-07-18T01:39:22.893Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/18/a40793962f1b6337938ddb0bca7496b54e70879e23b4d2cc8dfd7e5d1af3/ty-0.0.61-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cda607978ae271b77e51c947663218bce635c3507e256865444b10c37cdb60d", size = 11663403, upload-time = "2026-07-18T01:39:25.017Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/c1/7879244da5b30407dc368946d36be5024380073408b079f144ffe034030e/ty-0.0.61-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d78f160a0f9434d570cdcdbc4dafba1f6aac3c47a32f9f63995b3cb55ffe4b6", size = 11715250, upload-time = "2026-07-18T01:39:27.045Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/c4/8a4637cd58abd37f315dd515e24c582986cb1bfdf2edc4786882f5a4f69a/ty-0.0.61-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09aeab4800b36e93e4ce918699004da642d74988cac920b7592a6a2b9be6611c", size = 12393876, upload-time = "2026-07-18T01:39:29.197Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/4b/27e7c640b1272743503229aa17ae2167a538040c4716a2fa1777c2b34fea/ty-0.0.61-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dccc8136df44142a109953a168be17b4915c99876b047d0b6672c31dae939bdf", size = 12958187, upload-time = "2026-07-18T01:39:31.308Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3a/f5/70eaaefb6081fb0a8115cff66fbfaa20dafac8c646df2477adad95a59de2/ty-0.0.61-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:220760c2d13a887d027ee1093172c24ac35b6e634805329c93a30908ae4d3f5c", size = 12560101, upload-time = "2026-07-18T01:39:33.35Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/5a/17bae3b6429b5c479dc6c1e344d34e1f79efbc27531f15f3ee5b5da63745/ty-0.0.61-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:effefbb89da7128d18059529d1c2ea390fe7f1f3882690d257ca2143d49a0c34", size = 12225389, upload-time = "2026-07-18T01:39:35.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/0e/2ac380ba20d6395542c8df1d6fa4f00e2aead784c2e6aaefa1e02ed0610c/ty-0.0.61-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:ba8b28a5ef811d5bb6461e37d76110c06fd20487474865c323d3d18b08b972b2", size = 12548403, upload-time = "2026-07-18T01:39:37.556Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/e5/7da4b73e825e1a9808c26d68b0156e9a37aede1846191210dfffb8c64042/ty-0.0.61-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:88ecd6d9b05e8174b1860dac9bd3e188d6cef5702b0d3239fd9f94f6ac73a29d", size = 11621813, upload-time = "2026-07-18T01:39:39.919Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9b/3c/5b58015e998cd0d89b17a463b6321421457d86d987574e8dac65ddfceba3/ty-0.0.61-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fb0cdfe4c48542ffb9a1139825dfa3d4aae49e96e966682ef7da762ab97831ff", size = 11734101, upload-time = "2026-07-18T01:39:42.097Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a6/21/294f4cc819b7b12ed659fd860e5cdfbd592d4c768c8f23596685dbc43e6b/ty-0.0.61-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dff03873c0c3d0b44738f8b6d403b0756a31cf54c65136397df7624c6159b1f0", size = 11988401, upload-time = "2026-07-18T01:39:44.183Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/26/0f96f79fdac118521a9771e9eef3f9b3f447d647b2c77953e80a1715c7e8/ty-0.0.61-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a9210e80e3d41c1dfc751e9e8e0980272f475031fafd0fb0f48aee233c78da03", size = 12330624, upload-time = "2026-07-18T01:39:46.662Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/08/1e62d1bca5c0cebdc7a34db1f4b61557aab85961cedd56953dd2c32d3e66/ty-0.0.61-py3-none-win32.whl", hash = "sha256:e3e1fe06f49a5492a922a5df2739834aa5ee978c7dd10414119dc8755cc40c9c", size = 11313991, upload-time = "2026-07-18T01:39:48.761Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/f1/d8e33b3aeb36b73d81ae34d10e46ec4abf506d68f4e0a1491a76a593dd42/ty-0.0.61-py3-none-win_amd64.whl", hash = "sha256:25f2291169e0298fcdbba1b1fea64f8207a6c1908dddef32346fd5e3e6ac9221", size = 12311717, upload-time = "2026-07-18T01:39:50.881Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/14/7caec26d93a943c0e7d15eb7374644508d08cbd387d112b722b12d14e044/ty-0.0.61-py3-none-win_arm64.whl", hash = "sha256:3e496f7698bc4b5bbb1eb66d8b5799ba87596d88d36604ca359083893fa2fc49", size = 11693485, upload-time = "2026-07-18T01:39:52.73Z" }, +]