Skip to content

Multi Repository Wikis

github-actions[bot] edited this page Mar 14, 2026 · 1 revision

Multi-Repository Wikis

Multi-repository wiki support in wikigen enables grouping multiple related repositories into a single comprehensive wiki with cross-repository documentation. This feature allows teams to generate unified architectural documentation that shows how services, modules, and components interact across repository boundaries. This page documents the repos.txt format, project grouping syntax, handling of standalone versus grouped repositories, and the generation of cross-repository pages showing inter-service interactions.

Overview

wikigen supports two documentation models:

  • Standalone wikis: Each repository generates its own isolated wiki
  • Multi-repository (grouped) wikis: Multiple repositories are merged into a single wiki with cross-repository documentation pages

The multi-repository model is particularly useful for microservices architectures, frontend-backend separations, and projects where multiple repositories form a cohesive system. When generating multi-repository wikis, Claude Code analyzes all repositories together to create documentation pages that span repositories and show how services interact.

repos.txt Format and Project Grouping

The repos.txt file contains a line-separated list of repositories with optional project grouping. The format supports two syntax variants:

Standalone Repositories

Each line with the owner/repo format creates an independent wiki:

tomohiro-owada/wikigen
anthropics/anthropic-sdk-python
golang/go

This generates three separate wiki directories: wiki-output/wikigen/, wiki-output/anthropic-sdk-python/, and wiki-output/go/.

Grouped Repositories (Multi-Repository Wikis)

Lines with the project:owner/repo format group multiple repositories into a single wiki:

myproject:owner/frontend
myproject:owner/backend
myproject:owner/shared-lib

This generates a single wiki directory wiki-output/myproject/ containing documentation that spans all three repositories, with cross-repository pages explaining how the frontend calls the backend API, how both use the shared library, and system-wide architectural patterns.

Mixed Configuration

A repos.txt file can combine both formats:

# Standalone wikis
repo1:owner/one
repo2:owner/two

# Multi-repository wiki
platform:owner/api-gateway
platform:owner/auth-service
platform:owner/data-service

This creates four wikis:

  • wiki-output/one/ (standalone)
  • wiki-output/two/ (standalone)
  • wiki-output/platform/ (grouped, spanning three repos)

Sources: main.go:672-688

Parsing and Validation

The parseRepoList() function parses the repos.txt file and separates entries into standalone and grouped repositories:

func parseRepoList(lines []string) (standalone []RepoEntry, groups map[string][]string) {
	groups = make(map[string][]string)
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		if before, after, ok := strings.Cut(line, ":"); ok && !strings.Contains(before, "/") {
			// project:owner/repo format
			groups[before] = append(groups[before], after)
		} else {
			// standalone owner/repo format
			standalone = append(standalone, RepoEntry{Repo: line})
		}
	}
	return
}

