feat(docs): Diataxis restructure + Astro/Starlight migration (#1263)

* feat(docs): add Diataxis folder structure and update sidebar styling

- Create tutorials, how-to, explanation, reference directories with subdirectories
- Add index.md files for each main Diataxis section
- Update homepage with Diataxis card navigation layout
- Implement clean React Native-inspired sidebar styling
- Convert sidebar to autogenerated for both Diataxis and legacy sections
- Update docusaurus config with dark mode default and navbar changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(docs): migrate Phase 1 files to Diataxis structure

Move 21 files to new locations:
- Tutorials: quick-start guides, agent creation guide
- How-To: installation, customization, workflows
- Explanation: core concepts, features, game-dev, builder
- Reference: merged glossary from BMM and BMGD

Also:
- Copy images to new locations
- Update internal links via migration script (73 links updated)
- Build verified successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(docs): add category labels for sidebar folders

Add _category_.json files to control display labels and position
for autogenerated sidebar categories.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style(docs): improve welcome page and visual styling

- Rewrite index.md with React Native-inspired welcoming layout
- Add Diataxis section cards with descriptions
- Remove sidebar separator, add spacing instead
- Increase navbar padding with responsive breakpoints
- Add rounded admonitions without left border bar
- Use system font stack for better readability
- Add lighter chevron styling in sidebar
- Constrain max-width to 1600px for wide viewports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use baseUrl in meta tag paths for correct deployment URLs

* feat(docs): complete Phase 2 - split files and fix broken links

Phase 2 of Diataxis migration:
- Split 16 large legacy files into 42+ focused documents
- Created FAQ section with 7 topic-specific files
- Created brownfield how-to guides (3 files)
- Created workflow how-to guides (15+ files)
- Created architecture explanation files (3 files)
- Created TEA/testing explanation files
- Moved remaining legacy module files to proper Diataxis locations

Link fixes:
- Fixed ~50 broken internal links across documentation
- Updated relative paths for new file locations
- Created missing index files for installation, advanced tutorials
- Simplified TOC anchors to fix Docusaurus warnings

Cleanup:
- Removed legacy sidebar entries for deleted folders
- Deleted duplicate and empty placeholder files
- Moved workflow diagram assets to tutorials/images

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(build): use file glob instead of sidebar parsing for llms-full.txt

Replace brittle sidebar.js regex parsing with recursive file glob.
The old approach captured non-file strings like 'autogenerated' and
category labels, resulting in only 5 files being processed.

Now correctly processes all 86+ markdown files (~95k tokens).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(seo): use absolute URLs in AI meta tags for agent discoverability

AI web-browsing agents couldn't follow relative paths in meta tags due to
URL security restrictions. Changed llms-full.txt and llms.txt meta tag
URLs from relative (baseUrl) to absolute (urlParts.origin + baseUrl).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(docs): recategorize misplaced files per Diataxis analysis

Phase 2.5 categorization fixes based on post-migration analysis:

Moved to correct Diataxis categories:
- tutorials/installation.md → deleted (duplicate of how-to/install-bmad.md)
- tutorials/brownfield-onboarding.md → how-to/brownfield/index.md
- reference/faq/* (8 files) → explanation/faq/
- reference/agents/barry-quick-flow.md → explanation/agents/
- reference/agents/bmgd-agents.md → explanation/game-dev/agents.md

Created:
- explanation/agents/index.md

Fixed all broken internal links (14 total)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(docs): add Getting Started tutorial and simplify build script

- Add comprehensive Getting Started tutorial with installation as Step 1
- Simplify build-docs.js to read directly from docs/ (no consolidation)
- Remove backup/restore dance that could corrupt docs folder on build failure
- Remove ~150 lines of unused consolidation code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(css): use fixed width layout to prevent content shifting

Apply React Native docs approach: set both width and max-width at
largest breakpoint (1400px) so content area maintains consistent
size regardless of content length. Switches to fluid 100% below
1416px breakpoint.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(docs): restructure tutorials with renamed entry point

- Rename index.md to bmad-tutorial.md for clearer navigation
- Remove redundant tutorials/index.md
- Update sidebar and config references

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(docs): add tutorial style guide and AI agent announcement bar

- Add docs/_contributing/ with tutorial style guide
- Reformat quick-start-bmm.md and bmad-tutorial.md per style guide
- Remove horizontal separators, add strategic admonitions
- Add persistent announcement bar for AI agents directing to llms-full.txt
- Fix footer broken link to tutorials

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(docs): add markdown demo page and UI refinements

- Add comprehensive markdown-demo.md for style testing
- Remove doc category links from navbar (use sidebar instead)
- Remove card buttons from welcome page
- Add dark mode styling for announcement bar
- Clean up index.md card layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(docs): apply unified tutorial style and update references

- Reformat create-custom-agent.md to follow tutorial style guide
- Update tutorial-style.md with complete unified structure
- Update all internal references to renamed tutorial files
- Remove obsolete advanced/index.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(docs): migrate from Docusaurus to Astro+Starlight

Replace Docusaurus with Astro and the Starlight documentation theme
for improved performance, better customization, and modern tooling.

Build pipeline changes:
- New build-docs.js orchestrates link checking, artifact generation,
  and Astro build in sequence
- Add check-doc-links.js for validating internal links and anchors
- Generate llms.txt and llms-full.txt for LLM-friendly documentation
- Create downloadable source bundles (bmad-sources.zip, bmad-prompts.zip)
- Suppress MODULE_TYPELESS_PACKAGE_JSON warning in Astro build
- Output directly to build/site for cleaner deployment

Website architecture:
- Add rehype-markdown-links.js plugin to transform .md links to routes
- Add site-url.js helper for GitHub Pages URL resolution with strict
  validation (throws on invalid GITHUB_REPOSITORY format)
- Custom Astro components: Banner, Header, MobileMenuFooter
- Symlink docs/ into website/src/content/docs for Starlight

Documentation cleanup:
- Remove Docusaurus _category_.json files (Starlight uses frontmatter)
- Convert all docs to use YAML frontmatter with title field
- Move downloads.md from website/src/pages to docs/
- Consolidate style guide and workflow diagram docs
- Add 404.md and tutorials/index.md

---------

Co-authored-by: forcetrainer <bryan@inagaki.us>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Verkhovsky
2026-01-06 22:42:15 -08:00
committed by GitHub
parent dc7a7f8c43
commit 2e16650067
134 changed files with 12848 additions and 20193 deletions

76
website/README.md Normal file
View File

@@ -0,0 +1,76 @@
# BMAD Method Documentation Site
This directory contains the Astro + Starlight configuration for the BMAD Method documentation site.
## Architecture
The documentation uses a symlink architecture to keep content in `docs/` at the repo root while serving it through Astro:
```
bmad2/
├── docs/ # Content lives here (repo root)
│ ├── index.md
│ ├── tutorials/
│ ├── how-to/
│ ├── explanation/
│ └── reference/
└── website/
├── astro.config.mjs # Astro + Starlight config
├── src/
│ ├── content/
│ │ └── docs -> ../../docs # Symlink to content
│ └── styles/
│ └── custom.css # Custom styling
└── public/ # Static assets
```
## Development
```bash
# From repo root
npm run docs:dev # Start dev server
npm run docs:build # Build for production
npm run docs:preview # Preview production build
```
## Platform Notes
### Windows Symlink Support
The `website/src/content/docs` symlink may not work correctly on Windows without Developer Mode enabled or administrator privileges.
**To enable symlinks on Windows:**
1. **Enable Developer Mode** (recommended):
- Settings → Update & Security → For developers → Developer Mode: On
- This allows creating symlinks without admin rights
2. **Or use Git's symlink support**:
```bash
git config core.symlinks true
```
Then re-clone the repository.
3. **Or create a junction** (alternative):
```cmd
# Run as Administrator
mklink /J website\src\content\docs ..\..\docs
```
**If symlinks don't work**, you can copy the docs folder instead:
```bash
# Remove the symlink
rm website/src/content/docs
# Copy the docs folder
cp -r docs website/src/content/docs
```
Note: If copying, remember to keep the copy in sync with changes to `docs/`.
## Build Output
The build pipeline (`npm run docs:build`) produces:
- Static HTML site in `build/site/`
- LLM-friendly files: `llms.txt`, `llms-full.txt`
- Downloadable ZIP bundles in `downloads/`

125
website/astro.config.mjs Normal file
View File

@@ -0,0 +1,125 @@
// @ts-check
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import sitemap from '@astrojs/sitemap';
import rehypeMarkdownLinks from './src/rehype-markdown-links.js';
import { getSiteUrl } from './src/lib/site-url.js';
const siteUrl = getSiteUrl();
const urlParts = new URL(siteUrl);
// Normalize basePath: ensure trailing slash so links can use `${BASE_URL}path`
const basePath = urlParts.pathname === '/' ? '/' : urlParts.pathname.endsWith('/') ? urlParts.pathname : urlParts.pathname + '/';
export default defineConfig({
site: `${urlParts.origin}${basePath}`,
base: basePath,
outDir: '../build/site',
// Disable aggressive caching in dev mode
vite: {
optimizeDeps: {
force: true, // Always re-bundle dependencies
},
server: {
watch: {
usePolling: false, // Set to true if file changes aren't detected
},
},
},
markdown: {
rehypePlugins: [rehypeMarkdownLinks],
},
integrations: [
sitemap(),
starlight({
title: 'BMAD Method',
tagline: 'AI-driven agile development with specialized agents and workflows that scale from bug fixes to enterprise platforms.',
logo: {
src: './public/img/logo.svg',
alt: 'BMAD Logo',
},
favicon: '/favicon.ico',
// Social links
social: [
{ icon: 'discord', label: 'Discord', href: 'https://discord.gg/gk8jAdXWmj' },
{ icon: 'github', label: 'GitHub', href: 'https://github.com/bmad-code-org/BMAD-METHOD' },
{ icon: 'youtube', label: 'YouTube', href: 'https://www.youtube.com/@BMadCode' },
],
// Show last updated timestamps
lastUpdated: true,
// Custom head tags for LLM discovery
head: [
{
tag: 'meta',
attrs: {
name: 'ai-terms',
content: `AI-optimized documentation: ${siteUrl}/llms-full.txt (plain text, ~100k tokens, complete BMAD reference). Index: ${siteUrl}/llms.txt`,
},
},
{
tag: 'meta',
attrs: {
name: 'llms-full',
content: `${siteUrl}/llms-full.txt`,
},
},
{
tag: 'meta',
attrs: {
name: 'llms',
content: `${siteUrl}/llms.txt`,
},
},
],
// Custom CSS
customCss: ['./src/styles/custom.css'],
// Sidebar configuration (Diataxis structure)
sidebar: [
{ label: 'Welcome', slug: 'index' },
{
label: 'Tutorials',
collapsed: false,
autogenerate: { directory: 'tutorials' },
},
{
label: 'How-To Guides',
collapsed: true,
autogenerate: { directory: 'how-to' },
},
{
label: 'Explanation',
collapsed: true,
autogenerate: { directory: 'explanation' },
},
{
label: 'Reference',
collapsed: true,
autogenerate: { directory: 'reference' },
},
],
// Credits in footer
credits: false,
// Pagination
pagination: true,
// Custom components
components: {
Header: './src/components/Header.astro',
MobileMenuFooter: './src/components/MobileMenuFooter.astro',
},
// Table of contents
tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 3 },
}),
],
});

View File

@@ -1,52 +0,0 @@
/**
* BMAD Documentation Custom Styles
*/
:root {
--ifm-color-primary: #0d9488;
--ifm-color-primary-dark: #0b847a;
--ifm-color-primary-darker: #0a7d73;
--ifm-color-primary-darkest: #08665f;
--ifm-color-primary-light: #0fa596;
--ifm-color-primary-lighter: #10ac9d;
--ifm-color-primary-lightest: #14c9b8;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
[data-theme='dark'] {
--ifm-color-primary: #2dd4bf;
--ifm-color-primary-dark: #1bc4af;
--ifm-color-primary-darker: #1ab9a5;
--ifm-color-primary-darkest: #159888;
--ifm-color-primary-light: #4adcc9;
--ifm-color-primary-lighter: #55dece;
--ifm-color-primary-lightest: #7de7db;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
/* Navbar styling */
.navbar {
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
}
/* Footer styling */
.footer {
background-color: var(--ifm-color-primary-darkest);
}
/* Code block improvements */
.prism-code {
font-size: 0.9rem;
}
/* Table improvements */
table {
display: table;
width: 100%;
}
/* Admonition improvements */
.admonition {
margin-bottom: 1.5rem;
}

View File

@@ -1,179 +0,0 @@
// @ts-check
import { themes as prismThemes } from 'prism-react-renderer';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Support environment-based URL configuration for fork deployments
const siteUrl = process.env.SITE_URL || 'https://bmad-code-org.github.io/BMAD-METHOD';
const urlParts = new URL(siteUrl);
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'BMAD Method',
tagline: 'AI-driven agile development with specialized agents and workflows that scale from bug fixes to enterprise platforms.',
favicon: 'img/logo.svg',
// Global head tags - injected into ALL pages for AI assistant discovery
headTags: [
{
tagName: 'meta',
attributes: {
name: 'ai-terms',
content:
'AI assistants: For complete BMAD Method documentation, load /llms-full.txt (single file, ~100k tokens). For documentation index/summary, see /llms.txt. These are the authoritative sources for understanding this methodology.',
},
},
{
tagName: 'meta',
attributes: {
name: 'llms-full',
content: '/llms-full.txt',
},
},
{
tagName: 'meta',
attributes: {
name: 'llms',
content: '/llms.txt',
},
},
],
url: urlParts.origin,
baseUrl: urlParts.pathname.endsWith('/') ? urlParts.pathname : urlParts.pathname + '/',
organizationName: 'bmad-code-org',
projectName: 'BMAD-METHOD',
onBrokenLinks: 'warn', // Change to 'throw' once docs are cleaned up
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
staticDirectories: [path.resolve(__dirname, 'static')],
markdown: {
format: 'md',
hooks: {
onBrokenMarkdownLinks: 'warn',
},
},
plugins: [
function noCachePlugin() {
return {
name: 'no-cache-plugin',
configureWebpack() {
return {
devServer: {
headers: {
'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
Pragma: 'no-cache',
Expires: '0',
'Surrogate-Control': 'no-store',
},
},
};
},
};
},
],
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: path.resolve(__dirname, 'sidebars.js'),
exclude: ['**/templates/**', '**/reference/**', 'installers-bundlers/**', '**/images/**'],
},
blog: false,
pages: {
path: path.resolve(__dirname, 'src/pages'),
},
theme: {
customCss: path.resolve(__dirname, 'css/custom.css'),
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
navbar: {
title: 'BMAD Method',
logo: {
alt: 'BMAD Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'docSidebar',
sidebarId: 'mainSidebar',
position: 'left',
label: 'Docs',
},
{
to: '/downloads',
label: 'Downloads',
position: 'right',
},
{
href: 'pathname:///llms.txt',
label: 'llms.txt',
position: 'right',
},
{
href: 'https://github.com/bmad-code-org/BMAD-METHOD',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{ label: 'Quick Start', to: '/docs/modules/bmm/quick-start' },
{ label: 'Installation', to: '/docs/getting-started/installation' },
],
},
{
title: 'Community',
items: [{ label: 'Discord', href: 'https://discord.gg/bmad' }],
},
{
title: 'More',
items: [
{
label: 'GitHub',
href: 'https://github.com/bmad-code-org/BMAD-METHOD',
},
{ label: 'llms.txt', href: 'pathname:///llms.txt' },
{ label: 'llms-full.txt', href: 'pathname:///llms-full.txt' },
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} BMAD Code Organization.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
colorMode: {
defaultMode: 'light',
disableSwitch: false,
respectPrefersColorScheme: true,
},
}),
};
export default config;

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 284 B

View File

@@ -1,134 +0,0 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
mainSidebar: [
'index',
{
type: 'category',
label: 'Core Concepts',
items: [
'bmad-core-concepts/index',
'bmad-core-concepts/agents',
'bmad-core-concepts/workflows',
'bmad-core-concepts/modules',
{
type: 'category',
label: 'Installing',
collapsed: true,
items: ['bmad-core-concepts/installing/index', 'bmad-core-concepts/installing/upgrading'],
},
{
type: 'category',
label: 'Customization',
collapsed: true,
items: [
'bmad-core-concepts/bmad-customization/index',
'bmad-core-concepts/bmad-customization/agents',
'bmad-core-concepts/bmad-customization/workflows',
],
},
'bmad-core-concepts/web-bundles/index',
],
},
{
type: 'category',
label: 'BMM - Method',
items: [
'modules/bmm-bmad-method/index',
'modules/bmm-bmad-method/quick-start',
{
type: 'category',
label: 'Quick Flows',
collapsed: true,
items: [
'modules/bmm-bmad-method/bmad-quick-flow',
'modules/bmm-bmad-method/quick-flow-solo-dev',
'modules/bmm-bmad-method/quick-spec-flow',
],
},
{
type: 'category',
label: 'Workflows',
collapsed: true,
items: [
'modules/bmm-bmad-method/workflows-planning',
'modules/bmm-bmad-method/workflows-solutioning',
'modules/bmm-bmad-method/workflows-analysis',
'modules/bmm-bmad-method/workflows-implementation',
],
},
{
type: 'category',
label: 'Advanced Topics',
collapsed: true,
items: [
'modules/bmm-bmad-method/party-mode',
'modules/bmm-bmad-method/agents-guide',
'modules/bmm-bmad-method/brownfield-guide',
'modules/bmm-bmad-method/test-architecture',
],
},
{
type: 'category',
label: 'Reference',
collapsed: true,
items: [
'modules/bmm-bmad-method/workflow-document-project-reference',
'modules/bmm-bmad-method/troubleshooting',
'modules/bmm-bmad-method/faq',
'modules/bmm-bmad-method/glossary',
],
},
],
},
{
type: 'category',
label: 'BMB - Builder',
collapsed: true,
items: [
'modules/bmb-bmad-builder/index',
'modules/bmb-bmad-builder/agent-creation-guide',
'modules/bmb-bmad-builder/workflow-vendoring-customization-inheritance',
'modules/bmb-bmad-builder/custom-content',
'modules/bmb-bmad-builder/custom-content-installation',
],
},
{
type: 'category',
label: 'BMGD - Game Dev',
collapsed: true,
items: [
'modules/bmgd-bmad-game-dev/index',
'modules/bmgd-bmad-game-dev/quick-start',
'modules/bmgd-bmad-game-dev/quick-flow-guide',
'modules/bmgd-bmad-game-dev/agents-guide',
'modules/bmgd-bmad-game-dev/workflows-guide',
'modules/bmgd-bmad-game-dev/game-types-guide',
'modules/bmgd-bmad-game-dev/troubleshooting',
'modules/bmgd-bmad-game-dev/glossary',
],
},
{
type: 'category',
label: 'CIS - Creative Intelligence',
collapsed: true,
items: ['modules/cis-creative-intelligence-suite/index'],
},
{
type: 'category',
label: 'Core Module',
collapsed: true,
items: [
'modules/core/index',
'modules/core/party-mode',
'modules/core/core-tasks',
'modules/core/core-workflows',
'modules/core/advanced-elicitation',
'modules/core/brainstorming',
'modules/core/document-sharding-guide',
'modules/core/global-core-config',
],
},
],
};
export default sidebars;

View File

@@ -0,0 +1,59 @@
---
import { getSiteUrl } from '../lib/site-url.js';
const SITE_URL = getSiteUrl();
const fullDocsUrl = `${SITE_URL}/llms-full.txt`;
---
<div class="ai-banner">
<span>🤖 Consolidated, AI-optimized BMAD docs: <a href={fullDocsUrl}>llms-full.txt</a>. Fetch this plain text file for complete context.</span>
</div>
<style>
.ai-banner {
width: 100vw; /* Full viewport width */
margin-left: calc(-50vw + 50%); /* Center and break out of container */
height: var(--ai-banner-height, 2.75rem);
background: #334155;
color: rgb(148, 163, 184);
padding: 0.5rem 1rem;
font-size: 0.875rem;
border-bottom: 1px solid rgba(140, 140, 255, 0.15);
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
font-family: system-ui, sans-serif;
}
/* Truncate text on narrow screens */
.ai-banner span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.ai-banner a {
color: #8C8CFF;
text-decoration: none;
font-weight: 600;
}
.ai-banner a:hover {
text-decoration: underline;
}
/* Match navbar padding at breakpoints */
@media (min-width: 50rem) {
.ai-banner {
padding-left: 2.5rem;
padding-right: 2.5rem;
}
}
@media (min-width: 72rem) {
.ai-banner {
padding-left: 3rem;
padding-right: 3rem;
}
}
</style>

