mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-29 16:14:59 +00:00
feat: add custom agents and quick-flow workflows, remove tech-spec track
Major Changes: - Add sample custom agents demonstrating installable agent system - commit-poet: Generates semantic commit messages (BMAD Method repo sample) - toolsmith: Development tooling expert with knowledge base covering bundlers, deployment, docs, installers, modules, and tests (BMAD Method repo sample) - Both agents demonstrate custom agent architecture and are installable to projects via BMAD installer system - Include comprehensive installation guides and sidecar knowledge bases - Add bmad-quick-flow methodology for rapid development - create-tech-spec: Direct technical specification workflow - quick-dev: Flexible execution workflow supporting both tech-spec-driven and direct instruction development - quick-flow-solo-dev (Barry): 1 man show agent specialized in bmad-quick-flow methodology - Comprehensive documentation for quick-flow approach and solo development - Remove deprecated tech-spec workflow track - Delete entire tech-spec workflow directory and templates - Remove quick-spec-flow.md documentation (replaced by quick-flow docs) - Clean up unused epic and story templates - Fix custom agent installation across IDE installers - Repair antigravity and multiple IDE installers to properly support custom agents - Enable custom agent installation via quick installer, agent installer, regular installer, and special agent installer - All installation methods now accessible via npx with full documentation Infrastructure: - Update BMM module configurations and team setups - Modify workflow status paths to support quick-flow integration - Reorganize documentation with new agent and workflow guides - Add custom/ directory for user customizations - Update platform codes and installer configurations
This commit is contained in:
@@ -1629,14 +1629,9 @@ class Installer {
|
||||
spinner.succeed('No custom agents found to rebuild');
|
||||
}
|
||||
|
||||
// Regenerate manifests after compilation (including custom agents)
|
||||
spinner.start('Regenerating manifests...');
|
||||
const installedModules = entries
|
||||
.filter((e) => e.isDirectory() && e.name !== '_cfg' && e.name !== 'docs' && e.name !== 'agents' && e.name !== 'core')
|
||||
.map((e) => e.name);
|
||||
const manifestGen = new ManifestGenerator();
|
||||
|
||||
// Get existing IDE list from manifest
|
||||
// Skip full manifest regeneration during compileAgents to preserve custom agents
|
||||
// Custom agents are already added to manifests during individual installation
|
||||
// Only regenerate YAML manifest for IDE updates if needed
|
||||
const existingManifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||
let existingIdes = [];
|
||||
if (await fs.pathExists(existingManifestPath)) {
|
||||
@@ -1646,11 +1641,6 @@ class Installer {
|
||||
existingIdes = manifest.ides || [];
|
||||
}
|
||||
|
||||
await manifestGen.generateManifests(bmadDir, installedModules, [], {
|
||||
ides: existingIdes,
|
||||
});
|
||||
spinner.succeed('Manifests regenerated');
|
||||
|
||||
// Update IDE configurations using the existing IDE list from manifest
|
||||
if (existingIdes && existingIdes.length > 0) {
|
||||
spinner.start('Updating IDE configurations...');
|
||||
@@ -2369,8 +2359,16 @@ class Installer {
|
||||
|
||||
// Update manifest CSV
|
||||
if (await fs.pathExists(manifestFile)) {
|
||||
const manifestData = extractManifestData(xml, { ...metadata, name: finalAgentName }, relativePath, 'custom');
|
||||
manifestData.name = finalAgentName;
|
||||
// Preserve YAML metadata for persona name, but override id for filename
|
||||
const manifestMetadata = {
|
||||
...metadata,
|
||||
id: relativePath, // Use the compiled agent path for id
|
||||
name: metadata.name || finalAgentName, // Use YAML metadata.name (persona name) or fallback
|
||||
title: metadata.title, // Use YAML title
|
||||
icon: metadata.icon, // Use YAML icon
|
||||
};
|
||||
const manifestData = extractManifestData(xml, manifestMetadata, relativePath, 'custom');
|
||||
manifestData.name = finalAgentName; // Use filename for the name field
|
||||
manifestData.path = relativePath;
|
||||
addToManifest(manifestFile, manifestData);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||
@@ -44,7 +45,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'antigravity', 'injections.yaml');
|
||||
|
||||
if (await this.exists(injectionConfigPath)) {
|
||||
const fs = require('fs-extra');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
try {
|
||||
@@ -88,7 +88,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* @param {string} projectDir - Project directory
|
||||
*/
|
||||
async cleanup(projectDir) {
|
||||
const fs = require('fs-extra');
|
||||
const bmadWorkflowsDir = path.join(projectDir, this.configDir, this.workflowsDir, 'bmad');
|
||||
|
||||
if (await fs.pathExists(bmadWorkflowsDir)) {
|
||||
@@ -191,7 +190,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* Read and process file content
|
||||
*/
|
||||
async readAndProcess(filePath, metadata) {
|
||||
const fs = require('fs-extra');
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
return this.processContent(content, metadata);
|
||||
}
|
||||
@@ -208,7 +206,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* Get agents from source modules (not installed location)
|
||||
*/
|
||||
async getAgentsFromSource(sourceDir, selectedModules) {
|
||||
const fs = require('fs-extra');
|
||||
const agents = [];
|
||||
|
||||
// Add core agents
|
||||
@@ -387,7 +384,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* Inject content at specified point in file
|
||||
*/
|
||||
async injectContent(projectDir, injection, subagentChoices = null) {
|
||||
const fs = require('fs-extra');
|
||||
const targetPath = path.join(projectDir, injection.file);
|
||||
|
||||
if (await this.exists(targetPath)) {
|
||||
@@ -413,7 +409,6 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* Copy selected subagents to appropriate Antigravity agents directory
|
||||
*/
|
||||
async copySelectedSubagents(projectDir, handlerBaseDir, subagentConfig, choices, location) {
|
||||
const fs = require('fs-extra');
|
||||
const os = require('node:os');
|
||||
|
||||
// Determine target directory based on user choice
|
||||
@@ -468,10 +463,12 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
* @returns {Object} Installation result
|
||||
*/
|
||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||
// Create .agent/workflows/bmad directory structure (same as regular agents)
|
||||
const agentDir = path.join(projectDir, this.configDir);
|
||||
const workflowsDir = path.join(agentDir, this.workflowsDir);
|
||||
const bmadWorkflowsDir = path.join(workflowsDir, 'bmad');
|
||||
|
||||
// Create .agent directory if it doesn't exist
|
||||
await fs.ensureDir(agentDir);
|
||||
await fs.ensureDir(bmadWorkflowsDir);
|
||||
|
||||
// Create custom agent launcher with same pattern as regular agents
|
||||
const launcherContent = `name: '${agentName}'
|
||||
@@ -493,7 +490,7 @@ usage: |
|
||||
⚠️ **IMPORTANT**: Run @${agentPath} to load the complete agent before using this launcher!`;
|
||||
|
||||
const fileName = `bmad-custom-agents-${agentName}.md`;
|
||||
const launcherPath = path.join(agentDir, fileName);
|
||||
const launcherPath = path.join(bmadWorkflowsDir, fileName);
|
||||
|
||||
// Write the launcher file
|
||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
@@ -187,9 +188,10 @@ BMAD ${workflow.module.toUpperCase()} module
|
||||
// Auggie uses .augment/commands directory
|
||||
const location = path.join(projectDir, '.augment', 'commands');
|
||||
const bmadCommandsDir = path.join(location, 'bmad');
|
||||
const agentsDir = path.join(bmadCommandsDir, 'agents');
|
||||
|
||||
// Create .augment/commands/bmad directory if it doesn't exist
|
||||
await fs.ensureDir(bmadCommandsDir);
|
||||
// Create .augment/commands/bmad/agents directory if it doesn't exist
|
||||
await fs.ensureDir(agentsDir);
|
||||
|
||||
// Create custom agent launcher
|
||||
const launcherContent = `---
|
||||
@@ -213,7 +215,7 @@ BMAD Custom agent
|
||||
`;
|
||||
|
||||
const fileName = `custom-${agentName.toLowerCase()}.md`;
|
||||
const launcherPath = path.join(bmadCommandsDir, fileName);
|
||||
const launcherPath = path.join(agentsDir, fileName);
|
||||
|
||||
// Write the launcher file
|
||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||
@@ -43,7 +44,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'claude-code', 'injections.yaml');
|
||||
|
||||
if (await this.exists(injectionConfigPath)) {
|
||||
const fs = require('fs-extra');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
try {
|
||||
@@ -87,7 +87,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
* @param {string} projectDir - Project directory
|
||||
*/
|
||||
async cleanup(projectDir) {
|
||||
const fs = require('fs-extra');
|
||||
const bmadCommandsDir = path.join(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||
|
||||
if (await fs.pathExists(bmadCommandsDir)) {
|
||||
@@ -199,7 +198,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
* Read and process file content
|
||||
*/
|
||||
async readAndProcess(filePath, metadata) {
|
||||
const fs = require('fs-extra');
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
return this.processContent(content, metadata);
|
||||
}
|
||||
@@ -216,7 +214,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
* Get agents from source modules (not installed location)
|
||||
*/
|
||||
async getAgentsFromSource(sourceDir, selectedModules) {
|
||||
const fs = require('fs-extra');
|
||||
const agents = [];
|
||||
|
||||
// Add core agents
|
||||
@@ -395,7 +392,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
* Inject content at specified point in file
|
||||
*/
|
||||
async injectContent(projectDir, injection, subagentChoices = null) {
|
||||
const fs = require('fs-extra');
|
||||
const targetPath = path.join(projectDir, injection.file);
|
||||
|
||||
if (await this.exists(targetPath)) {
|
||||
@@ -421,7 +417,6 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
* Copy selected subagents to appropriate Claude agents directory
|
||||
*/
|
||||
async copySelectedSubagents(projectDir, handlerBaseDir, subagentConfig, choices, location) {
|
||||
const fs = require('fs-extra');
|
||||
const os = require('node:os');
|
||||
|
||||
// Determine target directory based on user choice
|
||||
|
||||
@@ -354,7 +354,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||
* @returns {Object|null} Info about created command
|
||||
*/
|
||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||
const destDir = this.getCodexPromptDir();
|
||||
const destDir = this.getCodexPromptDir(projectDir, 'project');
|
||||
await fs.ensureDir(destDir);
|
||||
|
||||
const launcherContent = `---
|
||||
@@ -379,7 +379,7 @@ You must fully embody this agent's persona and follow all activation instruction
|
||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
||||
|
||||
return {
|
||||
path: launcherPath,
|
||||
path: path.relative(projectDir, launcherPath),
|
||||
command: `/${fileName.replace('.md', '')}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
|
||||
Reference in New Issue
Block a user