diff --git a/docs/_STYLE_GUIDE.md b/docs/_STYLE_GUIDE.md
index 801314cd0..f9b38ed86 100644
--- a/docs/_STYLE_GUIDE.md
+++ b/docs/_STYLE_GUIDE.md
@@ -78,7 +78,6 @@ your-project/
├── _bmad/ # BMad configuration
├── _bmad-output/
│ ├── PRD.md # Your requirements document
-│ └── bmm-workflow-status.yaml # Progress tracking
└── ...
```
````
@@ -142,12 +141,12 @@ your-project/
### Types
-| Type | Example |
-| ----------------- | ---------------------------- |
-| **Index/Landing** | `core-concepts/index.md` |
-| **Concept** | `what-are-agents.md` |
-| **Feature** | `quick-flow.md` |
-| **Philosophy** | `why-solutioning-matters.md` |
+| Type | Example |
+| ----------------- | ----------------------------- |
+| **Index/Landing** | `core-concepts/index.md` |
+| **Concept** | `what-are-agents.md` |
+| **Feature** | `quick-flow.md` |
+| **Philosophy** | `why-solutioning-matters.md` |
| **FAQ** | `established-projects-faq.md` |
### General Template
diff --git a/package.json b/package.json
index 9cd7e90ad..6fc2e1024 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
},
"scripts": {
"bmad:install": "node tools/cli/bmad-cli.js install",
+ "bmad:uninstall": "node tools/cli/bmad-cli.js uninstall",
"docs:build": "node tools/build-docs.mjs",
"docs:dev": "astro dev --root website",
"docs:fix-links": "node tools/fix-doc-links.js",
diff --git a/src/bmm/workflows/document-project/instructions.md b/src/bmm/workflows/document-project/instructions.md
index 059134259..0354be610 100644
--- a/src/bmm/workflows/document-project/instructions.md
+++ b/src/bmm/workflows/document-project/instructions.md
@@ -8,55 +8,7 @@
This router determines workflow mode and delegates to specialized sub-workflows
-
-
-
- mode: data
- data_request: project_config
-
-
-
-
-
- Set standalone_mode = true
- Set status_file_found = false
-
-
-
- Store {{status_file_path}} for later updates
- Set status_file_found = true
-
-
-
-
- Continue anyway to document planning artifacts? (y/n)
-
- Exit workflow
-
-
-
-
-
- mode: validate
- calling_workflow: document-project
-
-
-
-
-
- Continue with documentation? (y/n)
-
-
- Exit workflow
-
-
-
-
-
-
-
-SMART LOADING STRATEGY: Check state file FIRST before loading any CSV files
-
+
Check for existing state file at: {project_knowledge}/project-scan-report.json
@@ -66,21 +18,21 @@
I found an in-progress workflow state from {{last_updated}}.
-**Current Progress:**
+ **Current Progress:**
-- Mode: {{mode}}
-- Scan Level: {{scan_level}}
-- Completed Steps: {{completed_steps_count}}/{{total_steps}}
-- Last Step: {{current_step}}
-- Project Type(s): {{cached_project_types}}
+ - Mode: {{mode}}
+ - Scan Level: {{scan_level}}
+ - Completed Steps: {{completed_steps_count}}/{{total_steps}}
+ - Last Step: {{current_step}}
+ - Project Type(s): {{cached_project_types}}
-Would you like to:
+ Would you like to:
-1. **Resume from where we left off** - Continue from step {{current_step}}
-2. **Start fresh** - Archive old state and begin new scan
-3. **Cancel** - Exit without changes
+ 1. **Resume from where we left off** - Continue from step {{current_step}}
+ 2. **Start fresh** - Archive old state and begin new scan
+ 3. **Cancel** - Exit without changes
-Your choice [1/2/3]:
+ Your choice [1/2/3]:
@@ -175,47 +127,4 @@ Your choice [1/2/3]:
-
-
-
-
- mode: update
- action: complete_workflow
- workflow_name: document-project
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tools/cli/README.md b/tools/cli/README.md
index 8ba164d36..9e943d689 100644
--- a/tools/cli/README.md
+++ b/tools/cli/README.md
@@ -16,8 +16,8 @@ Always displayed after the module is configured:
```yaml
post-install-notes: |
- Remember to set the API_KEY environment variable.
- See: https://example.com/setup
+ Thank you for choosing the XYZ Cool Module
+ For Support about this Module call 555-1212
```
### Conditional Format
diff --git a/tools/cli/commands/uninstall.js b/tools/cli/commands/uninstall.js
new file mode 100644
index 000000000..99734791e
--- /dev/null
+++ b/tools/cli/commands/uninstall.js
@@ -0,0 +1,167 @@
+const path = require('node:path');
+const fs = require('fs-extra');
+const prompts = require('../lib/prompts');
+const { Installer } = require('../installers/lib/core/installer');
+
+const installer = new Installer();
+
+module.exports = {
+ command: 'uninstall',
+ description: 'Remove BMAD installation from the current project',
+ options: [
+ ['-y, --yes', 'Remove all BMAD components without prompting (preserves user artifacts)'],
+ ['--directory ', 'Project directory (default: current directory)'],
+ ],
+ action: async (options) => {
+ try {
+ let projectDir;
+
+ if (options.directory) {
+ // Explicit --directory flag takes precedence
+ projectDir = path.resolve(options.directory);
+ } else if (options.yes) {
+ // Non-interactive mode: use current directory
+ projectDir = process.cwd();
+ } else {
+ // Interactive: ask user which directory to uninstall from
+ // select() handles cancellation internally (exits process)
+ const dirChoice = await prompts.select({
+ message: 'Where do you want to uninstall BMAD from?',
+ choices: [
+ { value: 'cwd', name: `Current directory (${process.cwd()})` },
+ { value: 'other', name: 'Another directory...' },
+ ],
+ });
+
+ if (dirChoice === 'other') {
+ // text() handles cancellation internally (exits process)
+ const customDir = await prompts.text({
+ message: 'Enter the project directory path:',
+ placeholder: process.cwd(),
+ validate: (value) => {
+ if (!value || value.trim().length === 0) return 'Directory path is required';
+ },
+ });
+
+ projectDir = path.resolve(customDir.trim());
+ } else {
+ projectDir = process.cwd();
+ }
+ }
+
+ if (!(await fs.pathExists(projectDir))) {
+ await prompts.log.error(`Directory does not exist: ${projectDir}`);
+ process.exit(1);
+ }
+
+ const { bmadDir } = await installer.findBmadDir(projectDir);
+
+ if (!(await fs.pathExists(bmadDir))) {
+ await prompts.log.warn('No BMAD installation found.');
+ process.exit(0);
+ }
+
+ const existingInstall = await installer.getStatus(projectDir);
+ const version = existingInstall.version || 'unknown';
+ const modules = (existingInstall.modules || []).map((m) => m.id || m.name).join(', ');
+ const ides = (existingInstall.ides || []).join(', ');
+
+ const outputFolder = await installer.getOutputFolder(projectDir);
+
+ await prompts.intro('BMAD Uninstall');
+ await prompts.note(`Version: ${version}\nModules: ${modules}\nIDE integrations: ${ides}`, 'Current Installation');
+
+ let removeModules = true;
+ let removeIdeConfigs = true;
+ let removeOutputFolder = false;
+
+ if (!options.yes) {
+ // multiselect() handles cancellation internally (exits process)
+ const selected = await prompts.multiselect({
+ message: 'Select components to remove:',
+ options: [
+ {
+ value: 'modules',
+ label: `BMAD Modules & data (${installer.bmadFolderName}/)`,
+ hint: 'Core installation, agents, workflows, config',
+ },
+ { value: 'ide', label: 'IDE integrations', hint: ides || 'No IDEs configured' },
+ { value: 'output', label: `User artifacts (${outputFolder}/)`, hint: 'WARNING: Contains your work products' },
+ ],
+ initialValues: ['modules', 'ide'],
+ required: true,
+ });
+
+ removeModules = selected.includes('modules');
+ removeIdeConfigs = selected.includes('ide');
+ removeOutputFolder = selected.includes('output');
+
+ const red = (s) => `\u001B[31m${s}\u001B[0m`;
+ await prompts.note(
+ red('💀 This action is IRREVERSIBLE! Removed files cannot be recovered!') +
+ '\n' +
+ red('💀 IDE configurations and modules will need to be reinstalled.') +
+ '\n' +
+ red('💀 User artifacts are preserved unless explicitly selected.'),
+ '!! DESTRUCTIVE ACTION !!',
+ );
+
+ const confirmed = await prompts.confirm({
+ message: 'Proceed with uninstall?',
+ default: false,
+ });
+
+ if (!confirmed) {
+ await prompts.outro('Uninstall cancelled.');
+ process.exit(0);
+ }
+ }
+
+ // Phase 1: IDE integrations
+ if (removeIdeConfigs) {
+ const s = await prompts.spinner();
+ s.start('Removing IDE integrations...');
+ await installer.uninstallIdeConfigs(projectDir, existingInstall, { silent: true });
+ s.stop(`Removed IDE integrations (${ides || 'none'})`);
+ }
+
+ // Phase 2: User artifacts
+ if (removeOutputFolder) {
+ const s = await prompts.spinner();
+ s.start(`Removing user artifacts (${outputFolder}/)...`);
+ await installer.uninstallOutputFolder(projectDir, outputFolder);
+ s.stop('User artifacts removed');
+ }
+
+ // Phase 3: BMAD modules & data (last — other phases may need _bmad/)
+ if (removeModules) {
+ const s = await prompts.spinner();
+ s.start(`Removing BMAD modules & data (${installer.bmadFolderName}/)...`);
+ await installer.uninstallModules(projectDir);
+ s.stop('Modules & data removed');
+ }
+
+ const summary = [];
+ if (removeIdeConfigs) summary.push('IDE integrations cleaned');
+ if (removeModules) summary.push('Modules & data removed');
+ if (removeOutputFolder) summary.push('User artifacts removed');
+ if (!removeOutputFolder) summary.push(`User artifacts preserved in ${outputFolder}/`);
+
+ await prompts.note(summary.join('\n'), 'Summary');
+ await prompts.outro('To reinstall, run: npx bmad-method install');
+
+ process.exit(0);
+ } catch (error) {
+ try {
+ const errorMessage = error instanceof Error ? error.message : String(error);
+ await prompts.log.error(`Uninstall failed: ${errorMessage}`);
+ if (error instanceof Error && error.stack) {
+ await prompts.log.message(error.stack);
+ }
+ } catch {
+ console.error(error instanceof Error ? error.message : error);
+ }
+ process.exit(1);
+ }
+ },
+};
diff --git a/tools/cli/installers/install-messages.yaml b/tools/cli/installers/install-messages.yaml
index 66e683a27..6138c7c2c 100644
--- a/tools/cli/installers/install-messages.yaml
+++ b/tools/cli/installers/install-messages.yaml
@@ -34,7 +34,7 @@ startMessage: |
- Subscribe on YouTube: https://www.youtube.com/@BMadCode
- Every star & sub helps us reach more developers!
- Latest updates: https://github.com/bmad-code-org/BMAD-METHOD/CHANGELOG.md
+ Latest updates: https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js
index 3acb36465..b7197d44d 100644
--- a/tools/cli/installers/lib/core/installer.js
+++ b/tools/cli/installers/lib/core/installer.js
@@ -1528,20 +1528,157 @@ class Installer {
}
/**
- * Uninstall BMAD
+ * Uninstall BMAD with selective removal options
+ * @param {string} directory - Project directory
+ * @param {Object} options - Uninstall options
+ * @param {boolean} [options.removeModules=true] - Remove _bmad/ directory
+ * @param {boolean} [options.removeIdeConfigs=true] - Remove IDE configurations
+ * @param {boolean} [options.removeOutputFolder=false] - Remove user artifacts output folder
+ * @returns {Object} Result with success status and removed components
*/
- async uninstall(directory) {
+ async uninstall(directory, options = {}) {
const projectDir = path.resolve(directory);
const { bmadDir } = await this.findBmadDir(projectDir);
- if (await fs.pathExists(bmadDir)) {
- await fs.remove(bmadDir);
+ if (!(await fs.pathExists(bmadDir))) {
+ return { success: false, reason: 'not-installed' };
}
- // Clean up IDE configurations
- await this.ideManager.cleanup(projectDir);
+ // 1. DETECT: Read state BEFORE deleting anything
+ const existingInstall = await this.detector.detect(bmadDir);
+ const outputFolder = await this._readOutputFolder(bmadDir);
- return { success: true };
+ const removed = { modules: false, ideConfigs: false, outputFolder: false };
+
+ // 2. IDE CLEANUP (before _bmad/ deletion so configs are accessible)
+ if (options.removeIdeConfigs !== false) {
+ await this.uninstallIdeConfigs(projectDir, existingInstall, { silent: options.silent });
+ removed.ideConfigs = true;
+ }
+
+ // 3. OUTPUT FOLDER (only if explicitly requested)
+ if (options.removeOutputFolder === true && outputFolder) {
+ removed.outputFolder = await this.uninstallOutputFolder(projectDir, outputFolder);
+ }
+
+ // 4. BMAD DIRECTORY (last, after everything that needs it)
+ if (options.removeModules !== false) {
+ removed.modules = await this.uninstallModules(projectDir);
+ }
+
+ return { success: true, removed, version: existingInstall.version };
+ }
+
+ /**
+ * Uninstall IDE configurations only
+ * @param {string} projectDir - Project directory
+ * @param {Object} existingInstall - Detection result from detector.detect()
+ * @param {Object} [options] - Options (e.g. { silent: true })
+ * @returns {Promise