Compare commits
No commits in common. "169e983e622d770b47cbfd15f25f5dc6f23d0f92" and "961c50f752be4c8e5f82337df05fcb6e46be0739" have entirely different histories.
169e983e62
...
961c50f752
|
|
@ -21,12 +21,6 @@ agent:
|
||||||
- "Remember the users name is {user_name}"
|
- "Remember the users name is {user_name}"
|
||||||
- "ALWAYS communicate in {communication_language}"
|
- "ALWAYS communicate in {communication_language}"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Greetings! The BMad Master is here to orchestrate and guide you through any workflow."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-lessac-medium
|
|
||||||
- mac: Samantha
|
|
||||||
|
|
||||||
# Agent menu items
|
# Agent menu items
|
||||||
menu:
|
menu:
|
||||||
- trigger: "list-tasks"
|
- trigger: "list-tasks"
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,6 @@ agent:
|
||||||
- Articulate requirements with absolute precision. Ensure all stakeholder voices heard.
|
- Articulate requirements with absolute precision. Ensure all stakeholder voices heard.
|
||||||
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hi there! I'm Mary, your Business Analyst. I'll help uncover the real requirements."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-kristin-medium
|
|
||||||
- mac: Allison
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: workflow-status
|
- trigger: workflow-status
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,6 @@ agent:
|
||||||
- Design simple solutions that scale when needed. Developer productivity is architecture. Connect every decision to business value and user impact.
|
- Design simple solutions that scale when needed. Developer productivity is architecture. Connect every decision to business value and user impact.
|
||||||
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hello! Winston here, your Architect. I'll ensure we build something scalable and pragmatic."
|
|
||||||
voices:
|
|
||||||
- piper: en_GB-alan-medium
|
|
||||||
- mac: Daniel
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: workflow-status
|
- trigger: workflow-status
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,6 @@ agent:
|
||||||
- "Update File List with ALL changed files after each task completion"
|
- "Update File List with ALL changed files after each task completion"
|
||||||
- "NEVER lie about tests being written or passing - tests must actually exist and pass 100%"
|
- "NEVER lie about tests being written or passing - tests must actually exist and pass 100%"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hey! Amelia here, your Developer. Ready to turn specs into working code."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-amy-medium
|
|
||||||
- mac: Samantha
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: develop-story
|
- trigger: develop-story
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/4-implementation/dev-story/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/4-implementation/dev-story/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,6 @@ agent:
|
||||||
- Align efforts with measurable business impact. Back all claims with data and user insights.
|
- Align efforts with measurable business impact. Back all claims with data and user insights.
|
||||||
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hey team! John here, your Product Manager. Let's make sure we're building the right thing."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-ryan-high
|
|
||||||
- mac: Alex
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: workflow-status
|
- trigger: workflow-status
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/workflow-status/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,6 @@ agent:
|
||||||
- "When running *create-story, always run as *yolo. Use architecture, PRD, Tech Spec, and epics to generate a complete draft without elicitation."
|
- "When running *create-story, always run as *yolo. Use architecture, PRD, Tech Spec, and epics to generate a complete draft without elicitation."
|
||||||
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hi everyone! Bob here, your Scrum Master. I'll keep us focused and moving forward."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-joe-medium
|
|
||||||
- mac: Fred
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: sprint-planning
|
- trigger: sprint-planning
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/4-implementation/sprint-planning/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/4-implementation/sprint-planning/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,6 @@ agent:
|
||||||
- "Cross-check recommendations with the current official Playwright, Cypress, Pact, and CI platform documentation"
|
- "Cross-check recommendations with the current official Playwright, Cypress, Pact, and CI platform documentation"
|
||||||
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hello! Murat here, your Test Architect. Quality is my obsession."
|
|
||||||
voices:
|
|
||||||
- piper: en_US-kusal-medium
|
|
||||||
- mac: Tom
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: framework
|
- trigger: framework
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/testarch/framework/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/testarch/framework/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,6 @@ agent:
|
||||||
- "CRITICAL: Load COMPLETE file {project-root}/{bmad_folder}/bmm/data/documentation-standards.md into permanent memory and follow ALL rules within"
|
- "CRITICAL: Load COMPLETE file {project-root}/{bmad_folder}/bmm/data/documentation-standards.md into permanent memory and follow ALL rules within"
|
||||||
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hi! I'm Paige, your Technical Writer. I'll make sure everything is documented clearly."
|
|
||||||
voices:
|
|
||||||
- piper: jenny
|
|
||||||
- mac: Karen
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: document-project
|
- trigger: document-project
|
||||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/document-project/workflow.yaml"
|
workflow: "{project-root}/{bmad_folder}/bmm/workflows/document-project/workflow.yaml"
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,6 @@ agent:
|
||||||
critical_actions:
|
critical_actions:
|
||||||
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
|
||||||
|
|
||||||
tts:
|
|
||||||
intro: "Hey! Sally here, your UX Designer. The user experience is my top priority."
|
|
||||||
voices:
|
|
||||||
- piper: kristin
|
|
||||||
- mac: Victoria
|
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
- trigger: create-ux-design
|
- trigger: create-ux-design
|
||||||
exec: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md"
|
exec: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md"
|
||||||
|
|
|
||||||
|
|
@ -269,21 +269,6 @@ class ManifestGenerator {
|
||||||
.replaceAll('"', '""'); // Escape quotes for CSV
|
.replaceAll('"', '""'); // Escape quotes for CSV
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try to read TTS data from source YAML file
|
|
||||||
let ttsData = null;
|
|
||||||
const yamlFilePath = path.join(dirPath, `${agentName}.agent.yaml`);
|
|
||||||
if (await fs.pathExists(yamlFilePath)) {
|
|
||||||
try {
|
|
||||||
const yamlContent = await fs.readFile(yamlFilePath, 'utf8');
|
|
||||||
const agentYaml = yaml.load(yamlContent);
|
|
||||||
if (agentYaml?.agent?.tts) {
|
|
||||||
ttsData = agentYaml.agent.tts;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Silently skip if YAML parsing fails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
agents.push({
|
agents.push({
|
||||||
name: agentName,
|
name: agentName,
|
||||||
displayName: nameMatch ? nameMatch[1] : agentName,
|
displayName: nameMatch ? nameMatch[1] : agentName,
|
||||||
|
|
@ -295,7 +280,6 @@ class ManifestGenerator {
|
||||||
principles: principlesMatch ? cleanForCSV(principlesMatch[1]) : '',
|
principles: principlesMatch ? cleanForCSV(principlesMatch[1]) : '',
|
||||||
module: moduleName,
|
module: moduleName,
|
||||||
path: installPath,
|
path: installPath,
|
||||||
tts: ttsData, // Add TTS data from YAML
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add to files list
|
// Add to files list
|
||||||
|
|
@ -611,47 +595,62 @@ class ManifestGenerator {
|
||||||
async writeVoiceMap(cfgDir) {
|
async writeVoiceMap(cfgDir) {
|
||||||
const csvPath = path.join(cfgDir, 'agent-voice-map.csv');
|
const csvPath = path.join(cfgDir, 'agent-voice-map.csv');
|
||||||
|
|
||||||
// Determine TTS provider from AgentVibes configuration
|
// Default voice assignments and intros for BMAD agents
|
||||||
// Default to 'piper' if not specified
|
// These can be customized by editing the generated CSV
|
||||||
const ttsProvider = this.agentVibes?.provider || 'piper';
|
const agentDefaults = {
|
||||||
|
'bmad-master': {
|
||||||
// Map provider names to voice field names
|
voice: 'en_US-lessac-medium',
|
||||||
const providerVoiceField = {
|
intro: 'Greetings! The BMad Master is here to orchestrate and guide you through any workflow.',
|
||||||
piper: 'piper',
|
},
|
||||||
macos: 'mac',
|
analyst: {
|
||||||
|
voice: 'en_US-kristin-medium',
|
||||||
|
intro: "Hi there! I'm Mary, your Business Analyst. I'll help uncover the real requirements.",
|
||||||
|
},
|
||||||
|
architect: {
|
||||||
|
voice: 'en_GB-alan-medium',
|
||||||
|
intro: "Hello! Winston here, your Architect. I'll ensure we build something scalable and pragmatic.",
|
||||||
|
},
|
||||||
|
dev: {
|
||||||
|
voice: 'en_US-joe-medium',
|
||||||
|
intro: 'Hey! Amelia here, your Developer. Ready to turn specs into working code.',
|
||||||
|
},
|
||||||
|
pm: {
|
||||||
|
voice: 'en_US-ryan-high',
|
||||||
|
intro: "Hey team! John here, your Product Manager. Let's make sure we're building the right thing.",
|
||||||
|
},
|
||||||
|
sm: {
|
||||||
|
voice: 'en_US-amy-medium',
|
||||||
|
intro: "Hi everyone! Bob here, your Scrum Master. I'll keep us focused and moving forward.",
|
||||||
|
},
|
||||||
|
tea: {
|
||||||
|
voice: 'en_US-kusal-medium',
|
||||||
|
intro: 'Hello! Murat here, your Test Architect. Quality is my obsession.',
|
||||||
|
},
|
||||||
|
'tech-writer': {
|
||||||
|
voice: 'jenny',
|
||||||
|
intro: "Hi! I'm Paige, your Technical Writer. I'll make sure everything is documented clearly.",
|
||||||
|
},
|
||||||
|
'ux-designer': {
|
||||||
|
voice: 'kristin',
|
||||||
|
intro: 'Hey! Sally here, your UX Designer. The user experience is my top priority.',
|
||||||
|
},
|
||||||
|
'frame-expert': {
|
||||||
|
voice: 'en_GB-alan-medium',
|
||||||
|
intro: "Hello! Saif here, your Visual Design Expert. I'll help visualize your ideas.",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const voiceField = providerVoiceField[ttsProvider] || 'piper';
|
// Fallback values for agents not in the default map
|
||||||
|
const fallbackVoice = 'en_US-lessac-medium';
|
||||||
// Fallback values for agents without TTS data
|
|
||||||
const fallbackVoice = voiceField === 'mac' ? 'Samantha' : 'en_US-lessac-medium';
|
|
||||||
const fallbackIntro = 'Hello! Ready to help with the discussion.';
|
const fallbackIntro = 'Hello! Ready to help with the discussion.';
|
||||||
|
|
||||||
let csv = 'agent,voice,intro\n';
|
let csv = 'agent,voice,intro\n';
|
||||||
|
|
||||||
// Add voice mapping and intro for each discovered agent
|
// Add voice mapping and intro for each discovered agent
|
||||||
for (const agent of this.agents) {
|
for (const agent of this.agents) {
|
||||||
let voice = fallbackVoice;
|
const defaults = agentDefaults[agent.name] || {};
|
||||||
let intro = fallbackIntro;
|
const voice = defaults.voice || fallbackVoice;
|
||||||
|
const intro = defaults.intro || fallbackIntro;
|
||||||
// Extract voice and intro from agent's TTS data if available
|
|
||||||
if (agent.tts) {
|
|
||||||
// Get intro
|
|
||||||
if (agent.tts.intro) {
|
|
||||||
intro = agent.tts.intro;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get voice for the selected provider
|
|
||||||
if (agent.tts.voices && Array.isArray(agent.tts.voices)) {
|
|
||||||
for (const voiceEntry of agent.tts.voices) {
|
|
||||||
if (voiceEntry[voiceField]) {
|
|
||||||
voice = voiceEntry[voiceField];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape quotes in intro for CSV
|
// Escape quotes in intro for CSV
|
||||||
const escapedIntro = intro.replaceAll('"', '""');
|
const escapedIntro = intro.replaceAll('"', '""');
|
||||||
csv += `${agent.name},${voice},"${escapedIntro}"\n`;
|
csv += `${agent.name},${voice},"${escapedIntro}"\n`;
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ function buildAgentSchema(expectedModule) {
|
||||||
metadata: buildMetadataSchema(expectedModule),
|
metadata: buildMetadataSchema(expectedModule),
|
||||||
persona: buildPersonaSchema(),
|
persona: buildPersonaSchema(),
|
||||||
critical_actions: z.array(createNonEmptyString('agent.critical_actions[]')).optional(),
|
critical_actions: z.array(createNonEmptyString('agent.critical_actions[]')).optional(),
|
||||||
tts: buildTTSSchema().optional(),
|
|
||||||
menu: z.array(buildMenuItemSchema()).min(1, { message: 'agent.menu must include at least one entry' }),
|
menu: z.array(buildMenuItemSchema()).min(1, { message: 'agent.menu must include at least one entry' }),
|
||||||
prompts: z.array(buildPromptSchema()).optional(),
|
prompts: z.array(buildPromptSchema()).optional(),
|
||||||
webskip: z.boolean().optional(),
|
webskip: z.boolean().optional(),
|
||||||
|
|
@ -196,34 +195,6 @@ function buildPersonaSchema() {
|
||||||
.strict();
|
.strict();
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTTSSchema() {
|
|
||||||
return z
|
|
||||||
.object({
|
|
||||||
intro: createNonEmptyString('agent.tts.intro'),
|
|
||||||
voices: z
|
|
||||||
.array(
|
|
||||||
z.object({
|
|
||||||
piper: createNonEmptyString('agent.tts.voices[].piper').optional(),
|
|
||||||
mac: createNonEmptyString('agent.tts.voices[].mac').optional(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.min(1, { message: 'agent.tts.voices must include at least one voice mapping' })
|
|
||||||
.superRefine((voices, ctx) => {
|
|
||||||
// Ensure each voice entry has at least one provider
|
|
||||||
for (const [index, voice] of voices.entries()) {
|
|
||||||
if (!voice.piper && !voice.mac) {
|
|
||||||
ctx.addIssue({
|
|
||||||
code: 'custom',
|
|
||||||
path: [index],
|
|
||||||
message: 'agent.tts.voices[] must include at least one voice provider (piper or mac)',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.strict();
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildPromptSchema() {
|
function buildPromptSchema() {
|
||||||
return z
|
return z
|
||||||
.object({
|
.object({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue