[project] name = "mistral-vibe" version = "2.26.0" description = "Minimal CLI coding agent by Mistral" readme = "README.md" requires-python = ">=3.12" license = { text = "Apache-2.0" } authors = [{ name = "Mistral AI" }] keywords = [ "ai", "cli", "coding-assistant", "mistral", "llm", "developer-tools", ] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Topic :: Software Development", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities", ] dependencies = [ "agent-client-protocol==0.11.0", "annotated-types==0.7.0", "anyio==4.15.1", "attrs==26.1.0", "beautifulsoup4==4.14.3", "cachetools==7.0.6", "certifi==2026.7.22", "cffi==2.0.0 ; platform_machine != 'aarch64' or platform_python_implementation != 'PyPy' or sys_platform != 'linux'", "charset-normalizer==3.4.7", "click==8.3.3 ; sys_platform != 'emscripten'", "colorama==0.4.6 ; sys_platform == 'win32'", "croniter==6.2.4", "cryptography==50.0.0", "eval-type-backport==0.3.1", "gitdb==4.0.12", "gitpython==3.1.62", "giturlparse==0.15.0", "google-auth==2.49.2", "googleapis-common-protos==1.74.0", "h11==0.16.0", "httpcore==1.0.9", "httpx==0.28.1", "httpx-sse==0.4.3", "humanize==4.16.0", "idna==3.18", "importlib-metadata==8.7.1", "jaraco-classes==3.4.0", "jaraco-context==6.1.2", "jaraco-functools==4.4.0", "jeepney==0.9.0 ; sys_platform == 'linux'", "jsonpatch==1.33", "jsonpath-python==1.1.5", "jsonpointer==3.1.1", "jsonschema==4.26.0", "jsonschema-specifications==2025.9.1", "keyring==25.7.0", "linkify-it-py==2.1.0", "markdown-it-py==4.0.0", "markdownify==1.2.3", "mcp==1.28.1", "mdit-py-plugins==0.5.0", "mdurl==0.1.2", "miniaudio==1.71 ; platform_machine != 'aarch64' or sys_platform != 'linux'", "mistralai==2.6.0", "more-itertools==11.0.2", "opentelemetry-api==1.39.1", "opentelemetry-exporter-otlp-proto-common==1.39.1", "opentelemetry-exporter-otlp-proto-http==1.39.1", "opentelemetry-proto==1.39.1", "opentelemetry-sdk==1.39.1", "opentelemetry-semantic-conventions==0.60b1", "packaging==26.2", "pexpect==4.9.0", "platformdirs==4.9.6", "protobuf==6.33.6", "ptyprocess==0.7.0", "pyasn1==0.6.4", "pyasn1-modules==0.4.2", "pycparser==3.0 ; (implementation_name != 'PyPy' and platform_machine != 'aarch64') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') or (implementation_name != 'PyPy' and sys_platform != 'linux')", "pydantic==2.13.4", "pydantic-core==2.46.4", "pydantic-settings==2.14.2", "pygments==2.20.0", "pyjwt==2.15.1", "pyperclip==1.11.0", "python-dateutil==2.9.0.post0", "python-dotenv==1.2.2", "python-multipart==0.0.32", "pywin32==311 ; sys_platform == 'win32'", "pywin32-ctypes==0.2.3 ; sys_platform == 'win32'", "pywinpty==3.0.5 ; sys_platform == 'win32'", "pyyaml==6.0.3", "referencing==0.37.0", "requests==2.34.2", "rfc8785==0.1.4", "rich==15.0.0", "rpds-py==0.30.0", "secretstorage==3.5.0 ; sys_platform == 'linux'", "sentry-sdk==2.64.0", "setproctitle==1.3.7", "six==1.17.0", "smmap==5.0.3", "soupsieve==2.9.2", "sse-starlette==3.4.1", "starlette==1.3.1", "textual==8.2.8", "textual-speedups==0.2.1", "tomli-w==1.2.0", "tree-sitter==0.26.0", "tree-sitter-bash==0.25.1", "truststore==0.10.4", "typing-extensions==4.16.0", "typing-inspection==0.4.2", "uc-micro-py==2.0.0", "urllib3==2.8.0", "uvicorn==0.46.0 ; sys_platform != 'emscripten'", "watchfiles==1.2.0", "websockets==16.0", "zipp==3.23.1", "zstandard==0.25.0", ] [project.optional-dependencies] # Opt-in for aarch64 Linux, where upstream publishes no miniaudio wheel. The # default install needs no C++ toolchain; uv tool install "mistral-vibe[voice-aarch64]" # resolves the prebuilt manylinux wheel the release CI publishes to Gemfury # (see the miniaudio-aarch64 job in vibe-release-gemfury.yaml). voice-aarch64 = ["miniaudio>=1.59"] [project.urls] Homepage = "https://github.com/mistralai/mistral-vibe" Repository = "https://github.com/mistralai/mistral-vibe" Issues = "https://github.com/mistralai/mistral-vibe/issues" Documentation = "https://github.com/mistralai/mistral-vibe#readme" [build-system] requires = ["maturin==1.14.1"] build-backend = "maturin_backend" backend-path = ["build_backend"] [[tool.uv.index]] default = true name = "pypi" url = "https://pypi.org/simple" [tool.maturin] manifest-path = ".native-build/harness-core/Cargo.toml" module-name = "mistralai_vibe_local_harness._native" python-source = "." python-packages = ["vibe", "mistralai_vibe_local_harness"] include = [ { path = "vibe/_bin/*", format = "wheel" }, # The runtime is staged during the build and ignored by Git. Include it # explicitly so Maturin does not filter its Python sources out. { path = "mistralai_vibe_local_harness/*", format = "wheel" }, { path = "mistralai_vibe_local_harness/**/*", format = "wheel" }, ] exclude = [ "**/__pycache__/**", "**/*.pyc", "vibe/cli-rust/**", ] features = ["extension-module"] [project.scripts] vibe = "vibe.cli.launcher:main" vibe-acp = "vibe.acp.entrypoint:main" vibe-app-server = "vibe.app_server.stdio:main" [tool.uv] exclude-newer = "2 days" cache-keys = [ { file = "pyproject.toml" }, { file = "build_backend/**/*.py" }, { file = "vibe/cli-rust/Cargo.toml" }, { file = "vibe/cli-rust/Cargo.lock" }, { file = "vibe/cli-rust/src/**/*.rs" }, { file = "harness/core/Cargo.toml" }, { file = "harness/core/Cargo.lock" }, { file = "harness/core/src/**/*.rs" }, { file = "harness/runtimes/python/python/mistralai_vibe_local_harness/**/*" }, # Selects which editable build the backend produces; see build_backend. { env = "VIBE_EXTERNAL_HARNESS" }, ] index-strategy = "first-index" package = true required-version = ">=0.8.0" override-dependencies = [ # pytest-textual-snapshot exact-pins syrupy==4.8.0, which caps pytest<9. # syrupy 4.8.0 runs fine on pytest 9 (generation, comparison and diffs all # verified); the cap is conservative, so override it to clear GHSA-6w46-j5rx-g56g. "pytest>=9.0.3", ] [tool.uv.build-backend] # Read only by the builds the backend hands to uv_build: the sdist (the backend # appends the Harness sources) and an editable install with VIBE_EXTERNAL_HARNESS=1. # Wheels go through Maturin and ignore this table. module-name = "vibe" module-root = "" source-include = ["build_backend/**", "LICENSE"] source-exclude = ["vibe/_bin", "vibe/cli-rust/target"] [dependency-groups] dev = [ "cryptography>=48.0.0", "maturin==1.14.1", "pre-commit-uv>=4.3.0", "pre-commit>=4.2.0", "pyinstrument>=5.1.2", "pyright>=1.1.403", "pytest>=8.3.5", "pytest-asyncio>=1.2.0", "pytest-textual-snapshot>=1.1.0", "pytest-timeout>=2.4.0", "pytest-xdist>=3.8.0", "pyte>=0.8.2", "respx>=0.22.0", "ruff>=0.15.18", "tomlkit>=0.13.0", "twine>=5.0.0", "typos>=1.34.0", "vulture>=2.14", ] build = [ "altgraph==0.17.5", "macholib==1.16.4 ; sys_platform == 'darwin'", "packaging==26.2", "pefile==2024.8.26 ; sys_platform == 'win32'", "pyinstaller==6.20.0", "pyinstaller-hooks-contrib==2026.4", "pywin32-ctypes==0.2.3 ; sys_platform == 'win32'", "setuptools==83.0.0", ] [tool.pyright] pythonVersion = "3.12" reportMissingTypeStubs = false reportPrivateImportUsage = false include = ["build_backend/**/*.py", "vibe/**/*.py", "tests/**/*.py", "pyinstaller/unified_runtime.py"] venvPath = "." venv = ".venv" [tool.ruff] include = ["build_backend/**/*.py", "vibe/**/*.py", "tests/**/*.py", "pyinstaller/unified_runtime.py"] line-length = 88 target-version = "py312" preview = true [tool.ruff.format] skip-magic-trailing-comma = true [tool.ruff.lint] select = [ "F", "I", "D2", "UP", "TID", "ANN", "PLR", "B0", "B905", "RUF022", "RUF010", "RUF012", "RUF019", "RUF100", "TC004", ] ignore = ["D203", "D205", "D213", "ANN401", "PLR6301"] [tool.ruff.lint.per-file-ignores] "tests/*" = ["ANN", "PLR"] [tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" [tool.ruff.lint.isort] known-first-party = ["vibe", "mistralai_vibe_local_harness"] force-sort-within-sections = true split-on-trailing-comma = false combine-as-imports = true force-wrap-aliases = false order-by-type = true required-imports = ["from __future__ import annotations"] [tool.ruff.lint.pylint] max-public-methods = 26 max-positional-args = 10 max-statements = 50 max-branches = 15 max-locals = 15 max-args = 10 max-returns = 6 max-nested-blocks = 5 [tool.vulture] ignore_decorators = ["@*"] [tool.pytest.ini_options] # client-e2e is a standalone harness with its own pytest.ini; the main suite must not collect it. addopts = "-p pytest_vibe -vvvv -q -n auto --dist=loadgroup --durations=10 --import-mode=importlib --maxschedchunk=1 --ignore=client-e2e" timeout = 10 markers = [ "unified_supported: backend contract behavior implemented by the Unified Harness", "unified_default: e2e test spawning the unflagged unified-default binary", ] filterwarnings = [ # (e2e) streaming mock server is started in a thread; and the cli is spawn in a fork "ignore:This process \\(pid=.*\\) is multi-threaded, use of forkpty\\(\\) may lead to deadlocks in the child\\.:DeprecationWarning", ]