addressed PR request from Brian
This commit is contained in:
parent
1943ca2ad1
commit
2165c56e91
|
|
@ -5,62 +5,3 @@
|
||||||
For external official modules to be discoverable during install, ensure an entry for the external repo is added to external-official-modules.yaml.
|
For external official modules to be discoverable during install, ensure an entry for the external repo is added to external-official-modules.yaml.
|
||||||
|
|
||||||
For community modules - this will be handled in a different way. This file is only for registration of modules under the bmad-code-org.
|
For community modules - this will be handled in a different way. This file is only for registration of modules under the bmad-code-org.
|
||||||
|
|
||||||
## Post-Install Configuration Notes for Module Authors
|
|
||||||
|
|
||||||
The installer can display setup guidance to users after a module's configuration is collected. This is handled by the `displayModulePostConfigNotes(moduleName)` method in `installers/lib/core/config-collector.js`.
|
|
||||||
|
|
||||||
### When It Runs
|
|
||||||
|
|
||||||
The method is called in two places:
|
|
||||||
|
|
||||||
- After `collectModuleConfig()` completes (full interactive configuration)
|
|
||||||
- After `collectModuleConfigQuick()` completes (quick mode with existing config)
|
|
||||||
|
|
||||||
This ensures users see relevant setup instructions regardless of installation path.
|
|
||||||
|
|
||||||
### Guards
|
|
||||||
|
|
||||||
Output is suppressed when:
|
|
||||||
|
|
||||||
- **Silent mode** (`this._silentConfig`) — non-interactive installations skip all output
|
|
||||||
- **Feature disabled** — e.g., if the config value is `'none'`, no guidance is needed
|
|
||||||
|
|
||||||
### Adding Support for a New Module
|
|
||||||
|
|
||||||
To add post-config notes for your module, add a conditional block in `displayModulePostConfigNotes()`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
async displayModulePostConfigNotes(moduleName) {
|
|
||||||
if (this._silentConfig) return;
|
|
||||||
|
|
||||||
// Existing: TEA module handler
|
|
||||||
if (moduleName !== 'tea') return;
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// To add your module, replace the early return above with:
|
|
||||||
if (moduleName === 'your-module') {
|
|
||||||
const config = this.collectedConfig[moduleName];
|
|
||||||
if (!config || !config.your_config_key) return;
|
|
||||||
|
|
||||||
const value = config.your_config_key;
|
|
||||||
if (value === 'none') return;
|
|
||||||
|
|
||||||
const color = await prompts.getColor();
|
|
||||||
await prompts.log.message('');
|
|
||||||
await prompts.log.info(color.bold('Your Setup Instructions:'));
|
|
||||||
await prompts.log.message(color.dim(' Instructions based on selected value...'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Details
|
|
||||||
|
|
||||||
- Read config values from `this.collectedConfig[moduleName]`
|
|
||||||
- Use `prompts.log.info()` for headers and `prompts.log.message()` for details
|
|
||||||
- Use `color.bold()` and `color.dim()` for visual hierarchy
|
|
||||||
- The config question that drives the output is defined in the module's `module.yaml`
|
|
||||||
|
|
||||||
### Working Example: TEA Module
|
|
||||||
|
|
||||||
The TEA module defines a `tea_browser_automation` config question with options: `auto`, `cli`, `mcp`, `none`. After configuration, the handler at lines 1207-1235 displays Playwright CLI install commands and/or MCP setup links based on the user's selection.
|
|
||||||
|
|
|
||||||
|
|
@ -550,7 +550,7 @@ class ConfigCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.displayModulePostConfigNotes(moduleName);
|
await this.displayModulePostConfigNotes(moduleName, moduleConfig);
|
||||||
|
|
||||||
return newKeys.length > 0 || newStaticKeys.length > 0; // Return true if we had any new fields (interactive or static)
|
return newKeys.length > 0 || newStaticKeys.length > 0; // Return true if we had any new fields (interactive or static)
|
||||||
}
|
}
|
||||||
|
|
@ -926,7 +926,7 @@ class ConfigCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.displayModulePostConfigNotes(moduleName);
|
await this.displayModulePostConfigNotes(moduleName, moduleConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1202,35 +1202,53 @@ class ConfigCollector {
|
||||||
/**
|
/**
|
||||||
* Display post-configuration notes for a module
|
* Display post-configuration notes for a module
|
||||||
* Shows prerequisite guidance based on collected config values
|
* Shows prerequisite guidance based on collected config values
|
||||||
|
* Reads notes from the module's `post-install-notes` section in module.yaml
|
||||||
|
* Supports two formats:
|
||||||
|
* - Simple string: always displayed
|
||||||
|
* - Object keyed by config field name, with value-specific messages
|
||||||
* @param {string} moduleName - Module name
|
* @param {string} moduleName - Module name
|
||||||
|
* @param {Object} moduleConfig - Parsed module.yaml content
|
||||||
*/
|
*/
|
||||||
async displayModulePostConfigNotes(moduleName) {
|
async displayModulePostConfigNotes(moduleName, moduleConfig) {
|
||||||
if (this._silentConfig) return;
|
if (this._silentConfig) return;
|
||||||
if (moduleName !== 'tea') return;
|
if (!moduleConfig || !moduleConfig['post-install-notes']) return;
|
||||||
|
|
||||||
const teaConfig = this.collectedConfig[moduleName];
|
|
||||||
if (!teaConfig || !teaConfig.tea_browser_automation) return;
|
|
||||||
|
|
||||||
const mode = teaConfig.tea_browser_automation;
|
|
||||||
|
|
||||||
if (mode === 'none') return;
|
|
||||||
|
|
||||||
|
const notes = moduleConfig['post-install-notes'];
|
||||||
const color = await prompts.getColor();
|
const color = await prompts.getColor();
|
||||||
|
|
||||||
|
// Format 1: Simple string - always display
|
||||||
|
if (typeof notes === 'string') {
|
||||||
await prompts.log.message('');
|
await prompts.log.message('');
|
||||||
|
for (const line of notes.trim().split('\n')) {
|
||||||
if (mode === 'cli' || mode === 'auto') {
|
await prompts.log.message(color.dim(line));
|
||||||
await prompts.log.info(color.bold('Playwright CLI Setup:'));
|
}
|
||||||
await prompts.log.message(color.dim(' npm install -g @playwright/cli@latest'));
|
return;
|
||||||
await prompts.log.message(color.dim(' playwright-cli install --skills # Run from project root'));
|
|
||||||
await prompts.log.message(color.dim(' Node.js 18+ required.'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode === 'mcp' || mode === 'auto') {
|
// Format 2: Conditional on config values
|
||||||
if (mode === 'auto') await prompts.log.message('');
|
if (typeof notes === 'object') {
|
||||||
await prompts.log.info(color.bold('Playwright MCP Setup:'));
|
const config = this.collectedConfig[moduleName];
|
||||||
await prompts.log.message(color.dim(' Configure MCP servers in your IDE'));
|
if (!config) return;
|
||||||
await prompts.log.message(color.dim(' See: https://github.com/microsoft/playwright-mcp'));
|
|
||||||
|
let hasOutput = false;
|
||||||
|
for (const [configKey, valueMessages] of Object.entries(notes)) {
|
||||||
|
const selectedValue = config[configKey];
|
||||||
|
if (!selectedValue || !valueMessages[selectedValue]) continue;
|
||||||
|
|
||||||
|
if (hasOutput) await prompts.log.message('');
|
||||||
|
hasOutput = true;
|
||||||
|
|
||||||
|
const message = valueMessages[selectedValue];
|
||||||
|
await prompts.log.message('');
|
||||||
|
for (const line of message.trim().split('\n')) {
|
||||||
|
const trimmedLine = line.trim();
|
||||||
|
if (trimmedLine.endsWith(':') && !trimmedLine.startsWith(' ')) {
|
||||||
|
await prompts.log.info(color.bold(trimmedLine));
|
||||||
|
} else {
|
||||||
|
await prompts.log.message(color.dim(' ' + trimmedLine));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue