Compare commits

...

3 Commits

Author SHA1 Message Date
Vidit Bhavsar b34be6c3d2
Merge 6143754b13 into 903710be1b 2026-01-29 13:59:16 +00:00
Michael Pursifull 903710be1b
fix: HELP_STEP placeholder not replaced in compiled agents, fix hardcoded path, fix single quote in HELP_STEP (#1437)
* fix: correct malformed XML syntax and remove hardcoded path

- Fix missing opening quote in activation-steps.txt: `n={HELP_STEP}"` → `n="{HELP_STEP}"`
- Remove spurious hyphen: `-Let` → `Let`
- Replace hardcoded `/Users/brianmadison/...` path with relative path

Fixes #1435

* fix: add missing HELP_STEP placeholder replacement

The activation-steps.txt template includes a {HELP_STEP} placeholder,
but activation-builder.js never calculated or replaced it. This caused
the literal string "{HELP_STEP}" to appear in compiled agent files.

Added helpStep calculation between menuStep and haltStep, and adjusted
subsequent step numbers accordingly.

Fixes #1441

* Update src/bmm/workflows/2-plan-workflows/create-prd/validation-report-prd-workflow.md

---------

Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
2026-01-29 05:58:56 -08:00
ViditBee 6143754b13 Fixed: https://github.com/bmad-code-org/BMAD-METHOD/issues/929 2026-01-28 23:57:11 +05:30
3 changed files with 24 additions and 33 deletions

View File

@ -8,7 +8,7 @@ validationStatus: COMPLETE - PRODUCTION READY
# PRD Workflow Validation Report # PRD Workflow Validation Report
**Workflow Being Validated:** /Users/brianmadison/dev/BMAD-METHOD/src/bmm/workflows/2-plan-workflows/create-prd **Workflow Being Validated:** _bmad/bmm/workflows/2-plan-workflows/create-prd
**Validation Date:** 2026-01-08 **Validation Date:** 2026-01-08
**Validator:** BMAD Workflow Validation System **Validator:** BMAD Workflow Validation System

View File

@ -1,4 +1,5 @@
const path = require('node:path'); const path = require('node:path');
const YAML = require('yaml');
const { BaseIdeSetup } = require('./_base-ide'); const { BaseIdeSetup } = require('./_base-ide');
const chalk = require('chalk'); const chalk = require('chalk');
const { AgentCommandGenerator } = require('./shared/agent-command-generator'); const { AgentCommandGenerator } = require('./shared/agent-command-generator');
@ -92,43 +93,31 @@ class KiloSetup extends BaseIdeSetup {
* Create a mode entry for an agent * Create a mode entry for an agent
*/ */
async createModeEntry(artifact, projectDir) { async createModeEntry(artifact, projectDir) {
// Extract metadata from launcher content const title = artifact.content.match(/title="([^"]+)"/)?.[1] ?? this.formatTitle(artifact.name);
const titleMatch = artifact.content.match(/title="([^"]+)"/);
const title = titleMatch ? titleMatch[1] : this.formatTitle(artifact.name);
const iconMatch = artifact.content.match(/icon="([^"]+)"/); const icon = artifact.content.match(/icon="([^"]+)"/)?.[1] ?? '🤖';
const icon = iconMatch ? iconMatch[1] : '🤖';
const whenToUseMatch = artifact.content.match(/whenToUse="([^"]+)"/); const whenToUse = artifact.content.match(/whenToUse="([^"]+)"/)?.[1] ?? `Use for ${title} tasks`;
const whenToUse = whenToUseMatch ? whenToUseMatch[1] : `Use for ${title} tasks`;
const roleDefinition =
artifact.content.match(/roleDefinition="([^"]+)"/)?.[1] ?? `You are a ${title} specializing in ${title.toLowerCase()} tasks.`;
// Get the activation header from central template
const activationHeader = await this.getAgentCommandHeader(); const activationHeader = await this.getAgentCommandHeader();
const roleDefinitionMatch = artifact.content.match(/roleDefinition="([^"]+)"/);
const roleDefinition = roleDefinitionMatch
? roleDefinitionMatch[1]
: `You are a ${title} specializing in ${title.toLowerCase()} tasks.`;
// Get relative path
const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/'); const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/');
// Build mode entry (KiloCode uses same schema as Roo) const entry = {
const slug = `bmad-${artifact.module}-${artifact.name}`; slug: `bmad-${artifact.module}-${artifact.name}`,
let modeEntry = ` - slug: ${slug}\n`; name: `${icon} ${title}`,
modeEntry += ` name: '${icon} ${title}'\n`; roleDefinition,
modeEntry += ` roleDefinition: ${roleDefinition}\n`; whenToUse,
modeEntry += ` whenToUse: ${whenToUse}\n`; customInstructions:
modeEntry += ` customInstructions: |\n`; `${activationHeader}` +
modeEntry += ` ${activationHeader} Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`; `Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode`,
modeEntry += ` groups:\n`; groups: ['read', 'edit', 'browser', 'command', 'mcp'],
modeEntry += ` - read\n`; };
modeEntry += ` - edit\n`;
modeEntry += ` - browser\n`;
modeEntry += ` - command\n`;
modeEntry += ` - mcp\n`;
return modeEntry; return YAML.stringify([entry], { indent: 2 });
} }
/** /**

View File

@ -121,9 +121,10 @@ class ActivationBuilder {
// Calculate final step numbers // Calculate final step numbers
const menuStep = currentStepNum; const menuStep = currentStepNum;
const haltStep = currentStepNum + 1; const helpStep = currentStepNum + 1;
const inputStep = currentStepNum + 2; const haltStep = currentStepNum + 2;
const executeStep = currentStepNum + 3; const inputStep = currentStepNum + 3;
const executeStep = currentStepNum + 4;
// Replace placeholders // Replace placeholders
const processed = stepsTemplate const processed = stepsTemplate
@ -131,6 +132,7 @@ class ActivationBuilder {
.replace('{{module}}', metadata.module || 'core') // Fixed to use {{module}} .replace('{{module}}', metadata.module || 'core') // Fixed to use {{module}}
.replace('{AGENT_SPECIFIC_STEPS}', agentStepsXml) .replace('{AGENT_SPECIFIC_STEPS}', agentStepsXml)
.replace('{MENU_STEP}', menuStep.toString()) .replace('{MENU_STEP}', menuStep.toString())
.replace('{HELP_STEP}', helpStep.toString())
.replace('{HALT_STEP}', haltStep.toString()) .replace('{HALT_STEP}', haltStep.toString())
.replace('{INPUT_STEP}', inputStep.toString()) .replace('{INPUT_STEP}', inputStep.toString())
.replace('{EXECUTE_STEP}', executeStep.toString()); .replace('{EXECUTE_STEP}', executeStep.toString());