View File

@@ -0,0 +1,121 @@
---
import config from 'virtual:starlight/user-config';
import type { Props } from '@astrojs/starlight/props';
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import Search from 'virtual:starlight/components/Search';
import SiteTitle from 'virtual:starlight/components/SiteTitle';
import SocialIcons from 'virtual:starlight/components/SocialIcons';
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
import Banner from './Banner.astro';
/**
* Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
*/
const shouldRenderSearch =
config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
---
<Banner />
<div class="header sl-flex">
<div class="title-wrapper sl-flex">
<SiteTitle {...Astro.props} />
</div>
<div class="sl-flex print:hidden">
{shouldRenderSearch && <Search {...Astro.props} />}
</div>
<div class="sl-hidden md:sl-flex print:hidden right-group">
<nav class="sl-flex nav-links">
<a href={`${import.meta.env.BASE_URL}downloads/`}>Downloads</a>
</nav>
<div class="sl-flex social-icons">
<SocialIcons {...Astro.props} />
</div>
<ThemeSelect {...Astro.props} />
<LanguageSelect {...Astro.props} />
</div>
</div>
<style>
.header {
gap: var(--sl-nav-gap);
justify-content: space-between;
align-items: center;
height: 100%;
}
.title-wrapper {
/* Prevent long titles overflowing and covering the search and menu buttons on narrow viewports. */
overflow: clip;
/* Avoid clipping focus ring around link inside title wrapper. */
padding: 0.25rem;
margin: -0.25rem;
min-width: 0;
}
.right-group,
.social-icons,
.nav-links {
gap: 1rem;
align-items: center;
}
.nav-links a {
color: var(--sl-color-white);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
padding: 0.25rem 0.5rem;
border-radius: 4px;
transition: color 0.15s ease, background-color 0.15s ease;
}
.nav-links a:hover {
color: var(--sl-color-accent);
background-color: rgba(140, 140, 255, 0.1);
}
.nav-links::after {
content: '';
height: 2rem;
border-inline-end: 1px solid var(--sl-color-gray-5);
}
.social-icons::after {
content: '';
height: 2rem;
border-inline-end: 1px solid var(--sl-color-gray-5);
}
@media (min-width: 50rem) {
:global(:root[data-has-sidebar]) {
--__sidebar-pad: calc(2 * var(--sl-nav-pad-x));
}
:global(:root:not([data-has-toc])) {
--__toc-width: 0rem;
}
.header {
--__sidebar-width: max(0rem, var(--sl-content-inline-start, 0rem) - var(--sl-nav-pad-x));
--__main-column-fr: calc(
(
100% + var(--__sidebar-pad, 0rem) - var(--__toc-width, var(--sl-sidebar-width)) -
(2 * var(--__toc-width, var(--sl-nav-pad-x))) - var(--sl-content-inline-start, 0rem) -
var(--sl-content-width)
) / 2
);
display: grid;
grid-template-columns:
/* 1 (site title): runs up until the main content columns left edge or the width of the title, whichever is the largest */
minmax(
calc(var(--__sidebar-width) + max(0rem, var(--__main-column-fr) - var(--sl-nav-gap))),
auto
)
/* 2 (search box): all free space that is available. */
1fr
/* 3 (right items): use the space that these need. */
auto;
align-content: center;
}
}
</style>

