BMAD-METHOD/tools/generators/wds-setup.js

206 lines
5.0 KiB
JavaScript

#!/usr/bin/env node
'use strict';
const fs = require('node:fs');
const path = require('node:path');
const readline = require('node:readline');
const VALID_TYPES = ['greenfield', 'brownfield', 'feature', 'design-system'];
function parseArgs() {
const args = process.argv.slice(2);
const result = {};
for (let i = 0; i < args.length; i++) {
if (args[i] === '--name' && args[i + 1]) result.name = args[++i];
if (args[i] === '--type' && args[i + 1]) result.type = args[++i];
}
return result;
}
function prompt(rl, question) {
return new Promise((resolve) => rl.question(question, resolve));
}
async function getInputs(args) {
let { name, type } = args;
if (name && type) return { name, type };
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
if (!name) {
name = await prompt(rl, 'Project name: ');
name = name.trim();
}
if (!type) {
console.log(`Types: ${VALID_TYPES.join(' | ')}`);
type = await prompt(rl, 'Project type: ');
type = type.trim();
}
rl.close();
return { name, type };
}
function todayISO() {
return new Date().toISOString().slice(0, 10);
}
function generateOutlineYaml(name, type) {
return `# WDS Project Outline
# Auto-generated by wds-setup.js
project_name: "${name}"
project_type: "${type}"
started: "${todayISO()}"
method: "Whiteport Design Studio (WDS)"
version: "0.4.1"
# Phases
phases:
0_setup: started
1_product_brief: not_started
2_trigger_map: not_started
3_ux_scenarios: not_started
4_ux_design: not_started
5_design_system: not_started
# Configuration (fill in during Phase 0 setup dialog)
platform: ""
tech_stack: ""
complexity: ""
primary_language: ""
`;
}
function generateDesignLog(name, type) {
const date = todayISO();
return `# Design Log
**Project:** ${name}
**Started:** ${date}
**Method:** Whiteport Design Studio (WDS)
---
## Backlog
> Business-value items. Add links to detail files if needed.
- [ ] Complete product brief — Phase 1
- [ ] Define trigger map — Phase 2
- [ ] Create user scenarios — Phase 3
---
## Current
| Task | Started | Agent |
|------|---------|-------|
| — | — | — |
**Rules:** Mark what you start. Complete it when done (move to Log). One task at a time per agent.
---
## Design Loop Status
> Per-page design progress. Updated by agents at every design transition.
| Scenario | Step | Page | Status | Updated |
|----------|------|------|--------|---------|
**Status values:** \`discussed\`\`wireframed\`\`specified\`\`explored\`\`building\`\`built\`\`approved\` | \`removed\`
**How to use:**
- **Append a row** when a page reaches a new status (do not overwrite — latest row per page is current status)
- **Read on startup** to see where the project stands and what to suggest next
---
## Log
### ${date} — Project initialized (Phase 0)
- Type: ${type}
- Complexity: [to be determined]
- Tech stack: [to be determined]
---
## About This Folder
- **This file** — Single source of truth for project progress
- **agent-experiences/** — Compressed insights from design discussions (dated files)
- **wds-project-outline.yaml** — Project configuration from Phase 0 setup
**Do not modify \`wds-project-outline.yaml\`** — it is the source of truth for project configuration.
`;
}
function scaffold(name, type, cwd) {
const created = [];
// Create directory structure
const dirs = [
'_progress',
'design-process/A-Product-Brief',
'design-process/B-Trigger-Map',
'design-process/C-UX-Scenarios',
'design-process/D-UX-Design',
'design-process/E-Design-System',
];
for (const dir of dirs) {
const fullPath = path.join(cwd, dir);
fs.mkdirSync(fullPath, { recursive: true });
}
// Write wds-project-outline.yaml
const outlinePath = path.join(cwd, '_progress', 'wds-project-outline.yaml');
fs.writeFileSync(outlinePath, generateOutlineYaml(name, type), 'utf8');
created.push('_progress/wds-project-outline.yaml');
// Write 00-design-log.md
const logPath = path.join(cwd, '_progress', '00-design-log.md');
fs.writeFileSync(logPath, generateDesignLog(name, type), 'utf8');
created.push('_progress/00-design-log.md');
// Note created directories
for (const dir of dirs) {
created.push(`${dir}/`);
}
return created;
}
async function main() {
const args = parseArgs();
const { name, type } = await getInputs(args);
if (!name) {
console.error('Error: Project name is required.');
process.exit(1);
}
if (!VALID_TYPES.includes(type)) {
console.error(`Error: Invalid type "${type}". Must be one of: ${VALID_TYPES.join(', ')}`);
process.exit(1);
}
const cwd = process.cwd();
const created = scaffold(name, type, cwd);
console.log(`\nWDS project scaffolded: ${name} (${type})\n`);
console.log('Created:');
for (const item of created) {
console.log(` ${item}`);
}
console.log('\nNext: Run Phase 0 setup dialog with Saga to fill in wds-project-outline.yaml.');
}
main().catch((err) => {
console.error(err.message);
process.exit(1);
});