fix: lint and formatting issues in non-interactive installation PR

- Fix ESLint errors: use switch over else-if, remove unused catch bindings, use slice over substring, use replaceAll over replace
- Fix Prettier formatting issues across all modified files
- Fix markdown lint: wrap bare URL in angle brackets

All tests passing: schemas, installation, validation, lint, markdown lint, and formatting checks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nikita Levyankov 2025-12-18 12:23:46 +02:00
parent 57bd2c0731
commit 1dca5fb4b7
7 changed files with 73 additions and 67 deletions

View File

@ -21,6 +21,7 @@ npx bmad-method@alpha install -y
```
This installs BMAD with:
- Default user name from system (USER environment variable)
- Intermediate skill level
- Default output folder (`_bmad-output`)
@ -49,10 +50,11 @@ cat _bmad/bmm/config.yaml
```
Example output:
```yaml
user_name: Alice
user_skill_level: intermediate
output_folder: "{project-root}/_bmad-output"
output_folder: '{project-root}/_bmad-output'
communication_language: English
```
@ -169,29 +171,29 @@ npx bmad-method@alpha install -y \
### Core Options
| Option | Description | Default | Example |
|--------|-------------|---------|---------|
| `-y, --non-interactive` | Skip all prompts | `false` | `install -y` |
| `--user-name <name>` | User name | System user | `--user-name=Alice` |
| `--skill-level <level>` | Skill level | `intermediate` | `--skill-level=advanced` |
| `--output-folder <path>` | Output folder | `_bmad-output` | `--output-folder=.artifacts` |
| `--communication-language <lang>` | Communication language | `English` | `--communication-language=Spanish` |
| `--document-language <lang>` | Document language | `English` | `--document-language=French` |
| Option | Description | Default | Example |
| --------------------------------- | ---------------------- | -------------- | ---------------------------------- |
| `-y, --non-interactive` | Skip all prompts | `false` | `install -y` |
| `--user-name <name>` | User name | System user | `--user-name=Alice` |
| `--skill-level <level>` | Skill level | `intermediate` | `--skill-level=advanced` |
| `--output-folder <path>` | Output folder | `_bmad-output` | `--output-folder=.artifacts` |
| `--communication-language <lang>` | Communication language | `English` | `--communication-language=Spanish` |
| `--document-language <lang>` | Document language | `English` | `--document-language=French` |
### Module & Selection Options
| Option | Description | Example |
|--------|-------------|---------|
| `--modules <list>` | Comma-separated modules | `--modules=core,bmm,bmbb` |
| `--agents <list>` | Comma-separated agents | `--agents=dev,architect,pm` |
| Option | Description | Example |
| -------------------- | ------------------------- | ---------------------------------- |
| `--modules <list>` | Comma-separated modules | `--modules=core,bmm,bmbb` |
| `--agents <list>` | Comma-separated agents | `--agents=dev,architect,pm` |
| `--workflows <list>` | Comma-separated workflows | `--workflows=create-prd,dev-story` |
### Team & Profile Options
| Option | Description | Example |
|--------|-------------|---------|
| `--team <name>` | Install predefined team | `--team=fullstack` |
| `--profile <name>` | Installation profile | `--profile=minimal` |
| Option | Description | Example |
| ------------------ | ----------------------- | ------------------- |
| `--team <name>` | Install predefined team | `--team=fullstack` |
| `--profile <name>` | Installation profile | `--profile=minimal` |
## Team-Based Installation
@ -206,6 +208,7 @@ npx bmad-method@alpha install -y --team=fullstack
```
**Includes:**
- Agents: analyst, architect, pm, sm, ux-designer
- Module: BMM
@ -218,6 +221,7 @@ npx bmad-method@alpha install -y --team=gamedev
```
**Includes:**
- Agents: game-designer, game-dev, game-architect, game-scrum-master
- Workflows: brainstorm-game, game-brief, gdd, narrative
- Module: BMGD (Game Development)
@ -252,6 +256,7 @@ npx bmad-method@alpha install -y --profile=minimal
```
**Includes:**
- Modules: core
- Agents: dev
- Workflows: create-tech-spec, quick-dev
@ -265,6 +270,7 @@ npx bmad-method@alpha install -y --profile=solo-dev
```
**Includes:**
- Modules: core, bmm
- Agents: dev, architect, analyst, tech-writer
- Workflows: create-tech-spec, quick-dev, dev-story, code-review, create-prd, create-architecture
@ -278,6 +284,7 @@ npx bmad-method@alpha install -y --profile=full
```
**Includes:**
- All modules
- All agents
- All workflows
@ -291,6 +298,7 @@ npx bmad-method@alpha install -y --profile=team
```
**Includes:**
- Modules: core, bmm
- Agents: dev, architect, pm, sm, analyst, ux-designer
- Workflows: create-product-brief, create-prd, create-architecture, create-epics-and-stories, sprint-planning, create-story, dev-story, code-review, workflow-init
@ -437,4 +445,4 @@ fi
## Feedback
Found an issue or have a suggestion? Please report it at:
https://github.com/bmad-code-org/BMAD-METHOD/issues
<https://github.com/bmad-code-org/BMAD-METHOD/issues>

View File

@ -885,22 +885,37 @@ class ConfigCollector {
// Resolution order: CLI → ENV → existing → default → hardcoded
if (moduleName === 'core') {
// Core module has special mappings
if (key === 'user_name') {
value = resolveValue(cliOptions.userName, null, envDefaults.userName);
} else if (key === 'user_skill_level') {
value = resolveValue(cliOptions.skillLevel, null, item.default || 'intermediate');
} else if (key === 'communication_language') {
value = resolveValue(
cliOptions.communicationLanguage,
null,
envDefaults.communicationLanguage,
);
} else if (key === 'document_output_language') {
value = resolveValue(cliOptions.documentLanguage, null, envDefaults.documentLanguage);
} else if (key === 'output_folder') {
value = resolveValue(cliOptions.outputFolder, null, item.default);
} else if (item.default !== undefined) {
value = item.default;
switch (key) {
case 'user_name': {
value = resolveValue(cliOptions.userName, null, envDefaults.userName);
break;
}
case 'user_skill_level': {
value = resolveValue(cliOptions.skillLevel, null, item.default || 'intermediate');
break;
}
case 'communication_language': {
value = resolveValue(cliOptions.communicationLanguage, null, envDefaults.communicationLanguage);
break;
}
case 'document_output_language': {
value = resolveValue(cliOptions.documentLanguage, null, envDefaults.documentLanguage);
break;
}
case 'output_folder': {
value = resolveValue(cliOptions.outputFolder, null, item.default);
break;
}
default: {
if (item.default !== undefined) {
value = item.default;
}
}
}
} else {
// For other modules, use defaults

View File

@ -26,7 +26,7 @@ function getUserName() {
if (userInfo.username) {
return userInfo.username;
}
} catch (error) {
} catch {
// os.userInfo() can fail in some environments
}

View File

@ -161,7 +161,7 @@ class ManifestGenerator {
// Wildcard matching: create-* matches create-prd, create-tech-spec, etc.
if (pattern.includes('*')) {
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
const regex = new RegExp('^' + pattern.replaceAll('*', '.*') + '$');
return regex.test(workflowName);
}
@ -318,7 +318,7 @@ class ManifestGenerator {
// Wildcard matching: dev* matches dev, dev-story, etc.
if (pattern.includes('*')) {
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
const regex = new RegExp('^' + pattern.replaceAll('*', '.*') + '$');
return regex.test(agentName);
}

View File

@ -58,9 +58,9 @@ function separateModifiers(list) {
for (const item of list) {
if (item.startsWith('+')) {
result.add.push(item.substring(1));
result.add.push(item.slice(1));
} else if (item.startsWith('-')) {
result.remove.push(item.substring(1));
result.remove.push(item.slice(1));
} else {
result.base.push(item);
}
@ -118,9 +118,7 @@ function parseOptions(cliOptions) {
if (normalized.profile) {
const profile = getProfile(normalized.profile);
if (!profile) {
throw new Error(
`Unknown profile: ${normalized.profile}. Valid profiles: minimal, full, solo-dev, team`,
);
throw new Error(`Unknown profile: ${normalized.profile}. Valid profiles: minimal, full, solo-dev, team`);
}
// Profile provides defaults, but CLI options override
@ -136,9 +134,7 @@ function parseOptions(cliOptions) {
normalized.agents = Array.isArray(profile.agents) ? profile.agents : profile.agents;
}
if (!normalized.workflows) {
normalized.workflows = Array.isArray(profile.workflows)
? profile.workflows
: profile.workflows;
normalized.workflows = Array.isArray(profile.workflows) ? profile.workflows : profile.workflows;
}
}
@ -157,9 +153,7 @@ function validateOptions(options) {
if (options.skillLevel) {
const validLevels = ['beginner', 'intermediate', 'advanced'];
if (!validLevels.includes(options.skillLevel.toLowerCase())) {
errors.push(
`Invalid skill level: ${options.skillLevel}. Valid values: beginner, intermediate, advanced`,
);
errors.push(`Invalid skill level: ${options.skillLevel}. Valid values: beginner, intermediate, advanced`);
}
}
@ -167,9 +161,7 @@ function validateOptions(options) {
if (options.profile) {
const validProfiles = ['minimal', 'full', 'solo-dev', 'team'];
if (!validProfiles.includes(options.profile.toLowerCase())) {
errors.push(
`Invalid profile: ${options.profile}. Valid values: minimal, full, solo-dev, team`,
);
errors.push(`Invalid profile: ${options.profile}. Valid values: minimal, full, solo-dev, team`);
}
}

View File

@ -28,14 +28,7 @@ const PROFILES = {
description: 'Single developer setup - dev tools and planning workflows',
modules: ['core', 'bmm'],
agents: ['dev', 'architect', 'analyst', 'tech-writer'],
workflows: [
'create-tech-spec',
'quick-dev',
'dev-story',
'code-review',
'create-prd',
'create-architecture',
],
workflows: ['create-tech-spec', 'quick-dev', 'dev-story', 'code-review', 'create-prd', 'create-architecture'],
},
team: {

View File

@ -49,7 +49,7 @@ async function discoverTeams(projectRoot) {
}
return teams;
} catch (error) {
} catch {
// If glob fails, return empty array
return [];
}
@ -75,9 +75,7 @@ async function loadTeam(teamName, projectRoot) {
if (!team) {
// Provide helpful error with suggestions
const availableTeams = teams.map((t) => t.name).join(', ');
throw new Error(
`Team '${teamName}' not found. Available teams: ${availableTeams || 'none'}`,
);
throw new Error(`Team '${teamName}' not found. Available teams: ${availableTeams || 'none'}`);
}
// Load full team definition
@ -130,12 +128,12 @@ function applyTeamModifiers(team, agentModifiers = [], workflowModifiers = []) {
// Parse and apply agent modifiers
for (const modifier of agentModifiers) {
if (modifier.startsWith('+')) {
const agent = modifier.substring(1);
const agent = modifier.slice(1);
if (!result.agents.includes(agent)) {
result.agents.push(agent);
}
} else if (modifier.startsWith('-')) {
const agent = modifier.substring(1);
const agent = modifier.slice(1);
result.agents = result.agents.filter((a) => a !== agent);
}
}
@ -143,12 +141,12 @@ function applyTeamModifiers(team, agentModifiers = [], workflowModifiers = []) {
// Parse and apply workflow modifiers
for (const modifier of workflowModifiers) {
if (modifier.startsWith('+')) {
const workflow = modifier.substring(1);
const workflow = modifier.slice(1);
if (!result.workflows.includes(workflow)) {
result.workflows.push(workflow);
}
} else if (modifier.startsWith('-')) {
const workflow = modifier.substring(1);
const workflow = modifier.slice(1);
result.workflows = result.workflows.filter((w) => w !== workflow);
}
}