leadtech-bmad-mcp: close lot 1 and implement lot 2 index

This commit is contained in:
MaksTinyWorkshop
2026-03-31 15:57:09 +02:00
parent ff8eac0dfb
commit bafc872030
9 changed files with 344 additions and 25 deletions

View File

@@ -9,6 +9,10 @@ from leadtech_bmad_mcp.knowledge import (
list_domain_files,
search_knowledge,
search_global_docs,
build_search_index,
write_search_index,
load_search_index,
get_index_path,
read_knowledge_doc,
read_knowledge_document,
_extract_excerpt,
@@ -147,6 +151,56 @@ def test_search_knowledge_uses_front_matter_tags(tmp_path):
assert results[0]["title"] == "Backend — Patterns : NestJS"
def test_build_search_index_includes_knowledge_and_global_docs(tmp_path):
paths = _make_knowledge(tmp_path)
_make_global_docs(tmp_path)
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
payload = build_search_index()
assert payload["version"] == 1
assert any(entry["kind"] == "knowledge" for entry in payload["entries"])
assert any(entry["kind"] == "global" for entry in payload["entries"])
def test_search_knowledge_uses_index_when_present(tmp_path):
paths = _make_knowledge(tmp_path)
_make_global_docs(tmp_path)
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
write_search_index()
(paths.knowledge / "backend" / "patterns" / "contracts.md").write_text(
"contenu remplace sans mot cle",
encoding="utf-8",
)
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
results = search_knowledge("backend", "zod")
assert results
assert results[0]["title"] == "contracts"
def test_search_knowledge_falls_back_when_index_missing(tmp_path):
paths = _make_knowledge(tmp_path)
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
results = search_knowledge("backend", "zod contract")
index = load_search_index()
assert results
assert index is None
def test_load_search_index_invalid_json_returns_none(tmp_path):
paths = _make_knowledge(tmp_path)
get_index_path(paths).write_text("{invalid", encoding="utf-8")
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
payload = load_search_index()
assert payload is None
# ---------------------------------------------------------------------------
# read_knowledge_doc
# ---------------------------------------------------------------------------
@@ -290,6 +344,22 @@ def test_search_global_docs_includes_excerpt(tmp_path):
assert len(results[0]["excerpt"]) > 0
def test_search_global_docs_uses_index_when_present(tmp_path):
paths = _make_global_docs(tmp_path)
(paths.knowledge / "backend" / "patterns").mkdir(parents=True)
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
write_search_index()
(tmp_path / "40_decisions_et_archi.md").write_text("contenu modifie sans postgres", encoding="utf-8")
with patch("leadtech_bmad_mcp.knowledge.get_paths", return_value=paths):
results = search_global_docs("PostgreSQL")
assert results
assert results[0]["title"] == "architecture"
def test_search_global_docs_missing_file_skipped(tmp_path):
# Seulement 40_ créé, les deux autres absents
(tmp_path / "40_decisions_et_archi.md").write_text("PostgreSQL recommandé.")