Fix installer: skills path, pitch deck prompt, learn folder location
Three community-reported installer fixes:
1. Remove pitch deck question from installer — this is a workflow
decision that changes per product, not a one-time config choice.
Saga now asks at runtime instead.
2. Fix Claude Code skills path from .claude/skills/wds/{name}.md
to .claude/skills/{name}/SKILL.md (correct format).
3. Move _wds-learn/ from project root into _bmad/wds/learn/ to
reduce root-level noise in monorepos.
Also: fix LF line endings on npx wrapper, add ROADMAP.md.
Reported by: @Mr-z3r0 (BMad Discord)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dd5fa936bb
commit
cfcbdf3b3d
|
|
@ -1,5 +1,12 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.3.4 (unreleased)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- **Pitch deck question removed from installer** - The "start with pitch or Product Brief?" prompt was a config-time decision that should be runtime. Removed from installer; Saga now asks at activation when relevant. Supports monorepo workflows where multiple products have different starting points.
|
||||||
|
- **Skills file format** - Skills were installed to `.claude/skills/wds/saga.md` but Claude Code expects `.claude/skills/{name}/SKILL.md`. Fixed paths to `.claude/skills/saga/SKILL.md` and `.claude/skills/freya/SKILL.md`.
|
||||||
|
- **Learning material location** - `_wds-learn/` moved from project root into `_bmad/wds/learn/` to reduce root-level noise, especially in monorepos.
|
||||||
|
|
||||||
## 0.3.0 (2026-03-01)
|
## 0.3.0 (2026-03-01)
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
# WDS Roadmap
|
||||||
|
|
||||||
|
## 0.3.4 — Installer Fixes
|
||||||
|
|
||||||
|
- [x] Remove pitch deck question from installer (runtime Saga prompt instead)
|
||||||
|
- [x] Fix skills path to `.claude/skills/{name}/SKILL.md`
|
||||||
|
- [x] Move `_wds-learn/` into `_bmad/wds/learn/`
|
||||||
|
|
||||||
|
## 0.4.0 — Agent Space
|
||||||
|
|
||||||
|
Active development on `feature/design-space-agent-messaging`.
|
||||||
|
|
||||||
|
- Agent Space (formerly Design Space) — shared semantic knowledge database with agent messaging
|
||||||
|
- Headless Excalidraw export — local Node script in `tools/` using `@excalidraw/utils` to render `.excalidraw` JSON to PNG. Agent uses it for wireframe previews during Design Loop iteration. Approval gate unchanged — user still exports manually to approve.
|
||||||
|
- Details TBD as feature branch stabilizes
|
||||||
|
|
@ -8,7 +8,7 @@ const chalk = require('chalk');
|
||||||
class ClaudeCodeSetup extends BaseIdeSetup {
|
class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('claude-code', 'Claude Code', true); // preferred IDE
|
super('claude-code', 'Claude Code', true); // preferred IDE
|
||||||
this.configDir = '.claude/skills/wds';
|
this.configDir = '.claude/skills';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -18,10 +18,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
* @param {Object} options - Setup options
|
* @param {Object} options - Setup options
|
||||||
*/
|
*/
|
||||||
async setup(projectDir, wdsDir, options = {}) {
|
async setup(projectDir, wdsDir, options = {}) {
|
||||||
// Create .claude/skills/wds directory
|
|
||||||
const targetDir = path.join(projectDir, this.configDir);
|
|
||||||
await this.ensureDir(targetDir);
|
|
||||||
|
|
||||||
// Get all WDS agents
|
// Get all WDS agents
|
||||||
const agents = await this.getAgents(wdsDir);
|
const agents = await this.getAgents(wdsDir);
|
||||||
|
|
||||||
|
|
@ -29,7 +25,8 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
throw new Error('No agents found in WDS installation');
|
throw new Error('No agents found in WDS installation');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create launcher file for each agent
|
// Create launcher file for each agent in .claude/skills/{slug}/SKILL.md
|
||||||
|
const skillsDir = path.join(projectDir, this.configDir);
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const agent of agents) {
|
||||||
// Create launcher content that references the compiled agent
|
// Create launcher content that references the compiled agent
|
||||||
|
|
@ -38,8 +35,10 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
// Add Claude Code-specific YAML frontmatter
|
// Add Claude Code-specific YAML frontmatter
|
||||||
const content = this.processContent(launcher, agent.metadata);
|
const content = this.processContent(launcher, agent.metadata);
|
||||||
|
|
||||||
// Write launcher file
|
// Write launcher file as .claude/skills/{slug}/SKILL.md
|
||||||
const filePath = path.join(targetDir, `${agent.slug}.md`);
|
const agentDir = path.join(skillsDir, agent.slug);
|
||||||
|
await this.ensureDir(agentDir);
|
||||||
|
const filePath = path.join(agentDir, 'SKILL.md');
|
||||||
await this.writeFile(filePath, content);
|
await this.writeFile(filePath, content);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
|
|
@ -84,11 +83,20 @@ description: ${description}
|
||||||
* @param {string} projectDir - Project directory
|
* @param {string} projectDir - Project directory
|
||||||
*/
|
*/
|
||||||
async cleanup(projectDir) {
|
async cleanup(projectDir) {
|
||||||
const wdsPath = path.join(projectDir, this.configDir);
|
// Remove per-agent skill directories
|
||||||
|
const agents = ['saga', 'freya'];
|
||||||
|
for (const slug of agents) {
|
||||||
|
const skillPath = path.join(projectDir, this.configDir, slug);
|
||||||
|
if (await this.exists(skillPath)) {
|
||||||
|
await this.remove(skillPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (await this.exists(wdsPath)) {
|
// Also clean up legacy .claude/skills/wds/ if present
|
||||||
await this.remove(wdsPath);
|
const legacyPath = path.join(projectDir, '.claude/skills/wds');
|
||||||
console.log(chalk.dim(`Removed Claude Code WDS configuration`));
|
if (await this.exists(legacyPath)) {
|
||||||
|
await this.remove(legacyPath);
|
||||||
|
console.log(chalk.dim(`Removed legacy Claude Code WDS configuration`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ class Installer {
|
||||||
const learnSpinner = ora('Copying learning & reference material...').start();
|
const learnSpinner = ora('Copying learning & reference material...').start();
|
||||||
try {
|
try {
|
||||||
await this.copyLearningMaterial(projectDir);
|
await this.copyLearningMaterial(projectDir);
|
||||||
learnSpinner.succeed('Learning material added to _wds-learn/ (safe to remove when no longer needed)');
|
learnSpinner.succeed('Learning material added to _bmad/wds/learn/ (safe to remove when no longer needed)');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
learnSpinner.fail('Failed to copy learning material');
|
learnSpinner.fail('Failed to copy learning material');
|
||||||
throw error;
|
throw error;
|
||||||
|
|
@ -225,7 +225,6 @@ class Installer {
|
||||||
const configData = {
|
const configData = {
|
||||||
user_name: getUserName(),
|
user_name: getUserName(),
|
||||||
project_name: config.project_name || 'Untitled Project',
|
project_name: config.project_name || 'Untitled Project',
|
||||||
starting_point: config.starting_point || 'brief',
|
|
||||||
communication_language: 'en',
|
communication_language: 'en',
|
||||||
document_output_language: 'en',
|
document_output_language: 'en',
|
||||||
output_folder: config.root_folder || 'design-process',
|
output_folder: config.root_folder || 'design-process',
|
||||||
|
|
@ -260,7 +259,7 @@ class Installer {
|
||||||
* Users can safely delete this folder without affecting agents or workflows.
|
* Users can safely delete this folder without affecting agents or workflows.
|
||||||
*/
|
*/
|
||||||
async copyLearningMaterial(projectDir) {
|
async copyLearningMaterial(projectDir) {
|
||||||
const learnDir = path.join(projectDir, '_wds-learn');
|
const learnDir = path.join(projectDir, '_bmad/wds/learn');
|
||||||
const learningDirs = ['getting-started', 'learn', 'method', 'models', 'tools'];
|
const learningDirs = ['getting-started', 'learn', 'method', 'models', 'tools'];
|
||||||
const excludeDirs = new Set(['course-explainers', 'Webinars']);
|
const excludeDirs = new Set(['course-explainers', 'Webinars']);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,16 +140,6 @@ class UI {
|
||||||
message: 'Output folder name:',
|
message: 'Output folder name:',
|
||||||
default: 'design-process',
|
default: 'design-process',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: 'list',
|
|
||||||
name: 'starting_point',
|
|
||||||
message: 'Do you need to create a pitch deck & project contract before starting the project?',
|
|
||||||
choices: [
|
|
||||||
{ name: 'No, start directly with the Product Brief', value: 'brief' },
|
|
||||||
{ name: 'Yes, start with a project pitch', value: 'pitch' },
|
|
||||||
],
|
|
||||||
default: 'brief',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
name: 'ides',
|
name: 'ides',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue