[project]
name = "codelogician"
version = "2.0.0b5"
description = """CodeLogician applies neurosymbolic AI to translate source code into precise mathematical logic, striving to
create a formal model of the program's behavior that's functionally equivalent to the original source code."""
readme = "src/codelogician/README.md"
authors = [
    { name = "hongyu", email = "hongyu@imandra.ai" },
    { name = "samer", email = "samer@imandra.ai" },
    { name = "denis", email = "denis@imandra.ai" }
]
requires-python = ">=3.12, <3.14"
dependencies = [
  "chromadb>=1.0.12",
  "fastapi>=0.116.1",
  "fastapi-mcp>=0.4.0",
  "fuzzysearch>=0.8.1",
  "imandra[universe]>=2.3.0",
  "imandrax-api-models>=1.1.1",
  "iml-query>=0.5.1",
  "joblib>=1.5.1",
  "matplotlib>=3.10.3",
  "networkx>=3.5",
  "networkx-mermaid>=0.1.7",
  "pydantic>=2.11.5",
  "pydantic-yaml>=1.6.0",
  "pytest-textual-snapshot>=1.1.0",
  "regex>=2025.11.3",
  "rich>=14.0.0",
  "termcolor>=3.1.0",
  "textual>=6.0.0",
  "textual-dev>=1.7.0",
  "textual-image>=0.8.3",
  "watchdog>=6.0.0",
]

[project.scripts]
codelogician = "main:run_codelogician"
codelogician-tools = "codelogician.tool_cli:app"

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

[tool.hatch.build.targets.wheel]
packages = ["src/codelogician"]
only-include = [
  "src/",
  "main.py",
  "pyproject.toml",
  "LICENSE",
]


[tool.hatch.build.targets.wheel.force-include]
"main.py" = "main.py"

[tool.hatch.build.targets.sdist]
only-include = [
  "src/",
  "main.py",
  "pyproject.toml",
  "LICENSE",
]
exclude = [
  ".gitignore",
]

[tool.uv.sources]
# imandrax-api-models = { path = "../imandrax-tools/packages/imandrax-api-models", editable = true }
# iml-query = { path = "../imandrax-tools/packages/iml-query", editable = true }

[dependency-groups]
dev = [
  "dowhen>=0.1.0",
  "inline-snapshot[dirty-equals]>=0.24.0",
  "ipykernel>=6.29.5",
  "pytest>=8.4.1",
  "pytest-asyncio>=1.1.0",
  "pytest-pretty>=1.3.0",
]

[tool.ruff]
line-length = 88
fix = true
show-fixes = true
src = ["src"]
exclude = ["*.ipynb", "data/"]

[tool.ruff.format]
quote-style = "single"

[tool.ruff.lint]
extend-select = [
    "Q",
    "RUF100",
    "RUF018", # https://docs.astral.sh/ruff/rules/assignment-in-assert/
    "C90",
    "UP",
    "I",
    # "D",
    "TID251",
]
mccabe = { max-complexity = 15 }
ignore = [
    "D100",  # ignore missing docstring in module
    "D101",  # ignore missing docstring in public class
    "D102",  # ignore missing docstring in public method
    "D103",  # ignore missing docstring in public function
    "D104",  # ignore missing docstring in public package
    "D105",  # ignore missing docstring in magic methods
    "D106",  # ignore missing docstring in public nested class
    "D107",  # ignore missing docstring in __init__ methods
    "D203",
    "D212",
    "E701",  # multiple statements on one line
]
task-tags = ["HACK"]
pycodestyle.ignore-overlong-task-comments = true
isort.combine-as-imports = true

[tool.ruff.lint.flake8-quotes]
inline-quotes = "single"

[tool.ruff.lint.per-file-ignores]
"scripts/**/*.py" = ["F401", "RUF100", "D", "E402", "B018"]
"data/**/*.py" = ["F401", "RUF100", "D", "E402", "B018"]

[tool.ty]
environment.python = ".venv"

[tool.ty.rules]
# Handled by pyright
unsupported-operator = "ignore"
invalid-argument-type = "ignore"
invalid-return-type = "ignore"
possibly-missing-import = "ignore"
unresolved-import = "ignore"

[tool.pyright]
venvPath = "."
venv = ".venv"
pythonVersion = "3.12"
# We should aim for strict mode
# typeCheckingMode = "strict"
typeCheckingMode = "basic"
reportMissingTypeStubs = false
reportUnnecessaryIsInstance = false
reportUnnecessaryTypeIgnoreComment = true
reportUnusedImport = "none"
reportUnusedExpression = false

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
enable_assertion_pass_hook = true

[tool.inline-snapshot]
format-command = "uv run ruff format --stdin-filename {filename}"

[[tool.uv.index]]
name = "pypi"
url = "https://pypi.org/simple/"
publish-url = "https://upload.pypi.org/legacy/"
explicit = true

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true
