Ctrl K
ComunidadGuías…

pyproject.toml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
[project]
name = "muselab"
version = "2.1.0"
description = "Self-hosted multi-model Agent workbench for local workspaces, files, terminals, and artifacts."
readme = "README.md"
license = { file = "LICENSE" }
authors = [
    { name = "hesorchen", email = "hesorchen@gmail.com" },
]
keywords = [
    "claude",
    "anthropic",
    "claude-agent-sdk",
    "mcp",
    "self-hosted",
    "llm",
    "ai-assistant",
    "agent-workspace",
    "deepseek",
    "pwa",
]
classifiers = [
    # PyPI Trove classifiers — surface project status / audience / license /
    # platform / Python version so PyPI search and dependency-graph tools
    # can categorise muselab even though it's not meant to be `pip install`-able
    # (it's a server you self-host, not a library).
    "Development Status :: 5 - Production/Stable",
    "Environment :: Web Environment",
    "Framework :: FastAPI",
    "Intended Audience :: End Users/Desktop",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Operating System :: POSIX :: Linux",
    "Operating System :: MacOS",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.12",
    "Topic :: Communications :: Chat",
    "Topic :: Office/Business",
    "Topic :: Scientific/Engineering :: Artificial Intelligence",
]
requires-python = ">=3.12"
dependencies = [
    # Exact pin is deliberate: muselab adapts both SDK and bundled-CLI contracts
    # that are not capability-negotiated — the harness-tool denylist, JSONL
    # transcript shape, and native AskUserQuestion answer injection. Every SDK
    # upgrade must refresh the tool catalog and rerun the native question matrix.
    # Path/effort drift is already auto-eliminated via
    # project_key_for_directory() + EffortLevel.
    "claude-agent-sdk==0.2.157",
    # Security floor for CVE-2026-63374 and CVE-2026-64847.
    "anyio>=4.14.2",
    "fastapi>=0.138.1",
    # Pin starlette above the fastapi-transitive 1.0.0, which carries
    # PYSEC-2026-161 (fixed in 1.0.1). Direct constraint so the pip-audit
    # CVE-scan CI job stays green.
    "starlette>=1.3.1",
    "python-dotenv>=1.2.2",
    "python-multipart>=0.0.32",
    "uvicorn[standard]>=0.49.0",
    # Live file-tree refresh for Agent / terminal / external-editor changes.
    # One on-demand watcher per subscribed workspace feeds the durable SQLite
    # index; offline reconciliation runs when that workspace is reactivated.
    "watchfiles>=1.2.0",
    # xlsx preview — read-only, used by /api/files/xlsx. Pure-Python, no
    # native deps; safe to ship in the muselab Docker image.
    "openpyxl>=3.1.5",
    # Web Push: VAPID-signed pushes to browsers / PWAs subscribed to
    # /api/push/subscribe. Has a transitive cryptography dep but no
    # external binaries.
    "pywebpush>=2.0.0",
    # Keep aiohttp at the currently audited security floor rather than the
    # older pywebpush-transitive range. Direct constraint keeps fresh lock
    # resolutions aligned with the pip-audit CI baseline.
    "aiohttp>=3.14.3",
    # Security floor for the C-extension reference leak in CVE-2026-104874.
    "multidict>=6.9.1",
    "pillow>=12.3.0",
    # Security floors for the claim-verification and parser advisories
    # affecting PyJWT 2.13.0 and the proxy/redirect advisories in urllib3 2.7.0.
    # Keep both explicit so future lock resolutions retain the fixes.
    "pyjwt[crypto]>=2.15.1",
    "urllib3>=2.8.0",
    # Direct async HTTP client. Used by backend/memory_client.py to talk to the
    # optional self-hosted mem0 daemon. It is already an SDK/httpcore transitive
    # dep today, but we import it directly, so declare it explicitly — otherwise
    # an upstream drop would make `import httpx` fail and (because mem0 is
    # fail-soft) silently disable memory with no signal.
    "httpx>=0.27",
    # Optional pgvector adapter for the long-term memory index. Imported only
    # when pgvector is selected; Qdrant deployments never open a Postgres
    # connection, but keeping the driver installed makes provider switching a
    # runtime setting instead of a redeploy.
    "psycopg[binary]>=3.2.9",
]

[project.urls]
Homepage      = "https://github.com/hesorchen/muselab"
Source        = "https://github.com/hesorchen/muselab"
Issues        = "https://github.com/hesorchen/muselab/issues"
Documentation = "https://github.com/hesorchen/muselab/blob/main/docs/quickstart.md"
Container     = "https://github.com/hesorchen/muselab/pkgs/container/muselab"

[dependency-groups]
dev = [
    "pytest>=9.1.1",
    "pytest-asyncio>=1.4.0",
    # Parallelize the large unit/integration suite on multi-core development
    # machines and CI. Browser E2E and upgrade smoke tests stay serial because
    # they intentionally share one live server/runtime.
    "pytest-xdist>=3.8.0",
    # Starlette 1.2+ prefers httpx2 for TestClient. Keep production httpx
    # separately because memory_client imports that package directly.
    "httpx2>=2.0.0",
    # Browser regressions cover Alpine rendering races and trusted mobile
    # touch gestures that static source assertions cannot exercise.
    "pytest-playwright>=0.7.0",
    # Pinned alongside dev deps so `scripts/lint.sh` and CI both have a
    # deterministic ruff version. Without this each dev / CI run pulled
    # latest via `uv run --with ruff`, occasionally causing rule churn.
    "ruff>=0.15.20",
    # CI collects coverage in its existing primary test run; lock the plugin
    # so worker instrumentation and the later report use the same toolchain.
    "pytest-cov>=7.1.0",
]

# Ruff config — keep targeted, not aggressive. Goal: catch real bugs
# (unused imports / variables, broken syntax-adjacent patterns) without
# fighting a project that values terse multi-statement-on-one-line where
# it reads naturally. Style enforcement is left to human review.
[tool.ruff]
target-version = "py312"
line-length = 100   # informational; we don't auto-format

[tool.ruff.lint]
# Default ruleset (E, F, W) — pyflakes + pycodestyle errors only.
# Explicitly NO opinionated rule families (B, I, N, UP) — they'd churn
# 6k LOC of working code for marginal gain.
select = ["E", "F", "W"]
# Project-specific tolerances:
# - E501 line-too-long: many existing lines are 100-120 chars by deliberate
#   choice (one full sentence per comment line). Not worth the churn.
ignore = ["E501"]