View File

@@ -0,0 +1,53 @@
---
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import SocialIcons from 'virtual:starlight/components/SocialIcons';
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
import type { Props } from '@astrojs/starlight/props';
---
<div class="mobile-preferences sl-flex">
<div class="sl-flex social-icons">
<SocialIcons {...Astro.props} />
</div>
<nav class="sl-flex nav-links">
<a href={`${import.meta.env.BASE_URL}downloads/`}>Downloads</a>
</nav>
<ThemeSelect {...Astro.props} />
<LanguageSelect {...Astro.props} />
</div>
<style>
.social-icons {
gap: 1rem;
align-items: center;
padding-block: 1rem;
}
.social-icons:empty {
display: none;
}
.mobile-preferences {
justify-content: space-between;
flex-wrap: wrap;
border-top: 1px solid var(--sl-color-gray-6);
column-gap: 1rem;
padding: 0.5rem 0;
align-items: center;
}
.nav-links {
gap: 1rem;
align-items: center;
}
.nav-links a {
color: var(--sl-color-white);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
padding: 0.5rem 0.75rem;
border-radius: 4px;
transition: color 0.15s ease, background-color 0.15s ease;
}
.nav-links a:hover {
color: var(--sl-color-accent);
background-color: rgba(140, 140, 255, 0.1);
}
</style>

