Compare commits
7 Commits
3799450c7f
...
ff89b8063c
| Author | SHA1 | Date |
|---|---|---|
|
|
ff89b8063c | |
|
|
d401afd3f3 | |
|
|
b4d6a92e65 | |
|
|
246270bef2 | |
|
|
79a6876a65 | |
|
|
83f374c254 | |
|
|
84a3aa57de |
|
|
@ -291,3 +291,14 @@ Run both `bmad-review-adversarial-general` and `bmad-review-edge-case-hunter` to
|
|||
**Input:** Target folder path
|
||||
|
||||
**Output:** `index.md` with organized file listings, relative links, and brief descriptions
|
||||
|
||||
|
||||
|
||||
## 3rd Party Tools Integration: Pencil
|
||||
|
||||
If you are using **Pencil** within BMAD workflows for creating mockups or UI designs, it is critical that the LLM is fully aware of its existence early in the process rather than treating it merely as a nice-to-have MCP (Model Context Protocol).
|
||||
|
||||
**Important Guidelines for Pencil:**
|
||||
- **Introduce Early:** The sooner you bring Pencil into your planning process, the better. You must specify Pencil in your tooling **before** generating the `_bmad-output/planning-artifacts/architecture.md` document.
|
||||
- **Enforce Context:** Explicitly enforce the inclusion of your `.pen` (Pencil) files in the `_bmad-output/project-context.md` file.
|
||||
- **Why this matters:** If you bring Pencil in after the PRD, UX, and Architecture docs are already drafted without establishing these guardrails, the AI will not integrate it smoothly and will cause avoidable course corrections during sprints.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
code: core
|
||||
name: "BMad Core Module"
|
||||
description: "Core configuration and shared resources"
|
||||
|
||||
header: "BMad Core Configuration"
|
||||
subheader: "Configure the core settings for your BMad installation.\nThese settings will be used across all installed bmad skills, workflows, and agents."
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ class UI {
|
|||
const officialCodes = new Set(officialSelected);
|
||||
const externalManager = new ExternalModuleManager();
|
||||
const registryModules = await externalManager.listAvailable();
|
||||
const officialRegistryCodes = new Set(registryModules.map((m) => m.code));
|
||||
const officialRegistryCodes = new Set(['core', 'bmm', ...registryModules.map((m) => m.code)]);
|
||||
const installedNonOfficial = [...installedModuleIds].filter((id) => !officialRegistryCodes.has(id));
|
||||
|
||||
// Phase 2: Community modules (category drill-down)
|
||||
|
|
@ -630,6 +630,11 @@ class UI {
|
|||
* @returns {Array} Selected official module codes
|
||||
*/
|
||||
async _selectOfficialModules(installedModuleIds = new Set()) {
|
||||
// Built-in modules (core, bmm) come from local source, not the registry
|
||||
const { OfficialModules } = require('./modules/official-modules');
|
||||
const builtInModules = (await new OfficialModules().listAvailable()).modules || [];
|
||||
|
||||
// External modules come from the registry (with fallback)
|
||||
const externalManager = new ExternalModuleManager();
|
||||
const registryModules = await externalManager.listAvailable();
|
||||
|
||||
|
|
@ -637,20 +642,34 @@ class UI {
|
|||
const initialValues = [];
|
||||
const lockedValues = ['core'];
|
||||
|
||||
const buildModuleEntry = async (mod) => {
|
||||
const isInstalled = installedModuleIds.has(mod.code);
|
||||
const version = await getMarketplaceVersion(mod.code);
|
||||
const label = version ? `${mod.name} (v${version})` : mod.name;
|
||||
const buildModuleEntry = async (code, name, description, isDefault) => {
|
||||
const isInstalled = installedModuleIds.has(code);
|
||||
const version = await getMarketplaceVersion(code);
|
||||
const label = version ? `${name} (v${version})` : name;
|
||||
return {
|
||||
label,
|
||||
value: mod.code,
|
||||
hint: mod.description,
|
||||
selected: isInstalled,
|
||||
value: code,
|
||||
hint: description,
|
||||
selected: isInstalled || isDefault,
|
||||
};
|
||||
};
|
||||
|
||||
// Add built-in modules first (always available regardless of network)
|
||||
const builtInCodes = new Set();
|
||||
for (const mod of builtInModules) {
|
||||
const code = mod.id;
|
||||
builtInCodes.add(code);
|
||||
const entry = await buildModuleEntry(code, mod.name, mod.description, mod.defaultSelected);
|
||||
allOptions.push({ label: entry.label, value: entry.value, hint: entry.hint });
|
||||
if (entry.selected) {
|
||||
initialValues.push(code);
|
||||
}
|
||||
}
|
||||
|
||||
// Add external registry modules (skip built-in duplicates)
|
||||
for (const mod of registryModules) {
|
||||
const entry = await buildModuleEntry(mod);
|
||||
if (mod.builtIn || builtInCodes.has(mod.code)) continue;
|
||||
const entry = await buildModuleEntry(mod.code, mod.name, mod.description, mod.defaultSelected);
|
||||
allOptions.push({ label: entry.label, value: entry.value, hint: entry.hint });
|
||||
if (entry.selected) {
|
||||
initialValues.push(mod.code);
|
||||
|
|
@ -1122,12 +1141,26 @@ class UI {
|
|||
* @returns {Array} Default module codes
|
||||
*/
|
||||
async getDefaultModules(installedModuleIds = new Set()) {
|
||||
// Built-in modules with default_selected come from local source
|
||||
const { OfficialModules } = require('./modules/official-modules');
|
||||
const builtInModules = (await new OfficialModules().listAvailable()).modules || [];
|
||||
|
||||
const defaultModules = [];
|
||||
const seen = new Set();
|
||||
|
||||
for (const mod of builtInModules) {
|
||||
if (mod.defaultSelected || installedModuleIds.has(mod.id)) {
|
||||
defaultModules.push(mod.id);
|
||||
seen.add(mod.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Add external registry defaults
|
||||
const externalManager = new ExternalModuleManager();
|
||||
const registryModules = await externalManager.listAvailable();
|
||||
|
||||
const defaultModules = [];
|
||||
|
||||
for (const mod of registryModules) {
|
||||
if (mod.builtIn || seen.has(mod.code)) continue;
|
||||
if (mod.defaultSelected || installedModuleIds.has(mod.code)) {
|
||||
defaultModules.push(mod.code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@
|
|||
.agent-icon.john { background: linear-gradient(135deg, #60a5fa, #3b82f6); }
|
||||
.agent-icon.sally { background: linear-gradient(135deg, #fbbf24, #f59e0b); color: #000; }
|
||||
.agent-icon.winston { background: linear-gradient(135deg, #a78bfa, #8b5cf6); }
|
||||
.agent-icon.bob { background: linear-gradient(135deg, #34d399, #10b981); color: #000; }
|
||||
.agent-icon.amelia { background: linear-gradient(135deg, #fb7185, #ef4444); }
|
||||
|
||||
.agent-name { font-size: 0.65rem; }
|
||||
|
|
@ -261,7 +260,7 @@
|
|||
<span class="workflow-name">sprint-planning</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">sprint-status.yaml →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -270,7 +269,7 @@
|
|||
<span class="workflow-name">create-story</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">story-[slug].md →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -308,7 +307,7 @@
|
|||
<span class="badge adhoc">par Epic</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">leçons</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@
|
|||
.agent-icon.john { background: linear-gradient(135deg, #60a5fa, #3b82f6); }
|
||||
.agent-icon.sally { background: linear-gradient(135deg, #fbbf24, #f59e0b); color: #000; }
|
||||
.agent-icon.winston { background: linear-gradient(135deg, #a78bfa, #8b5cf6); }
|
||||
.agent-icon.bob { background: linear-gradient(135deg, #34d399, #10b981); color: #000; }
|
||||
.agent-icon.amelia { background: linear-gradient(135deg, #fb7185, #ef4444); }
|
||||
|
||||
.agent-name { font-size: 0.65rem; }
|
||||
|
|
@ -272,7 +271,7 @@
|
|||
<span class="workflow-name">sprint-planning</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">sprint-status.yaml →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -281,7 +280,7 @@
|
|||
<span class="workflow-name">create-story</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">story-[slug].md →</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -319,7 +318,7 @@
|
|||
<span class="badge adhoc">per epic</span>
|
||||
</div>
|
||||
<div class="workflow-meta">
|
||||
<div class="agent"><div class="agent-icon bob">B</div><span class="agent-name">Bob</span></div>
|
||||
<div class="agent"><div class="agent-icon amelia">A</div><span class="agent-name">Amelia</span></div>
|
||||
<span class="output">lessons</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue