sync-docs

This commit is contained in:
Danilo Reyes
2026-02-01 11:31:48 -06:00
parent a29aa773fc
commit f0d28b4a1e
4 changed files with 83 additions and 25 deletions

View File

@@ -2,10 +2,13 @@
from __future__ import annotations
import re
from pathlib import Path
from mcp_server.tools import DocsPath, tool_catalog
_REFERENCE_DOC = DocsPath / "reference" / "mcp-server.md"
def check_catalog_parity() -> dict[str, object]:
"""Compare documented anchors with the live tool catalog and report drift."""
@@ -13,14 +16,14 @@ def check_catalog_parity() -> dict[str, object]:
missing_in_catalog: list[str] = []
mismatches: list[dict[str, str]] = []
docs_tools = _doc_anchors()
docs_tools = _doc_tool_anchors()
catalog = tool_catalog()
catalog_names = {tool.name for tool in catalog}
for tool in catalog:
anchor_key = _anchor_key(tool.docs_anchor.path, tool.docs_anchor.anchor)
if anchor_key not in docs_tools:
if not _anchor_exists(tool.docs_anchor.path, tool.docs_anchor.anchor):
missing_in_docs.append(tool.name)
for anchor_key, tool_name in docs_tools.items():
if tool_name not in {t.name for t in catalog}:
if tool_name not in catalog_names:
missing_in_catalog.append(anchor_key)
return {
"status": (
@@ -34,21 +37,51 @@ def check_catalog_parity() -> dict[str, object]:
}
def _doc_anchors() -> dict[str, str]:
"""Derive anchors from docs files to detect missing catalog entries."""
def _doc_tool_anchors() -> dict[str, str]:
"""Derive documented tool anchors from the MCP reference page."""
anchors: dict[str, str] = {}
files = list(DocsPath.rglob("*.md"))
for path in files:
tool_name = _derive_tool_name(path)
anchor_id = path.stem
anchors[_anchor_key(path, anchor_id)] = tool_name
for heading in _heading_texts(_REFERENCE_DOC, prefix="### "):
tool_name = heading
anchor_id = _slugify_heading(heading)
anchors[_anchor_key(_REFERENCE_DOC, anchor_id)] = tool_name
return anchors
def _derive_tool_name(path: Path) -> str:
"""Create a best-effort tool name from a documentation path."""
parts = path.parts[-3:]
return "-".join(filter(None, parts)).replace(".md", "")
def _anchor_exists(path: Path, anchor: str) -> bool:
"""Check whether a heading anchor exists in the target doc."""
if not path.exists() or path.is_dir():
return False
return anchor in _heading_anchors(path)
def _heading_anchors(path: Path) -> set[str]:
"""Collect slugified heading anchors from a markdown file."""
anchors: set[str] = set()
for heading in _heading_texts(path, prefix="#"):
anchors.add(_slugify_heading(heading))
return anchors
def _heading_texts(path: Path, prefix: str) -> list[str]:
"""Return heading text lines matching a prefix."""
if not path.exists():
return []
headings: list[str] = []
for line in path.read_text().splitlines():
if not line.startswith(prefix):
continue
heading = line.lstrip("#").strip()
if heading:
headings.append(heading)
return headings
def _slugify_heading(text: str) -> str:
"""Normalize heading text to a GitHub-style anchor."""
slug = text.strip().lower()
slug = re.sub(r"[^a-z0-9\s-]", " ", slug)
slug = re.sub(r"\s+", "-", slug)
return re.sub(r"-+", "-", slug).strip("-")
def _anchor_key(path: Path, anchor: str) -> str:

View File

@@ -168,17 +168,17 @@ def tool_catalog() -> tuple[Tool, ...]:
)
anchor_reference = DocsAnchor(
path=DocsPath / "reference" / "index.md",
anchor="reference-index",
anchor="reference-map",
summary="Navigation map for repository docs",
)
anchor_search = DocsAnchor(
path=DocsPath,
anchor="docs-search",
path=DocsPath / "reference" / "mcp-server.md",
anchor="search-docs",
summary="Search across docs for maintenance topics",
)
anchor_tasks = DocsAnchor(
path=RepoPath / "specs" / "001-mcp-server" / "tasks.md",
anchor="tasks",
anchor="tasks-mcp-server-for-repo-maintenance",
summary="Implementation tasks for MCP feature",
)
anchor_sync = DocsAnchor(