[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "cognithor"
version = "0.91.0"
description = "Cognithor · Agent OS — Local-first autonomous agent operating system"
readme = "README.md"
license = "Apache-2.0"
requires-python = ">=3.12"
authors = [
    { name = "Alexander Söllner" },
]
keywords = ["ai", "agent", "ollama", "local-first", "automation"]
classifiers = [
    "Development Status :: 4 - Beta",
    "Environment :: Console",
    "Intended Audience :: End Users/Desktop",
    "Operating System :: POSIX :: Linux",
    "Operating System :: Microsoft :: Windows",
    "Operating System :: MacOS",
    "Programming Language :: Python :: 3.12",
    "Topic :: Scientific/Engineering :: Artificial Intelligence",
]

dependencies = [
    # Core
    "pydantic>=2.10,<3",
    "pydantic-settings>=2.7,<3",
    "httpx>=0.28,<1",
    "pyyaml>=6.0,<7",
    # Hashing (Hashline Guard)
    "xxhash>=3.0,<4",
    # Logging
    "structlog>=25.4,<26",
    # CLI
    "rich>=13.0,<14",
    "prompt-toolkit>=3.0,<4",
    # Async
    "anyio>=4.0,<5",
    # Security
    "cryptography>=46.0.5",
    # .env file loading
    "python-dotenv>=1.0,<2",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0,<9",
    "pytest-asyncio>=0.24,<1",
    "pytest-cov>=6.0,<7",
    "ruff>=0.9,<1",
    "mypy>=1.14,<2",
]
memory = [
    "numpy>=2.0,<3",
    "sqlite-vec>=0.1",
    "beautifulsoup4>=4.12",
]
vector = [
    "faiss-cpu>=1.7",
]
mcp = [
    "mcp>=1.7,<2",
]
telegram = [
    "python-telegram-bot>=21.0,<22",
]
web = [
    "fastapi>=0.115,<1",
    "uvicorn[standard]>=0.34,<1",
    "websockets>=14.0,<15",
]
voice = [
    "faster-whisper>=1.0",
    "piper-tts>=1.0",
    "sounddevice>=0.5",
]
elevenlabs = [
    "elevenlabs>=1.0",
]
google-chat = [
    "google-auth>=2.0",
    "google-api-core>=2.0",
]
discord = [
    "discord.py>=2.0",
]
slack = [
    "slack-sdk>=3.0",
]
matrix = [
    "matrix-nio>=0.24",
]
whatsapp = [
    "aiohttp>=3.9",
]
signal = [
    "aiohttp>=3.9",
]
teams = [
    "aiohttp>=3.9",
]
irc = [
    "irc>=20.0",
]
twitch = [
    "twitchio>=2.0",
]
documents = [
    "fpdf2>=2.7,<3",
    "python-docx>=1.0,<2",
    "pymupdf>=1.23",
    "python-pptx>=0.6",
    "openpyxl>=3.1",
    "typst>=0.1",
]
search = [
    "trafilatura>=2.0",
    "ddgs>=9.0,<10",
]
cron = [
    "apscheduler>=3.10,<4",
    "croniter>=1.0",
]
postgresql = [
    "psycopg[binary]>=3.1",
    "psycopg-pool>=3.1",
    "pgvector>=0.2",
]
distributed = [
    "redis>=5.0,<6",
]
browser = [
    "playwright>=1.40",
]
desktop = [
    "pyautogui>=0.9",
    "pywinauto>=0.6.8",
    "mss>=9.0",
    "pyperclip>=1.8",
    "Pillow>=10.0",
]
encryption = [
    "sqlcipher3>=0.6.0",
    "keyring>=25.0",
]
identity = [
    "chromadb>=1.5.0",
    "sentence-transformers>=5.0.0",
    "numpy>=2.0,<3",
]
worm = [
    "boto3>=1.28",
]
blockchain = [
    "web3>=7.0.0",
]
arc = [
    "arc-agi>=0.3.0",
    "numpy>=2.0,<3",
    "scipy>=1.14",
]
arc-gpu = [
    "cognithor[arc]",
    "torch>=2.2.0",
]
all = [
    "cognithor[memory,vector,mcp,telegram,web,search,cron,documents,identity,desktop,arc,encryption]",
]
full = [
    "cognithor[all,voice,elevenlabs,postgresql,google-chat,discord,slack,matrix,whatsapp,signal,teams,irc,twitch,distributed,browser,encryption,dev]",
]

[project.urls]
Homepage = "https://github.com/Alex8791-cyber/cognithor"
Repository = "https://github.com/Alex8791-cyber/cognithor"
"Bug Tracker" = "https://github.com/Alex8791-cyber/cognithor/issues"

[project.scripts]
cognithor = "cognithor.__main__:main"
jarvis = "cognithor.__main__:main"

[tool.hatch.build.targets.wheel]
packages = ["src/cognithor"]

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
markers = [
    "slow: marks tests as slow",
    "integration: marks tests requiring external services",
]
filterwarnings = [
    # starlette uses deprecated multipart import — third-party, can't fix
    "ignore::PendingDeprecationWarning:starlette",
    # asyncio transport cleanup after event loop is closed (Windows + Linux)
    "ignore:Exception ignored in.*Transport:pytest.PytestUnraisableExceptionWarning",
    # Mock artifacts: coroutines created by AsyncMock but never awaited
    "ignore:coroutine .* was never awaited:RuntimeWarning",
]

[tool.ruff]
target-version = "py312"
line-length = 100
src = ["src", "tests"]

[tool.ruff.lint]
select = [
    "E", "W", "F", "I", "N", "UP", "B", "SIM", "TCH", "RUF",
]
ignore = [
    "RUF001",  # Ambiguous EN DASH in strings (korrekt im Deutschen)
    "RUF002",  # Ambiguous EN DASH in docstrings
    "RUF003",  # Ambiguous EN DASH in comments
    "RUF012",  # Mutable class defaults — dataclass pattern, harmless
    "N806",    # Non-lowercase variable in function — Windows API constants
    "N801",    # Invalid class name — test naming conventions
    "N802",    # Invalid function name — intentional conventions
    "N805",    # Invalid first argument name — intentional
    "N811",    # Constant imported as non-constant — intentional
    "N814",    # Camelcase imported as constant — intentional
    "N818",    # Error suffix on exception name — intentional
    "E402",    # Module import not at top — conditional imports by design
    "E741",    # Ambiguous variable name — l, O, I in math code
    "SIM117",  # Multiple with statements — style preference only
    "SIM103",  # Needless bool — style preference
    "SIM108",  # If-else-block instead of if-exp — readability preference
    "SIM112",  # Uncapitalized env vars — intentional
    "SIM115",  # Open file with context handler — controlled usage
    "B027",    # Empty method without abstract decorator — intentional pattern
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]  # Re-exports in __init__.py are intentional
"tests/test_install_fixes.py" = ["E501"]  # Embedded shell/JS scripts in strings

[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_configs = true
