Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions .github/scripts/generate-index.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
"""Generate INDEX.md and community-index.yaml from registry YAML files."""

import yaml
import sys
from datetime import datetime, timezone
from pathlib import Path

import yaml

REGISTRY_DIR = Path("registry")
CATEGORIES_FILE = Path("categories.yaml")
OUTPUT_FILE = Path("INDEX.md")
Expand All @@ -23,16 +25,48 @@ def load_categories():

def load_modules():
modules = []
for directory in ["official", "utility", "community"]:
seen = set()

def add_module(module, directory, source):
if not isinstance(module, dict):
print(f"Warning: module entry in {source} is not a mapping; skipping", file=sys.stderr)
return
name = module.get("name")
if not name:
print(f"Warning: module in {source} is missing a name; skipping", file=sys.stderr)
return
key = (directory, name)
if key in seen:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(.github/scripts/generate-index.py:36) Duplicate modules (same (directory, name)) are currently dropped silently, which can make it hard to notice conflicting registry sources or unintended duplicates.

Severity: low

Generating Fix in Augment link...

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

print(f"Warning: duplicate module {name!r} in {source}; skipping", file=sys.stderr)
return
seen.add(key)
module["_directory"] = directory
modules.append(module)

official_file = REGISTRY_DIR / "official.yaml"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(.github/scripts/generate-index.py:42) With registry/official.yaml now loaded as the official source, load_modules() will still also read registry/official/*.yaml if that directory exists; ensure that’s intended since it can reintroduce the mixed-model state the docs are moving away from.

Severity: low

Generating Fix in Augment link...

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

if official_file.exists():
data = load_yaml(official_file)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(.github/scripts/generate-index.py:44) If registry/official.yaml exists but is empty/invalid, load_yaml() can return None and data.get("modules", []) will raise, breaking the index generation workflow.

Severity: medium

Generating Fix in Augment link...

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

if data is None:
print(f"Warning: {official_file} is empty; skipping", file=sys.stderr)
elif not isinstance(data, dict):
print(f"Warning: {official_file} must contain a top-level mapping; skipping", file=sys.stderr)
else:
modules_data = data.get("modules", [])
if not isinstance(modules_data, list):
print(f"Warning: {official_file} has a non-list modules field; skipping", file=sys.stderr)
modules_data = []
for module in modules_data:
add_module(module, "official", official_file)

for directory in ["utility", "community"]:
dir_path = REGISTRY_DIR / directory
if not dir_path.exists():
continue
for yaml_file in sorted(dir_path.glob("*.yaml")):
if yaml_file.name == "registry-schema.yaml":
continue
module = load_yaml(yaml_file)
module["_directory"] = directory
modules.append(module)
add_module(module, directory, yaml_file)
return modules


Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Registry Structure

| Category | Directory | Description | SHA Required | Updates |
| -------- | --------- | ----------- | ------------ | ------- |
| **Official** | `registry/official/` | Core BMad modules maintained by the BMad team | No — always tracks main | Managed internally |
| Category | Registry Location | Description | SHA Required | Updates |
| -------- | ----------------- | ----------- | ------------ | ------- |
| **Official** | `registry/official.yaml` | Core BMad modules maintained by the BMad team | No — always tracks main | Managed internally |
| **Utility** | `registry/utility/` | BMad ecosystem tools and utilities | No — always tracks main | Managed internally |
| **Community** | `registry/community/` | Modules built and maintained by community members | Yes — pinned to tag + SHA | Author submits update PRs |

Expand Down
25 changes: 23 additions & 2 deletions INDEX.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
# BMad Marketplace Module Index

*Auto-generated from registry entries. 3 modules registered.*
*Auto-generated from registry entries. 9 modules registered.*

**Official:** 0 | **Utility:** 1 | **Community:** 2
**Official:** 6 | **Utility:** 1 | **Community:** 2

## Business & Strategy

| Module | Type | Subcategory | Trust | Description |
| ------ | ---- | ----------- | ----- | ----------- |
| [bmad-creative-intelligence-suite](https://github.com/bmad-code-org/bmad-module-creative-intelligence-suite) | official | Strategy & Planning | BMad Certified | Creative tools for writing, brainstorming, and more |

## Core

| Module | Type | Subcategory | Trust | Description |
| ------ | ---- | ----------- | ----- | ----------- |
| [bmad-core](https://github.com/bmad-code-org/BMAD-METHOD) | official | Core | BMad Certified | Core configuration and shared resources |

## Design & Creative

Expand All @@ -11,8 +23,17 @@
| [suno-band-manager](https://github.com/zarlor/suno-band-manager) | community | Audio & Music | Unverified | AI-powered music production assistant for creating Suno-ready song packages |
| [whiteport-design-studio](https://github.com/bmad-code-org/bmad-method-wds-expansion) | community | UX Design | BMad Certified | Whiteport Design Studio (For UX Professionals) |

## Game Development

| Module | Type | Subcategory | Trust | Description |
| ------ | ---- | ----------- | ----- | ----------- |
| [bmad-game-dev-studio](https://github.com/bmad-code-org/bmad-module-game-dev-studio) | official | Game Engine | BMad Certified | Game development agents and workflows |

## Software Development

| Module | Type | Subcategory | Trust | Description |
| ------ | ---- | ----------- | ----- | ----------- |
| [bmad-builder](https://github.com/bmad-code-org/bmad-builder) | official | Developer Tools | BMad Certified | Build AI agents, workflows, and modules from a conversation |
| [bmad-method](https://github.com/bmad-code-org/BMAD-METHOD) | official | methodology | BMad Certified | AI-driven agile development framework |
| [bmad-method-test-architecture-enterprise](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise) | official | Testing & QA | BMad Certified | Master Test Architect for quality strategy, test automation, and release gates |
| [bmad-utility-skills](https://github.com/bmad-code-org/bmad-utility-skills) | utility | Developer Tools | BMad Certified | Utility skills for BMad contributors - issue triage, changelog drafting, and release automation |
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ Full details in [CONTRIBUTING.md](CONTRIBUTING.md). Before submitting, review th

## How It Works

The registry contains a YAML entry for each module, organized into three directories:
The registry contains a YAML entry for each module, organized by registry location:

| Category | Directory | Description |
| -------- | --------- | ----------- |
| **Official** | `registry/official/` | Core BMad modules maintained by the BMad team — always tracks main |
| Category | Registry Location | Description |
| -------- | ----------------- | ----------- |
| **Official** | `registry/official.yaml` | Core BMad modules maintained by the BMad team — always tracks main |
| **Utility** | `registry/utility/` | BMad ecosystem tools and utilities — always tracks main |
| **Community** | `registry/community/` | Modules built by community members — pinned to approved version tag + commit SHA |

Each module also declares a `category` and `subcategory` from [categories.yaml](categories.yaml) for discoverability.
Official modules are listed in `registry/official.yaml`. Utility and community modules are stored as one YAML file per module in their registry directories. Each module also declares a `category` and `subcategory` from [categories.yaml](categories.yaml) for discoverability.

Browse all available modules in the **[Module Index](INDEX.md)** (auto-generated).

Expand Down
7 changes: 7 additions & 0 deletions categories.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
categories:
core:
name: Core
subcategories:
core:
name: Core
description: Shared configuration, foundational resources, and installer defaults

ai-and-machine-learning:
name: AI & Machine Learning
subcategories:
Expand Down
2 changes: 1 addition & 1 deletion registry/community-index.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto-generated from registry/community/*.yaml - do not edit manually
generated: '2026-05-06T22:29:43Z'
generated: '2026-05-09T13:38:54Z'
modules:
- name: suno-band-manager
display_name: Suno Band Manager (Mac)
Expand Down
65 changes: 60 additions & 5 deletions registry/registry-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ schema:
required: false
description: Path to module.yaml within the repo (e.g., skills/module.yaml)

source_root:
type: string
required: false
description: Path to a pure-skill payload root when a module is not module.yaml-based

npm_package:
type: string
required: false
Expand All @@ -54,6 +59,11 @@ schema:
required: false
description: Whether the module is selected by default in the installer

built_in:
type: boolean
required: false
description: Whether the module is built into the core installer

# Classification
type:
type: string
Expand All @@ -76,12 +86,57 @@ schema:
required: false
description: List of keywords for search and discovery

default_channel:
type: string
required: false
enum: [stable, next]
description: Default install channel when the installer supports channel selection

install_targets:
type: array
required: false
description: IDE or runtime entrypoints where runnable skills should be installed

worker_targets:
type: array
required: false
description: Worker runtimes supported by the module

requirements:
type: array
required: false
description: Runtime requirements or operator prerequisites for the module

install_note:
type: string
required: false
description: Installer-facing note shown when the module is selected

# Version and trust
# version: (community only, required) — pinned approved version
# approved_tag: (community only, required) — git tag of approved version
# approved_sha: (community only, required) — full commit SHA of approved tag
# approved_date: (community only, required) — date of approval (YYYY-MM-DD)
# reviewer: (community only, required) — GitHub handle of reviewer
version:
type: string
required: false
description: Community module pinned approved version

approved_tag:
type: string
required: false
description: Community module git tag for the approved version

approved_sha:
type: string
required: false
description: Community module full commit SHA for the approved tag

approved_date:
type: string
required: false
description: Community module approval date in YYYY-MM-DD format

reviewer:
type: string
required: false
description: GitHub handle of the community module reviewer

trust_tier:
type: string
Expand Down