feat: add link auditor tools and fix broken docs links
- Add audit-doc-links.js to scan docs for broken links with auto-resolution - Add fix-doc-links.js to apply suggested fixes (dry-run by default) - Remove stale "Back to Core Concepts" breadcrumb links - Update BMad acronym to "Breakthrough Method of Agile AI Driven Development" - Update README links to docs.bmad-method.org - Simplify upgrade callout in getting-started tutorial Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8e165b9b57
commit
db0c3dcab4
242
README.md
242
README.md
|
|
@ -1,237 +1,75 @@
|
|||
# BMad Method & BMad Core
|
||||
# BMAD Method
|
||||
|
||||
[](https://www.npmjs.com/package/bmad-method)
|
||||
[](https://www.npmjs.com/package/bmad-method)
|
||||
[](https://www.npmjs.com/package/bmad-method)
|
||||
[](LICENSE)
|
||||
[](https://nodejs.org)
|
||||
[](https://discord.gg/gk8jAdXWmj)
|
||||
|
||||
---
|
||||
**Build More, Architect Dreams** — An AI-driven agile development framework with 21 specialized agents, 50+ guided workflows, and scale-adaptive intelligence that adjusts from bug fixes to enterprise systems.
|
||||
|
||||
<div align="center">
|
||||
## Why BMAD?
|
||||
|
||||
## 🎉 NEW: BMAD V6 Installer - Create & Share Custom Content!
|
||||
Traditional AI tools do the thinking for you, producing average results. BMAD agents act as expert collaborators who guide you through structured workflows to bring out your best thinking.
|
||||
|
||||
The completely revamped **BMAD V6 installer** now includes built-in support for creating, installing, and sharing custom modules, agents, workflows, templates, and tools! Build your own AI solutions or share them with your team - and real soon, with the whole BMad Community througha verified community sharing portal!
|
||||
- **Scale-Adaptive**: Automatically adjusts planning depth based on project complexity (Level 0-4)
|
||||
- **Structured Workflows**: Grounded in agile best practices across analysis, planning, architecture, and implementation
|
||||
- **Specialized Agents**: 12+ domain experts (PM, Architect, Developer, UX, Scrum Master, and more)
|
||||
- **Complete Lifecycle**: From brainstorming to deployment, with just-in-time documentation
|
||||
|
||||
**✨ What's New:**
|
||||
## Quick Start
|
||||
|
||||
- 📦 **Streamlined Custom Module Installation** - Package your custom content as installable modules
|
||||
- 🤖 **Agent & Workflow Sharing** - Distribute standalone agents and workflows
|
||||
- 🔄 **Unitary Module Support** - Install individual components without full modules
|
||||
- ⚙️ **Dependency Management** - Automatic handling of module dependencies
|
||||
- 🛡️ **Update-Safe Customization** - Your custom content persists through updates
|
||||
|
||||
**📚 Learn More:**
|
||||
|
||||
- [**Custom Content Overview**](http://docs.bmad-method.org/explanation/bmad-builder/custom-content-types/) - Discover all supported content types
|
||||
- [**Installation Guide**](http://docs.bmad-method.org/how-to/installation/install-custom-modules/) - Learn to create and install custom content
|
||||
- [**2 Very simple Custom Modules of questionable quality**](./samples/sample-custom-modules/README.md) - if you want to download and try to install a custom shared module, get an idea of how to bundle and share your own, or create your own personal agents, workflows and modules.
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## AI-Driven Agile Development That Scales From Bug Fixes to Enterprise
|
||||
|
||||
**Build More, Architect Dreams** (BMAD) with **21 specialized AI agents** across 4 official modules, and **50+ guided workflows** that adapt to your project's complexity—from quick bug fixes to enterprise platforms, and new step file workflows that allow for incredibly long workflows to stay on the rails longer than ever before!
|
||||
|
||||
Additionally - when we say 'Build More, Architect Dreams' - we mean it! The BMad Builder has landed, and now as of Alpha.15 is fully supported in the installation flow via NPX - custom stand along agents, workflows and the modules of your dreams! The community forge will soon open, endless possibility awaits!
|
||||
|
||||
> **🚀 v6 is a MASSIVE upgrade from v4!** Complete architectural overhaul, scale-adaptive intelligence, visual workflows, and the powerful BMad Core framework. v4 users: this changes everything. [See what's new →](#whats-new-in-v6)
|
||||
|
||||
> **📌 v6 Alpha Status:** Near-beta quality with vastly improved stability. Documentation is being finalized. New videos coming soon to [BMadCode YouTube](https://www.youtube.com/@BMadCode).
|
||||
|
||||
## 🎯 Why BMad Method?
|
||||
|
||||
Unlike generic AI coding assistants, BMad Method provides **structured, battle-tested workflows** powered by specialized agents who understand agile development. Each agent has deep domain expertise—from product management to architecture to testing—working together seamlessly.
|
||||
|
||||
**✨ Key Benefits:**
|
||||
|
||||
- **Scale-Adaptive Intelligence** - Automatically adjusts planning depth from bug fixes to enterprise systems
|
||||
- **Complete Development Lifecycle** - Analysis → Planning → Architecture → Implementation
|
||||
- **Specialized Expertise** - 19 agents with specific roles (PM, Architect, Developer, UX Designer, etc.)
|
||||
- **Proven Methodologies** - Built on agile best practices with AI amplification
|
||||
- **IDE Integration** - Works with Claude Code, Cursor, Windsurf, VS Code
|
||||
|
||||
## 🏗️ The Power of BMad Core
|
||||
|
||||
**BMad Method** is actually a sophisticated module built on top of **BMad Core** (**C**ollaboration **O**ptimized **R**eflection **E**ngine). This revolutionary architecture means:
|
||||
|
||||
- **BMad Core** provides the universal framework for human-AI collaboration
|
||||
- **BMad Method** leverages Core to deliver agile development workflows
|
||||
- **BMad Builder** lets YOU create custom modules as powerful as BMad Method itself
|
||||
|
||||
With **BMad Builder**, you can architect both simple agents and vastly complex domain-specific modules (legal, medical, finance, education, creative) that will soon be sharable in an **official community marketplace**. Imagine building and sharing your own specialized AI team!
|
||||
|
||||
## 📊 See It In Action
|
||||
|
||||
<p align="center">
|
||||
<img src="./docs/tutorials/getting-started/images/workflow-method-greenfield.svg" alt="BMad Method Workflow" width="100%">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<em>Complete BMad Method workflow showing all phases, agents, and decision points</em>
|
||||
</p>
|
||||
|
||||
## 🚀 Get Started in 3 Steps
|
||||
|
||||
### 1. Install BMad Method
|
||||
**Prerequisites**: [Node.js](https://nodejs.org) v20+
|
||||
|
||||
```bash
|
||||
# Install v6 RECOMMENDED
|
||||
npx bmad-method@alpha install
|
||||
```
|
||||
|
||||
Follow the installer prompts to configure your project. Then run:
|
||||
|
||||
```bash
|
||||
# Install v4 Legacy (not recommended if starting fresh)
|
||||
npx bmad-method install
|
||||
# OR
|
||||
npx bmad-method@latest install
|
||||
```
|
||||
|
||||
|
||||
### 2. Initialize Your Project
|
||||
|
||||
Load any agent in your IDE and run:
|
||||
|
||||
```
|
||||
*workflow-init
|
||||
```
|
||||
|
||||
This analyzes your project and recommends the right workflow track.
|
||||
This analyzes your project and recommends a track:
|
||||
|
||||
### 3. Choose Your Track
|
||||
| Track | Best For | Time to First Story |
|
||||
| --------------- | ------------------------- | ------------------- |
|
||||
| **Quick Flow** | Bug fixes, small features | ~5 minutes |
|
||||
| **BMad Method** | Products and platforms | ~15 minutes |
|
||||
| **Enterprise** | Compliance-heavy systems | ~30 minutes |
|
||||
|
||||
BMad Method adapts to your needs with three intelligent tracks:
|
||||
## Modules
|
||||
|
||||
| Track | Use For | Planning | Time to Start |
|
||||
| ----------------- | ------------------------- | ----------------------- | ------------- |
|
||||
| **⚡ Quick Flow** | Bug fixes, small features | Tech spec only | < 5 minutes |
|
||||
| **📋 BMad Method** | Products, platforms | PRD + Architecture + UX | < 15 minutes |
|
||||
| **🏢 Enterprise** | Compliance, scale | Full governance suite | < 30 minutes |
|
||||
| Module | Purpose |
|
||||
| ------------------------------------- | -------------------------------------------------------- |
|
||||
| **BMad Method (BMM)** | Core agile development with 34 workflows across 4 phases |
|
||||
| **BMad Builder (BMB)** | Create custom agents and domain-specific modules |
|
||||
| **Creative Intelligence Suite (CIS)** | Innovation, brainstorming, and problem-solving |
|
||||
|
||||
> **Not sure?** Run `*workflow-init` and let BMad analyze your project goal.
|
||||
## Documentation
|
||||
|
||||
## 🔄 How It Works: 4-Phase Methodology
|
||||
**[Full Documentation](http://docs.bmad-method.org)** — Tutorials, how-to guides, concepts, and reference
|
||||
|
||||
BMad Method guides you through a proven development lifecycle:
|
||||
- [Getting Started Tutorial](http://docs.bmad-method.org/tutorials/getting-started/getting-started-bmadv6/)
|
||||
- [Upgrading from Previous Versions](http://docs.bmad-method.org/how-to/installation/upgrade-to-v6/)
|
||||
|
||||
1. **📊 Analysis** (Optional) - Brainstorm, research, and explore solutions
|
||||
2. **📝 Planning** - Create PRDs, tech specs, or game design documents
|
||||
3. **🏗️ Solutioning** - Design architecture, UX, and technical approach
|
||||
4. **⚡ Implementation** - Story-driven development with continuous validation
|
||||
## Community
|
||||
|
||||
Each phase has specialized workflows and agents working together to deliver exceptional results.
|
||||
- [Discord](https://discord.gg/gk8jAdXWmj) — Get help, share ideas, collaborate
|
||||
- [YouTube](https://www.youtube.com/@BMadCode) — Video tutorials and updates
|
||||
- [GitHub Issues](https://github.com/bmad-code-org/BMAD-METHOD/issues) — Bug reports and feature requests
|
||||
- [Discussions](https://github.com/bmad-code-org/BMAD-METHOD/discussions) — Community conversations
|
||||
|
||||
## 🤖 Meet Your Team
|
||||
## Contributing
|
||||
|
||||
**12 Specialized Agents** working in concert:
|
||||
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
||||
|
||||
| Development | Architecture | Product | Leadership |
|
||||
| ----------- | -------------- | ----------- | ------------ |
|
||||
| Developer | Architect | PM | Scrum Master |
|
||||
| UX Designer | Test Architect | Analyst | BMad Master |
|
||||
| | | Tech Writer | |
|
||||
## License
|
||||
|
||||
**Test Architect** integrates with `@seontechnologies/playwright-utils` for production-ready web app fixture-based utilities.
|
||||
|
||||
Each agent brings deep expertise and can be customized to match your team's style.
|
||||
|
||||
## 📦 What's Included
|
||||
|
||||
### Official Modules
|
||||
|
||||
- **BMad Method (BMM)** - Complete agile development framework
|
||||
- 12 specialized agents
|
||||
- 34 workflows across 4 phases
|
||||
- Stand Along Quick Spec Flow for a streamlined simple implementation process
|
||||
- [→ Documentation Hub](http://docs.bmad-method.org/explanation/bmm/)
|
||||
|
||||
- **BMad Builder (BMB)** - Create custom agents and workflows
|
||||
- Build anything from simple agents to complex modules
|
||||
- Create domain-specific solutions (legal, medical, finance, education)
|
||||
- [→ Builder Guide](http://docs.bmad-method.org/explanation/bmad-builder/)
|
||||
|
||||
- **Creative Intelligence Suite (CIS)** - Innovation & problem-solving
|
||||
- Brainstorming, design thinking, storytelling
|
||||
- 5 creative facilitation workflows
|
||||
- [→ Creative Workflows](http://docs.bmad-method.org/explanation/creative-intelligence/)
|
||||
|
||||
### Key Features
|
||||
|
||||
- **🎨 Customizable Agents** - Modify personalities, expertise, and communication styles
|
||||
- **🌐 Multi-Language Support** - Separate settings for communication and code output
|
||||
- **📄 Document Sharding** - 90% token savings for large projects
|
||||
- **🔄 Update-Safe** - Your customizations persist through updates
|
||||
- **🚀 Web Bundles** - Use in ChatGPT, Claude Projects, or Gemini Gems
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
### Quick Links
|
||||
|
||||
- **[Quick Start Guide](http://docs.bmad-method.org/tutorials/getting-started/getting-started-bmadv6/)** - 15-minute introduction
|
||||
- **[Complete BMM Documentation](http://docs.bmad-method.org/explanation/bmm/)** - All guides and references
|
||||
- **[Agent Customization](http://docs.bmad-method.org/how-to/customization/customize-agents/)** - Personalize your agents
|
||||
- **[All Documentation](http://docs.bmad-method.org/)** - Complete documentation index
|
||||
|
||||
### For v4 Users
|
||||
|
||||
- **[v4 Documentation](https://github.com/bmad-code-org/BMAD-METHOD/tree/V4/docs)**
|
||||
- **[v4 to v6 Upgrade Guide](http://docs.bmad-method.org/how-to/installation/upgrade-to-v6/)**
|
||||
|
||||
## 💬 Community & Support
|
||||
|
||||
- **[Discord Community](https://discord.gg/gk8jAdXWmj)** - Get help, share projects
|
||||
- **[GitHub Issues](https://github.com/bmad-code-org/BMAD-METHOD/issues)** - Report bugs, request features
|
||||
- **[YouTube Channel](https://www.youtube.com/@BMadCode)** - Video tutorials and demos
|
||||
- **[Web Bundles](https://bmad-code-org.github.io/bmad-bundles/)** - Pre-built agent bundles (Currently not functioning, reworking soon)
|
||||
- **[Code of Conduct](.github/CODE_OF_CONDUCT.md)** - Community guidelines
|
||||
|
||||
## 🛠️ Development
|
||||
|
||||
If you would like to contribute, first check the [CONTRIBUTING.md](CONTRIBUTING.md) for full development guidelines.
|
||||
|
||||
## What's New in v6
|
||||
|
||||
**v6 represents a complete architectural revolution from v4:**
|
||||
|
||||
### 🚀 Major Upgrades
|
||||
|
||||
- **BMad Core Framework** - Modular architecture enabling custom domain solutions
|
||||
- **Scale-Adaptive Intelligence** - Automatic adjustment from bug fixes to enterprise
|
||||
- **Visual Workflows** - Beautiful SVG diagrams showing complete methodology
|
||||
- **BMad Builder Module** - Create and share your own AI agent teams
|
||||
- **50+ Workflows** - Up from 20 in v4, covering every development scenario
|
||||
- **19 Specialized Agents** - Enhanced with customizable personalities and expertise
|
||||
- **Update-Safe Customization** - Your configs persist through all updates
|
||||
- **Web Bundles** - Use agents in ChatGPT, Claude, and Gemini
|
||||
- **Multi-Language Support** - Separate settings for communication and code
|
||||
- **Document Sharding** - 90% token savings for large projects
|
||||
|
||||
### 🔄 For v4 Users
|
||||
|
||||
- **[Comprehensive Upgrade Guide](http://docs.bmad-method.org/how-to/installation/upgrade-to-v6/)** - Step-by-step migration
|
||||
- **[v4 Documentation Archive](https://github.com/bmad-code-org/BMAD-METHOD/tree/V4)** - Legacy reference
|
||||
- Backwards compatibility where possible
|
||||
- Smooth migration path with installer detection
|
||||
|
||||
## 📄 License
|
||||
|
||||
MIT License - See [LICENSE](LICENSE) for details.
|
||||
|
||||
**Trademarks:** BMad™ and BMAD-METHOD™ are trademarks of BMad Code, LLC.
|
||||
|
||||
Supported by: <a href="https://m.do.co/c/00f11bd932bb"><img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" height="24" alt="DigitalOcean" style="vertical-align: middle;"></a>
|
||||
MIT License — see [LICENSE](LICENSE) for details.
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/bmad-code-org/BMAD-METHOD/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=bmad-code-org/BMAD-METHOD" alt="Contributors">
|
||||
</a>
|
||||
</p>
|
||||
**BMAD** and **BMAD-METHOD** are trademarks of BMad Code, LLC.
|
||||
|
||||
<p align="center">
|
||||
<sub>Built with ❤️ for the human-AI collaboration community</sub>
|
||||
</p>
|
||||
[](https://github.com/bmad-code-org/BMAD-METHOD/graphs/contributors)
|
||||
|
|
|
|||
|
|
@ -33,5 +33,3 @@ Web bundles package BMad agents as self-contained files that work in Gemini Gems
|
|||
- Some quality reduction vs local usage
|
||||
- Less convenient than full local installation
|
||||
- Limited to agent capabilities (no workflow file access)
|
||||
|
||||
[← Back to Core Concepts](../index.md)
|
||||
|
|
|
|||
|
|
@ -25,5 +25,3 @@ Replace or extend workflow steps to create tailored processes. (Coming soon)
|
|||
---
|
||||
|
||||
**Next:** Read the [Agent Customization Guide](./customize-agents.md) to start personalizing your agents.
|
||||
|
||||
[← Back to Core Concepts](../index.md)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Welcome to BMad
|
||||
title: Welcome to the BMad Method
|
||||
---
|
||||
|
||||
BMad (**B**uild **M**ore, **A**rchitect **D**reams) is an AI-driven development framework that helps you build software faster and smarter. It provides specialized AI agents, guided workflows, and intelligent planning that adapts to your project's complexity—whether you're fixing a bug or building an enterprise platform.
|
||||
The BMad Method (**B**reakthrough **M**ethod of **A**gile AI **D**riven Development) is an AI-driven development framework that helps you build software faster and smarter. It provides specialized AI agents, guided workflows, and intelligent planning that adapts to your project's complexity—whether you're fixing a bug or building an enterprise platform.
|
||||
|
||||
If you're comfortable working with AI coding assistants like Claude, Cursor, or GitHub Copilot, you're ready to get started.
|
||||
|
||||
|
|
@ -12,8 +12,7 @@ If you're comfortable working with AI coding assistants like Claude, Cursor, or
|
|||
|
||||
The fastest way to understand BMad is to try it. Choose a tutorial to walk through your first project in about 10 minutes.
|
||||
|
||||
- **[Get Started with v4 (Stable)](./tutorials/getting-started/getting-started-bmadv4.md)** — Production-ready version with battle-tested workflows
|
||||
- **[Try v6 (Alpha)](./tutorials/getting-started/getting-started-bmadv6.md)** — Latest features, still in active development
|
||||
- **[Get Started with BMad](./tutorials/getting-started/getting-started-bmadv6.md)** — Latest features, still in active development
|
||||
|
||||
:::tip[Already familiar with AI-assisted development?]
|
||||
Feel free to skip around. Use the sidebar to jump to any topic, or check out [What Are Agents?](./explanation/core-concepts/what-are-agents.md) to understand how BMad organizes its AI personas.
|
||||
|
|
@ -26,11 +25,11 @@ Feel free to skip around. Use the sidebar to jump to any topic, or check out [Wh
|
|||
These docs are organized into four sections based on what you're trying to do:
|
||||
|
||||
| Section | Purpose |
|
||||
|---------|---------|
|
||||
| **[Tutorials](./tutorials/index.md)** | Learning-oriented. Step-by-step guides that walk you through building something. Start here if you're new. |
|
||||
| **[How-To Guides](./how-to/index.md)** | Task-oriented. Practical guides for solving specific problems. "How do I customize an agent?" lives here. |
|
||||
| **[Explanation](./explanation/index.md)** | Understanding-oriented. Deep dives into concepts and architecture. Read when you want to know *why*. |
|
||||
| **[Reference](./reference/index.md)** | Information-oriented. Technical specifications for agents, workflows, and configuration. |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| **Tutorials** | Learning-oriented. Step-by-step guides that walk you through building something. Start here if you're new. |
|
||||
| **How-To Guides** | Task-oriented. Practical guides for solving specific problems. "How do I customize an agent?" lives here. |
|
||||
| **Explanation** | Understanding-oriented. Deep dives into concepts and architecture. Read when you want to know *why*. |
|
||||
| **Reference** | Information-oriented. Technical specifications for agents, workflows, and configuration. |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -61,5 +60,4 @@ Get help, share what you're building, or contribute to BMad:
|
|||
|
||||
Ready to dive in? Pick a tutorial and start building.
|
||||
|
||||
- **[Get Started with v4 (Stable)](./tutorials/getting-started/getting-started-bmadv4.md)** — Recommended for production projects
|
||||
- **[Try v6 (Alpha)](./tutorials/getting-started/getting-started-bmadv6.md)** — Explore the latest features
|
||||
- **[Get Started with BMadv6](./tutorials/getting-started/getting-started-bmadv6.md)** — Explore the latest features
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
---
|
||||
title: "Getting Started with BMad v6 Alpha"
|
||||
description: Install BMad v6 Alpha and build your first project
|
||||
title: "Getting Started with the BMad Method"
|
||||
description: Install BMad and build your first project
|
||||
---
|
||||
|
||||
**Upgrading from previous versions?** See the [Upgrade Guide](../../how-to/installation/upgrade-to-v6.md) instead.
|
||||
|
||||
---
|
||||
|
||||
Build software faster using AI-powered workflows with specialized agents that guide you through planning, architecture, and implementation.
|
||||
|
||||
:::caution[Alpha Software]
|
||||
BMad v6 is currently in **alpha**. Expect breaking changes, incomplete features, and evolving documentation. For a stable experience, use the [BMad v4 tutorial](./getting-started-bmadv4.md) instead.
|
||||
:::
|
||||
|
||||
## What You'll Learn
|
||||
|
||||
- Install and initialize BMad Method for a new project
|
||||
|
|
@ -37,7 +36,7 @@ BMad v6 is currently in **alpha**. Expect breaking changes, incomplete features,
|
|||
BMad helps you build software through guided workflows with specialized AI agents. The process follows four phases:
|
||||
|
||||
| Phase | Name | What Happens |
|
||||
|-------|------|--------------|
|
||||
| ----- | -------------- | --------------------------------------------------- |
|
||||
| 1 | Analysis | Brainstorming, research, product brief *(optional)* |
|
||||
| 2 | Planning | Create requirements (PRD or tech-spec) |
|
||||
| 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* |
|
||||
|
|
@ -50,7 +49,7 @@ BMad helps you build software through guided workflows with specialized AI agent
|
|||
Based on your project's complexity, BMad offers three planning tracks:
|
||||
|
||||
| Track | Best For | Documents Created |
|
||||
|-------|----------|-------------------|
|
||||
| --------------- | ------------------------------------------------------ | -------------------------------------- |
|
||||
| **Quick Flow** | Bug fixes, simple features, clear scope (1-15 stories) | Tech-spec only |
|
||||
| **BMad Method** | Products, platforms, complex features (10-50+ stories) | PRD + Architecture + UX |
|
||||
| **Enterprise** | Compliance, multi-tenant systems (30+ stories) | PRD + Architecture + Security + DevOps |
|
||||
|
|
@ -167,7 +166,7 @@ Load the **SM agent** and run `sprint-planning`. This creates `sprint-status.yam
|
|||
For each story, repeat this cycle with fresh chats:
|
||||
|
||||
| Step | Agent | Workflow | Purpose |
|
||||
|------|-------|----------|---------|
|
||||
| ---- | ----- | -------------- | ------------------------------------- |
|
||||
| 1 | SM | `create-story` | Create story file from epic |
|
||||
| 2 | DEV | `dev-story` | Implement the story |
|
||||
| 3 | TEA | `automate` | Generate guardrail tests *(optional)* |
|
||||
|
|
@ -201,7 +200,7 @@ your-project/
|
|||
## Quick Reference
|
||||
|
||||
| Command | Agent | Purpose |
|
||||
|---------|-------|---------|
|
||||
| --------------------------- | --------- | ------------------------------------ |
|
||||
| `*workflow-init` | Analyst | Initialize a new project |
|
||||
| `*workflow-status` | Any | Check progress and next steps |
|
||||
| `*prd` | PM | Create Product Requirements Document |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,341 @@
|
|||
/**
|
||||
* Documentation Link Auditor
|
||||
*
|
||||
* Scans markdown files in docs/ and:
|
||||
* - Identifies broken relative links
|
||||
* - Attempts to find where files may have moved
|
||||
* - Generates a report with auto-fix suggestions
|
||||
* - Outputs JSON for the fixer script to consume
|
||||
*
|
||||
* Usage: node tools/audit-doc-links.js
|
||||
*/
|
||||
|
||||
const { readFileSync, writeFileSync, existsSync } = require('node:fs');
|
||||
const { resolve, dirname, join, normalize, relative, basename } = require('node:path');
|
||||
const { glob } = require('glob');
|
||||
|
||||
const DOCS_DIR = resolve(process.cwd(), 'docs');
|
||||
const REPORT_PATH = resolve(__dirname, '.link-audit-report.json');
|
||||
|
||||
// Regex to match markdown links: [text](path)
|
||||
const LINK_PATTERN = /\[([^\]]*)\]\(([^)]+)\)/g;
|
||||
|
||||
// Colors for console output
|
||||
const colors = {
|
||||
reset: '\u001B[0m',
|
||||
red: '\u001B[31m',
|
||||
green: '\u001B[32m',
|
||||
yellow: '\u001B[33m',
|
||||
cyan: '\u001B[36m',
|
||||
dim: '\u001B[2m',
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines whether a link should be ignored during validation.
|
||||
*/
|
||||
function shouldIgnoreLink(link) {
|
||||
return (
|
||||
link.startsWith('http://') ||
|
||||
link.startsWith('https://') ||
|
||||
link.startsWith('mailto:') ||
|
||||
link.startsWith('tel:') ||
|
||||
link.startsWith('/') || // Absolute paths handled by Astro routing
|
||||
link.startsWith('#') // Same-file anchors
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove fenced and inline code segments from Markdown content.
|
||||
*/
|
||||
function stripCodeBlocks(content) {
|
||||
return content
|
||||
.replaceAll(/```[\s\S]*?```/g, '')
|
||||
.replaceAll(/~~~[\s\S]*?~~~/g, '')
|
||||
.replaceAll(/`[^`\n]+`/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse link to extract path and anchor.
|
||||
*/
|
||||
function parseLink(link) {
|
||||
const hashIndex = link.indexOf('#');
|
||||
if (hashIndex === -1) {
|
||||
return { path: link, anchor: null };
|
||||
}
|
||||
return {
|
||||
path: link.slice(0, hashIndex) || null,
|
||||
anchor: link.slice(hashIndex + 1),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line number for a character position in content.
|
||||
*/
|
||||
function getLineNumber(content, charIndex) {
|
||||
const lines = content.slice(0, charIndex).split('\n');
|
||||
return lines.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract links with their line numbers from markdown content.
|
||||
*/
|
||||
function extractLinksWithPositions(content, filePath) {
|
||||
const strippedContent = stripCodeBlocks(content);
|
||||
const links = [];
|
||||
|
||||
let match;
|
||||
LINK_PATTERN.lastIndex = 0;
|
||||
|
||||
while ((match = LINK_PATTERN.exec(strippedContent)) !== null) {
|
||||
const rawLink = match[2];
|
||||
if (!shouldIgnoreLink(rawLink)) {
|
||||
const lineNumber = getLineNumber(strippedContent, match.index);
|
||||
links.push({
|
||||
raw: rawLink,
|
||||
text: match[1],
|
||||
line: lineNumber,
|
||||
fullMatch: match[0],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a relative link path to an absolute file path.
|
||||
*/
|
||||
function resolveLink(fromFile, linkPath) {
|
||||
if (!linkPath) return fromFile;
|
||||
|
||||
const fromDir = dirname(fromFile);
|
||||
let resolved = normalize(resolve(fromDir, linkPath));
|
||||
|
||||
// If link doesn't have extension, try .md
|
||||
if (!resolved.endsWith('.md') && !resolved.endsWith('.mdx') && !existsSync(resolved)) {
|
||||
const withMd = resolved + '.md';
|
||||
if (existsSync(withMd)) {
|
||||
return withMd;
|
||||
}
|
||||
// Try as directory with index.md
|
||||
const asIndex = join(resolved, 'index.md');
|
||||
if (existsSync(asIndex)) {
|
||||
return asIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a file that may have moved.
|
||||
* Uses multiple strategies to find the best match.
|
||||
*
|
||||
* @param {string} brokenPath - The original broken link path (e.g., "../tutorials/getting-started/foo.md")
|
||||
* @returns {string[]} Array of matching absolute paths
|
||||
*/
|
||||
async function findMovedFile(brokenPath) {
|
||||
const fileName = basename(brokenPath);
|
||||
const searchName = fileName.endsWith('.md') ? fileName : `${fileName}.md`;
|
||||
|
||||
// Strategy 1: Try to match with directory context
|
||||
// e.g., for "tutorials/getting-started/foo.md", look for "*/getting-started/foo.md"
|
||||
const pathParts = brokenPath.replace(/^\.\.?\/?/, '').split('/');
|
||||
if (pathParts.length >= 2) {
|
||||
const parentDir = pathParts.at(-2);
|
||||
const contextPattern = `**/${parentDir}/${searchName}`;
|
||||
const contextMatches = await glob(contextPattern, {
|
||||
cwd: DOCS_DIR,
|
||||
absolute: true,
|
||||
ignore: ['**/_*/**'],
|
||||
});
|
||||
if (contextMatches.length > 0) {
|
||||
return contextMatches;
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy 2: For non-index files, try filename-only match
|
||||
// Skip this for index.md since it's too generic (exists in every directory)
|
||||
if (searchName !== 'index.md') {
|
||||
const matches = await glob(`**/${searchName}`, {
|
||||
cwd: DOCS_DIR,
|
||||
absolute: true,
|
||||
ignore: ['**/_*/**'],
|
||||
});
|
||||
return matches;
|
||||
}
|
||||
|
||||
// For index.md with no context match, return empty (truly missing)
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the relative path from source file to target file.
|
||||
*/
|
||||
function calculateRelativePath(fromFile, toFile) {
|
||||
const fromDir = dirname(fromFile);
|
||||
let relativePath = relative(fromDir, toFile);
|
||||
|
||||
// Ensure path starts with ./ or ../
|
||||
if (!relativePath.startsWith('.')) {
|
||||
relativePath = './' + relativePath;
|
||||
}
|
||||
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main audit function.
|
||||
*/
|
||||
async function main() {
|
||||
console.log('\n Documentation Link Auditor');
|
||||
console.log(' ==========================\n');
|
||||
console.log(' Scanning for broken links and attempting auto-resolution...\n');
|
||||
|
||||
// Find all markdown files, excluding underscore directories
|
||||
const files = await glob('**/*.{md,mdx}', {
|
||||
cwd: DOCS_DIR,
|
||||
absolute: true,
|
||||
ignore: ['**/_*/**'],
|
||||
});
|
||||
|
||||
console.log(` Found ${files.length} markdown files to scan.\n`);
|
||||
|
||||
const brokenLinks = [];
|
||||
const autoFixable = [];
|
||||
const needsReview = [];
|
||||
const missing = [];
|
||||
|
||||
// Track all files for fast lookup
|
||||
const allFiles = new Set(files);
|
||||
|
||||
for (const file of files) {
|
||||
const content = readFileSync(file, 'utf-8');
|
||||
const links = extractLinksWithPositions(content, file);
|
||||
const relativePath = relative(DOCS_DIR, file);
|
||||
|
||||
for (const linkInfo of links) {
|
||||
const { path: linkPath } = parseLink(linkInfo.raw);
|
||||
|
||||
if (!linkPath) continue; // Same-file anchor only
|
||||
|
||||
const targetFile = resolveLink(file, linkPath);
|
||||
|
||||
// Check if target exists
|
||||
if (!existsSync(targetFile)) {
|
||||
const fileName = basename(linkPath);
|
||||
|
||||
// Try to find the file elsewhere
|
||||
const candidates = await findMovedFile(linkPath);
|
||||
|
||||
const brokenInfo = {
|
||||
sourceFile: relativePath,
|
||||
sourceFileAbsolute: file,
|
||||
line: linkInfo.line,
|
||||
linkText: linkInfo.text,
|
||||
originalLink: linkInfo.raw,
|
||||
expectedTarget: linkPath,
|
||||
fullMatch: linkInfo.fullMatch,
|
||||
};
|
||||
|
||||
if (candidates.length === 1) {
|
||||
// Found exactly one match - auto-fixable
|
||||
const newPath = calculateRelativePath(file, candidates[0]);
|
||||
brokenInfo.suggestedFix = newPath;
|
||||
brokenInfo.foundAt = relative(DOCS_DIR, candidates[0]);
|
||||
brokenInfo.status = 'auto-fixable';
|
||||
autoFixable.push(brokenInfo);
|
||||
} else if (candidates.length > 1) {
|
||||
// Multiple matches - needs manual review
|
||||
brokenInfo.candidates = candidates.map((c) => relative(DOCS_DIR, c));
|
||||
brokenInfo.status = 'needs-review';
|
||||
needsReview.push(brokenInfo);
|
||||
} else {
|
||||
// No matches found
|
||||
brokenInfo.status = 'missing';
|
||||
missing.push(brokenInfo);
|
||||
}
|
||||
|
||||
brokenLinks.push(brokenInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate report
|
||||
const report = {
|
||||
timestamp: new Date().toISOString(),
|
||||
summary: {
|
||||
totalFiles: files.length,
|
||||
totalBroken: brokenLinks.length,
|
||||
autoFixable: autoFixable.length,
|
||||
needsReview: needsReview.length,
|
||||
missing: missing.length,
|
||||
},
|
||||
autoFixable,
|
||||
needsReview,
|
||||
missing,
|
||||
};
|
||||
|
||||
// Write JSON report
|
||||
writeFileSync(REPORT_PATH, JSON.stringify(report, null, 2));
|
||||
|
||||
// Console output
|
||||
console.log(' ' + '─'.repeat(50));
|
||||
console.log('\n SUMMARY\n');
|
||||
|
||||
if (brokenLinks.length === 0) {
|
||||
console.log(` ${colors.green}✓${colors.reset} No broken links found!\n`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(` Total broken links: ${colors.red}${brokenLinks.length}${colors.reset}`);
|
||||
console.log(` ├─ Auto-fixable: ${colors.green}${autoFixable.length}${colors.reset}`);
|
||||
console.log(` ├─ Needs review: ${colors.yellow}${needsReview.length}${colors.reset}`);
|
||||
console.log(` └─ Missing: ${colors.red}${missing.length}${colors.reset}\n`);
|
||||
|
||||
// Show auto-fixable
|
||||
if (autoFixable.length > 0) {
|
||||
console.log(` ${colors.green}AUTO-FIXABLE${colors.reset} (file found elsewhere)\n`);
|
||||
for (const item of autoFixable) {
|
||||
console.log(` ${colors.cyan}${item.sourceFile}${colors.reset}:${item.line}`);
|
||||
console.log(` ${colors.dim}Link:${colors.reset} ${item.originalLink}`);
|
||||
console.log(` ${colors.dim}Fix:${colors.reset} ${item.suggestedFix}`);
|
||||
console.log(` ${colors.dim}Found at:${colors.reset} ${item.foundAt}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
// Show needs review
|
||||
if (needsReview.length > 0) {
|
||||
console.log(` ${colors.yellow}NEEDS REVIEW${colors.reset} (multiple matches found)\n`);
|
||||
for (const item of needsReview) {
|
||||
console.log(` ${colors.cyan}${item.sourceFile}${colors.reset}:${item.line}`);
|
||||
console.log(` ${colors.dim}Link:${colors.reset} ${item.originalLink}`);
|
||||
console.log(` ${colors.dim}Candidates:${colors.reset}`);
|
||||
for (const candidate of item.candidates) {
|
||||
console.log(` - ${candidate}`);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
|
||||
// Show missing
|
||||
if (missing.length > 0) {
|
||||
console.log(` ${colors.red}MISSING${colors.reset} (file not found anywhere)\n`);
|
||||
for (const item of missing) {
|
||||
console.log(` ${colors.cyan}${item.sourceFile}${colors.reset}:${item.line}`);
|
||||
console.log(` ${colors.dim}Link:${colors.reset} ${item.originalLink}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(50));
|
||||
console.log(`\n Report saved to: ${colors.dim}${relative(process.cwd(), REPORT_PATH)}${colors.reset}`);
|
||||
console.log(`\n To fix auto-fixable links, run:`);
|
||||
console.log(` node tools/fix-doc-links.js --apply\n`);
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Error:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* Documentation Link Fixer
|
||||
*
|
||||
* Reads the audit report generated by audit-doc-links.js and applies fixes
|
||||
* to broken links where a single match was found.
|
||||
*
|
||||
* Usage:
|
||||
* node tools/fix-doc-links.js # Dry-run (preview changes)
|
||||
* node tools/fix-doc-links.js --apply # Apply changes
|
||||
*/
|
||||
|
||||
const { readFileSync, writeFileSync, existsSync } = require('node:fs');
|
||||
const { resolve, relative } = require('node:path');
|
||||
|
||||
const REPORT_PATH = resolve(__dirname, '.link-audit-report.json');
|
||||
|
||||
// Colors for console output
|
||||
const colors = {
|
||||
reset: '\u001B[0m',
|
||||
red: '\u001B[31m',
|
||||
green: '\u001B[32m',
|
||||
yellow: '\u001B[33m',
|
||||
cyan: '\u001B[36m',
|
||||
dim: '\u001B[2m',
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the audit report.
|
||||
*/
|
||||
function loadReport() {
|
||||
if (!existsSync(REPORT_PATH)) {
|
||||
console.error(`\n ${colors.red}Error:${colors.reset} No audit report found.`);
|
||||
console.error(` Run 'node tools/audit-doc-links.js' first.\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const content = readFileSync(REPORT_PATH, 'utf-8');
|
||||
return JSON.parse(content);
|
||||
} catch (error) {
|
||||
console.error(`\n ${colors.red}Error:${colors.reset} Failed to parse audit report.`);
|
||||
console.error(` ${error.message}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a fix to a file by replacing the original link with the suggested fix.
|
||||
*/
|
||||
function applyFix(filePath, originalLink, suggestedFix) {
|
||||
const content = readFileSync(filePath, 'utf-8');
|
||||
|
||||
// Create the replacement pattern - we need to match the exact link in markdown syntax
|
||||
// Original might have anchor, so we need to handle that
|
||||
const originalWithoutAnchor = originalLink.split('#')[0];
|
||||
const suggestedWithoutAnchor = suggestedFix.split('#')[0];
|
||||
|
||||
// Also preserve any anchor from the original if the fix doesn't include one
|
||||
let finalFix = suggestedFix;
|
||||
if (originalLink.includes('#') && !suggestedFix.includes('#')) {
|
||||
const anchor = originalLink.slice(originalLink.indexOf('#'));
|
||||
finalFix = suggestedFix + anchor;
|
||||
}
|
||||
|
||||
// Replace the link - be careful to only replace inside markdown link syntax
|
||||
const linkPattern = new RegExp(`\\]\\(${escapeRegex(originalLink)}\\)`, 'g');
|
||||
|
||||
const newContent = content.replace(linkPattern, `](${finalFix})`);
|
||||
|
||||
if (newContent === content) {
|
||||
return false; // No change made
|
||||
}
|
||||
|
||||
writeFileSync(filePath, newContent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape special regex characters in a string.
|
||||
*/
|
||||
function escapeRegex(string) {
|
||||
return string.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function.
|
||||
*/
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const applyChanges = args.includes('--apply');
|
||||
|
||||
console.log('\n Documentation Link Fixer');
|
||||
console.log(' ========================\n');
|
||||
|
||||
if (applyChanges) {
|
||||
console.log(` ${colors.green}APPLYING CHANGES${colors.reset}\n`);
|
||||
} else {
|
||||
console.log(` ${colors.yellow}DRY RUN${colors.reset} - No files will be modified.`);
|
||||
console.log(` Use --apply to apply changes.\n`);
|
||||
}
|
||||
|
||||
const report = loadReport();
|
||||
|
||||
if (report.autoFixable.length === 0) {
|
||||
console.log(` ${colors.green}✓${colors.reset} No auto-fixable links found.\n`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(` Found ${report.autoFixable.length} auto-fixable link(s).\n`);
|
||||
|
||||
const fixed = [];
|
||||
const failed = [];
|
||||
|
||||
// Group fixes by file for efficiency
|
||||
const byFile = {};
|
||||
for (const item of report.autoFixable) {
|
||||
if (!byFile[item.sourceFileAbsolute]) {
|
||||
byFile[item.sourceFileAbsolute] = [];
|
||||
}
|
||||
byFile[item.sourceFileAbsolute].push(item);
|
||||
}
|
||||
|
||||
for (const [filePath, items] of Object.entries(byFile)) {
|
||||
const displayPath = relative(process.cwd(), filePath);
|
||||
console.log(` ${colors.cyan}${displayPath}${colors.reset}`);
|
||||
|
||||
for (const item of items) {
|
||||
console.log(` Line ${item.line}:`);
|
||||
console.log(` ${colors.dim}Old:${colors.reset} ${item.originalLink}`);
|
||||
console.log(` ${colors.dim}New:${colors.reset} ${item.suggestedFix}`);
|
||||
|
||||
if (applyChanges) {
|
||||
try {
|
||||
const success = applyFix(filePath, item.originalLink, item.suggestedFix);
|
||||
if (success) {
|
||||
console.log(` ${colors.green}✓ Fixed${colors.reset}`);
|
||||
fixed.push(item);
|
||||
} else {
|
||||
console.log(` ${colors.yellow}⚠ No match found (may have been fixed already)${colors.reset}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ${colors.red}✗ Error: ${error.message}${colors.reset}`);
|
||||
failed.push({ ...item, error: error.message });
|
||||
}
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
|
||||
// Summary
|
||||
console.log(' ' + '─'.repeat(50));
|
||||
console.log('\n SUMMARY\n');
|
||||
|
||||
if (applyChanges) {
|
||||
console.log(` Fixed: ${colors.green}${fixed.length}${colors.reset}`);
|
||||
if (failed.length > 0) {
|
||||
console.log(` Failed: ${colors.red}${failed.length}${colors.reset}`);
|
||||
}
|
||||
console.log(`\n Run 'node tools/audit-doc-links.js' to verify remaining issues.\n`);
|
||||
} else {
|
||||
console.log(` Would fix: ${colors.yellow}${report.autoFixable.length}${colors.reset} link(s)`);
|
||||
console.log(`\n To apply these fixes, run:`);
|
||||
console.log(` node tools/fix-doc-links.js --apply\n`);
|
||||
}
|
||||
|
||||
process.exit(failed.length > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Error:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Reference in New Issue