chore: Setup code formatting and linting

- Add `.editorconfig` for editor consistency.
- Configure GitHub Actions workflow for linting (`.github/workflows/lint.yml`).
- Add pre-commit hooks for automated checks (`.pre-commit-config.yaml`).
- Configure Prettier and exclusions (`.prettierrc.yaml`, `.prettierignore`).
- Update VS Code extensions to include formatting tools (`.vscode/extensions.json`).
- Adjust VS Code settings for auto-formatting (`.vscode/settings.json`).
This commit is contained in:
Aditya Bavadekar
2025-10-21 21:27:53 +05:30
committed by James Murdza
parent 93e64cb58c
commit e04bfaea5e
12 changed files with 1659 additions and 525 deletions

12
.editorconfig Normal file
View File

@@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = lf
insert_final_newline = false
trim_trailing_whitespace = true
[*.{js,ts,jsx,tsx,json,css,scss,html,md}]
indent_size = 2

40
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Lint & Format Check
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
lint:
name: Lint & Format
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 20
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- run: pip install uv
- run: uv sync
# Python checks (isort, black, ruff, mypy)
- run: uv run isort --check-only .
- run: uv run black --check .
- run: uv run ruff check --ignore E501,E402 .
- run: uv run mypy .
# JS/TS/Markdown/YAML checks
- run: uv run prettier --check "**/*.{ts,tsx,js,jsx,json,md,yaml,yml}"

43
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,43 @@
repos:
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0
hooks:
- id: prettier
name: Prettier (TS/JS/JSON/Markdown/YAML)
entry: prettier --write
language: node
files: \.(ts|tsx|js|jsx|json|md|yaml|yml)$
- repo: https://github.com/PyCQA/isort
rev: 7.0.0
hooks:
- id: isort
name: isort code formatter
language_version: python3.11
args: ['--profile', 'black']
files: \.(py)$
- repo: https://github.com/psf/black
rev: 25.9.0
hooks:
- id: black
name: Black code formatter
language_version: python3.11
files: \.(py)$
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.14.1
hooks:
- id: ruff
name: ruff linter
language_version: python3.11
args: ['--fix', '--ignore', 'E501,E402'] # Ignore line length and module level import not at top of file
files: \.(py)$
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
- id: mypy
name: mypy type checker
language_version: python3.11
files: \.(py)$

29
.prettierignore Normal file
View File

@@ -0,0 +1,29 @@
# Node / JS
node_modules/
dist/
build/
out/
*.min.js
# Python
__pycache__/
*.pyc
*.pyo
*.pyd
.venv/
venv/
.env
.env.local
# Logs
*.log
*.tmp
# VSCode / editor files
.vscode/
.idea/
# Other generated files
*.lock
*.db
*.sqlite

7
.prettierrc.yaml Normal file
View File

@@ -0,0 +1,7 @@
semi: true
singleQuote: true
trailingComma: none
tabWidth: 2
printWidth: 100
arrowParens: always
bracketSpacing: true

10
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"charliermarsh.ruff",
"ms-python.black-formatter",
"ms-python.mypy-type-checker",
"ms-python.vscode-pylance",
"ms-python.isort"
]
}

25
.vscode/settings.json vendored
View File

@@ -1,4 +1,25 @@
{
"python-envs.pythonProjects": [],
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
"python-envs.pythonProjects": [],
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit",
"source.fixAll": "explicit"
},
"extensions.ignoreRecommendations": false,
"python.formatting.provider": "black",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
},
"[javascript][typescript][typescriptreact][javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"ruff.configuration": "${workspaceFolder}/pyproject.toml",
"mypy-type-checker.args": [
"--config-file",
"${workspaceFolder}/pyproject.toml"
],
"mypy-type-checker.path": [
"${workspaceFolder}"
]
}

View File

