import uuid from datetime import date, datetime from typing import Any, Literal from pydantic import BaseModel, Field from hub_core.schemas.managed_repo import ( RepoCreate as CoreRepoCreate, RepoPathRegister, RepoRead as CoreRepoRead, ) class RepoCreate(CoreRepoCreate): topic_id: uuid.UUID | None = None class RepoUpdate(BaseModel): name: str | None = None local_path: str | None = None remote_url: str | None = None git_fingerprint: str | None = None description: str | None = None topic_id: uuid.UUID | None = None last_state_synced_at: datetime | None = None class RepoOnboardRequest(BaseModel): """Start scripted onboarding for a working copy that is visible to State Hub.""" domain_slug: str project_path: str agent_profile: Literal["claude-code", "codex"] = "codex" additional: bool = False class RepoOnboardResult(BaseModel): ok: bool repo_slug: str | None = None agent_profile: str command: list[str] stdout: str = "" stderr: str = "" class RepoRead(CoreRepoRead): topic_id: uuid.UUID | None = None sbom_source: str | None = None last_sbom_at: datetime | None = None last_state_synced_at: datetime | None = None created_at: datetime updated_at: datetime class DispatchTask(BaseModel): id: uuid.UUID title: str priority: str status: str needs_human: bool class DispatchWorkstream(BaseModel): id: uuid.UUID title: str status: str pending_tasks: list[DispatchTask] class PendingInterfaceChange(BaseModel): id: uuid.UUID title: str change_type: str interface_type: str origin_repo_slug: str affected_paths: list[str] planned_for: date | None published_at: datetime | None class ScopeIssueDetail(BaseModel): id: str label: str status: str detail: str missing_sections: list[str] = Field(default_factory=list) invalid_capability_blocks: list[dict[str, Any]] = Field(default_factory=list) needs_refresh_sections: list[str] = Field(default_factory=list) class RepoDispatch(BaseModel): repo_slug: str active_goal: dict[str, Any] | None active_workstreams: list[DispatchWorkstream] human_interventions: list[DispatchTask] pending_interface_changes: list[PendingInterfaceChange] scope_needs_review: bool scope_issue_details: list[ScopeIssueDetail] last_state_synced_at: datetime | None class RepoScopeHealth(BaseModel): repo_slug: str domain_slug: str | None = None local_path: str | None = None path_available: bool scope_needs_review: bool scope_issue_details: list[ScopeIssueDetail]