feat: support claude cowork
This commit is contained in:
parent
e36f219c81
commit
0227b55eee
|
|
@ -20,6 +20,7 @@
|
||||||
"skills": [
|
"skills": [
|
||||||
"./src/core-skills/bmad-help",
|
"./src/core-skills/bmad-help",
|
||||||
"./src/core-skills/bmad-brainstorming",
|
"./src/core-skills/bmad-brainstorming",
|
||||||
|
"./src/core-skills/bmad-customize",
|
||||||
"./src/core-skills/bmad-distillator",
|
"./src/core-skills/bmad-distillator",
|
||||||
"./src/core-skills/bmad-party-mode",
|
"./src/core-skills/bmad-party-mode",
|
||||||
"./src/core-skills/bmad-shard-doc",
|
"./src/core-skills/bmad-shard-doc",
|
||||||
|
|
@ -44,6 +45,7 @@
|
||||||
"./src/bmm-skills/1-analysis/bmad-agent-analyst",
|
"./src/bmm-skills/1-analysis/bmad-agent-analyst",
|
||||||
"./src/bmm-skills/1-analysis/bmad-agent-tech-writer",
|
"./src/bmm-skills/1-analysis/bmad-agent-tech-writer",
|
||||||
"./src/bmm-skills/1-analysis/bmad-document-project",
|
"./src/bmm-skills/1-analysis/bmad-document-project",
|
||||||
|
"./src/bmm-skills/1-analysis/bmad-prfaq",
|
||||||
"./src/bmm-skills/1-analysis/research/bmad-domain-research",
|
"./src/bmm-skills/1-analysis/research/bmad-domain-research",
|
||||||
"./src/bmm-skills/1-analysis/research/bmad-market-research",
|
"./src/bmm-skills/1-analysis/research/bmad-market-research",
|
||||||
"./src/bmm-skills/1-analysis/research/bmad-technical-research",
|
"./src/bmm-skills/1-analysis/research/bmad-technical-research",
|
||||||
|
|
@ -67,7 +69,8 @@
|
||||||
"./src/bmm-skills/4-implementation/bmad-create-story",
|
"./src/bmm-skills/4-implementation/bmad-create-story",
|
||||||
"./src/bmm-skills/4-implementation/bmad-correct-course",
|
"./src/bmm-skills/4-implementation/bmad-correct-course",
|
||||||
"./src/bmm-skills/4-implementation/bmad-retrospective",
|
"./src/bmm-skills/4-implementation/bmad-retrospective",
|
||||||
"./src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests"
|
"./src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests",
|
||||||
|
"./src/bmm-skills/4-implementation/bmad-checkpoint-preview"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -111,3 +111,6 @@ jobs:
|
||||||
|
|
||||||
- name: Validate skills
|
- name: Validate skills
|
||||||
run: npm run validate:skills
|
run: npm run validate:skills
|
||||||
|
|
||||||
|
- name: Validate marketplace manifest
|
||||||
|
run: npm run validate:marketplace
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ npx bmad-method install --yes \
|
||||||
|
|
||||||
[See all installation options](https://docs.bmad-method.org/how-to/non-interactive-installation/)
|
[See all installation options](https://docs.bmad-method.org/how-to/non-interactive-installation/)
|
||||||
|
|
||||||
|
**Using Claude Cowork?** The npx installer doesn't reach Cowork's sandboxed VM. Use the plugin marketplace instead — register the marketplace then install the plugins from it. See [How to Install BMad in Claude Cowork](https://docs.bmad-method.org/how-to/install-claude-cowork/) for the full walkthrough.
|
||||||
|
|
||||||
> **Not sure what to do?** Ask `bmad-help` — it tells you exactly what's next and what's optional. You can also ask questions like `bmad-help I just finished the architecture, what do I do next?`
|
> **Not sure what to do?** Ask `bmad-help` — it tells you exactly what's next and what's optional. You can also ask questions like `bmad-help I just finished the architecture, what do I do next?`
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
@ -82,11 +84,11 @@ BMad Method extends with official modules for specialized domains. Available dur
|
||||||
[BMad Method Docs Site](https://docs.bmad-method.org) — Tutorials, guides, concepts, and reference
|
[BMad Method Docs Site](https://docs.bmad-method.org) — Tutorials, guides, concepts, and reference
|
||||||
|
|
||||||
**Quick links:**
|
**Quick links:**
|
||||||
|
|
||||||
- [Getting Started Tutorial](https://docs.bmad-method.org/tutorials/getting-started/)
|
- [Getting Started Tutorial](https://docs.bmad-method.org/tutorials/getting-started/)
|
||||||
- [Upgrading from Previous Versions](https://docs.bmad-method.org/how-to/upgrade-to-v6/)
|
- [Upgrading from Previous Versions](https://docs.bmad-method.org/how-to/upgrade-to-v6/)
|
||||||
- [Test Architect Documentation](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/)
|
- [Test Architect Documentation](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/)
|
||||||
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
- [Discord](https://discord.gg/gk8jAdXWmj) — Get help, share ideas, collaborate
|
- [Discord](https://discord.gg/gk8jAdXWmj) — Get help, share ideas, collaborate
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
title: 'How to Install BMad in Claude Cowork'
|
||||||
|
description: Install BMad in Claude Cowork using the Claude Code plugin marketplace.
|
||||||
|
sidebar:
|
||||||
|
order: 11
|
||||||
|
---
|
||||||
|
|
||||||
|
Claude.ai web and the Claude desktop chat have no access to your project files, so `npx bmad-method install` can't reach them. [Claude Cowork](https://www.claude.com/product/claude-code) does — it sandboxes your project in a VM and exposes a plugin manager. The `npx` installer still can't write into that sandbox, but Cowork accepts plugins via its marketplace API, which BMad's `.claude-plugin/marketplace.json` ships with.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Two steps — register the marketplace, then install the plugins:
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin marketplace add bmad-code-org/BMAD-METHOD
|
||||||
|
/plugin install bmad-pro-skills@bmad-method
|
||||||
|
/plugin install bmad-method-lifecycle@bmad-method
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart the Cowork session, then `/bmad-pro-skills:*` and `/bmad-method-lifecycle:*` slash commands appear.
|
||||||
|
|
||||||
|
## Update
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin marketplace update bmad-method
|
||||||
|
```
|
||||||
|
|
||||||
|
The marketplace name is `bmad-method`, not the GitHub slug.
|
||||||
|
|
||||||
|
## Uninstall
|
||||||
|
|
||||||
|
```
|
||||||
|
/plugin uninstall bmad-pro-skills@bmad-method
|
||||||
|
/plugin uninstall bmad-method-lifecycle@bmad-method
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known issue
|
||||||
|
|
||||||
|
Cowork's plugin reconciler currently has open bugs ([anthropics/claude-code#38429](https://github.com/anthropics/claude-code/issues/38429), [#39274](https://github.com/anthropics/claude-code/issues/39274)) that can purge third-party marketplace plugins on session sync. If your slash commands disappear, re-run the `/plugin install` lines.
|
||||||
|
|
||||||
|
## Pairing With TEA
|
||||||
|
|
||||||
|
To install TEA alongside BMad, register and install its marketplace too. See the [TEA README](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise#claude-cowork) for the exact commands.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- [How to Install BMad](./install-bmad.md) — the standard `npx bmad-method install` flow for non-Cowork tools.
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: "Getting Started"
|
title: 'Getting Started'
|
||||||
description: Install BMad and build your first project
|
description: Install BMad and build your first project
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -14,11 +14,12 @@ Build software faster using AI-powered workflows with specialized agents that gu
|
||||||
- Use agents and workflows effectively
|
- Use agents and workflows effectively
|
||||||
|
|
||||||
:::note[Prerequisites]
|
:::note[Prerequisites]
|
||||||
|
|
||||||
- **Node.js 20+** — Required for the installer
|
- **Node.js 20+** — Required for the installer
|
||||||
- **Git** — Recommended for version control
|
- **Git** — Recommended for version control
|
||||||
- **AI-powered IDE** — Claude Code, Cursor, or similar
|
- **AI-powered IDE** — Claude Code, Cursor, or similar
|
||||||
- **A project idea** — Even a simple one works for learning
|
- **A project idea** — Even a simple one works for learning
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::tip[The Easiest Path]
|
:::tip[The Easiest Path]
|
||||||
**Install** → `npx bmad-method install`
|
**Install** → `npx bmad-method install`
|
||||||
|
|
@ -50,6 +51,7 @@ bmad-help I have an idea for a SaaS product, I already know all the features I w
|
||||||
```
|
```
|
||||||
|
|
||||||
BMad-Help will respond with:
|
BMad-Help will respond with:
|
||||||
|
|
||||||
- What's recommended for your situation
|
- What's recommended for your situation
|
||||||
- What the first required task is
|
- What the first required task is
|
||||||
- What the rest of the process looks like
|
- What the rest of the process looks like
|
||||||
|
|
@ -66,12 +68,12 @@ After installing BMad, invoke the `bmad-help` skill immediately. It will detect
|
||||||
|
|
||||||
BMad helps you build software through guided workflows with specialized AI agents. The process follows four phases:
|
BMad helps you build software through guided workflows with specialized AI agents. The process follows four phases:
|
||||||
|
|
||||||
| Phase | Name | What Happens |
|
| Phase | Name | What Happens |
|
||||||
| ----- | -------------- | --------------------------------------------------- |
|
| ----- | -------------- | ------------------------------------------------------------ |
|
||||||
| 1 | Analysis | Brainstorming, research, product brief or PRFAQ *(optional)* |
|
| 1 | Analysis | Brainstorming, research, product brief or PRFAQ _(optional)_ |
|
||||||
| 2 | Planning | Create requirements (PRD or spec) |
|
| 2 | Planning | Create requirements (PRD or spec) |
|
||||||
| 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* |
|
| 3 | Solutioning | Design architecture _(BMad Method/Enterprise only)_ |
|
||||||
| 4 | Implementation | Build epic by epic, story by story |
|
| 4 | Implementation | Build epic by epic, story by story |
|
||||||
|
|
||||||
**[Open the Workflow Map](../reference/workflow-map.md)** to explore phases, workflows, and context management.
|
**[Open the Workflow Map](../reference/workflow-map.md)** to explore phases, workflows, and context management.
|
||||||
|
|
||||||
|
|
@ -100,9 +102,14 @@ If you want the newest prerelease build instead of the default release channel,
|
||||||
When prompted to select modules, choose **BMad Method**.
|
When prompted to select modules, choose **BMad Method**.
|
||||||
|
|
||||||
The installer creates two folders:
|
The installer creates two folders:
|
||||||
|
|
||||||
- `_bmad/` — agents, workflows, tasks, and configuration
|
- `_bmad/` — agents, workflows, tasks, and configuration
|
||||||
- `_bmad-output/` — empty for now, but this is where your artifacts will be saved
|
- `_bmad-output/` — empty for now, but this is where your artifacts will be saved
|
||||||
|
|
||||||
|
:::note[Using Claude Cowork?]
|
||||||
|
Cowork sandboxes your project in a VM, so the `npx` installer's writes to `.claude/skills/` aren't picked up. Install via the plugin marketplace instead — see [How to Install BMad in Claude Cowork](../how-to/install-claude-cowork.md).
|
||||||
|
:::
|
||||||
|
|
||||||
:::tip[Your Next Step]
|
:::tip[Your Next Step]
|
||||||
Open your AI IDE in the project folder and run:
|
Open your AI IDE in the project folder and run:
|
||||||
|
|
||||||
|
|
@ -134,6 +141,7 @@ Create it manually at `_bmad-output/project-context.md` or generate it after arc
|
||||||
### Phase 1: Analysis (Optional)
|
### Phase 1: Analysis (Optional)
|
||||||
|
|
||||||
All workflows in this phase are optional. [**Not sure which to use?**](../explanation/analysis-phase.md)
|
All workflows in this phase are optional. [**Not sure which to use?**](../explanation/analysis-phase.md)
|
||||||
|
|
||||||
- **brainstorming** (`bmad-brainstorming`) — Guided ideation
|
- **brainstorming** (`bmad-brainstorming`) — Guided ideation
|
||||||
- **research** (`bmad-market-research` / `bmad-domain-research` / `bmad-technical-research`) — Market, domain, and technical research
|
- **research** (`bmad-market-research` / `bmad-domain-research` / `bmad-technical-research`) — Market, domain, and technical research
|
||||||
- **product-brief** (`bmad-product-brief`) — Recommended foundation document when your concept is clear
|
- **product-brief** (`bmad-product-brief`) — Recommended foundation document when your concept is clear
|
||||||
|
|
@ -142,11 +150,13 @@ All workflows in this phase are optional. [**Not sure which to use?**](../explan
|
||||||
### Phase 2: Planning (Required)
|
### Phase 2: Planning (Required)
|
||||||
|
|
||||||
**For BMad Method and Enterprise tracks:**
|
**For BMad Method and Enterprise tracks:**
|
||||||
|
|
||||||
1. Invoke the **PM agent** (`bmad-agent-pm`) in a new chat
|
1. Invoke the **PM agent** (`bmad-agent-pm`) in a new chat
|
||||||
2. Run the `bmad-create-prd` workflow (`bmad-create-prd`)
|
2. Run the `bmad-create-prd` workflow (`bmad-create-prd`)
|
||||||
3. Output: `PRD.md`
|
3. Output: `PRD.md`
|
||||||
|
|
||||||
**For Quick Flow track:**
|
**For Quick Flow track:**
|
||||||
|
|
||||||
- Run `bmad-quick-dev` — it handles planning and implementation in a single workflow, skip to implementation
|
- Run `bmad-quick-dev` — it handles planning and implementation in a single workflow, skip to implementation
|
||||||
|
|
||||||
:::note[UX Design (Optional)]
|
:::note[UX Design (Optional)]
|
||||||
|
|
@ -156,6 +166,7 @@ If your project has a user interface, invoke the **UX-Designer agent** (`bmad-ag
|
||||||
### Phase 3: Solutioning (BMad Method/Enterprise)
|
### Phase 3: Solutioning (BMad Method/Enterprise)
|
||||||
|
|
||||||
**Create Architecture**
|
**Create Architecture**
|
||||||
|
|
||||||
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
||||||
2. Run `bmad-create-architecture` (`bmad-create-architecture`)
|
2. Run `bmad-create-architecture` (`bmad-create-architecture`)
|
||||||
3. Output: Architecture document with technical decisions
|
3. Output: Architecture document with technical decisions
|
||||||
|
|
@ -163,14 +174,15 @@ If your project has a user interface, invoke the **UX-Designer agent** (`bmad-ag
|
||||||
**Create Epics and Stories**
|
**Create Epics and Stories**
|
||||||
|
|
||||||
:::tip[V6 Improvement]
|
:::tip[V6 Improvement]
|
||||||
Epics and stories are now created *after* architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
|
Epics and stories are now created _after_ architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
1. Invoke the **PM agent** (`bmad-agent-pm`) in a new chat
|
1. Invoke the **PM agent** (`bmad-agent-pm`) in a new chat
|
||||||
2. Run `bmad-create-epics-and-stories` (`bmad-create-epics-and-stories`)
|
2. Run `bmad-create-epics-and-stories` (`bmad-create-epics-and-stories`)
|
||||||
3. The workflow uses both PRD and Architecture to create technically-informed stories
|
3. The workflow uses both PRD and Architecture to create technically-informed stories
|
||||||
|
|
||||||
**Implementation Readiness Check** *(Highly Recommended)*
|
**Implementation Readiness Check** _(Highly Recommended)_
|
||||||
|
|
||||||
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
1. Invoke the **Architect agent** (`bmad-agent-architect`) in a new chat
|
||||||
2. Run `bmad-check-implementation-readiness` (`bmad-check-implementation-readiness`)
|
2. Run `bmad-check-implementation-readiness` (`bmad-check-implementation-readiness`)
|
||||||
3. Validates cohesion across all planning documents
|
3. Validates cohesion across all planning documents
|
||||||
|
|
@ -187,11 +199,11 @@ Invoke the **Developer agent** (`bmad-agent-dev`) and run `bmad-sprint-planning`
|
||||||
|
|
||||||
For each story, repeat this cycle with fresh chats:
|
For each story, repeat this cycle with fresh chats:
|
||||||
|
|
||||||
| Step | Agent | Workflow | Command | Purpose |
|
| Step | Agent | Workflow | Command | Purpose |
|
||||||
| ---- | ----- | -------------- | -------------------------- | ---------------------------------- |
|
| ---- | ----- | ------------------- | ------------------- | ---------------------------------- |
|
||||||
| 1 | DEV | `bmad-create-story` | `bmad-create-story` | Create story file from epic |
|
| 1 | DEV | `bmad-create-story` | `bmad-create-story` | Create story file from epic |
|
||||||
| 2 | DEV | `bmad-dev-story` | `bmad-dev-story` | Implement the story |
|
| 2 | DEV | `bmad-dev-story` | `bmad-dev-story` | Implement the story |
|
||||||
| 3 | DEV | `bmad-code-review` | `bmad-code-review` | Quality validation *(recommended)* |
|
| 3 | DEV | `bmad-code-review` | `bmad-code-review` | Quality validation _(recommended)_ |
|
||||||
|
|
||||||
After completing all stories in an epic, invoke the **Developer agent** (`bmad-agent-dev`) and run `bmad-retrospective` (`bmad-retrospective`).
|
After completing all stories in an epic, invoke the **Developer agent** (`bmad-agent-dev`) and run `bmad-retrospective` (`bmad-retrospective`).
|
||||||
|
|
||||||
|
|
@ -222,18 +234,18 @@ your-project/
|
||||||
|
|
||||||
## Quick Reference
|
## Quick Reference
|
||||||
|
|
||||||
| Workflow | Command | Agent | Purpose |
|
| Workflow | Command | Agent | Purpose |
|
||||||
| ------------------------------------- | ------------------------------------------ | --------- | ----------------------------------------------- |
|
| ------------------------------------- | ------------------------------------- | --------- | ------------------------------------------ |
|
||||||
| **`bmad-help`** ⭐ | `bmad-help` | Any | **Your intelligent guide — ask anything!** |
|
| **`bmad-help`** ⭐ | `bmad-help` | Any | **Your intelligent guide — ask anything!** |
|
||||||
| `bmad-create-prd` | `bmad-create-prd` | PM | Create Product Requirements Document |
|
| `bmad-create-prd` | `bmad-create-prd` | PM | Create Product Requirements Document |
|
||||||
| `bmad-create-architecture` | `bmad-create-architecture` | Architect | Create architecture document |
|
| `bmad-create-architecture` | `bmad-create-architecture` | Architect | Create architecture document |
|
||||||
| `bmad-generate-project-context` | `bmad-generate-project-context` | Analyst | Create project context file |
|
| `bmad-generate-project-context` | `bmad-generate-project-context` | Analyst | Create project context file |
|
||||||
| `bmad-create-epics-and-stories` | `bmad-create-epics-and-stories` | PM | Break down PRD into epics |
|
| `bmad-create-epics-and-stories` | `bmad-create-epics-and-stories` | PM | Break down PRD into epics |
|
||||||
| `bmad-check-implementation-readiness` | `bmad-check-implementation-readiness` | Architect | Validate planning cohesion |
|
| `bmad-check-implementation-readiness` | `bmad-check-implementation-readiness` | Architect | Validate planning cohesion |
|
||||||
| `bmad-sprint-planning` | `bmad-sprint-planning` | DEV | Initialize sprint tracking |
|
| `bmad-sprint-planning` | `bmad-sprint-planning` | DEV | Initialize sprint tracking |
|
||||||
| `bmad-create-story` | `bmad-create-story` | DEV | Create a story file |
|
| `bmad-create-story` | `bmad-create-story` | DEV | Create a story file |
|
||||||
| `bmad-dev-story` | `bmad-dev-story` | DEV | Implement a story |
|
| `bmad-dev-story` | `bmad-dev-story` | DEV | Implement a story |
|
||||||
| `bmad-code-review` | `bmad-code-review` | DEV | Review implemented code |
|
| `bmad-code-review` | `bmad-code-review` | DEV | Review implemented code |
|
||||||
|
|
||||||
## Common Questions
|
## Common Questions
|
||||||
|
|
||||||
|
|
@ -253,6 +265,7 @@ Not strictly. Once you learn the flow, you can run workflows directly using the
|
||||||
|
|
||||||
:::tip[First Stop: BMad-Help]
|
:::tip[First Stop: BMad-Help]
|
||||||
**Invoke `bmad-help` anytime** — it's the fastest way to get unstuck. Ask it anything:
|
**Invoke `bmad-help` anytime** — it's the fastest way to get unstuck. Ask it anything:
|
||||||
|
|
||||||
- "What should I do after installing?"
|
- "What should I do after installing?"
|
||||||
- "I'm stuck on workflow X"
|
- "I'm stuck on workflow X"
|
||||||
- "What are my options for Y?"
|
- "What are my options for Y?"
|
||||||
|
|
@ -267,10 +280,11 @@ BMad-Help inspects your project, detects what you've completed, and tells you ex
|
||||||
## Key Takeaways
|
## Key Takeaways
|
||||||
|
|
||||||
:::tip[Remember These]
|
:::tip[Remember These]
|
||||||
|
|
||||||
- **Start with `bmad-help`** — Your intelligent guide that knows your project and options
|
- **Start with `bmad-help`** — Your intelligent guide that knows your project and options
|
||||||
- **Always use fresh chats** — Start a new chat for each workflow
|
- **Always use fresh chats** — Start a new chat for each workflow
|
||||||
- **Track matters** — Quick Flow uses `bmad-quick-dev`; Method/Enterprise need PRD and architecture
|
- **Track matters** — Quick Flow uses `bmad-quick-dev`; Method/Enterprise need PRD and architecture
|
||||||
- **BMad-Help runs automatically** — Every workflow ends with guidance on what's next
|
- **BMad-Help runs automatically** — Every workflow ends with guidance on what's next
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Ready to start? Install BMad, invoke `bmad-help`, and let your intelligent guide lead the way.
|
Ready to start? Install BMad, invoke `bmad-help`, and let your intelligent guide lead the way.
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,14 @@
|
||||||
"lint:fix": "eslint . --ext .js,.cjs,.mjs,.yaml --fix",
|
"lint:fix": "eslint . --ext .js,.cjs,.mjs,.yaml --fix",
|
||||||
"lint:md": "markdownlint-cli2 \"**/*.md\"",
|
"lint:md": "markdownlint-cli2 \"**/*.md\"",
|
||||||
"prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0",
|
"prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0",
|
||||||
"quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run test:install && npm run test:urls && npm run validate:refs && npm run validate:skills",
|
"quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run test:install && npm run test:urls && npm run validate:refs && npm run validate:skills && npm run validate:marketplace",
|
||||||
"rebundle": "node tools/installer/bundlers/bundle-web.js rebundle",
|
"rebundle": "node tools/installer/bundlers/bundle-web.js rebundle",
|
||||||
"test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run lint && npm run lint:md && npm run format:check",
|
"test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run lint && npm run lint:md && npm run format:check",
|
||||||
"test:channels": "node test/test-installer-channels.js",
|
"test:channels": "node test/test-installer-channels.js",
|
||||||
"test:install": "node test/test-installation-components.js",
|
"test:install": "node test/test-installation-components.js",
|
||||||
"test:refs": "node test/test-file-refs-csv.js",
|
"test:refs": "node test/test-file-refs-csv.js",
|
||||||
"test:urls": "node test/test-parse-source-urls.js",
|
"test:urls": "node test/test-parse-source-urls.js",
|
||||||
|
"validate:marketplace": "node tools/validate-marketplace.js --strict",
|
||||||
"validate:refs": "node tools/validate-file-refs.js --strict",
|
"validate:refs": "node tools/validate-file-refs.js --strict",
|
||||||
"validate:skills": "node tools/validate-skills.js --strict"
|
"validate:skills": "node tools/validate-skills.js --strict"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marketplace Drift Validator
|
||||||
|
*
|
||||||
|
* Verifies .claude-plugin/marketplace.json stays in sync with src/**\/SKILL.md.
|
||||||
|
* The marketplace.json is what Claude Code (and Claude Cowork) consume when a
|
||||||
|
* user runs `/plugin marketplace add bmad-code-org/BMAD-METHOD` — every skill
|
||||||
|
* shipped to other IDEs through the regular installer must also be reachable
|
||||||
|
* through the marketplace, or Cowork users silently miss skills.
|
||||||
|
*
|
||||||
|
* Checks:
|
||||||
|
* - Every src/**\/SKILL.md path is declared in some plugin's `skills` array.
|
||||||
|
* - Every declared skill path resolves to an existing src/.../SKILL.md.
|
||||||
|
* - No skill path is declared by more than one plugin.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* node tools/validate-marketplace.js human-readable report
|
||||||
|
* node tools/validate-marketplace.js --strict exit 1 on any drift (CI)
|
||||||
|
* node tools/validate-marketplace.js --json JSON output
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
||||||
|
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
|
||||||
|
const MARKETPLACE_PATH = path.join(PROJECT_ROOT, '.claude-plugin', 'marketplace.json');
|
||||||
|
|
||||||
|
const args = new Set(process.argv.slice(2));
|
||||||
|
const STRICT = args.has('--strict');
|
||||||
|
const JSON_OUTPUT = args.has('--json');
|
||||||
|
|
||||||
|
function findSkillPaths(dir, acc = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
findSkillPaths(full, acc);
|
||||||
|
} else if (entry.name === 'SKILL.md') {
|
||||||
|
// Normalize to forward slashes so the string-equal comparison against
|
||||||
|
// marketplace.json paths works on Windows (where path.relative uses '\').
|
||||||
|
const rel = path.relative(PROJECT_ROOT, path.dirname(full)).split(path.sep).join('/');
|
||||||
|
acc.push('./' + rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function suggestPlugin(skillPath, plugins) {
|
||||||
|
// Score by shared path-segment depth (not raw character prefix), so a new
|
||||||
|
// module like ./src/cis-skills/foo doesn't get falsely suggested under
|
||||||
|
// bmad-pro-skills just because both share './src/'.
|
||||||
|
// Suggest only when the match goes beyond the './src/<family>/' boundary.
|
||||||
|
const skillSegments = skillPath.split('/');
|
||||||
|
let best = null;
|
||||||
|
let bestScore = 0;
|
||||||
|
for (const plugin of plugins) {
|
||||||
|
for (const declared of plugin.skills || []) {
|
||||||
|
const declaredSegments = declared.split('/');
|
||||||
|
let i = 0;
|
||||||
|
while (i < skillSegments.length && i < declaredSegments.length && skillSegments[i] === declaredSegments[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i > bestScore) {
|
||||||
|
bestScore = i;
|
||||||
|
best = plugin.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Two skills in the same module family (e.g., both under ./src/core-skills/)
|
||||||
|
// share exactly 3 segments: '.', 'src', '<family>'. A skill in a brand-new
|
||||||
|
// family (e.g., ./src/cis-skills/) only shares 2 segments. Require >= 3
|
||||||
|
// so suggestions stay within the same family and don't leak across modules.
|
||||||
|
return bestScore >= 3 ? best : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
if (!fs.existsSync(MARKETPLACE_PATH)) {
|
||||||
|
return { ok: false, fatal: `marketplace.json not found at ${MARKETPLACE_PATH}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
let marketplace;
|
||||||
|
try {
|
||||||
|
marketplace = JSON.parse(fs.readFileSync(MARKETPLACE_PATH, 'utf8'));
|
||||||
|
} catch (error) {
|
||||||
|
return { ok: false, fatal: `marketplace.json is not valid JSON: ${error.message}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugins = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
|
||||||
|
const declaredBy = new Map(); // skillPath -> [pluginName]
|
||||||
|
for (const plugin of plugins) {
|
||||||
|
for (const skillPath of plugin.skills || []) {
|
||||||
|
if (!declaredBy.has(skillPath)) declaredBy.set(skillPath, []);
|
||||||
|
declaredBy.get(skillPath).push(plugin.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDisk = new Set(findSkillPaths(SRC_DIR));
|
||||||
|
|
||||||
|
const missing = []; // SKILL.md exists in src/ but no plugin declares it
|
||||||
|
for (const skillPath of [...onDisk].sort()) {
|
||||||
|
if (!declaredBy.has(skillPath)) {
|
||||||
|
missing.push({ path: skillPath, suggestedPlugin: suggestPlugin(skillPath, plugins) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const orphans = []; // plugin declares a path that has no SKILL.md
|
||||||
|
for (const skillPath of declaredBy.keys()) {
|
||||||
|
if (!onDisk.has(skillPath)) {
|
||||||
|
orphans.push({ path: skillPath, declaredBy: declaredBy.get(skillPath) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const duplicates = []; // same path declared by multiple plugins
|
||||||
|
for (const [skillPath, names] of declaredBy) {
|
||||||
|
if (names.length > 1) duplicates.push({ path: skillPath, declaredBy: names });
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: missing.length === 0 && orphans.length === 0 && duplicates.length === 0,
|
||||||
|
totals: { onDisk: onDisk.size, declared: declaredBy.size, plugins: plugins.length },
|
||||||
|
missing,
|
||||||
|
orphans,
|
||||||
|
duplicates,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportHuman(result) {
|
||||||
|
if (result.fatal) {
|
||||||
|
console.error(`✗ ${result.fatal}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { totals, missing, orphans, duplicates, ok } = result;
|
||||||
|
console.log(`Marketplace coverage: ${totals.declared} declared / ${totals.onDisk} on disk across ${totals.plugins} plugin(s)`);
|
||||||
|
|
||||||
|
if (missing.length > 0) {
|
||||||
|
console.log(`\n✗ ${missing.length} skill(s) on disk are not declared in marketplace.json:`);
|
||||||
|
for (const m of missing) {
|
||||||
|
const hint = m.suggestedPlugin ? ` → likely belongs in "${m.suggestedPlugin}"` : '';
|
||||||
|
console.log(` ${m.path}${hint}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orphans.length > 0) {
|
||||||
|
console.log(`\n✗ ${orphans.length} declared skill path(s) do not exist on disk:`);
|
||||||
|
for (const o of orphans) {
|
||||||
|
console.log(` ${o.path} (declared by: ${o.declaredBy.join(', ')})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicates.length > 0) {
|
||||||
|
console.log(`\n✗ ${duplicates.length} skill path(s) declared by multiple plugins:`);
|
||||||
|
for (const d of duplicates) {
|
||||||
|
console.log(` ${d.path} (in: ${d.declaredBy.join(', ')})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) console.log('\n✓ marketplace.json is in sync with src/');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = validate();
|
||||||
|
|
||||||
|
if (JSON_OUTPUT) {
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
} else {
|
||||||
|
reportHuman(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.ok && (STRICT || result.fatal)) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue