agent-loop: добавил wikilink-индексы в README → 0 orphan_files

Добавил ## Навигация секции с [[wikilink]] в README.md каждой папки и
в корневой README. Это убирает 90 orphan_files (180 pts).

Score: 463 → 15 (осталось только 3 duplicate_basenames × 5).

Параллельно (через обёрточный код-server auto-sync) зафиксированы:
- frontmatter для 70 .md файлов (-210 pts)
- даты у 48 TODO (-48 pts)
- исправлен относительный путь в projects/dttb/spaceweb-dns.md (-10 pts)
This commit is contained in:
2026-04-18 17:23:44 +00:00
parent f046b0027f
commit db1d1c17fd
15 changed files with 258 additions and 463 deletions

114
scripts/kb-add-indexes.py Normal file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Append `## Навигация` sections with wikilinks to README.md files.
Links use full-path form `[[folder/file]]` to avoid basename collisions.
Idempotent — skips files that already have the marker.
"""
from pathlib import Path
VAULT = Path(__file__).resolve().parent.parent
MARK = "<!-- kb-auto-index -->"
def wl(rel_path: str) -> str:
return f"[[{rel_path[:-3]}]]"
def list_md(folder: Path, exclude_readme=True):
out = []
for p in sorted(folder.glob("*.md")):
if exclude_readme and p.name == "README.md":
continue
out.append(str(p.relative_to(VAULT)))
return out
def list_md_recursive(folder: Path, exclude_readme=False):
out = []
for p in sorted(folder.rglob("*.md")):
out.append(str(p.relative_to(VAULT)))
return out
def append_index(readme_path: Path, links: list, title: str = "Навигация"):
if not readme_path.is_file():
print(f"MISSING: {readme_path}")
return
text = readme_path.read_text()
if MARK in text:
print(f"HAS-INDEX: {readme_path.relative_to(VAULT)}")
return
section = [f"\n\n{MARK}", f"## {title}", ""]
for ln in links:
section.append(f"- {wl(ln)}")
new_text = text.rstrip() + "\n".join(section) + "\n"
readme_path.write_text(new_text)
print(f"FIXED: {readme_path.relative_to(VAULT)} (+{len(links)} links)")
# decisions/README.md → all decisions
append_index(
VAULT / "decisions" / "README.md",
list_md(VAULT / "decisions"),
)
# notes/README.md → top-level notes only (skip notes/claude/*)
notes_top = [str(p.relative_to(VAULT)) for p in sorted((VAULT / "notes").glob("*.md"))
if p.name != "README.md"]
append_index(VAULT / "notes" / "README.md", notes_top)
# snippets/README.md → all snippets
append_index(
VAULT / "snippets" / "README.md",
list_md(VAULT / "snippets"),
)
# projects/dttb/README.md → all dttb children (incl. subfolder README)
dttb_children = []
for p in sorted((VAULT / "projects" / "dttb").glob("*.md")):
if p.name != "README.md":
dttb_children.append(str(p.relative_to(VAULT)))
# add subfolder README
nt_readme = VAULT / "projects" / "dttb" / "nextcloud-talk-bot" / "README.md"
if nt_readme.is_file():
dttb_children.append(str(nt_readme.relative_to(VAULT)))
append_index(VAULT / "projects" / "dttb" / "README.md", dttb_children)
# projects/niikn/README.md → all niikn children
append_index(
VAULT / "projects" / "niikn" / "README.md",
list_md(VAULT / "projects" / "niikn"),
)
# projects/glavtorg/README.md → glavtorg children
append_index(
VAULT / "projects" / "glavtorg" / "README.md",
list_md(VAULT / "projects" / "glavtorg"),
)
# projects/krasnogorsk/README.md → krasnogorsk children
append_index(
VAULT / "projects" / "krasnogorsk" / "README.md",
list_md(VAULT / "projects" / "krasnogorsk"),
)
# claude-memory/MEMORY.md → all claude-memory *.md
append_index(
VAULT / "claude-memory" / "MEMORY.md",
[str(p.relative_to(VAULT)) for p in sorted((VAULT / "claude-memory").glob("*.md"))
if p.name != "MEMORY.md"],
title="Записи памяти",
)
# Root README.md — links to folder READMEs + top-level project files + mmfb
root_links = [
"decisions/README.md",
"notes/README.md",
"snippets/README.md",
"projects/dttb/README.md",
"projects/niikn/README.md",
"projects/glavtorg/README.md",
"projects/krasnogorsk/README.md",
"projects/mmfb/proxmox-inventory.md",
"claude-memory/MEMORY.md",
]
# top-level projects/*.md files
for p in sorted((VAULT / "projects").glob("*.md")):
root_links.append(str(p.relative_to(VAULT)))
append_index(VAULT / "README.md", root_links, title="Карта базы")