View File

@@ -0,0 +1,6 @@
import { defineCollection } from 'astro:content';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ schema: docsSchema() }),
};

1
website/src/content/docs Symbolic link
View File

@@ -0,0 +1 @@
../../../docs

View File

@@ -0,0 +1,25 @@
/**
* Resolve the site's base URL using cascading environment defaults.
*
* Preference order: use SITE_URL if set; otherwise derive a GitHub Pages URL from GITHUB_REPOSITORY; otherwise use the local development URL.
* @returns {string} The resolved site URL (SITE_URL override, or `https://{owner}.github.io/{repo}`, or `http://localhost:3000`).
*/
export function getSiteUrl() {
// Explicit override (works in both local and GitHub Actions)
if (process.env.SITE_URL) {
return process.env.SITE_URL;
}
// GitHub Actions: compute from repository context
if (process.env.GITHUB_REPOSITORY) {
const parts = process.env.GITHUB_REPOSITORY.split('/');
if (parts.length !== 2 || !parts[0] || !parts[1]) {
throw new Error(`Invalid GITHUB_REPOSITORY format: "${process.env.GITHUB_REPOSITORY}". Expected "owner/repo".`);
}
const [owner, repo] = parts;
return `https://${owner}.github.io/${repo}`;
}
// Local development: use dev server
return 'http://localhost:3000';
}

View File