@@ -6,7 +6,9 @@
"main": "index.js",
"scripts": {
"dev": "tsx watch src/index.ts",
"start": "tsx src/index.ts"
"start": "tsx src/index.ts",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"keywords": [],
"author": "",
@@ -22,4 +24,4 @@
"tsx": "^4.20.3",
"typescript": "^5.8.3"
}
}
}

View File

@@ -14,11 +14,14 @@
"test:core": "pnpm --filter @trycua/core test",
"test:computer": "pnpm --filter @trycua/computer test",
"test": "pnpm -r test",
"typecheck": "pnpm -r typecheck"
"typecheck": "pnpm -r typecheck",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"packageManager": "pnpm@10.12.3",
"devDependencies": {
"@biomejs/biome": "^1.9.4"
"@biomejs/biome": "^1.9.4",
"prettier": "^3.6.2"
},
"pnpm": {
"onlyBuiltDependencies": [
@@ -29,4 +32,4 @@
"unrs-resolver"
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,8 @@ dev = [
"ruff>=0.9.2",
"types-requests>=2.31.0",
"hud-python[agent]==0.4.52",
"pre-commit>=4.3.0",
"isort>=7.0.0",
]
docs = [
"mkdocs-material>=9.2.0",
@@ -89,7 +91,10 @@ strict = true
warn_return_any = true
warn_unused_ignores = false
[tool.isort]
profile = "black"
[tool.pytest.ini_options]
asyncio_mode = "auto"
python_files = "test_*.py"
testpaths = ["libs/*/tests"]
testpaths = ["libs/*/tests"]

111
uv.lock generated
View File

@@ -618,6 +618,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
]
[[package]]
name = "cfgv"
version = "3.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.4"
@@ -1154,6 +1163,7 @@ dev = [
{ name = "jedi" },
{ name = "jupyter" },
{ name = "mypy" },
{ name = "pre-commit" },
{ name = "ruff" },
{ name = "types-requests" },
]
@@ -1190,6 +1200,7 @@ dev = [
{ name = "jedi", specifier = ">=0.19.2" },
{ name = "jupyter", specifier = ">=1.0.0" },
{ name = "mypy", specifier = ">=1.10.0" },
{ name = "pre-commit", specifier = ">=4.3.0" },
{ name = "ruff", specifier = ">=0.9.2" },
{ name = "types-requests", specifier = ">=2.31.0" },
]
@@ -1300,6 +1311,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" },
]
[[package]]
name = "distlib"
version = "0.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" },
]
[[package]]
name = "distro"
version = "1.9.0"
@@ -2013,6 +2033,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/31/a0/651f93d154cb72323358bf2bbae3e642bdb5d2f1bfc874d096f7cb159fa0/huggingface_hub-0.35.3-py3-none-any.whl", hash = "sha256:0e3a01829c19d86d03793e4577816fe3bdfc1602ac62c7fb220d593d351224ba", size = 564262, upload-time = "2025-09-29T14:29:55.813Z" },
]
[[package]]
name = "identify"
version = "2.6.15"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" },
]
[[package]]
name = "idna"
version = "3.11"
@@ -3178,12 +3207,12 @@ name = "mlx-lm"
version = "0.28.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jinja2" },
{ name = "jinja2", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "mlx", marker = "sys_platform == 'darwin'" },
{ name = "numpy" },
{ name = "protobuf" },
{ name = "pyyaml" },
{ name = "transformers" },
{ name = "numpy", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "protobuf", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "pyyaml", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "transformers", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/51/f6/15e002d52c28d8c544ec3aaf9053677468333e6ef0e76ea68579fd77b76d/mlx_lm-0.28.3.tar.gz", hash = "sha256:75df2b925d343ebaf50b63008dede4fe98cd3b02b1b24b7da71ebeb198d674f0", size = 214455, upload-time = "2025-10-17T21:44:33.921Z" }
wheels = [
@@ -3205,19 +3234,19 @@ name = "mlx-vlm"
version = "0.3.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "datasets" },
{ name = "fastapi" },
{ name = "mlx" },
{ name = "mlx-lm" },
{ name = "numpy" },
{ name = "opencv-python" },
{ name = "pillow" },
{ name = "requests" },
{ name = "scipy" },
{ name = "soundfile" },
{ name = "tqdm" },
{ name = "transformers" },
{ name = "uvicorn" },
{ name = "datasets", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "fastapi", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "mlx", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "mlx-lm", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "numpy", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "opencv-python", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "pillow", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "requests", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "scipy", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "soundfile", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "tqdm", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "transformers", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "uvicorn", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ff/9f/de419334820da334203de28eaf861b57ae0d06b0882770e5e5d0671dc5dd/mlx_vlm-0.3.3.tar.gz", hash = "sha256:5a08c802d1bf32cc47bd6aebe348d3554ce21bfce417a585bba83f9d213a6e66", size = 231935, upload-time = "2025-08-20T14:52:51.323Z" }
wheels = [
@@ -3623,7 +3652,7 @@ name = "nvidia-cudnn-cu12"
version = "9.10.2.21"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-cublas-cu12" },
{ name = "nvidia-cublas-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" },
@@ -3634,7 +3663,7 @@ name = "nvidia-cufft-cu12"
version = "11.3.3.83"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-nvjitlink-cu12" },
{ name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" },
@@ -3661,9 +3690,9 @@ name = "nvidia-cusolver-cu12"
version = "11.7.3.90"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-cublas-cu12" },
{ name = "nvidia-cusparse-cu12" },
{ name = "nvidia-nvjitlink-cu12" },
{ name = "nvidia-cublas-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
{ name = "nvidia-cusparse-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
{ name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" },
@@ -3674,7 +3703,7 @@ name = "nvidia-cusparse-cu12"
version = "12.5.8.93"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-nvjitlink-cu12" },
{ name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" },
@@ -4276,6 +4305,22 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/ce/5e5ede2f0b24db113544f9f7ce08d395a4107cbc66d77b8d05d9eaeaeada/posthog-6.7.8-py3-none-any.whl", hash = "sha256:842ccb518f925425f714bae29e4ac36a059a8948c45f6ed155543ca7386d554b", size = 137299, upload-time = "2025-10-16T14:46:51.547Z" },
]
[[package]]
name = "pre-commit"
version = "4.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cfgv" },
{ name = "identify" },
{ name = "nodeenv" },
{ name = "pyyaml" },
{ name = "virtualenv" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" },
]
[[package]]
name = "prometheus-client"
version = "0.23.1"
@@ -5591,8 +5636,8 @@ name = "soundfile"
version = "0.13.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi" },
{ name = "numpy" },
{ name = "cffi", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
{ name = "numpy", marker = "(python_full_version < '3.13' and sys_platform != 'win32') or sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e1/41/9b873a8c055582859b239be17902a85339bec6a30ad162f98c9b0288a2cc/soundfile-0.13.1.tar.gz", hash = "sha256:b2c68dab1e30297317080a5b43df57e302584c49e2942defdde0acccc53f0e5b", size = 46156, upload-time = "2025-01-25T09:17:04.831Z" }
wheels = [
@@ -6220,6 +6265,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" },
]
[[package]]
name = "virtualenv"
version = "20.35.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "distlib" },
{ name = "filelock" },
{ name = "platformdirs" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a4/d5/b0ccd381d55c8f45d46f77df6ae59fbc23d19e901e2d523395598e5f4c93/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44", size = 6002907, upload-time = "2025-10-10T21:23:33.178Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/27/73/d9a94da0e9d470a543c1b9d3ccbceb0f59455983088e727b8a1824ed90fb/virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a", size = 5981061, upload-time = "2025-10-10T21:23:30.433Z" },
]
[[package]]
name = "watchdog"
version = "6.0.0"