The function uses strings.Cut() to split on the first : character. A line is classified as grouped only if:

  1. It contains a : character, AND
  2. The part before the : does not contain / (ensuring it's a project name, not a URL with protocol)

Comments (lines starting with #) and empty lines are ignored.

Sources: main.go:672-688

RepoEntry Data Structure

The RepoEntry type represents a parsed repository entry:

type RepoEntry struct {
	Project string // group name (empty = standalone)
	Repo    string // owner/repo
}
  • Project: The project/group name (empty string for standalone repos)
  • Repo: The repository identifier in owner/repo format

Sources: main.go:72-75

Task Building and Processing

After parsing, wikigen constructs a task list where each task represents either a standalone wiki or a grouped wiki:

type task struct {
	name  string
	repos []string
}

// For each standalone repo:
tasks = append(tasks, task{name: name, repos: []string{entry.Repo}})

// For each project group:
tasks = append(tasks, task{name: project, repos: repoList})

Each task is processed independently, either in serial or in parallel (controlled by the -p flag). For a multi-repository task, all repositories are cloned and passed together to Claude Code for unified analysis.

Sources: main.go:961-987

Wiki Generation for Grouped Repositories

When generating a multi-repository wiki, the generateWiki() function handles all grouped repositories as a cohesive unit:

Repository Cloning

All repositories in the group are cloned into the clone directory:

for _, repo := range repos {
	repoURL := repo
	if !strings.HasPrefix(repo, "http") {
		repoURL = fmt.Sprintf("https://github.com/%s", repo)
	}
	// Parse owner/repo from URL
	parts := strings.Split(...)
	owner := parts[0]
	repoName := strings.TrimSuffix(parts[1], ".git")

	// Clone to directory named owner_reponame
	repoDir := filepath.Join(cloneDir, fmt.Sprintf("%s_%s", owner, repoName))
	gitClone(repoURL, token, repoDir)
	repoDirs = append(repoDirs, repoDir)
}

Multiple cloned directories are collected into the repoDirs slice, enabling Claude Code to analyze all repositories together.

Sources: main.go:488-515

Structure Determination with All Repositories

Claude Code is invoked with all repository directories available via --add-dir:

structureContent, err := claudeCall(
	claudePath, model,
	repoDirs,  // all repos in the group
	xmlSystemPrompt,
	structurePrompt(projectName, repos, language),
	wikiDir
)

The structure prompt explicitly instructs Claude to create cross-repository documentation:

## Rules for Multi-Repository Projects
- When multiple repositories form one project, create CROSS-REPOSITORY documentation
- Show how repositories interact with each other (e.g., frontend calls backend API)
- Create architecture pages that span all repositories
- Individual repository details should still get their own focused pages
- Clearly indicate which repository each page primarily covers

Sources: main.go:527-531, main.go:183-272

Page Generation with Multi-Repository Context

Each wiki page is generated with all repository directories available, allowing pages to draw information and examples from multiple repositories:

_, err := claudeCall(claudePath, model, repoDirs, "",
	pagePrompt(*page, allPages, projectName, repos, language),
	wikiDir)

The page prompt includes the project name and all repositories, providing context for cross-repository documentation.

Sources: main.go:592

Output Structure for Multi-Repository Wikis

Multi-repository wikis generate a single unified output directory:

wiki-output/myproject/
  Home.md                    # Landing page listing all repos
  _Sidebar.md                # Navigation across all pages
  System-Architecture.md     # Cross-repo architecture
  API-Integration.md         # How frontend calls backend
  Shared-Components.md       # Common patterns used across repos
  Frontend-Specification.md  # Frontend-specific details
  Backend-API.md             # Backend-specific details
  Data-Model.md              # Unified data model across repos
  ... (other pages)
  _errors.log                # Error log if any pages failed

Home.md for Multi-Repository Wikis

The Home.md file includes a "Repositories" section when multiple repositories are involved:

if len(repos) > 1 {
	home.WriteString("## Repositories\n\n")
	for _, r := range repos {
		home.WriteString(fmt.Sprintf("- %s\n", r))
	}
	home.WriteString("\n")
}

This clearly identifies which repositories are included in the grouped wiki.

Sources: main.go:638-665

CLI Usage for Multi-Repository Wikis

Single-Line Generation from repos.txt

Generate all wikis defined in repos.txt with mixed standalone and grouped configurations:

./wikigen -f repos.txt

Inline Repository Specification

Specify grouped repositories directly on the command line:

# Multi-repository wiki
./wikigen -r "myproject:owner/frontend,myproject:owner/backend,myproject:owner/shared"

This generates a single wiki for myproject containing all three repositories.

Local Multi-Repository Generation

Use the -local flag to generate a wiki from multiple local directories:

./wikigen -local /path/to/project-dir myproject

Sources: main.go:904-923

Parallelism for Multi-Repository Wikis

wikigen supports two levels of parallelism:

  • -p flag: Number of wikis (projects/standalone repos) to process in parallel
  • -pp flag: Number of pages per wiki to generate in parallel

For example, with 3 standalone wikis and 1 grouped wiki:

./wikigen -f repos.txt -p 2 -pp 5
  • Up to 2 wikis are generated concurrently (e.g., one standalone while the grouped wiki's first pages are being generated)
  • Within each wiki, up to 5 pages are generated in parallel

Sources: main.go:912-913, main.go:1018-1047

Input Validation for Repositories

All repository inputs are validated to ensure security:

var validRepoPattern = regexp.MustCompile(`^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$`)

func validateRepo(repo string) error {
	if !validRepoPattern.MatchString(repo) {
		return fmt.Errorf("invalid repo format: %q (expected owner/repo)", repo)
	}
	if strings.Contains(repo, "..") {
		return fmt.Errorf("path traversal detected in repo: %q", repo)
	}
	if strings.ContainsAny(repo, ";&|`$(){}[]!~") {
		return fmt.Errorf("invalid characters in repo: %q", repo)
	}
	return nil
}

Validation is applied to each repository in both standalone and grouped configurations. Invalid repositories cause the entire wiki generation to fail with a clear error message.

Sources: main.go:79-92

Cross-Repository Documentation Pages

In a multi-repository wiki, Claude Code generates several types of pages:

Architecture Pages Spanning Repositories

Pages that document how services/modules interact:

  • System Architecture: Overall design showing all repositories and their interactions
  • API Integration: How frontend services call backend APIs
  • Data Flow: How data flows across repositories
  • Component Interactions: How shared libraries are used across repositories

Repository-Specific Pages with Cross-Repository References

Pages that focus on individual repositories while referencing how they interact with others:

  • Frontend Specification (if frontend repo exists): UI components, routing, calling backend APIs
  • Backend API (if backend repo exists): API endpoints, database, calling shared services
  • Shared Library: Components and utilities used by other repositories

Unified Pages

Pages that consolidate information from multiple repositories:

  • Configuration & Environment: Environment variables across all repositories
  • Build & Deployment: How all repositories are built and deployed together
  • Testing Strategy: How integration tests span multiple repositories

The exact pages generated depend on the actual code in the repositories, as determined by Claude Code's analysis. See Claude Code Integration for details on how structure determination works.

Sources: main.go:200-244

Error Handling in Multi-Repository Generation

Each repository in a group is validated before processing:

for _, repo := range repos {
	if err := validateRepo(repo); err != nil {
		return result, err
	}
}

If any repository in a group fails validation, the entire group fails. If cloning fails for any repository in the group, the group is skipped but other groups/standalone wikis continue.

Page-level failures are handled with automatic retry (up to 3 attempts). Failed pages are documented in _errors.log with timestamps.

Sources: main.go:481-486, main.go:462-470

Process Flow Diagram

flowchart TD
    A["repos.txt or CLI args"] --> B["parseRepoList()"]
    B --> C{Format?}
    C -->|owner/repo| D["Standalone<br/>RepoEntry"]
    C -->|project:owner/repo| E["Grouped<br/>RepoEntry"]
    D --> F["Task: name=owner/repo<br/>repos=[owner/repo]"]
    E --> G["Task: name=project<br/>repos=[repo1,repo2,...]"]
    F --> H["generateWiki()"]
    G --> H
    H --> I["Clone all repos<br/>in task"]
    I --> J["Structure Determination<br/>Claude Code analyzes all repos"]
    J --> K["Parse XML structure"]
    K --> L["Generate Home.md<br/>with Repositories section"]
    L --> M["Parallel Page Generation<br/>with all repo context"]
    M --> N["Validate and retry<br/>failed pages"]
    N --> O["Output: wiki-output/{project}/"]
Loading

Configuration and Environment Variables

Multi-repository generation respects the same configuration options as standalone generation:

Option Environment Variable Purpose
-f repos.txt - Read repos from file
-r repos - Comma-separated repos (both formats)
-token GITHUB_TOKEN GitHub PAT for authentication
-model CLAUDE_MODEL Claude model selection (haiku, sonnet, opus)
-o WIKI_OUTPUT_DIR Output directory for grouped wikis
-p WIKI_PARALLEL Parallel wikis (repos/projects)
-pp WIKI_PAGE_PARALLEL Parallel pages per wiki
-lang WIKI_LANGUAGE Output language

Sources: main.go:692-715, main.go:717-737

Example: Microservices Architecture

Consider a microservices project with three repositories:

# repos.txt
backend:acme/api-gateway
backend:acme/auth-service
backend:acme/payment-service

This generates a unified wiki at wiki-output/backend/ with pages such as:

  • Home.md: Lists all three services and provides navigation
  • System Architecture: Diagram showing API gateway routing to services
  • API Specification: All endpoints across all services
  • Authentication Flow: How auth-service validates requests
  • Data Model: Shared database schemas
  • Service Integration: How services call each other
  • API Gateway Configuration: Routing and load balancing
  • Auth Service Details: Implementation specifics
  • Payment Service Details: Implementation specifics
  • Deployment: How all three services are deployed together

Each page can reference code from any of the three repositories, enabling comprehensive cross-service documentation.

Sources: README.md:95-108

Related Pages

Clone this wiki locally