Migrate all repos into monorepo context folders

Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
2026-06-30 20:39:52 +02:00
parent 2f2b295531
commit a5f8fb49ab
1717 changed files with 447332 additions and 0 deletions
@@ -0,0 +1 @@
"""Wiki-link generation and stub page creation."""
@@ -0,0 +1,71 @@
"""Wiki-link generation from detected entities.
Converts entity references to SilverBullet-compatible wiki-links:
- Person → [[people/firstname-lastname]]
- Project → [[projects/project-slug]]
Only the first occurrence of each entity is linked; subsequent mentions remain plain text.
"""
import logging
from slugify import slugify
from ingestion.enrichment.models import Entity
logger = logging.getLogger(__name__)
def _entity_to_wikilink(entity: Entity) -> str:
"""Convert an entity to its wiki-link representation."""
slug = slugify(entity.value)
if entity.type == "person":
return f"[[people/{slug}]]"
elif entity.type == "project":
return f"[[projects/{slug}]]"
return ""
def generate_wiki_links(text: str, entities: list[Entity]) -> str:
"""Insert wiki-links into text for person and project entities.
Only the first occurrence of each entity's value is converted to a wiki-link.
Dates and action_items are skipped (handled by frontmatter/renderer).
Args:
text: The document body text.
entities: List of detected entities from enrichment.
Returns:
Text with wiki-links inserted at first occurrence of each entity.
"""
# Filter to linkable entity types
linkable = [e for e in entities if e.type in ("person", "project")]
# Track which entity values we've already linked (case-insensitive)
linked_values: set[str] = set()
for entity in linkable:
lower_val = entity.value.lower()
if lower_val in linked_values:
continue
# Find first occurrence and replace it
idx = text.find(entity.value)
if idx == -1:
# Try case-insensitive search
idx = text.lower().find(lower_val)
if idx == -1:
continue
# Use the actual text at that position for replacement
original_text = text[idx : idx + len(entity.value)]
else:
original_text = entity.value
wikilink = _entity_to_wikilink(entity)
if wikilink:
# Replace only the first occurrence
text = text[:idx] + wikilink + text[idx + len(original_text) :]
linked_values.add(lower_val)
return text
@@ -0,0 +1,56 @@
"""Stub page creation for entities that don't yet have a NoteGraph page.
Creates minimal markdown pages in the appropriate directory (people/ or projects/)
so that wiki-links resolve immediately after import.
"""
import logging
from pathlib import Path
from slugify import slugify
from ingestion.enrichment.models import Entity
logger = logging.getLogger(__name__)
def create_stub_pages(entities: list[Entity], notes_dir: Path) -> list[Path]:
"""Create stub pages for entities that don't have existing pages.
Args:
entities: List of entities to check/create stubs for.
notes_dir: Root notes directory (e.g., ./notes).
Returns:
List of paths to newly created stub pages.
"""
notes_dir = Path(notes_dir)
created: list[Path] = []
linkable = [e for e in entities if e.type in ("person", "project")]
seen_slugs: set[str] = set()
for entity in linkable:
slug = slugify(entity.value)
if slug in seen_slugs:
continue
seen_slugs.add(slug)
if entity.type == "person":
target = notes_dir / "people" / f"{slug}.md"
elif entity.type == "project":
target = notes_dir / "projects" / f"{slug}.md"
else:
continue
if target.exists():
logger.debug("Page already exists: %s", target)
continue
# Create stub page
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(f"# {entity.value}\n", encoding="utf-8")
logger.info("Created stub page: %s", target)
created.append(target)
return created