From 5d01549ea29d36348ca0538e8b185252813eb3f2 Mon Sep 17 00:00:00 2001 From: Alex Verkhovsky Date: Wed, 1 Apr 2026 13:02:21 -0700 Subject: [PATCH] refactor(install): make edit-prd self-contained and remove install_to_bmad Give bmad-edit-prd its own copy of prd-purpose.md and replace the cross-skill validation workflow reference with a skill invocation, so all three PRD skills are fully self-contained. With no remaining consumers, remove the install_to_bmad flag from manifests, CSV output, the post-install cleanup loop, and the dedicated test file. --- .../bmad-create-prd/bmad-skill-manifest.yaml | 3 - .../bmad-edit-prd/data/prd-purpose.md | 197 ++++++++++++++++++ .../steps-e/step-e-01-discovery.md | 2 +- .../steps-e/step-e-01b-legacy-conversion.md | 2 +- .../bmad-edit-prd/steps-e/step-e-02-review.md | 2 +- .../bmad-edit-prd/steps-e/step-e-03-edit.md | 2 +- .../steps-e/step-e-04-complete.md | 4 +- .../bmad-skill-manifest.yaml | 3 - test/test-install-to-bmad.js | 157 -------------- test/test-installation-components.js | 8 +- tools/installer/core/manifest-generator.js | 14 +- tools/installer/ide/_config-driven.js | 12 -- tools/installer/ide/shared/skill-manifest.js | 20 +- 13 files changed, 210 insertions(+), 216 deletions(-) delete mode 100644 src/bmm-skills/2-plan-workflows/bmad-create-prd/bmad-skill-manifest.yaml create mode 100644 src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md delete mode 100644 src/bmm-skills/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml delete mode 100644 test/test-install-to-bmad.js diff --git a/src/bmm-skills/2-plan-workflows/bmad-create-prd/bmad-skill-manifest.yaml b/src/bmm-skills/2-plan-workflows/bmad-create-prd/bmad-skill-manifest.yaml deleted file mode 100644 index cdf2e1ac2..000000000 --- a/src/bmm-skills/2-plan-workflows/bmad-create-prd/bmad-skill-manifest.yaml +++ /dev/null @@ -1,3 +0,0 @@ -# Cross-referenced by bmad-edit-prd for prd-purpose.md and data files. -# Must remain in _bmad/ until those references are refactored. -install_to_bmad: true diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md new file mode 100644 index 000000000..755230be7 --- /dev/null +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md @@ -0,0 +1,197 @@ +# BMAD PRD Purpose + +**The PRD is the top of the required funnel that feeds all subsequent product development work in rhw BMad Method.** + +--- + +## What is a BMAD PRD? + +A dual-audience document serving: +1. **Human Product Managers and builders** - Vision, strategy, stakeholder communication +2. **LLM Downstream Consumption** - UX Design → Architecture → Epics → Development AI Agents + +Each successive document becomes more AI-tailored and granular. + +--- + +## Core Philosophy: Information Density + +**High Signal-to-Noise Ratio** + +Every sentence must carry information weight. LLMs consume precise, dense content efficiently. + +**Anti-Patterns (Eliminate These):** +- ❌ "The system will allow users to..." → ✅ "Users can..." +- ❌ "It is important to note that..." → ✅ State the fact directly +- ❌ "In order to..." → ✅ "To..." +- ❌ Conversational filler and padding → ✅ Direct, concise statements + +**Goal:** Maximum information per word. Zero fluff. + +--- + +## The Traceability Chain + +**PRD starts the chain:** +``` +Vision → Success Criteria → User Journeys → Functional Requirements → (future: User Stories) +``` + +**In the PRD, establish:** +- Vision → Success Criteria alignment +- Success Criteria → User Journey coverage +- User Journey → Functional Requirement mapping +- All requirements traceable to user needs + +**Why:** Each downstream artifact (UX, Architecture, Epics, Stories) must trace back to documented user needs and business objectives. This chain ensures we build the right thing. + +--- + +## What Makes Great Functional Requirements? + +### FRs are Capabilities, Not Implementation + +**Good FR:** "Users can reset their password via email link" +**Bad FR:** "System sends JWT via email and validates with database" (implementation leakage) + +**Good FR:** "Dashboard loads in under 2 seconds for 95th percentile" +**Bad FR:** "Fast loading time" (subjective, unmeasurable) + +### SMART Quality Criteria + +**Specific:** Clear, precisely defined capability +**Measurable:** Quantifiable with test criteria +**Attainable:** Realistic within constraints +**Relevant:** Aligns with business objectives +**Traceable:** Links to source (executive summary or user journey) + +### FR Anti-Patterns + +**Subjective Adjectives:** +- ❌ "easy to use", "intuitive", "user-friendly", "fast", "responsive" +- ✅ Use metrics: "completes task in under 3 clicks", "loads in under 2 seconds" + +**Implementation Leakage:** +- ❌ Technology names, specific libraries, implementation details +- ✅ Focus on capability and measurable outcomes + +**Vague Quantifiers:** +- ❌ "multiple users", "several options", "various formats" +- ✅ "up to 100 concurrent users", "3-5 options", "PDF, DOCX, TXT formats" + +**Missing Test Criteria:** +- ❌ "The system shall provide notifications" +- ✅ "The system shall send email notifications within 30 seconds of trigger event" + +--- + +## What Makes Great Non-Functional Requirements? + +### NFRs Must Be Measurable + +**Template:** +``` +"The system shall [metric] [condition] [measurement method]" +``` + +**Examples:** +- ✅ "The system shall respond to API requests in under 200ms for 95th percentile as measured by APM monitoring" +- ✅ "The system shall maintain 99.9% uptime during business hours as measured by cloud provider SLA" +- ✅ "The system shall support 10,000 concurrent users as measured by load testing" + +### NFR Anti-Patterns + +**Unmeasurable Claims:** +- ❌ "The system shall be scalable" → ✅ "The system shall handle 10x load growth through horizontal scaling" +- ❌ "High availability required" → ✅ "99.9% uptime as measured by cloud provider SLA" + +**Missing Context:** +- ❌ "Response time under 1 second" → ✅ "API response time under 1 second for 95th percentile under normal load" + +--- + +## Domain-Specific Requirements + +**Auto-Detect and Enforce Based on Project Context** + +Certain industries have mandatory requirements that must be present: + +- **Healthcare:** HIPAA Privacy & Security Rules, PHI encryption, audit logging, MFA +- **Fintech:** PCI-DSS Level 1, AML/KYC compliance, SOX controls, financial audit trails +- **GovTech:** NIST framework, Section 508 accessibility (WCAG 2.1 AA), FedRAMP, data residency +- **E-Commerce:** PCI-DSS for payments, inventory accuracy, tax calculation by jurisdiction + +**Why:** Missing these requirements in the PRD means they'll be missed in architecture and implementation, creating expensive rework. During PRD creation there is a step to cover this - during validation we want to make sure it was covered. For this purpose steps will utilize a domain-complexity.csv and project-types.csv. + +--- + +## Document Structure (Markdown, Human-Readable) + +### Required Sections +1. **Executive Summary** - Vision, differentiator, target users +2. **Success Criteria** - Measurable outcomes (SMART) +3. **Product Scope** - MVP, Growth, Vision phases +4. **User Journeys** - Comprehensive coverage +5. **Domain Requirements** - Industry-specific compliance (if applicable) +6. **Innovation Analysis** - Competitive differentiation (if applicable) +7. **Project-Type Requirements** - Platform-specific needs +8. **Functional Requirements** - Capability contract (FRs) +9. **Non-Functional Requirements** - Quality attributes (NFRs) + +### Formatting for Dual Consumption + +**For Humans:** +- Clear, professional language +- Logical flow from vision to requirements +- Easy for stakeholders to review and approve + +**For LLMs:** +- ## Level 2 headers for all main sections (enables extraction) +- Consistent structure and patterns +- Precise, testable language +- High information density + +--- + +## Downstream Impact + +**How the PRD Feeds Next Artifacts:** + +**UX Design:** +- User journeys → interaction flows +- FRs → design requirements +- Success criteria → UX metrics + +**Architecture:** +- FRs → system capabilities +- NFRs → architecture decisions +- Domain requirements → compliance architecture +- Project-type requirements → platform choices + +**Epics & Stories (created after architecture):** +- FRs → user stories (1 FR could map to 1-3 stories potentially) +- Acceptance criteria → story acceptance tests +- Priority → sprint sequencing +- Traceability → stories map back to vision + +**Development AI Agents:** +- Precise requirements → implementation clarity +- Test criteria → automated test generation +- Domain requirements → compliance enforcement +- Measurable NFRs → performance targets + +--- + +## Summary: What Makes a Great BMAD PRD? + +✅ **High Information Density** - Every sentence carries weight, zero fluff +✅ **Measurable Requirements** - All FRs and NFRs are testable with specific criteria +✅ **Clear Traceability** - Each requirement links to user need and business objective +✅ **Domain Awareness** - Industry-specific requirements auto-detected and included +✅ **Zero Anti-Patterns** - No subjective adjectives, implementation leakage, or vague quantifiers +✅ **Dual Audience Optimized** - Human-readable AND LLM-consumable +✅ **Markdown Format** - Professional, clean, accessible to all stakeholders + +--- + +**Remember:** The PRD is the foundation. Quality here ripples through every subsequent phase. A dense, precise, well-traced PRD makes UX design, architecture, epic breakdown, and AI development dramatically more effective. diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md index f8d84ecb3..39e344946 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md @@ -1,6 +1,6 @@ --- # File references (ONLY variables used in this step) -prdPurpose: '{project-root}/_bmad/bmm/2-plan-workflows/bmad-create-prd/data/prd-purpose.md' +prdPurpose: '../data/prd-purpose.md' --- # Step E-1: Discovery & Understanding diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md index 8ce979f10..54f82525b 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md @@ -1,7 +1,7 @@ --- # File references (ONLY variables used in this step) prdFile: '{prd_file_path}' -prdPurpose: '{project-root}/_bmad/bmm/2-plan-workflows/bmad-create-prd/data/prd-purpose.md' +prdPurpose: '../data/prd-purpose.md' --- # Step E-1B: Legacy PRD Conversion Assessment diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md index 6eaac3c25..c01a0adb9 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md @@ -2,7 +2,7 @@ # File references (ONLY variables used in this step) prdFile: '{prd_file_path}' validationReport: '{validation_report_path}' # If provided -prdPurpose: '{project-root}/_bmad/bmm/2-plan-workflows/bmad-create-prd/data/prd-purpose.md' +prdPurpose: '../data/prd-purpose.md' --- # Step E-2: Deep Review & Analysis diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md index 99d942495..5b5e66902 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md @@ -1,7 +1,7 @@ --- # File references (ONLY variables used in this step) prdFile: '{prd_file_path}' -prdPurpose: '{project-root}/_bmad/bmm/2-plan-workflows/bmad-create-prd/data/prd-purpose.md' +prdPurpose: '../data/prd-purpose.md' --- # Step E-3: Edit & Update diff --git a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md index bba9385de..1406e631c 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +++ b/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md @@ -1,7 +1,6 @@ --- # File references (ONLY variables used in this step) prdFile: '{prd_file_path}' -validationWorkflow: '{project-root}/_bmad/bmm/2-plan-workflows/bmad-validate-prd/steps-v/step-v-01-discovery.md' --- # Step E-4: Complete & Validate @@ -117,8 +116,7 @@ Display: - Display: "This will run all 13 validation checks on the updated PRD." - Display: "Preparing to validate: {prd_file_path}" - Display: "**Proceeding to validation...**" - - Read fully and follow: {validationWorkflow} (steps-v/step-v-01-discovery.md) - - Note: This hands off to the validation workflow which will run its complete 13-step process + - Invoke the `bmad-validate-prd` skill to run the complete validation workflow - **IF E (Edit More):** - Display: "**Additional Edits**" diff --git a/src/bmm-skills/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml b/src/bmm-skills/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml deleted file mode 100644 index 86714441d..000000000 --- a/src/bmm-skills/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml +++ /dev/null @@ -1,3 +0,0 @@ -# Cross-referenced by bmad-edit-prd for validation workflow steps. -# Must remain in _bmad/ until those references are refactored. -install_to_bmad: true diff --git a/test/test-install-to-bmad.js b/test/test-install-to-bmad.js deleted file mode 100644 index f5df68d6c..000000000 --- a/test/test-install-to-bmad.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * install_to_bmad Flag — Design Contract Tests - * - * Unit tests against the functions that implement the install_to_bmad flag. - * These nail down the 4 core design decisions: - * - * 1. omitted → skill removed from _bmad/ (default behavior) - * 2. true → skill stays in _bmad/ (explicit opt-in) - * 2b. false → skill removed from _bmad/ after IDE install - * 3. No platform → no cleanup runs (cleanup lives in installVerbatimSkills) - * 4. Mixed flags → each skill evaluated independently - * - * Usage: node test/test-install-to-bmad.js - */ - -const path = require('node:path'); -const os = require('node:os'); -const fs = require('fs-extra'); -const { loadSkillManifest, getInstallToBmad } = require('../tools/installer/ide/shared/skill-manifest'); - -// ANSI colors -const colors = { - reset: '\u001B[0m', - green: '\u001B[32m', - red: '\u001B[31m', - yellow: '\u001B[33m', - cyan: '\u001B[36m', - dim: '\u001B[2m', -}; - -let passed = 0; -let failed = 0; - -function assert(condition, testName, errorMessage = '') { - if (condition) { - console.log(`${colors.green}✓${colors.reset} ${testName}`); - passed++; - } else { - console.log(`${colors.red}✗${colors.reset} ${testName}`); - if (errorMessage) { - console.log(` ${colors.dim}${errorMessage}${colors.reset}`); - } - failed++; - } -} - -async function runTests() { - console.log(`${colors.cyan}========================================`); - console.log('install_to_bmad — Design Contract Tests'); - console.log(`========================================${colors.reset}\n`); - - // ============================================================ - // 1. omitted → getInstallToBmad returns false (remove from _bmad/) - // Skills are self-contained in IDE directories, so the default - // is to clean up from _bmad/ after IDE install. - // ============================================================ - console.log(`${colors.yellow}Design decision 1: omitted → skill removed from _bmad/ (default)${colors.reset}\n`); - - // Null manifest (no bmad-skill-manifest.yaml) → false - assert(getInstallToBmad(null, 'workflow.md') === false, 'null manifest defaults to false'); - - // Single-entry, flag omitted → false - assert( - getInstallToBmad({ __single: { type: 'skill' } }, 'workflow.md') === false, - 'single-entry manifest with flag omitted defaults to false', - ); - - // Single-entry, explicit true → true (opt-in to keep in _bmad/) - assert( - getInstallToBmad({ __single: { type: 'skill', install_to_bmad: true } }, 'workflow.md') === true, - 'single-entry manifest with explicit true returns true', - ); - - console.log(''); - - // ============================================================ - // 2. false → getInstallToBmad returns false (remove from _bmad/) - // ============================================================ - console.log(`${colors.yellow}Design decision 2: false → skill removed from _bmad/${colors.reset}\n`); - - // Single-entry, explicit false → false - assert( - getInstallToBmad({ __single: { type: 'skill', install_to_bmad: false } }, 'workflow.md') === false, - 'single-entry manifest with explicit false returns false', - ); - - // loadSkillManifest round-trip: YAML with false is preserved through load - { - const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-itb-')); - await fs.writeFile(path.join(tmpDir, 'bmad-skill-manifest.yaml'), 'type: skill\ninstall_to_bmad: false\n'); - const loaded = await loadSkillManifest(tmpDir); - assert(getInstallToBmad(loaded, 'workflow.md') === false, 'loadSkillManifest preserves install_to_bmad: false through round-trip'); - await fs.remove(tmpDir); - } - - console.log(''); - - // ============================================================ - // 3. No platform → cleanup only runs inside installVerbatimSkills - // (This is a design invariant: getInstallToBmad is only consulted - // during IDE install. Without a platform, the flag has no effect.) - // ============================================================ - console.log(`${colors.yellow}Design decision 3: flag is a per-skill property, not a pipeline gate${colors.reset}\n`); - - // The flag value is stored but doesn't trigger any side effects by itself. - // Cleanup is driven by reading the CSV column inside installVerbatimSkills. - // We verify the flag is just data — getInstallToBmad doesn't touch the filesystem. - { - const manifest = { __single: { type: 'skill', install_to_bmad: false } }; - const result = getInstallToBmad(manifest, 'workflow.md'); - assert(typeof result === 'boolean', 'getInstallToBmad returns a boolean (pure data, no side effects)'); - assert(result === false, 'false value is faithfully returned for consumer to act on'); - } - - console.log(''); - - // ============================================================ - // 4. Mixed flags → each skill evaluated independently - // ============================================================ - console.log(`${colors.yellow}Design decision 4: mixed flags — each skill independent${colors.reset}\n`); - - // Multi-entry manifest: different files can have different flags - { - const manifest = { - 'workflow.md': { type: 'skill', install_to_bmad: false }, - 'other.md': { type: 'skill', install_to_bmad: true }, - }; - assert(getInstallToBmad(manifest, 'workflow.md') === false, 'multi-entry: workflow.md with false returns false'); - assert(getInstallToBmad(manifest, 'other.md') === true, 'multi-entry: other.md with true returns true'); - assert(getInstallToBmad(manifest, 'unknown.md') === false, 'multi-entry: unknown file defaults to false'); - } - - console.log(''); - - // ============================================================ - // Summary - // ============================================================ - console.log(`${colors.cyan}========================================`); - console.log('Results:'); - console.log(` Passed: ${colors.green}${passed}${colors.reset}`); - console.log(` Failed: ${colors.red}${failed}${colors.reset}`); - console.log(`========================================${colors.reset}\n`); - - if (failed === 0) { - console.log(`${colors.green}All install_to_bmad contract tests passed!${colors.reset}\n`); - process.exit(0); - } else { - console.log(`${colors.red}Some install_to_bmad contract tests failed${colors.reset}\n`); - process.exit(1); - } -} - -runTests().catch((error) => { - console.error(`${colors.red}Test runner failed:${colors.reset}`, error.message); - console.error(error.stack); - process.exit(1); -}); diff --git a/test/test-installation-components.js b/test/test-installation-components.js index 1ac4b386d..d514d907f 100644 --- a/test/test-installation-components.js +++ b/test/test-installation-components.js @@ -59,8 +59,8 @@ async function createTestBmadFixture() { await fs.writeFile( path.join(fixtureDir, '_config', 'skill-manifest.csv'), [ - 'canonicalId,name,description,module,path,install_to_bmad', - '"bmad-master","bmad-master","Minimal test agent fixture","core","_bmad/core/bmad-master/SKILL.md","true"', + 'canonicalId,name,description,module,path', + '"bmad-master","bmad-master","Minimal test agent fixture","core","_bmad/core/bmad-master/SKILL.md"', '', ].join('\n'), ); @@ -103,8 +103,8 @@ async function createSkillCollisionFixture() { await fs.writeFile( path.join(configDir, 'skill-manifest.csv'), [ - 'canonicalId,name,description,module,path,install_to_bmad', - '"bmad-help","bmad-help","Native help skill","core","_bmad/core/tasks/bmad-help/SKILL.md","true"', + 'canonicalId,name,description,module,path', + '"bmad-help","bmad-help","Native help skill","core","_bmad/core/tasks/bmad-help/SKILL.md"', '', ].join('\n'), ); diff --git a/tools/installer/core/manifest-generator.js b/tools/installer/core/manifest-generator.js index bef6f2d23..74972d36e 100644 --- a/tools/installer/core/manifest-generator.js +++ b/tools/installer/core/manifest-generator.js @@ -9,7 +9,6 @@ const { loadSkillManifest: loadSkillManifestShared, getCanonicalId: getCanonicalIdShared, getArtifactType: getArtifactTypeShared, - getInstallToBmad: getInstallToBmadShared, } = require('../ide/shared/skill-manifest'); // Load package.json for version info @@ -42,11 +41,6 @@ class ManifestGenerator { return getArtifactTypeShared(manifest, filename); } - /** Delegate to shared skill-manifest module */ - getInstallToBmad(manifest, filename) { - return getInstallToBmadShared(manifest, filename); - } - /** * Clean text for CSV output by normalizing whitespace. * Note: Quote escaping is handled by escapeCsv() at write time. @@ -127,7 +121,7 @@ class ManifestGenerator { * Recursively walk a module directory tree, collecting native SKILL.md entrypoints. * A directory is discovered as a skill when it contains a SKILL.md file with * valid name/description frontmatter (name must match directory name). - * Manifest YAML is loaded only when present — for install_to_bmad and agent metadata. + * Manifest YAML is loaded only when present — for agent metadata. * Populates this.skills[] and this.skillClaimedDirs (Set of absolute paths). */ async collectSkills() { @@ -156,7 +150,7 @@ class ManifestGenerator { const skillMeta = await this.parseSkillMd(skillMdPath, dir, dirName, debug); if (skillMeta) { - // Load manifest when present (for install_to_bmad and agent metadata) + // Load manifest when present (for agent metadata) const manifest = await this.loadSkillManifest(dir); const artifactType = this.getArtifactType(manifest, skillFile); @@ -182,7 +176,6 @@ class ManifestGenerator { module: moduleName, path: installPath, canonicalId, - install_to_bmad: this.getInstallToBmad(manifest, skillFile), }); // Add to files list @@ -472,7 +465,7 @@ class ManifestGenerator { const csvPath = path.join(cfgDir, 'skill-manifest.csv'); const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`; - let csvContent = 'canonicalId,name,description,module,path,install_to_bmad\n'; + let csvContent = 'canonicalId,name,description,module,path\n'; for (const skill of this.skills) { const row = [ @@ -481,7 +474,6 @@ class ManifestGenerator { escapeCsv(skill.description), escapeCsv(skill.module), escapeCsv(skill.path), - escapeCsv(skill.install_to_bmad), ].join(','); csvContent += row + '\n'; } diff --git a/tools/installer/ide/_config-driven.js b/tools/installer/ide/_config-driven.js index ec7dcaad6..15791e112 100644 --- a/tools/installer/ide/_config-driven.js +++ b/tools/installer/ide/_config-driven.js @@ -183,18 +183,6 @@ class ConfigDrivenIdeSetup { count++; } - // Post-install cleanup: remove _bmad/ directories for skills with install_to_bmad === "false" - for (const record of records) { - if (record.install_to_bmad === 'false') { - const relativePath = record.path.startsWith(bmadPrefix) ? record.path.slice(bmadPrefix.length) : record.path; - const sourceFile = path.join(bmadDir, relativePath); - const sourceDir = path.dirname(sourceFile); - if (await fs.pathExists(sourceDir)) { - await fs.remove(sourceDir); - } - } - } - return count; } diff --git a/tools/installer/ide/shared/skill-manifest.js b/tools/installer/ide/shared/skill-manifest.js index c5caa0cc8..746d5d16f 100644 --- a/tools/installer/ide/shared/skill-manifest.js +++ b/tools/installer/ide/shared/skill-manifest.js @@ -54,22 +54,4 @@ function getArtifactType(manifest, filename) { return null; } -/** - * Get the install_to_bmad flag for a specific file from a loaded skill manifest. - * Skills are self-contained in their IDE skill directories (.claude/skills/, etc.), - * so the default is false — skill content is removed from _bmad/ after IDE install. - * Set install_to_bmad: true in bmad-skill-manifest.yaml to opt a skill back in. - * @param {Object|null} manifest - Loaded manifest (from loadSkillManifest) - * @param {string} filename - Source filename to look up - * @returns {boolean} install_to_bmad value (defaults to false) - */ -function getInstallToBmad(manifest, filename) { - if (!manifest) return false; - // Single-entry manifest applies to all files in the directory - if (manifest.__single) return manifest.__single.install_to_bmad === true; - // Multi-entry: look up by filename directly - if (manifest[filename]) return manifest[filename].install_to_bmad === true; - return false; -} - -module.exports = { loadSkillManifest, getCanonicalId, getArtifactType, getInstallToBmad }; +module.exports = { loadSkillManifest, getCanonicalId, getArtifactType };