@@ -1,66 +0,0 @@
# Downloads
Download BMAD Method resources for offline use, AI training, or integration.
## LLM-Optimized Files
These files are designed for AI consumption - perfect for loading into Claude, ChatGPT, or any LLM context window.
| File | Description | Use Case |
| ----------------------------------- | ----------------------------------- | -------------------------- |
| **[llms.txt](/llms.txt)** | Documentation index with summaries | Quick overview, navigation |
| **[llms-full.txt](/llms-full.txt)** | Complete documentation concatenated | Full context loading |
### Using with LLMs
**Claude Projects:**
```
Upload llms-full.txt as project knowledge
```
**ChatGPT:**
```
Paste llms.txt for navigation, or sections from llms-full.txt as needed
```
**API Usage:**
```python
import requests
docs = requests.get("https://bmad-code-org.github.io/BMAD-METHOD/llms-full.txt").text
# Include in your system prompt or context
```
## Installation Options
### NPM (Recommended)
```bash
npx bmad-method@alpha install
```
## Version Information
- **Current Version:** See [CHANGELOG](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md)
- **Release Notes:** Available on [GitHub Releases](https://github.com/bmad-code-org/BMAD-METHOD/releases)
## API Access
For programmatic access to BMAD documentation:
```bash
# Get documentation index
curl https://bmad-code-org.github.io/BMAD-METHOD/llms.txt
# Get full documentation
curl https://bmad-code-org.github.io/BMAD-METHOD/llms-full.txt
```
## Contributing
Want to improve BMAD Method? Check out:
- [Contributing Guide](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CONTRIBUTING.md)
- [GitHub Repository](https://github.com/bmad-code-org/BMAD-METHOD)

View File

@@ -1,50 +0,0 @@
import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
export default function Home() {
const llmsFullUrl = useBaseUrl('/llms-full.txt');
return (
<Layout title="Home" description="BMAD Method - AI-driven agile development">
<main
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
minHeight: 'calc(100vh - 200px)',
textAlign: 'center',
padding: '2rem',
}}
>
<h1 style={{ fontSize: '3rem', marginBottom: '0.5rem' }}>BMAD Method</h1>
<p
style={{
fontSize: '1.5rem',
color: 'var(--ifm-color-emphasis-600)',
marginBottom: '2rem',
}}
>
Under Construction
</p>
<Link to="/docs/" className="button button--primary button--lg" style={{ marginBottom: '3rem' }}>
View Documentation
</Link>
<a
href={llmsFullUrl}
title="Complete BMAD documentation in a single file for AI assistants"
style={{
fontSize: '0.875rem',
color: 'var(--ifm-color-emphasis-500)',
}}
>
🤖 AI Context: llms-full.txt
</a>
</main>
</Layout>
);
}

View File

@@ -0,0 +1,88 @@
/**
* Rehype plugin to transform relative markdown file links (.md) to page routes
*
* Transforms:
* ./path/to/file.md → ./path/to/file/
* ./path/index.md → ./path/ (index.md becomes directory root)
* ../path/file.md#anchor → ../path/file/#anchor
* ./file.md?query=param → ./file/?query=param
*
* Only affects relative links (./, ../) - absolute and external links are unchanged
*/
import { visit } from 'unist-util-visit';
/**
* Convert relative Markdown file links (./ or ../) into equivalent page route-style links.
*
* The returned transformer walks the HTML tree and rewrites anchor `href` values that are relative paths pointing to `.md` files. It preserves query strings and hash anchors, rewrites `.../index.md` to the directory root path (`.../`), and rewrites other `.md` file paths by removing the `.md` extension and ensuring a trailing slash. Absolute, external, non-relative, non-string, or links without `.md` are left unchanged.
*
* @returns {function} A HAST tree transformer that mutates `a` element `href` properties as described.
*/
export default function rehypeMarkdownLinks() {
return (tree) => {
visit(tree, 'element', (node) => {
// Only process anchor tags with href
if (node.tagName !== 'a' || !node.properties?.href) {
return;
}
const href = node.properties.href;
// Skip if not a string (shouldn't happen, but be safe)
if (typeof href !== 'string') {
return;
}
// Only transform relative paths starting with ./ or ../
if (!href.startsWith('./') && !href.startsWith('../')) {
return;
}
// Extract path portion (before ? and #) to check if it's a .md file
const firstDelimiter = Math.min(
href.indexOf('?') === -1 ? Infinity : href.indexOf('?'),
href.indexOf('#') === -1 ? Infinity : href.indexOf('#'),
);
const pathPortion = firstDelimiter === Infinity ? href : href.substring(0, firstDelimiter);
// Don't transform if path doesn't end with .md
if (!pathPortion.endsWith('.md')) {
return;
}
// Split the URL into parts: path, anchor, and query
let urlPath = pathPortion;
let anchor = '';
let query = '';
// Extract query string and anchor from original href
if (firstDelimiter !== Infinity) {
const suffix = href.substring(firstDelimiter);
const anchorInSuffix = suffix.indexOf('#');
if (suffix.startsWith('?')) {
if (anchorInSuffix !== -1) {
query = suffix.substring(0, anchorInSuffix);
anchor = suffix.substring(anchorInSuffix);
} else {
query = suffix;
}
} else {
// starts with #
anchor = suffix;
}
}
// Transform .md to /
// Special case: index.md → directory root (e.g., ./tutorials/index.md → ./tutorials/)
if (urlPath.endsWith('/index.md')) {
urlPath = urlPath.replace(/\/index\.md$/, '/');
} else {
urlPath = urlPath.replace(/\.md$/, '/');
}
// Reconstruct the href
node.properties.href = urlPath + query + anchor;
});
};
}

View File

