build: configure Python development environment

This commit is contained in:
2026-07-30 16:45:36 +02:00
parent e6eb99556a
commit fa90a5c5de
9 changed files with 129 additions and 21 deletions
+1
View File
@@ -0,0 +1 @@
3.12
+2
View File
@@ -19,6 +19,8 @@ Alle wesentlichen Projektänderungen werden hier in verständlicher Form dokumen
- Tokenbewusste Arbeitsweise als dauerhafte Regel ergänzt; Qualität und Sicherheit bleiben vorrangig. - Tokenbewusste Arbeitsweise als dauerhafte Regel ergänzt; Qualität und Sicherheit bleiben vorrangig.
- Laufende Handoff-Aktualisierung nach jedem abgeschlossenen logischen Arbeitspaket festgelegt. - Laufende Handoff-Aktualisierung nach jedem abgeschlossenen logischen Arbeitspaket festgelegt.
- Vollständigen Erst-Handoff einmalig archiviert und die laufende Übergabe auf einen kompakten aktuellen Stand umgestellt. - Vollständigen Erst-Handoff einmalig archiviert und die laufende Übergabe auf einen kompakten aktuellen Stand umgestellt.
- Isolierte Python-3.12-Entwicklungsumgebung mit uv-Lockfile und Ruff vorbereitet.
- Offizielle VS-Code-Erweiterungen für Python, Pylance und Python Environments eingerichtet.
### Security ### Security
+20 -11
View File
@@ -50,7 +50,10 @@ Rootserver:
- Konfigurationsbeispiel, Sicherheitsdokumente, ADRs und Strukturtest sind vorhanden. - Konfigurationsbeispiel, Sicherheitsdokumente, ADRs und Strukturtest sind vorhanden.
- Living-Mind-Verzeichnis ist ausschließlich ein inaktiver Vertrag ohne Frontend oder Fantasiedaten. - Living-Mind-Verzeichnis ist ausschließlich ein inaktiver Vertrag ohne Frontend oder Fantasiedaten.
- Projektbezogene Codex-Rollen Scout, Architect, Builder, Verifier und Security Reviewer sind konfiguriert; maximal zwei Unteragenten, nur Builder schreibend. - Projektbezogene Codex-Rollen Scout, Architect, Builder, Verifier und Security Reviewer sind konfiguriert; maximal zwei Unteragenten, nur Builder schreibend.
- Im normalen Windows-`PATH` sind Git und VS Code verfügbar. Eine Projektinstallation von Python, `uv`, Ruff, Ollama oder llama.cpp ist noch nicht bestätigt. - Toolchain eingerichtet: uv 0.11.32 und CPython 3.12.13 isoliert unter `D:\Javis-Tools`; Ruff 0.16.0 in der lokalen `.venv`.
- Offizielle VS-Code-Erweiterungen installiert: Python 2026.4.0, Pylance 2026.3.1, Python Environments 1.36.0 und Debugpy 2026.6.0.
- Windows-PATH und vorhandene Python-Installationen wurden nicht verändert.
- Ollama oder llama.cpp sind noch nicht installiert.
- Kein Obsidian-, Laptop- oder Rootserverzugriff wurde implementiert. - Kein Obsidian-, Laptop- oder Rootserverzugriff wurde implementiert.
- Keine KI-, Sprach-, Mobil- oder Statusfunktion ist implementiert. - Keine KI-, Sprach-, Mobil- oder Statusfunktion ist implementiert.
@@ -77,6 +80,9 @@ Rootserver:
- Tokenbewusster Arbeitsablauf festgelegt: gezielte Reads, kurze Ergebnisse, keine unnötigen Agenten oder Plugins. - Tokenbewusster Arbeitsablauf festgelegt: gezielte Reads, kurze Ergebnisse, keine unnötigen Agenten oder Plugins.
- Werkzeugempfehlung auf `uv`, Microsoft Python/Pylance/Python Environments und Ruff begrenzt. - Werkzeugempfehlung auf `uv`, Microsoft Python/Pylance/Python Environments und Ruff begrenzt.
- Langer Handoff einmalig unverändert archiviert und durch diese kompakte aktuelle Zusammenfassung ersetzt. - Langer Handoff einmalig unverändert archiviert und durch diese kompakte aktuelle Zusammenfassung ersetzt.
- Handoff-Verdichtung als Commit `e6eb995` nach `origin/main` gepusht.
- Branch `feat/core-chat` von diesem Stand erstellt.
- uv, CPython 3.12, lokale `.venv`, Ruff, Lockfile und offizielle VS-Code-Python-Erweiterungen eingerichtet.
- Obsidian, Ubuntu-Laptop und Rootserver blieben unverändert. - Obsidian, Ubuntu-Laptop und Rootserver blieben unverändert.
## Aktuelle Tests ## Aktuelle Tests
@@ -89,15 +95,20 @@ Letzter bestätigter Grundgerüststand:
- UTF-8- und interne Markdown-Linkprüfung: bestanden - UTF-8- und interne Markdown-Linkprüfung: bestanden
- Secret-Musterprüfung: keine Treffer - Secret-Musterprüfung: keine Treffer
- Gitignore-Prüfung für lokale Secret-Dateien: bestanden - Gitignore-Prüfung für lokale Secret-Dateien: bestanden
- uv-Lock und `uv sync --dev`: bestanden
- Python in `.venv`: 3.12.13
- Ruff in `.venv`: 0.16.0
Für den Textchat existieren noch keine Funktions- oder Modell-Smoke-Tests. Für den Textchat existieren noch keine Funktions- oder Modell-Smoke-Tests.
## Git-Stand ## Git-Stand
- aktueller Branch: `feat/core-chat`
- stabiler Branch: `main` - stabiler Branch: `main`
- Grundgerüstcommit: `6d04171` - Grundgerüstcommit: `6d04171`
- letzter Commit vor der Handoff-Verdichtung: `0e82748` - letzter Commit vor der Handoff-Verdichtung: `0e82748`
- der Commit mit dieser Verdichtung ist über `git log -1 --oneline` zu bestimmen - Handoff-Verdichtung auf `main`: `e6eb995`
- aktueller Feature-Commit ist über `git log -1 --oneline` zu bestimmen
- `origin` verwendet HTTPS - `origin` verwendet HTTPS
- kein Force-Push und keine umgeschriebene Historie - kein Force-Push und keine umgeschriebene Historie
@@ -106,12 +117,12 @@ Für den Textchat existieren noch keine Funktions- oder Modell-Smoke-Tests.
- `49a1dd3`: erster Gitea-Verbindungstest - `49a1dd3`: erster Gitea-Verbindungstest
- `6d04171`: sicheres Javis-Grundgerüst - `6d04171`: sicheres Javis-Grundgerüst
- `0e82748`: Werkzeug-, Token- und Handoff-Regeln - `0e82748`: Werkzeug-, Token- und Handoff-Regeln
- aktuell: einmalige Archivierung und Verdichtung des Handoffs - `e6eb995`: einmalige Archivierung und Verdichtung des Handoffs
- aktuell: isolierte Python-Toolchain und reproduzierbare Entwicklungsumgebung
## Offene Entscheidungen und Fehler ## Offene Entscheidungen und Fehler
- endgültiger Produkt-/Repositoryname bleibt offen - endgültiger Produkt-/Repositoryname bleibt offen
- konkrete Python-Version und Installation sind noch festzulegen
- lokale Modelllaufzeit und erstes Modell sind noch nicht installiert oder benchmarked - lokale Modelllaufzeit und erstes Modell sind noch nicht installiert oder benchmarked
- genauer späterer Obsidian-Schreibbereich ist nicht freigegeben - genauer späterer Obsidian-Schreibbereich ist nicht freigegeben
- endgültiger Secret-Provider ist offen; lokale Klartext-XML wäre nur restriktiv geschützt und Git-ignoriert zulässig - endgültiger Secret-Provider ist offen; lokale Klartext-XML wäre nur restriktiv geschützt und Git-ignoriert zulässig
@@ -132,12 +143,10 @@ Für den Textchat existieren noch keine Funktions- oder Modell-Smoke-Tests.
Der genehmigte nächste Meilenstein ist `feat/core-chat`: Der genehmigte nächste Meilenstein ist `feat/core-chat`:
1. von sauberem `main` einen Feature-Branch erstellen 1. Ollama als einfachere Windows-Laufzeit installieren; llama.cpp bleibt dokumentierte Alternative
2. minimale Python-Toolchain mit `uv`, lokaler `.venv`, Ruff und offiziellen VS-Code-Erweiterungen einrichten 2. genau `qwen3:8b` (`Q4_K_M`, 5,2 GB, Apache-2.0) herunterladen und auf der RTX 3060 messen
3. Ollama und llama.cpp anhand aktueller offizieller Quellen vergleichen und nur eine Laufzeit installieren 3. echten lokalen CLI-Chat mit Provider-Schnittstelle und SQLite-Sitzungen implementieren
4. genau ein frei lokal nutzbares Modell unter ungefähr 10 GB herunterladen und auf der RTX 3060 messen 4. Unit-, Ruff-, Persistenz-, Secret- und echten Modell-Smoke-Test ausführen
5. echten lokalen CLI-Chat mit Provider-Schnittstelle und SQLite-Sitzungen implementieren 5. nur bei vollständig erfüllter Abnahme nach `main` mergen
6. Unit-, Ruff-, Persistenz-, Secret- und echten Modell-Smoke-Test ausführen
7. nur bei vollständig erfüllter Abnahme nach `main` mergen
Nicht Teil dieses Meilensteins: Obsidian-Integration, Serverzugriff, Sprache, Mobile Client oder Living-Mind-Code. Nicht Teil dieses Meilensteins: Obsidian-Integration, Serverzugriff, Sprache, Mobile Client oder Living-Mind-Code.
+38
View File
@@ -0,0 +1,38 @@
# Entwicklungsumgebung
Stand: 30.07.2026, Branch `feat/core-chat`.
## Installierte Werkzeuge
| Werkzeug | Version | Speicherort |
|---|---:|---|
| uv | 0.11.32 | `D:\Javis-Tools\uv` |
| CPython | 3.12.13 | `D:\Javis-Tools\python` |
| Ruff | 0.16.0 | lokale Projektumgebung `.venv` |
| VS Code Python | 2026.4.0 | Benutzerprofil von VS Code |
| VS Code Pylance | 2026.3.1 | Benutzerprofil von VS Code |
| VS Code Python Environments | 1.36.0 | Benutzerprofil von VS Code |
| VS Code Debugpy | 2026.6.0 | Abhängigkeit der Python-Erweiterung |
`uv` und Python wurden isoliert auf `D:` installiert. Eine vorhandene Python-Version wurde nicht ersetzt und der Windows-Benutzer- oder System-`PATH` wurde nicht verändert.
## Projektumgebung
- gewünschte Python-Linie: `3.12`, festgehalten in `.python-version`
- lokale Umgebung: `.venv`, durch Git ignoriert
- Abhängigkeiten: `pyproject.toml`
- reproduzierbare Auflösung: `uv.lock`
- einzige Entwicklungsabhängigkeit in dieser Phase: Ruff
Typische Befehle aus dem Repository:
```powershell
$env:UV_PYTHON_INSTALL_DIR = 'D:\Javis-Tools\python'
$env:UV_CACHE_DIR = 'D:\Javis-Tools\uv-cache'
& 'D:\Javis-Tools\uv\uv.exe' sync --dev
& 'D:\Javis-Tools\uv\uv.exe' run javis chat
& 'D:\Javis-Tools\uv\uv.exe' run ruff check .
& 'D:\Javis-Tools\uv\uv.exe' run ruff format --check .
```
Die absoluten Pfade sind ausschließlich lokale Entwicklungsdokumentation. Der Anwendungscode darf keine festen Windows-Pfade enthalten.
+1 -3
View File
@@ -2,7 +2,7 @@
## Ziel ## Ziel
Phase 1 auf `feat/core-chat`: minimale Python-Toolchain, genau eine lokale Modelllaufzeit und ein echter lokaler CLI-Textchat mit SQLite-Sitzungen. Nächstes Arbeitspaket auf `feat/core-chat`: genau eine lokale Modelllaufzeit und ein echter lokaler CLI-Textchat mit SQLite-Sitzungen.
## Vor Änderungen erneut prüfen ## Vor Änderungen erneut prüfen
@@ -13,8 +13,6 @@ Phase 1 auf `feat/core-chat`: minimale Python-Toolchain, genau eine lokale Model
## Vorgeschlagener Umfang ## Vorgeschlagener Umfang
- `uv`, unterstützte stabile Python-Version und offizielle VS-Code-Erweiterungen einrichten
- Microsoft Python/Pylance/Python Environments sowie Ruff als minimale Entwicklungswerkzeuge prüfen
- Ollama und llama.cpp offiziell vergleichen; nur eine Laufzeit und ein Modell unter ungefähr 10 GB installieren - Ollama und llama.cpp offiziell vergleichen; nur eine Laufzeit und ein Modell unter ungefähr 10 GB installieren
- lokale Konfiguration, Provider-Schnittstelle und SQLite-Sitzungen implementieren - lokale Konfiguration, Provider-Schnittstelle und SQLite-Sitzungen implementieren
- CLI mit neuen, gelisteten und fortsetzbaren Sitzungen - CLI mit neuen, gelisteten und fortsetzbaren Sitzungen
+8 -4
View File
@@ -1,6 +1,6 @@
# Projektstatus # Projektstatus
Stand: Dokumentationsverdichtung vor `feat/core-chat`, 30.07.2026. Stand: Toolchain-Arbeitspaket auf `feat/core-chat`, 30.07.2026.
## Erreicht ## Erreicht
@@ -12,6 +12,9 @@ Stand: Dokumentationsverdichtung vor `feat/core-chat`, 30.07.2026.
- projektinterne Codex-Agentensyntax anhand der aktuellen offiziellen Codex-Dokumentation geprüft - projektinterne Codex-Agentensyntax anhand der aktuellen offiziellen Codex-Dokumentation geprüft
- phasenbezogene Werkzeug- und Plugin-Empfehlungen sowie tokenbewusste Arbeitsregeln dokumentiert - phasenbezogene Werkzeug- und Plugin-Empfehlungen sowie tokenbewusste Arbeitsregeln dokumentiert
- vollständigen Erst-Handoff archiviert und kompakte laufende Übergabe eingeführt - vollständigen Erst-Handoff archiviert und kompakte laufende Übergabe eingeführt
- uv 0.11.32 und CPython 3.12.13 isoliert unter `D:\Javis-Tools` installiert
- lokale `.venv`, reproduzierbares `uv.lock` und Ruff 0.16.0 eingerichtet
- offizielle VS-Code-Erweiterungen Python, Pylance und Python Environments installiert
## Nicht implementiert ## Nicht implementiert
@@ -19,10 +22,11 @@ KI, Chat, Provider, Gedächtnis, Obsidian-Adapter, Tools, Serverzugriff, Sprache
## Git ## Git
- Branch: `main` - Branch: `feat/core-chat`
- Grundgerüstcommit: `6d04171` - Grundgerüstcommit: `6d04171`
- Der aktuelle Dokumentationscommit ist mit `git log -1` zu ermitteln. - Basis des Feature-Branches: `e6eb995`
- Der aktuelle Feature-Commit ist mit `git log -1` zu ermitteln.
## Bekannte Einschränkung ## Bekannte Einschränkung
Im normalen Windows-`PATH` sind Python, `uv`, Ruff und eine lokale Modelllaufzeit noch nicht bestätigt. Der Textchat ist noch nicht implementiert. Die Toolchain ist nutzbar, ohne den Windows-`PATH` zu verändern. Eine lokale Modelllaufzeit und der Textchat sind noch nicht implementiert.
+15
View File
@@ -10,8 +10,23 @@ readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
dependencies = [] dependencies = []
[project.scripts]
javis = "javis.interface.cli:main"
[dependency-groups]
dev = [
"ruff>=0.12,<1",
]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where = ["src"] where = ["src"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
testpaths = ["tests"] testpaths = ["tests"]
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["B", "E", "F", "I", "UP"]
+1 -3
View File
@@ -6,7 +6,6 @@ import sys
import tomllib import tomllib
from pathlib import Path from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
REQUIRED = ( REQUIRED = (
"README.md", "README.md",
@@ -46,8 +45,7 @@ def main() -> int:
forbidden = [ forbidden = [
path path
for path in ROOT.rglob("*") for path in ROOT.rglob("*")
if path.is_file() if path.is_file() and path.name.lower() in {"key-pw.xml", "secrets.local.xml", ".env"}
and path.name.lower() in {"key-pw.xml", "secrets.local.xml", ".env"}
] ]
if forbidden: if forbidden:
print("Forbidden local secret files are present:") print("Forbidden local secret files are present:")
Generated
+43
View File
@@ -0,0 +1,43 @@
version = 1
revision = 3
requires-python = ">=3.11"
[[package]]
name = "javis-ai"
version = "0.0.0"
source = { editable = "." }
[package.dev-dependencies]
dev = [
{ name = "ruff" },
]
[package.metadata]
[package.metadata.requires-dev]
dev = [{ name = "ruff", specifier = ">=0.12,<1" }]
[[package]]
name = "ruff"
version = "0.16.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" },
{ url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" },
{ url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" },
{ url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" },
{ url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" },
{ url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" },
{ url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" },
{ url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" },
{ url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" },
{ url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" },
{ url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" },
{ url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" },
{ url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" },
{ url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" },
{ url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" },
{ url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" },
{ url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" },
]