feat: support claude cowork

This commit is contained in:
murat 2026-05-08 11:00:21 -05:00
parent e36f219c81
commit 0227b55eee
7 changed files with 272 additions and 31 deletions

View File

@ -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"
] ]
} }
] ]

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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"
}, },

View File

@ -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);
}