-
Notifications
You must be signed in to change notification settings - Fork 1
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.
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.
The repos.txt file contains a line-separated list of repositories with optional project grouping. The format supports two syntax variants:
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/.
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.
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
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:
- It contains a
:character, AND - 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
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 inowner/repoformat
Sources: main.go:72-75
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
When generating a multi-repository wiki, the generateWiki() function handles all grouped repositories as a cohesive unit:
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
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
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
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
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
Generate all wikis defined in repos.txt with mixed standalone and grouped configurations:
./wikigen -f repos.txtSpecify 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.
Use the -local flag to generate a wiki from multiple local directories:
./wikigen -local /path/to/project-dir myprojectSources: main.go:904-923
wikigen supports two levels of parallelism:
-
-pflag: Number of wikis (projects/standalone repos) to process in parallel -
-ppflag: 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
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
In a multi-repository wiki, Claude Code generates several types of pages:
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
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
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
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
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}/"]
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
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
- System Overview — Introduction to wikigen and its architecture approach
- Repository Management & Cloning — Repository operations and authentication
- CLI Interface & Flags — Complete command-line interface documentation
- Wiki Generation Pipeline — Complete wiki generation process
- Claude Code Integration — How Claude Code analyzes multiple repositories
- Input Validation & Security — Repository validation mechanisms
- System Overview
- Architecture & Design
- CLI Usage & Commands
- Configuration & Environment
- Input Formats & Repository Configuration
- Authentication & Git Integration
- Output Format & Wiki Structure
- Error Handling & Retry Mechanism
- Parallel Processing & Performance
- Input Validation & Security
- Build & Deployment
- Claude Code Integration
- Wiki Generation Processing Flow
- Multi-Repository Wiki Support
- Progress Tracking & Output Modes