Source code for smarter.apps.mcpserver.models

"""
Models of the MCPServer app: the search index of The Smarter Project's repositories.

:class:`RepositoryIndex` records, for each repository of
:data:`~smarter.apps.mcpserver.repositories.SMARTER_PROJECT_REPOSITORIES`, the commit that
is indexed, and :class:`RepositoryFile` holds the text of each of its files. The index is
built by :func:`smarter.apps.mcpserver.indexer.index_repository`, and replaced whenever the
repository's branch moves to a new commit.

.. note::

    **Experimental.** The MCPServer was designed and coded by Claude Code (Anthropic's
    Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will
    be documented.
"""

from django.db import models

from smarter.lib.django.models import TimestampedModel


[docs] class RepositoryIndexStatus(models.TextChoices): """The status of a repository's index.""" PENDING = "pending", "Pending" """The repository has not been indexed yet.""" READY = "ready", "Ready" """The repository is indexed. The last attempt to refresh it may have failed: see ``error``. """ FAILED = "failed", "Failed" """The repository could not be indexed, and has no index."""
[docs] class RepositoryFileKind(models.TextChoices): """What a file of a repository is.""" DOCUMENTATION = "documentation", "Documentation" """Prose, e.g. reStructuredText and Markdown.""" CODE = "code", "Code" """Source code and configuration."""
[docs] class RepositoryIndex(TimestampedModel): """The index of one of The Smarter Project's repositories.""" # pylint: disable=C0115 class Meta: verbose_name_plural = "Repository Indexes" ordering = ["repository"] repository = models.CharField(max_length=100, unique=True, help_text="The repository's name, e.g. smarter-cli.") commit_sha = models.CharField(max_length=40, blank=True, null=True, help_text="The indexed commit.") status = models.CharField( max_length=16, choices=RepositoryIndexStatus.choices, default=RepositoryIndexStatus.PENDING ) indexed_at = models.DateTimeField(blank=True, null=True, help_text="When the indexed commit was indexed.") file_count = models.PositiveIntegerField(default=0) total_bytes = models.PositiveBigIntegerField(default=0) error = models.TextField(blank=True, null=True, help_text="Why the last attempt to index the repository failed.") def __str__(self) -> str: return f"{self.repository}@{(self.commit_sha or '')[:7]} {self.status}" @property def is_ready(self) -> bool: """Whether the repository has an index to search.""" return self.status == RepositoryIndexStatus.READY
[docs] class RepositoryFile(TimestampedModel): """One text file of an indexed repository.""" # pylint: disable=C0115 class Meta: ordering = ["index", "path"] constraints = [models.UniqueConstraint(fields=["index", "path"], name="mcpserver_unique_repository_file")] indexes = [models.Index(fields=["index", "kind"])] index = models.ForeignKey(RepositoryIndex, on_delete=models.CASCADE, related_name="files") path = models.CharField(max_length=512, help_text="The file's path in the repository.") kind = models.CharField(max_length=16, choices=RepositoryFileKind.choices) title = models.CharField(max_length=255, blank=True, default="", help_text="A document's first heading.") content = models.TextField() size = models.PositiveIntegerField(help_text="Bytes.") line_count = models.PositiveIntegerField() def __str__(self) -> str: return f"{self.index.repository}:{self.path}"
__all__ = [ "RepositoryFile", "RepositoryFileKind", "RepositoryIndex", "RepositoryIndexStatus", ]