Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions tools/cli/installers/lib/ide/_config-driven.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,8 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
getDefaultTemplate(artifactType) {
if (artifactType === 'agent') {
return `---
name: '{{name}}'
description: '{{description}}'
name: "{{name}}"
description: "{{description}}"
Comment on lines +406 to +407
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the relevant lines in _config-driven.js
head -n 480 tools/cli/installers/lib/ide/_config-driven.js | tail -n 85

Repository: bmad-code-org/BMAD-METHOD

Length of output: 2675


🏁 Script executed:

# Let's also check what the renderTemplate method does with name and description
rg -A 20 "renderTemplate.*{" tools/cli/installers/lib/ide/_config-driven.js | head -n 50

Repository: bmad-code-org/BMAD-METHOD

Length of output: 166


🏁 Script executed:

# Let's search for how name is used throughout the file
rg "artifact\.name|{{name}}" tools/cli/installers/lib/ide/_config-driven.js -B 2 -A 2

Repository: bmad-code-org/BMAD-METHOD

Length of output: 182


🏁 Script executed:

# Check if there are similar escaping patterns in related generator files mentioned in learnings
rg "description.*replace|escapeYaml" tools/cli/installers/lib/ide/ -r --type js

Repository: bmad-code-org/BMAD-METHOD

Length of output: 318


🏁 Script executed:

# Verify if name can contain special characters and trace how it's populated
rg -B 5 "artifact\.name\s*=" tools/cli/installers/lib/ide/_config-driven.js | head -n 40

Repository: bmad-code-org/BMAD-METHOD

Length of output: 51


🏁 Script executed:

# Check constructor and parameter sources to understand if name is user-controlled
rg "new\s+ConfigDrivenIdeSetup|\.name\s*=" tools/cli/installers/lib/ide/ -A 2 | head -n 50

Repository: bmad-code-org/BMAD-METHOD

Length of output: 1721


🏁 Script executed:

# Verify the escaping is indeed incomplete by checking what the current description escaping handles
cat tools/cli/installers/lib/ide/_config-driven.js | grep -A 1 "description.*replaceAll"

Repository: bmad-code-org/BMAD-METHOD

Length of output: 257


Escape {{name}} in double-quoted YAML frontmatter.

renderTemplate() injects artifact.name without escaping while the default templates now wrap it in double quotes (lines 406–407, 421–422). A name containing " or \ (e.g., C:\tools or Bob "QA") breaks YAML parsing and prevents the command/workflow/task/agent from loading.

Apply the same escaping logic as {{description}} (at minimum, replace " with \" and \ with \\ per YAML double-quote rules).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/cli/installers/lib/ide/_config-driven.js` around lines 406 - 407, The
YAML frontmatter uses name: "{{name}}" without escaping, so update the code path
that calls renderTemplate() (the place that injects artifact.name) to escape
double-quotes and backslashes the same way description is escaped: replace "
with \" and \ with \\ before passing artifact.name into the template. Locate the
renderTemplate() call or the variable that supplies artifact.name in
_config-driven.js and apply the same escaping function used for description (or
add a small helper) so names like C:\tools or Bob "QA" produce valid YAML.

disable-model-invocation: true
---

Expand All @@ -418,8 +418,8 @@ You must fully embody this agent's persona and follow all activation instruction
`;
}
return `---
name: '{{name}}'
description: '{{description}}'
name: "{{name}}"
description: "{{description}}"
---

# {{name}}
Expand Down Expand Up @@ -468,7 +468,7 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
.replaceAll('{{name}}', artifact.name || '')
.replaceAll('{{module}}', artifact.module || 'core')
.replaceAll('{{path}}', pathToUse)
.replaceAll('{{description}}', artifact.description || `${artifact.name} ${artifact.type || ''}`)
.replaceAll('{{description}}', (artifact.description || `${artifact.name} ${artifact.type || ''}`).replaceAll('"', String.raw`\"`))
.replaceAll('{{workflow_path}}', pathToUse);

return rendered;
Expand Down