@@ -0,0 +1,483 @@
/**
* BMAD Method Documentation - Custom Styles for Starlight
* Electric Blue theme optimized for dark mode
*
* CSS Variable Mapping:
* Docusaurus → Starlight
* --ifm-color-primary → --sl-color-accent
* --ifm-background-color → --sl-color-bg
* --ifm-font-color-base → --sl-color-text
*/
/* ============================================
COLOR PALETTE - Light Mode
============================================ */
:root {
--ai-banner-height: 2.75rem;
--sl-nav-height: 6.25rem; /* Base nav height (~3.5rem) + banner height (2.75rem) */
/* Primary accent colors - purple to match Docusaurus */
--sl-color-accent-low: #e0e0ff;
--sl-color-accent: #8C8CFF;
--sl-color-accent-high: #4141FF;
/* Text colors */
--sl-color-white: #1e293b;
--sl-color-gray-1: #334155;
--sl-color-gray-2: #475569;
--sl-color-gray-3: #64748b;
--sl-color-gray-4: #94a3b8;
--sl-color-gray-5: #cbd5e1;
--sl-color-gray-6: #e2e8f0;
--sl-color-black: #f8fafc;
/* Font settings */
--sl-font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
Arial, sans-serif;
--sl-text-base: 1rem;
--sl-line-height: 1.7;
/* Code highlighting */
--sl-color-bg-inline-code: rgba(140, 140, 255, 0.1);
}
/* ============================================
COLOR PALETTE - Dark Mode (Primary Focus)
============================================ */
:root[data-theme='dark'] {
/* Primary accent colors - purple to match Docusaurus */
--sl-color-accent-low: #2a2a5a;
--sl-color-accent: #8C8CFF;
--sl-color-accent-high: #B9B9FF;
/* Background colors */
--sl-color-bg: #1b1b1d;
--sl-color-bg-nav: #1b1b1d;
--sl-color-bg-sidebar: #1b1b1d;
--sl-color-hairline-light: rgba(140, 140, 255, 0.1);
--sl-color-hairline: rgba(140, 140, 255, 0.15);
/* Text colors */
--sl-color-white: #f8fafc;
--sl-color-gray-1: #e2e8f0;
--sl-color-gray-2: #cbd5e1;
--sl-color-gray-3: #94a3b8;
--sl-color-gray-4: #64748b;
--sl-color-gray-5: #475569;
--sl-color-gray-6: #334155;
--sl-color-black: #1b1b1d;
/* Code highlighting */
--sl-color-bg-inline-code: rgba(140, 140, 255, 0.15);
}
/* ============================================
TYPOGRAPHY
============================================ */
.sl-markdown-content h1 {
margin-bottom: 1.5rem;
}
.sl-markdown-content h2 {
margin-top: 2.5rem;
margin-bottom: 1rem;
}
.sl-markdown-content h3 {
margin-top: 2rem;
margin-bottom: 0.75rem;
}
.sl-markdown-content p {
margin-bottom: 1.25rem;
}
/* ============================================
SIDEBAR & NAVIGATION
Clean styling inspired by React Native docs
============================================ */
/* Base transition for all sidebar links */
.sidebar-content a {
transition:
background-color 0.15s ease,
color 0.15s ease,
border-color 0.15s ease;
border-radius: 4px;
}
/* Top-level sidebar items (Diataxis categories) */
.sidebar-content > ul > li > details > summary,
.sidebar-content > ul > li > a {
font-weight: 700;
font-size: 0.9375rem;
padding: 0.5rem 0.75rem;
}
/* Nested sidebar items */
.sidebar-content ul ul a {
font-weight: 500;
font-size: 0.875rem;
padding: 0.375rem 0.75rem;
padding-left: 1.5rem;
border-left: 3px solid transparent;
}
/* Deep nested items */
.sidebar-content ul ul ul a {
font-weight: 400;
font-size: 0.8125rem;
padding-left: 2.25rem;
}
/* Active state - thin left accent bar */
.sidebar-content a[aria-current='page'] {
background-color: rgba(140, 140, 255, 0.08);
color: var(--sl-color-accent);
border-left-color: var(--sl-color-accent);
font-weight: 600;
}
:root[data-theme='dark'] .sidebar-content a[aria-current='page'] {
background-color: rgba(140, 140, 255, 0.1);
color: var(--sl-color-accent-high);
border-left-color: var(--sl-color-accent);
}
/* Hover states */
.sidebar-content a:hover {
background-color: rgba(0, 0, 0, 0.05);
}
:root[data-theme='dark'] .sidebar-content a:hover {
background-color: rgba(255, 255, 255, 0.05);
}
/* Section spacing */
.sidebar-content > ul > li {
margin-top: 0.75rem;
}
.sidebar-content > ul > li:first-child {
margin-top: 0;
}
/* Lighter chevrons/carets */
.sidebar-content summary::marker,
.sidebar-content details > summary::after {
opacity: 0.4;
}
.sidebar-content summary:hover::marker,
.sidebar-content details > summary:hover::after {
opacity: 0.6;
}
/* ============================================
LAYOUT - Fixed width at large viewport
============================================ */
.content-panel {
max-width: 1400px;
margin: 0 auto;
}
/* Main content area */
main {
min-width: 0;
}
.sl-markdown-content {
min-width: 0;
overflow-wrap: break-word;
word-wrap: break-word;
}
/* Hide breadcrumbs if desired */
/* Uncomment to hide:
nav[aria-label="Breadcrumb"] {
display: none;
}
*/
/* ============================================
NAVBAR
============================================ */
header.header {
padding: 0 !important; /* Remove all padding for full-width banner */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
height: var(--sl-nav-height) !important;
display: flex;
flex-direction: column;
}
header.header .header.sl-flex {
padding: 0 1.5rem;
height: calc(var(--sl-nav-height) - var(--ai-banner-height));
width: 100%;
}
:root[data-theme='dark'] header.header {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.site-title {
font-weight: 700;
}
/* Logo sizing - constrain to reasonable size */
.site-title img {
height: 2.5rem;
width: auto;
}
/* Social links styling */
.social-icons a {
padding: 0.5rem;
transition:
background-color 0.15s ease,
color 0.15s ease;
border-radius: 6px;
}
.social-icons a:hover {
background-color: rgba(0, 0, 0, 0.05);
}
:root[data-theme='dark'] .social-icons a:hover {
background-color: rgba(255, 255, 255, 0.05);
}
/* ============================================
CARDS
============================================ */
.card {
border-radius: 12px;
border: 2px solid var(--sl-color-gray-5);
background-color: var(--sl-color-bg);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.2s ease;
}
.card:hover {
transform: translateY(-3px);
border-color: var(--sl-color-accent);
box-shadow: 0 8px 24px rgba(140, 140, 255, 0.15);
}
:root[data-theme='dark'] .card {
background: linear-gradient(145deg, rgba(30, 41, 59, 0.6), rgba(15, 23, 42, 0.8));
border-color: rgba(140, 140, 255, 0.2);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
:root[data-theme='dark'] .card:hover {
border-color: rgba(140, 140, 255, 0.5);
box-shadow:
0 8px 32px rgba(140, 140, 255, 0.2),
0 0 0 1px rgba(140, 140, 255, 0.1);
}
/* Starlight card grid */
.sl-link-card {
border-radius: 12px;
border: 2px solid var(--sl-color-gray-5);
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.2s ease;
}
.sl-link-card:hover {
transform: translateY(-3px);
border-color: var(--sl-color-accent);
}
:root[data-theme='dark'] .sl-link-card {
border-color: rgba(140, 140, 255, 0.2);
}
:root[data-theme='dark'] .sl-link-card:hover {
border-color: rgba(140, 140, 255, 0.5);
}
/* ============================================
BUTTONS
============================================ */
.sl-flex a[href],
button {
transition:
background-color 0.2s ease,
transform 0.1s ease;
}
.sl-flex a[href]:hover,
button:hover {
transform: translateY(-1px);
}
/* ============================================
MISC ENHANCEMENTS
============================================ */
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Better link underlines */
.sl-markdown-content a:not(.sl-link-card) {
text-decoration-thickness: 1px;
text-underline-offset: 2px;
}
/* Table styling */
table {
display: table;
width: 100%;
}
:root[data-theme='dark'] table {
border-color: rgba(140, 140, 255, 0.1);
}
:root[data-theme='dark'] table th {
background-color: rgba(140, 140, 255, 0.05);
}
:root[data-theme='dark'] table tr:nth-child(2n) {
background-color: rgba(140, 140, 255, 0.02);
}
/* Blockquotes */
blockquote {
border-left-color: var(--sl-color-accent);
background-color: rgba(140, 140, 255, 0.05);
border-radius: 0 8px 8px 0;
padding: 1rem 1.25rem;
}
/* ============================================
ADMONITIONS (Starlight Asides)
Rounded, no left border bar
============================================ */
.starlight-aside {
margin-bottom: 1.5rem;
padding: 1.25rem 1.5rem;
border-radius: 12px;
border: none;
border-left: 0;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
/* Tip aside */
.starlight-aside--tip {
background-color: rgba(16, 185, 129, 0.08);
}
.starlight-aside--tip .starlight-aside__title {
color: #059669;
}
:root[data-theme='dark'] .starlight-aside--tip {
background-color: rgba(16, 185, 129, 0.12);
}
:root[data-theme='dark'] .starlight-aside--tip .starlight-aside__title {
color: #34d399;
}
/* Note aside */
.starlight-aside--note {
background-color: rgba(140, 140, 255, 0.08);
}
.starlight-aside--note .starlight-aside__title {
color: #8C8CFF;
}
:root[data-theme='dark'] .starlight-aside--note {
background-color: rgba(140, 140, 255, 0.12);
}
:root[data-theme='dark'] .starlight-aside--note .starlight-aside__title {
color: #8C8CFF;
}
/* Caution aside */
.starlight-aside--caution {
background-color: rgba(245, 158, 11, 0.1);
}
.starlight-aside--caution .starlight-aside__title {
color: #d97706;
}
:root[data-theme='dark'] .starlight-aside--caution {
background-color: rgba(245, 158, 11, 0.15);
}
:root[data-theme='dark'] .starlight-aside--caution .starlight-aside__title {
color: #fbbf24;
}
/* Danger aside */
.starlight-aside--danger {
background-color: rgba(239, 68, 68, 0.1);
}
.starlight-aside--danger .starlight-aside__title {
color: #dc2626;
}
:root[data-theme='dark'] .starlight-aside--danger {
background-color: rgba(239, 68, 68, 0.15);
}
:root[data-theme='dark'] .starlight-aside--danger .starlight-aside__title {
color: #f87171;
}
/* Aside icon styling */
.starlight-aside__icon svg {
width: 1.25rem;
height: 1.25rem;
}
/* ============================================
FOOTER - Minimal styling
============================================ */
footer {
background-color: var(--sl-color-black);
border-top: 1px solid var(--sl-color-hairline);
}
:root[data-theme='dark'] footer {
background-color: #020617;
}
/* ============================================
RESPONSIVE ADJUSTMENTS
============================================ */
@media (max-width: 72rem) {
.content-panel {
max-width: 100%;
}
}
/* Responsive padding on navbar row only - banner stays full-width */
@media (min-width: 50rem) {
header.header .header.sl-flex {
padding-left: 2.5rem;
padding-right: 2.5rem;
}
}
@media (min-width: 72rem) {
header.header .header.sl-flex {
padding-left: 3rem;
padding-right: 3rem;
}
}