From baaa984a90250dbe64c89508676f23f541a97a18 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Sun, 7 Dec 2025 15:38:49 -0600 Subject: [PATCH] almost working installer updates --- .../cbt-coach/cognitive-distortions.md | 47 +++++++++++ .../cbt-coach/thought-records.md | 17 ++++ .../wellness-companion/insights.md | 13 +++ .../wellness-companion/instructions.md | 30 +++++++ .../wellness-companion/memories.md | 13 +++ .../wellness-companion/patterns.md | 17 ++++ tools/cli/installers/lib/core/detector.js | 7 +- tools/cli/installers/lib/modules/manager.js | 40 ++++++---- tools/cli/lib/ui.js | 79 ++++++++++++++----- 9 files changed, 222 insertions(+), 41 deletions(-) create mode 100644 .bmad-user-memory/cbt-coach/cognitive-distortions.md create mode 100644 .bmad-user-memory/cbt-coach/thought-records.md create mode 100644 .bmad-user-memory/wellness-companion/insights.md create mode 100644 .bmad-user-memory/wellness-companion/instructions.md create mode 100644 .bmad-user-memory/wellness-companion/memories.md create mode 100644 .bmad-user-memory/wellness-companion/patterns.md diff --git a/.bmad-user-memory/cbt-coach/cognitive-distortions.md b/.bmad-user-memory/cbt-coach/cognitive-distortions.md new file mode 100644 index 00000000..58e567b0 --- /dev/null +++ b/.bmad-user-memory/cbt-coach/cognitive-distortions.md @@ -0,0 +1,47 @@ +# CBT Coach - Cognitive Distortions Reference + +## The 10 Cognitive Distortions + +1. **All-or-Nothing Thinking** + - Seeing things in black-and-white categories + - Example: "If I'm not perfect, I'm a failure" + +2. **Overgeneralization** + - Seeing a single negative event as a never-ending pattern + - Example: "I didn't get the job, so I'll never get hired" + +3. **Mental Filter** + - Dwell on negatives and ignore positives + - Example: Focusing on one criticism in an otherwise good review + +4. **Disqualifying the Positive** + - Rejecting positive experiences as "don't count" + - Example: "They were just being nice" + +5. **Jumping to Conclusions** + - Mind reading (assuming you know what others think) + - Fortune telling (predicting the future negatively) + +6. **Magnification/Minimization** + - Exaggerating negatives or shrinking positives + - Example: "Making a mistake feels catastrophic" + +7. **Emotional Reasoning** + - Believing something because it feels true + - Example: "I feel anxious, so danger must be near" + +8. **"Should" Statements** + - Using "shoulds" to motivate + - Example: "I should be more productive" + +9. **Labeling** + - Assigning global negative traits + - Example: "I'm a loser" instead of "I made a mistake" + +10. **Personalization** + - Taking responsibility/blame for things outside your control + - Example: "It's my fault the party wasn't fun" + +## User's Common Patterns + +_Track which distortions appear most frequently_ diff --git a/.bmad-user-memory/cbt-coach/thought-records.md b/.bmad-user-memory/cbt-coach/thought-records.md new file mode 100644 index 00000000..6fd54e63 --- /dev/null +++ b/.bmad-user-memory/cbt-coach/thought-records.md @@ -0,0 +1,17 @@ +# CBT Coach - Thought Records + +## Thought Record History + +_CBT thought records are documented here for pattern tracking and progress review_ + +## Common Patterns Identified + +_Recurring cognitive distortions and thought patterns_ + +## Successful Reframes + +_Examples of successful cognitive restructuring_ + +## Homework Assignments + +_CBT exercises and behavioral experiments_ diff --git a/.bmad-user-memory/wellness-companion/insights.md b/.bmad-user-memory/wellness-companion/insights.md new file mode 100644 index 00000000..5ab17362 --- /dev/null +++ b/.bmad-user-memory/wellness-companion/insights.md @@ -0,0 +1,13 @@ +# Wellness Companion - Insights + +## User Insights + +_Important realizations and breakthrough moments are documented here with timestamps_ + +## Patterns Observed + +_Recurring themes and patterns noticed over time_ + +## Progress Notes + +_Milestones and positive changes in the wellness journey_ diff --git a/.bmad-user-memory/wellness-companion/instructions.md b/.bmad-user-memory/wellness-companion/instructions.md new file mode 100644 index 00000000..9062ac30 --- /dev/null +++ b/.bmad-user-memory/wellness-companion/instructions.md @@ -0,0 +1,30 @@ +# Wellness Companion - Instructions + +## Safety Protocols + +1. Always validate user feelings before offering guidance +2. Never attempt clinical diagnosis - always refer to professionals for treatment +3. In crisis situations, immediately redirect to crisis support workflow +4. Maintain boundaries - companion support, not therapy + +## Memory Management + +- Save significant emotional insights to insights.md +- Track recurring patterns in patterns.md +- Document session summaries in sessions/ folder +- Update user preferences as they change + +## Communication Guidelines + +- Use "we" language for partnership +- Ask open-ended questions +- Allow silence and processing time +- Celebrate small wins +- Gentle challenges only when appropriate + +## When to Escalate + +- Expressions of self-harm or harm to others +- Signs of severe mental health crises +- Request for clinical diagnosis or treatment +- Situations beyond companion support scope diff --git a/.bmad-user-memory/wellness-companion/memories.md b/.bmad-user-memory/wellness-companion/memories.md new file mode 100644 index 00000000..3b5330e3 --- /dev/null +++ b/.bmad-user-memory/wellness-companion/memories.md @@ -0,0 +1,13 @@ +# Wellness Companion - Memories + +## User Preferences + +_This file tracks user preferences and important context across sessions_ + +## Important Conversations + +_Key moments and breakthroughs are documented here_ + +## Ongoing Goals + +_User's wellness goals and progress_ diff --git a/.bmad-user-memory/wellness-companion/patterns.md b/.bmad-user-memory/wellness-companion/patterns.md new file mode 100644 index 00000000..263aac53 --- /dev/null +++ b/.bmad-user-memory/wellness-companion/patterns.md @@ -0,0 +1,17 @@ +# Wellness Companion - Patterns + +## Emotional Patterns + +_Track recurring emotional states and triggers_ + +## Behavioral Patterns + +_Note habits and routines that affect wellness_ + +## Coping Patterns + +_Identify effective coping strategies and challenges_ + +## Progress Patterns + +_Document growth trends and areas needing attention_ diff --git a/tools/cli/installers/lib/core/detector.js b/tools/cli/installers/lib/core/detector.js index 5f6edd81..4217ecbc 100644 --- a/tools/cli/installers/lib/core/detector.js +++ b/tools/cli/installers/lib/core/detector.js @@ -275,10 +275,9 @@ class Detector { hasV6Installation = true; // Don't break - continue scanning to be thorough } else { - // Not V6+, check if folder name contains "bmad" (case insensitive) - const nameLower = name.toLowerCase(); - if (nameLower.includes('bmad')) { - // Potential V4 legacy folder + // Not V6+, check if this is the exact V4 folder name "bmad-method" + if (name === 'bmad-method') { + // This is the V4 default folder - flag it as legacy potentialV4Folders.push(fullPath); } } diff --git a/tools/cli/installers/lib/modules/manager.js b/tools/cli/installers/lib/modules/manager.js index 79fd183d..ec657359 100644 --- a/tools/cli/installers/lib/modules/manager.js +++ b/tools/cli/installers/lib/modules/manager.js @@ -22,11 +22,12 @@ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/p * await manager.install('core-module', '/path/to/bmad'); */ class ModuleManager { - constructor() { + constructor(options = {}) { // Path to source modules directory this.modulesSourcePath = getSourcePath('modules'); this.xmlHandler = new XmlHandler(); this.bmadFolderName = 'bmad'; // Default, can be overridden + this.scanProjectForModules = options.scanProjectForModules !== false; // Default to true for backward compatibility } /** @@ -175,10 +176,11 @@ class ModuleManager { /** * List all available modules (excluding core which is always installed) - * @returns {Array} List of available modules with metadata + * @returns {Object} Object with modules array and customModules array */ async listAvailable() { const modules = []; + const customModules = []; // First, scan src/modules (the standard location) if (await fs.pathExists(this.modulesSourcePath)) { @@ -209,25 +211,31 @@ class ModuleManager { } } - // Then, find all other modules in the project - const otherModulePaths = await this.findModulesInProject(); - for (const modulePath of otherModulePaths) { - const moduleName = path.basename(modulePath); - const relativePath = path.relative(getProjectRoot(), modulePath); + // Then, find all other modules in the project (only if scanning is enabled) + if (this.scanProjectForModules) { + const otherModulePaths = await this.findModulesInProject(); + for (const modulePath of otherModulePaths) { + const moduleName = path.basename(modulePath); + const relativePath = path.relative(getProjectRoot(), modulePath); - // Skip core module - it's always installed first and not selectable - if (moduleName === 'core') { - continue; - } + // Skip core module - it's always installed first and not selectable + if (moduleName === 'core') { + continue; + } - const moduleInfo = await this.getModuleInfo(modulePath, moduleName, relativePath); - if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id)) { - // Avoid duplicates - skip if we already have this module ID - modules.push(moduleInfo); + const moduleInfo = await this.getModuleInfo(modulePath, moduleName, relativePath); + if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) { + // Avoid duplicates - skip if we already have this module ID + if (moduleInfo.isCustom) { + customModules.push(moduleInfo); + } else { + modules.push(moduleInfo); + } + } } } - return modules; + return { modules, customModules }; } /** diff --git a/tools/cli/lib/ui.js b/tools/cli/lib/ui.js index 9b7078fa..2ce6f437 100644 --- a/tools/cli/lib/ui.js +++ b/tools/cli/lib/ui.js @@ -52,9 +52,6 @@ class UI { await installer.handleLegacyV4Migration(confirmedDirectory, legacyV4); } - // Prompt for custom content location (separate from installation directory) - const customContentConfig = await this.promptCustomContentLocation(); - // Check if there's an existing BMAD installation const fs = require('fs-extra'); const path = require('node:path'); @@ -62,6 +59,13 @@ class UI { const bmadDir = await installer.findBmadDir(confirmedDirectory); const hasExistingInstall = await fs.pathExists(bmadDir); + // Only ask for custom content if it's a NEW installation + let customContentConfig = { hasCustomContent: false }; + if (!hasExistingInstall) { + // Prompt for custom content location (separate from installation directory) + customContentConfig = await this.promptCustomContentLocation(); + } + // Track action type (only set if there's an existing installation) let actionType; @@ -88,12 +92,11 @@ class UI { // Handle quick update separately if (actionType === 'quick-update') { - // Even for quick update, ask about custom content - const customContentConfig = await this.promptCustomContentLocation(); + // Quick update doesn't install custom content - just updates existing modules return { actionType: 'quick-update', directory: confirmedDirectory, - customContent: customContentConfig, + customContent: { hasCustomContent: false }, }; } @@ -511,11 +514,11 @@ class UI { const moduleChoices = []; const isNewInstallation = installedModuleIds.size === 0; - // Add custom content items first if found - if (customContentConfig && customContentConfig.hasCustomContent && customContentConfig.customPath) { - // Add separator before custom content - moduleChoices.push(new inquirer.Separator('── Custom Content ──')); + const customContentItems = []; + const hasCustomContentItems = false; + // Add custom content items from directory + if (customContentConfig && customContentConfig.hasCustomContent && customContentConfig.customPath) { // Get the custom content info to display proper names const { CustomHandler } = require('../installers/lib/custom/handler'); const customHandler = new CustomHandler(); @@ -524,29 +527,63 @@ class UI { for (const customFile of customFiles) { const customInfo = await customHandler.getCustomInfo(customFile); if (customInfo) { - moduleChoices.push({ + customContentItems.push({ name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`, value: `__CUSTOM_CONTENT__${customFile}`, // Unique value for each custom content checked: true, // Default to selected since user chose to provide custom content + path: customInfo.path, // Track path to avoid duplicates }); } } - - // Add separator for official content - moduleChoices.push(new inquirer.Separator('── Official Content ──')); } // Add official modules const { ModuleManager } = require('../installers/lib/modules/manager'); - const moduleManager = new ModuleManager(); - const availableModules = await moduleManager.listAvailable(); + // Only scan project for modules if user selected custom content + const moduleManager = new ModuleManager({ + scanProjectForModules: customContentConfig && customContentConfig.hasCustomContent && customContentConfig.selected, + }); + const { modules: availableModules, customModules: customModulesFromProject } = await moduleManager.listAvailable(); + // First, add all items to appropriate sections + const allCustomModules = []; + + // Add custom content items from directory + allCustomModules.push(...customContentItems); + + // Add custom modules from project scan (if scanning is enabled) + for (const mod of customModulesFromProject) { + // Skip if this module is already in customContentItems (by path) + const isDuplicate = allCustomModules.some((item) => item.path && mod.path && path.resolve(item.path) === path.resolve(mod.path)); + + if (!isDuplicate) { + allCustomModules.push({ + name: `${chalk.cyan('✓')} ${mod.name} ${chalk.gray(`(${mod.source})`)}`, + value: mod.id, + checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id), + }); + } + } + + // Add separators and modules in correct order + if (allCustomModules.length > 0) { + // Add separator for custom content, all custom modules, and official content separator + moduleChoices.push( + new inquirer.Separator('── Custom Content ──'), + ...allCustomModules, + new inquirer.Separator('── Official Content ──'), + ); + } + + // Add official modules (only non-custom ones) for (const mod of availableModules) { - moduleChoices.push({ - name: mod.name, - value: mod.id, - checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id), - }); + if (!mod.isCustom) { + moduleChoices.push({ + name: mod.name, + value: mod.id, + checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id), + }); + } } return moduleChoices;