Coder preparations

This commit is contained in:
2026-09-22 23:21:59 +03:00
parent 3d1df7fee5
commit 1f2dc25e0b
32 changed files with 3205 additions and 26 deletions
+113
View File
@@ -0,0 +1,113 @@
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Optional, Literal, Any
from pydantic import field_validator, BaseModel, Field
@dataclass(frozen=True)
class RepoContext:
url: str
default_branch: str
language_hint: str | None # "python" | "typescript" | "go" | None
class Language(str, Enum):
PYTHON = "python"
JAVASCRIPT = "javascript"
TYPESCRIPT = "typescript"
JAVA = "java"
GO = "go"
RUST = "rust"
CPP = "cpp"
C = "c"
LanguageLiteral = Literal[
Language.PYTHON,
Language.JAVASCRIPT,
Language.TYPESCRIPT,
Language.JAVA,
Language.GO,
Language.RUST,
Language.CPP,
Language.C,
]
class DependencyNode(BaseModel):
"""A single node in the dependency graph."""
id: str = Field(..., description="Unique identifier (file path or module name)")
label: str = Field(..., description="Human-readable label")
language: Language
is_external: bool = Field(
default=False,
description="True if the dependency is outside the repository",
)
class DependencyEdge(BaseModel):
"""A directed edge from source → target (source depends on target)."""
source: str = Field(..., description="Node id of the dependant")
target: str = Field(..., description="Node id of the dependency")
kind: str = Field(
default="import",
description="Edge kind: import, include, inherit, call, etc.",
)
class DependencyGraph(BaseModel):
"""Complete dependency graph result."""
root: str = Field(..., description="Entrypoint node id")
nodes: list[DependencyNode]
edges: list[DependencyEdge]
metadata: dict[str, str] = Field(default_factory=dict)
class ToolRequirement(BaseModel):
"""Describes a required external tool and how to install it."""
tool_name: str
command: str = Field(..., description="CLI command that must be on PATH")
install_guide: str = Field(..., description="Markdown installation instructions")
docs_url: Optional[str] = None
class AnalysisError(BaseModel):
"""Structured error returned when analysis cannot proceed."""
error_code: str
message: str
missing_tools: list[ToolRequirement] = Field(default_factory=list)
language: Optional[Language] = None
entrypoint: Optional[str] = None
class AnalysisInput(BaseModel):
"""Input schema for the analyzer."""
repo_path: Path = Field(..., description="Absolute path to the cloned repository")
language: Language
entrypoint: str = Field(
...,
description="Relative path from repo_path to the entrypoint file",
)
@field_validator("repo_path")
@classmethod
def repo_must_exist(cls, v: Path) -> Path:
if not v.is_dir():
raise ValueError(f"Repository path does not exist or is not a directory: {v}")
return v.resolve()
@field_validator("entrypoint")
@classmethod
def entrypoint_must_exist(cls, v: str, info) -> str:
repo = info.data.get("repo_path")
if repo and not (repo / v).is_file():
raise ValueError(f"Entrypoint not found: {repo / v}")
return v
class AnalysisResult(BaseModel):
"""Top-level result — either a graph or an error."""
success: bool
graph: Optional[DependencyGraph] = None
error: Optional[AnalysisError] = None
leaf_clusters: Any
res_all: Any