How code-review-graph Generates Wiki Documentation From Community Structure

The code-review-graph project transforms its code-knowledge graph communities into browsable markdown pages by detecting clusters, generating per-community documentation, and emitting an index file.

The code-review-graph open-source tool analyzes codebases as knowledge graphs and automatically produces wiki documentation. This article explains how it converts abstract community structure into practical markdown documentation based on the implementation in code_review_graph/wiki.py.

Detecting Communities From the Graph

The wiki generation process begins by identifying cohesive code communities. The generate_wiki function calls get_communities(store) from code_review_graph/communities.py to obtain community data:

def generate_wiki(store: GraphStore, output_dir: Path, force: bool = False) -> Dict[str, int]:
    communities = get_communities(store)  # Returns list of community dicts

    # ... each containing: name, size, members, cohesion, language, etc.

Each community dictionary contains metadata including name, size, members, cohesion score, and dominant programming language. These values drive the content of the resulting wiki pages.

Creating Safe Filenames With _slugify

Community names must become filesystem-safe paths. The _slugify function in code_review_graph/wiki.py handles this normalization:

  • Normalizes Unicode to ASCII
  • Drops non-ASCII characters entirely
  • Replaces non-alphanumeric characters with hyphens
  • Truncates to 80 characters maximum
  • Falls back to "unnamed" if the result is empty
def _slugify(name: str) -> str:
    # Normalization and truncation logic (lines 24-30)

    # Returns filesystem-safe string for markdown filenames

Building Per-Community Markdown Pages

The _generate_community_page function assembles comprehensive documentation for each community. This core generator creates structured markdown with multiple sections.

Page Structure

Section Content Source
Header Community name as H1
Overview Size, cohesion, language, optional description
Members table Up to 50 nodes via store.get_node
Execution Flows Top 10 flows via get_flows and store.get_flow_qualified_names
Dependencies Cross-community edges via store.get_outgoing_targets / store.get_incoming_sources

The members table displays node name, kind (function, class, etc.), file path, and line range. Execution flows show how code travels through community members. Dependency counts reveal coupling between communities.

Writing Pages and Handling Collisions

The main generate_wiki loop manages file output with several safeguards:

  1. Unique slugs – Appends "‑2", "‑3", etc. when community names collide
  2. Change detection – Skips writing if content matches existing file (unless force=True)
  3. Statistics tracking – Returns counts of generated, updated, and unchanged pages
stats = generate_wiki(store, Path("./wiki"), force=False)

# Returns: {'pages_generated': 12, 'pages_updated': 3, 'pages_unchanged': 5}

These mechanics ensure incremental updates rather than full regeneration, preserving modification timestamps and reducing I/O.

Generating the Index Page

After all community pages are emitted, generate_wiki constructs an index.md listing every community with:

  • Community name (linked to its page)
  • Member count
  • Quick navigation to subsections

The index follows the same change-detection logic—only rewritten when content differs from the previous version.

Retrieving Pages Programmatically

The get_wiki_page function enables runtime access to generated documentation. It supports flexible lookup:

  1. Slugified name match (primary)
  2. Exact filename match with path-traversal protection
  3. Partial substring search within the wiki directory
from code_review_graph.wiki import get_wiki_page

# Find by natural name, exact file, or partial match

markdown = get_wiki_page("./wiki", "Data Processing")

This three-tier resolution makes the wiki navigable by both humans and automated tools.

Practical Usage Example

from pathlib import Path
from code_review_graph.graph import GraphStore
from code_review_graph.wiki import generate_wiki, get_wiki_page

# Load your analyzed codebase graph

store = GraphStore.load("/tmp/graph.db")

# Generate complete wiki documentation

stats = generate_wiki(store, Path("./wiki"))
print(f"Created {stats['pages_generated']} new pages, "
      f"updated {stats['pages_updated']}, "
      f"skipped {stats['pages_unchanged']} unchanged")

# Later: retrieve specific community documentation

content = get_wiki_page("./wiki", "Authentication Handlers")

Running this produces a directory structure like:


wiki/
├── index.md
├── authentication-handlers.md
├── data-processing.md
├── http-routing.md
└── ...

Key Implementation Files

File Responsibility
code_review_graph/wiki.py Core generation: _slugify, _generate_community_page, generate_wiki, get_wiki_page
code_review_graph/communities.py Cluster detection via get_communities
code_review_graph/flows.py Execution flow analysis via get_flows
code_review_graph/graph.py Storage layer with GraphStore, get_node, get_outgoing_targets, get_incoming_sources

Summary

  • generate_wiki orchestrates the full pipeline: community detection → page generation → index creation
  • _slugify ensures safe, portable filenames from arbitrary community names
  • _generate_community_page produces rich markdown with members, flows, and dependencies
  • Incremental updates avoid unnecessary writes through content hashing
  • get_wiki_page provides flexible runtime access with security protections

Frequently Asked Questions

How does code-review-graph prevent filename collisions between communities?

When slugified names conflict, generate_wiki appends incrementing suffixes ("‑2", "‑3", etc.) to create unique paths within the generation run. This ensures no community page overwrites another regardless of naming similarities.

Can I force regeneration of unchanged wiki pages?

Yes. Pass force=True to generate_wiki. Without this flag, the function compares new content against existing files and skips writes when identical, tracking these as unchanged in the returned statistics.

What limits exist on the members table in community pages?

The _generate_community_page function caps the members table at 50 entries to prevent unwieldy documentation. All members remain queryable through the GraphStore directly; the wiki surfaces the most significant subset.

How does get_wiki_page protect against directory traversal attacks?

Before returning any file, get_wiki_page validates that the resolved path remains within the specified wiki directory. This prevents malicious inputs like "../../../etc/passwd" from escaping the intended documentation root.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →