chore: governance - tighten repo hygiene

This commit is contained in:
tukuaiai
2026-05-04 04:45:05 +08:00
parent bf73f011bc
commit 2eafa33fee
30 changed files with 424 additions and 405 deletions
+1 -26
View File
@@ -8,9 +8,9 @@ import sys
import urllib.parse
from pathlib import Path
from lib.taxonomy import taxonomy_document_paths
ROOT = Path(__file__).resolve().parents[1]
TAXONOMY = ROOT / "metadata/taxonomy.yml"
AI_ENTRY_FILES = [
Path("llms.txt"),
Path("assets/ai-citation/llms-full.txt"),
@@ -28,31 +28,6 @@ MARKDOWN_LINK_PATTERN = re.compile(r"!??\[[^\]]*\]\(([^)]+)\)")
EXTERNAL_PREFIXES = ("http://", "https://", "mailto:", "tel:", "data:")
def strip_quotes(value: str) -> str:
return value.strip().strip("\"'")
def taxonomy_document_paths() -> list[str]:
paths: list[str] = []
in_documents = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "documents:":
in_documents = True
continue
if in_documents and line and not line.startswith(" "):
break
if not in_documents:
continue
stripped = line.strip()
if stripped.startswith("- path:"):
_, value = stripped.split(":", 1)
paths.append(strip_quotes(value))
return paths
def github_slug(title: str) -> str:
title = re.sub(r"<[^>]+>", "", title.strip().lower())
title = re.sub(r"[`*_~]", "", title)
+42 -3
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Check required repository-owned directories have README.md and AGENTS.md."""
"""Check repository-owned directories have README.md and AGENTS.md."""
from __future__ import annotations
@@ -9,6 +9,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
REQUIRED_DIRS = [
Path(".github"),
Path(".github/ISSUE_TEMPLATE"),
Path(".github/workflows"),
Path("assets"),
Path("assets/ai-citation"),
Path("assets/datasets"),
@@ -23,24 +26,60 @@ REQUIRED_DIRS = [
Path("metadata"),
Path("prompts"),
Path("scripts"),
Path("scripts/lib"),
Path("skills"),
Path("skills/auto-skill"),
Path("skills/auto-skill/assets"),
Path("skills/auto-skill/references"),
Path("skills/auto-skill/scripts"),
Path("tools"),
Path("tools/chat-vault"),
Path("tools/config"),
Path("tools/config/.codex"),
Path("tools/external"),
Path("tools/prompts-library"),
Path("tools/prompts-library/docs"),
Path("tools/prompts-library/scripts"),
]
GENERATED_OR_VENDOR_DIRS = [
Path("node_modules"),
]
SKIP_PARTS = {".git", ".history", "node_modules", "__pycache__"}
SKIP_PREFIXES = [
Path(".github/wiki"),
]
VENDOR_SUBTREES = [
Path("tools/external"),
Path("tools/chat-vault"),
]
def should_skip(directory: Path) -> bool:
rel = directory.relative_to(ROOT)
if any(part in SKIP_PARTS for part in rel.parts):
return True
if directory.is_symlink():
return True
if any(rel == prefix or prefix in rel.parents for prefix in SKIP_PREFIXES):
return True
return any(vendor in rel.parents for vendor in VENDOR_SUBTREES)
def repository_owned_dirs() -> list[Path]:
dirs = set(REQUIRED_DIRS)
for directory in ROOT.rglob("*"):
if not directory.is_dir():
continue
if should_skip(directory):
continue
dirs.add(directory.relative_to(ROOT))
return sorted(dirs)
def main() -> int:
errors: list[str] = []
for rel_dir in REQUIRED_DIRS:
for rel_dir in repository_owned_dirs():
directory = ROOT / rel_dir
if not directory.is_dir():
errors.append(f"{rel_dir}: required directory is missing")
@@ -61,7 +100,7 @@ def main() -> int:
print(f"TOTAL={len(errors)}")
return 1
print(f"OK directory README/AGENTS pairs checked: {len(REQUIRED_DIRS)} directories")
print(f"OK directory README/AGENTS pairs checked: {len(repository_owned_dirs())} directories")
return 0
+1 -64
View File
@@ -7,9 +7,9 @@ import re
import sys
from pathlib import Path
from lib.taxonomy import doc_readmes_from_taxonomy, taxonomy_sections
ROOT = Path(__file__).resolve().parents[1]
TAXONOMY = ROOT / "metadata/taxonomy.yml"
SKIP_PARTS = {".git", ".history", "node_modules"}
SKIP_PREFIXES = [
Path(".github/wiki"),
@@ -19,69 +19,6 @@ ANCHOR_PATTERN = re.compile(r"<a\s+id=[\"']([^\"']+)[\"']")
SUMMARY_LINE = "<summary><strong>完整细粒度目录(点击展开/收起)</strong></summary>"
def strip_quotes(value: str) -> str:
return value.strip().strip("\"'")
def taxonomy_sections() -> dict[str, dict[str, str]]:
sections: dict[str, dict[str, str]] = {}
current: str | None = None
in_sections = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "sections:":
in_sections = True
continue
if in_sections and line and not line.startswith(" "):
break
if not in_sections:
continue
section_match = re.match(r"^ ([A-Za-z0-9_-]+):\s*$", line)
if section_match:
current = section_match.group(1)
sections[current] = {}
continue
field_match = re.match(r"^ (path|entry|agent_guide):\s*(.+?)\s*$", line)
if current and field_match:
sections[current][field_match.group(1)] = strip_quotes(field_match.group(2))
return sections
def taxonomy_document_paths() -> list[str]:
paths: list[str] = []
in_documents = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "documents:":
in_documents = True
continue
if in_documents and line and not line.startswith(" "):
break
if not in_documents:
continue
stripped = line.strip()
if stripped.startswith("- path:"):
_, value = stripped.split(":", 1)
paths.append(strip_quotes(value))
return paths
def doc_readmes_from_taxonomy() -> dict[Path, list[str]]:
readmes: dict[Path, list[str]] = {}
for target in taxonomy_document_paths():
path_part, _, anchor = target.partition("#")
if not anchor or not path_part.startswith("docs/") or not path_part.endswith("/README.md"):
continue
readmes.setdefault(Path(path_part), []).append(anchor)
return readmes
def strip_fenced_code(text: str) -> str:
lines: list[str] = []
in_fence = False
+9
View File
@@ -0,0 +1,9 @@
# scripts/lib/ Agent 指南
本目录是 `scripts/` 下质量门禁脚本的共享库。
## 约束
- 公共函数必须保持小而稳定,避免把具体业务规则塞进通用库。
- 不允许在 import 阶段执行文件写入、网络访问或命令调用。
- 变更后至少运行 `make test`,确认所有脚本入口仍可直接执行。
+13
View File
@@ -0,0 +1,13 @@
# scripts/lib
共享脚本库,放置多个质量门禁共同使用的解析与校验辅助函数。
## 当前模块
- `taxonomy.py` - 读取 `metadata/taxonomy.yml`,输出目录分区和文档路径。
## 约束
- 只放无副作用的纯辅助逻辑。
- 不在导入时读写仓库文件。
- 修改公共函数后必须运行 `make test`
+1
View File
@@ -0,0 +1 @@
"""Shared helpers for repository quality gate scripts."""
+81
View File
@@ -0,0 +1,81 @@
"""Helpers for reading the repository taxonomy file.
The project intentionally keeps metadata in a small YAML subset so the quality
gate scripts can run without extra Python dependencies.
"""
from __future__ import annotations
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
TAXONOMY = ROOT / "metadata/taxonomy.yml"
def strip_quotes(value: str) -> str:
"""Remove simple surrounding quotes from a taxonomy scalar."""
return value.strip().strip("\"'")
def taxonomy_sections() -> dict[str, dict[str, str]]:
"""Return top-level taxonomy sections keyed by section id."""
sections: dict[str, dict[str, str]] = {}
current: str | None = None
in_sections = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "sections:":
in_sections = True
continue
if in_sections and line and not line.startswith(" "):
break
if not in_sections:
continue
section_match = re.match(r"^ ([A-Za-z0-9_-]+):\s*$", line)
if section_match:
current = section_match.group(1)
sections[current] = {}
continue
field_match = re.match(r"^ (path|entry|agent_guide):\s*(.+?)\s*$", line)
if current and field_match:
sections[current][field_match.group(1)] = strip_quotes(field_match.group(2))
return sections
def taxonomy_document_paths() -> list[str]:
"""Return document path entries from metadata/taxonomy.yml."""
paths: list[str] = []
in_documents = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "documents:":
in_documents = True
continue
if in_documents and line and not line.startswith(" "):
break
if not in_documents:
continue
stripped = line.strip()
if stripped.startswith("- path:"):
_, value = stripped.split(":", 1)
paths.append(strip_quotes(value))
return paths
def doc_readmes_from_taxonomy() -> dict[Path, list[str]]:
"""Return docs README files and required main anchors from taxonomy."""
readmes: dict[Path, list[str]] = {}
for target in taxonomy_document_paths():
path_part, _, anchor = target.partition("#")
if not anchor or not path_part.startswith("docs/") or not path_part.endswith("/README.md"):
continue
readmes.setdefault(Path(path_part), []).append(anchor)
return readmes
+1 -38
View File
@@ -7,51 +7,14 @@ import re
import sys
from pathlib import Path
from lib.taxonomy import doc_readmes_from_taxonomy
ROOT = Path(__file__).resolve().parents[1]
TAXONOMY = ROOT / "metadata/taxonomy.yml"
SUMMARY_LINE = "<summary><strong>完整细粒度目录(点击展开/收起)</strong></summary>"
ANCHOR_PATTERN = re.compile(r"<a\s+id=[\"']([^\"']+)[\"']")
HEADING_PATTERN = re.compile(r"^(#{2,6})\s+(.+?)\s*#*\s*$")
def strip_quotes(value: str) -> str:
return value.strip().strip("\"'")
def taxonomy_document_paths() -> list[str]:
paths: list[str] = []
in_documents = False
for line in TAXONOMY.read_text(encoding="utf-8").splitlines():
if line == "documents:":
in_documents = True
continue
if in_documents and line and not line.startswith(" "):
break
if not in_documents:
continue
stripped = line.strip()
if stripped.startswith("- path:"):
_, value = stripped.split(":", 1)
paths.append(strip_quotes(value))
return paths
def doc_readmes_from_taxonomy() -> dict[Path, list[str]]:
readmes: dict[Path, list[str]] = {}
for target in taxonomy_document_paths():
path_part, _, anchor = target.partition("#")
if not anchor or not path_part.startswith("docs/") or not path_part.endswith("/README.md"):
continue
readmes.setdefault(Path(path_part), []).append(anchor)
return readmes
def heading_after(lines: list[str], start: int) -> tuple[int, str] | None:
for line in lines[start + 1 : start + 8]:
stripped = line.strip()