mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-17 17:55:34 +00:00
we only need one yaml lib
This commit is contained in:
parent
ce42d56fdd
commit
8642553bd7
@ -31,7 +31,6 @@ npm install -D @seontechnologies/playwright-utils
|
|||||||
|
|
||||||
- `@playwright/test` >= 1.54.1 (required)
|
- `@playwright/test` >= 1.54.1 (required)
|
||||||
- `ajv` >= 8.0.0 (optional - for JSON Schema validation)
|
- `ajv` >= 8.0.0 (optional - for JSON Schema validation)
|
||||||
- `js-yaml` >= 4.0.0 (optional - for YAML schema support)
|
|
||||||
- `zod` >= 3.0.0 (optional - for Zod schema validation)
|
- `zod` >= 3.0.0 (optional - for Zod schema validation)
|
||||||
|
|
||||||
## Available Utilities
|
## Available Utilities
|
||||||
|
|||||||
@ -269,7 +269,7 @@ The validation is integrated into the GitHub Actions workflow:
|
|||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- **zod**: Schema validation library
|
- **zod**: Schema validation library
|
||||||
- **js-yaml**: YAML parsing
|
- **yaml**: YAML parsing
|
||||||
- **glob**: File pattern matching
|
- **glob**: File pattern matching
|
||||||
- **c8**: Code coverage reporting
|
- **c8**: Code coverage reporting
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { validateAgentFile } = require('../tools/schema/agent.js');
|
const { validateAgentFile } = require('../tools/schema/agent.js');
|
||||||
const { glob } = require('glob');
|
const { glob } = require('glob');
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ function runTest(filePath) {
|
|||||||
let agentData;
|
let agentData;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
agentData = yaml.load(fileContent);
|
agentData = yaml.parse(fileContent);
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
// YAML parse error
|
// YAML parse error
|
||||||
if (shouldPass) {
|
if (shouldPass) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const inquirer = require('inquirer');
|
const inquirer = require('inquirer');
|
||||||
const { getProjectRoot, getModulePath } = require('../../../lib/project-root');
|
const { getProjectRoot, getModulePath } = require('../../../lib/project-root');
|
||||||
@ -109,7 +109,7 @@ class ConfigCollector {
|
|||||||
if (await fs.pathExists(moduleConfigPath)) {
|
if (await fs.pathExists(moduleConfigPath)) {
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(moduleConfigPath, 'utf8');
|
const content = await fs.readFile(moduleConfigPath, 'utf8');
|
||||||
const moduleConfig = yaml.load(content);
|
const moduleConfig = yaml.parse(content);
|
||||||
if (moduleConfig) {
|
if (moduleConfig) {
|
||||||
this.existingConfig[entry.name] = moduleConfig;
|
this.existingConfig[entry.name] = moduleConfig;
|
||||||
foundAny = true;
|
foundAny = true;
|
||||||
@ -238,7 +238,7 @@ class ConfigCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const configContent = await fs.readFile(configPath, 'utf8');
|
const configContent = await fs.readFile(configPath, 'utf8');
|
||||||
const moduleConfig = yaml.load(configContent);
|
const moduleConfig = yaml.parse(configContent);
|
||||||
|
|
||||||
if (!moduleConfig) {
|
if (!moduleConfig) {
|
||||||
return false;
|
return false;
|
||||||
@ -514,7 +514,7 @@ class ConfigCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const configContent = await fs.readFile(configPath, 'utf8');
|
const configContent = await fs.readFile(configPath, 'utf8');
|
||||||
const moduleConfig = yaml.load(configContent);
|
const moduleConfig = yaml.parse(configContent);
|
||||||
|
|
||||||
if (!moduleConfig) {
|
if (!moduleConfig) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -31,7 +31,7 @@ class CustomModuleCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const content = await fs.readFile(this.manifestPath, 'utf8');
|
const content = await fs.readFile(this.manifestPath, 'utf8');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
return yaml.parse(content) || {};
|
return yaml.parse(content) || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,11 +39,10 @@ class CustomModuleCache {
|
|||||||
* Update cache manifest
|
* Update cache manifest
|
||||||
*/
|
*/
|
||||||
async updateCacheManifest(manifest) {
|
async updateCacheManifest(manifest) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const content = yaml.dump(manifest, {
|
const content = yaml.stringify(manifest, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false,
|
sortKeys: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ const fs = require('fs-extra');
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependency Resolver for BMAD modules
|
* Dependency Resolver for BMAD modules
|
||||||
@ -147,7 +147,7 @@ class DependencyResolver {
|
|||||||
// Quote values with backticks to make them valid YAML
|
// Quote values with backticks to make them valid YAML
|
||||||
yamlContent = yamlContent.replaceAll(/: `([^`]+)`/g, ': "$1"');
|
yamlContent = yamlContent.replaceAll(/: `([^`]+)`/g, ': "$1"');
|
||||||
|
|
||||||
const frontmatter = yaml.load(yamlContent);
|
const frontmatter = yaml.parse(yamlContent);
|
||||||
if (frontmatter.dependencies) {
|
if (frontmatter.dependencies) {
|
||||||
const deps = Array.isArray(frontmatter.dependencies) ? frontmatter.dependencies : [frontmatter.dependencies];
|
const deps = Array.isArray(frontmatter.dependencies) ? frontmatter.dependencies : [frontmatter.dependencies];
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { Manifest } = require('./manifest');
|
const { Manifest } = require('./manifest');
|
||||||
|
|
||||||
class Detector {
|
class Detector {
|
||||||
@ -237,7 +237,7 @@ class Detector {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
||||||
const manifest = yaml.parse(manifestContent);
|
const manifest = yaml.parse(manifestContent);
|
||||||
// V6+ manifest has installation.version
|
// V6+ manifest has installation.version
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages IDE configuration persistence
|
* Manages IDE configuration persistence
|
||||||
@ -61,10 +61,9 @@ class IdeConfigManager {
|
|||||||
configuration: configuration || {},
|
configuration: configuration || {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const yamlContent = yaml.dump(configData, {
|
const yamlContent = yaml.stringify(configData, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false,
|
sortKeys: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -88,7 +87,7 @@ class IdeConfigManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(configPath, 'utf8');
|
const content = await fs.readFile(configPath, 'utf8');
|
||||||
const config = yaml.load(content);
|
const config = yaml.parse(content);
|
||||||
return config;
|
return config;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Warning: Failed to load IDE config for ${ideName}:`, error.message);
|
console.warn(`Warning: Failed to load IDE config for ${ideName}:`, error.message);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ const { CLIUtils } = require('../../../lib/cli-utils');
|
|||||||
const { ManifestGenerator } = require('./manifest-generator');
|
const { ManifestGenerator } = require('./manifest-generator');
|
||||||
const { IdeConfigManager } = require('./ide-config-manager');
|
const { IdeConfigManager } = require('./ide-config-manager');
|
||||||
const { CustomHandler } = require('../custom/handler');
|
const { CustomHandler } = require('../custom/handler');
|
||||||
|
const { filterCustomizationData } = require('../../../lib/agent/compiler');
|
||||||
|
|
||||||
class Installer {
|
class Installer {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -1457,7 +1458,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
* @param {Object} moduleConfigs - Collected configuration values
|
* @param {Object} moduleConfigs - Collected configuration values
|
||||||
*/
|
*/
|
||||||
async generateModuleConfigs(bmadDir, moduleConfigs) {
|
async generateModuleConfigs(bmadDir, moduleConfigs) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
// Extract core config values to share with other modules
|
// Extract core config values to share with other modules
|
||||||
const coreConfig = moduleConfigs.core || {};
|
const coreConfig = moduleConfigs.core || {};
|
||||||
@ -1504,11 +1505,10 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert config to YAML
|
// Convert config to YAML
|
||||||
let yamlContent = yaml.dump(finalConfig, {
|
let yamlContent = yaml.stringify(finalConfig, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
minContentWidth: 0,
|
||||||
sortKeys: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we have core values, reorganize the YAML to group them with their comment
|
// If we have core values, reorganize the YAML to group them with their comment
|
||||||
@ -1949,7 +1949,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
|
|
||||||
if (customizeExists) {
|
if (customizeExists) {
|
||||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const customizeYaml = yaml.parse(customizeContent);
|
const customizeYaml = yaml.parse(customizeContent);
|
||||||
|
|
||||||
// Detect what fields are customized (similar to rebuildAgentFiles)
|
// Detect what fields are customized (similar to rebuildAgentFiles)
|
||||||
@ -2040,8 +2040,8 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
|
|
||||||
if (customizeExists) {
|
if (customizeExists) {
|
||||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const customizeYaml = yaml.load(customizeContent);
|
const customizeYaml = yaml.parse(customizeContent);
|
||||||
|
|
||||||
// Detect what fields are customized
|
// Detect what fields are customized
|
||||||
if (customizeYaml) {
|
if (customizeYaml) {
|
||||||
@ -2085,18 +2085,21 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
customizeData = yaml.parse(customizeContent);
|
customizeData = yaml.parse(customizeContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build agent answers from customize data
|
// Build agent answers from customize data (filter empty values)
|
||||||
const answers = {};
|
const answers = {};
|
||||||
if (customizeData.persona) {
|
if (customizeData.persona) {
|
||||||
Object.assign(answers, customizeData.persona);
|
Object.assign(answers, filterCustomizationData(customizeData.persona));
|
||||||
}
|
}
|
||||||
if (customizeData.agent?.metadata) {
|
if (customizeData.agent?.metadata) {
|
||||||
Object.assign(answers, { metadata: customizeData.agent.metadata });
|
const filteredMetadata = filterCustomizationData(customizeData.agent.metadata);
|
||||||
|
if (Object.keys(filteredMetadata).length > 0) {
|
||||||
|
Object.assign(answers, { metadata: filteredMetadata });
|
||||||
}
|
}
|
||||||
if (customizeData.critical_actions) {
|
}
|
||||||
|
if (customizeData.critical_actions && customizeData.critical_actions.length > 0) {
|
||||||
answers.critical_actions = customizeData.critical_actions;
|
answers.critical_actions = customizeData.critical_actions;
|
||||||
}
|
}
|
||||||
if (customizeData.memories) {
|
if (customizeData.memories && customizeData.memories.length > 0) {
|
||||||
answers.memories = customizeData.memories;
|
answers.memories = customizeData.memories;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2153,8 +2156,8 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|||||||
let manifest = null;
|
let manifest = null;
|
||||||
if (await fs.pathExists(manifestPath)) {
|
if (await fs.pathExists(manifestPath)) {
|
||||||
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
manifest = yaml.load(manifestContent);
|
manifest = yaml.parse(manifestContent);
|
||||||
installedModules = manifest.modules || [];
|
installedModules = manifest.modules || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const crypto = require('node:crypto');
|
const crypto = require('node:crypto');
|
||||||
const { getSourcePath, getModulePath } = require('../../../lib/project-root');
|
const { getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||||
|
|
||||||
@ -480,10 +480,9 @@ class ManifestGenerator {
|
|||||||
ides: this.selectedIdes,
|
ides: this.selectedIdes,
|
||||||
};
|
};
|
||||||
|
|
||||||
const yamlStr = yaml.dump(manifest, {
|
const yamlStr = yaml.stringify(manifest, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false,
|
sortKeys: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class Manifest {
|
|||||||
*/
|
*/
|
||||||
async create(bmadDir, data, installedFiles = []) {
|
async create(bmadDir, data, installedFiles = []) {
|
||||||
const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
// Ensure _cfg directory exists
|
// Ensure _cfg directory exists
|
||||||
await fs.ensureDir(path.dirname(manifestPath));
|
await fs.ensureDir(path.dirname(manifestPath));
|
||||||
@ -28,10 +28,9 @@ class Manifest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Write YAML manifest
|
// Write YAML manifest
|
||||||
const yamlContent = yaml.dump(manifestData, {
|
const yamlContent = yaml.stringify(manifestData, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false,
|
sortKeys: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -48,12 +47,12 @@ class Manifest {
|
|||||||
*/
|
*/
|
||||||
async read(bmadDir) {
|
async read(bmadDir) {
|
||||||
const yamlPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
const yamlPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
if (await fs.pathExists(yamlPath)) {
|
if (await fs.pathExists(yamlPath)) {
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(yamlPath, 'utf8');
|
const content = await fs.readFile(yamlPath, 'utf8');
|
||||||
const manifestData = yaml.load(content);
|
const manifestData = yaml.parse(content);
|
||||||
|
|
||||||
// Flatten the structure for compatibility with existing code
|
// Flatten the structure for compatibility with existing code
|
||||||
return {
|
return {
|
||||||
@ -79,7 +78,7 @@ class Manifest {
|
|||||||
* @param {Array} installedFiles - Updated list of installed files
|
* @param {Array} installedFiles - Updated list of installed files
|
||||||
*/
|
*/
|
||||||
async update(bmadDir, updates, installedFiles = null) {
|
async update(bmadDir, updates, installedFiles = null) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const manifest = (await this.read(bmadDir)) || {};
|
const manifest = (await this.read(bmadDir)) || {};
|
||||||
|
|
||||||
// Merge updates
|
// Merge updates
|
||||||
@ -101,10 +100,9 @@ class Manifest {
|
|||||||
const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||||
await fs.ensureDir(path.dirname(manifestPath));
|
await fs.ensureDir(path.dirname(manifestPath));
|
||||||
|
|
||||||
const yamlContent = yaml.dump(manifestData, {
|
const yamlContent = yaml.stringify(manifestData, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1,
|
lineWidth: 0,
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false,
|
sortKeys: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -526,9 +524,9 @@ class Manifest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (await fs.pathExists(configPath)) {
|
if (await fs.pathExists(configPath)) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const content = await fs.readFile(configPath, 'utf8');
|
const content = await fs.readFile(configPath, 'utf8');
|
||||||
configs[moduleName] = yaml.load(content);
|
configs[moduleName] = yaml.parse(content);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Could not load config for module ${moduleName}:`, error.message);
|
console.warn(`Could not load config for module ${moduleName}:`, error.message);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { FileOps } = require('../../../lib/file-ops');
|
const { FileOps } = require('../../../lib/file-ops');
|
||||||
const { XmlHandler } = require('../../../lib/xml-handler');
|
const { XmlHandler } = require('../../../lib/xml-handler');
|
||||||
|
|
||||||
|
|||||||
@ -346,7 +346,7 @@ class BaseIdeSetup {
|
|||||||
} else if (entry.isFile() && entry.name === 'workflow.yaml') {
|
} else if (entry.isFile() && entry.name === 'workflow.yaml') {
|
||||||
// Read workflow.yaml to get name and standalone property
|
// Read workflow.yaml to get name and standalone property
|
||||||
try {
|
try {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const content = await fs.readFile(fullPath, 'utf8');
|
const content = await fs.readFile(fullPath, 'utf8');
|
||||||
const workflowData = yaml.parse(content);
|
const workflowData = yaml.parse(content);
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ class BaseIdeSetup {
|
|||||||
// Check for standalone: true in YAML frontmatter
|
// Check for standalone: true in YAML frontmatter
|
||||||
const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
||||||
if (frontmatterMatch) {
|
if (frontmatterMatch) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
try {
|
try {
|
||||||
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
||||||
standalone = frontmatter.standalone === true;
|
standalone = frontmatter.standalone === true;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
|||||||
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'antigravity', 'injections.yaml');
|
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'antigravity', 'injections.yaml');
|
||||||
|
|
||||||
if (await this.exists(injectionConfigPath)) {
|
if (await this.exists(injectionConfigPath)) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load injection configuration
|
// Load injection configuration
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|||||||
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'claude-code', 'injections.yaml');
|
const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'claude-code', 'injections.yaml');
|
||||||
|
|
||||||
if (await this.exists(injectionConfigPath)) {
|
if (await this.exists(injectionConfigPath)) {
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load injection configuration
|
// Load injection configuration
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|||||||
@ -2,7 +2,7 @@ const path = require('node:path');
|
|||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kiro CLI setup handler for BMad Method
|
* Kiro CLI setup handler for BMad Method
|
||||||
|
|||||||
@ -2,7 +2,7 @@ const path = require('node:path');
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const os = require('node:os');
|
const os = require('node:os');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { glob } = require('glob');
|
const { glob } = require('glob');
|
||||||
const { getSourcePath } = require('../../../../lib/project-root');
|
const { getSourcePath } = require('../../../../lib/project-root');
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { XmlHandler } = require('../../../lib/xml-handler');
|
const { XmlHandler } = require('../../../lib/xml-handler');
|
||||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||||
|
const { filterCustomizationData } = require('../../../lib/agent/compiler');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the installation, updating, and removal of BMAD modules.
|
* Manages the installation, updating, and removal of BMAD modules.
|
||||||
@ -12,7 +13,7 @@ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/p
|
|||||||
*
|
*
|
||||||
* @class ModuleManager
|
* @class ModuleManager
|
||||||
* @requires fs-extra
|
* @requires fs-extra
|
||||||
* @requires js-yaml
|
* @requires yaml
|
||||||
* @requires chalk
|
* @requires chalk
|
||||||
* @requires XmlHandler
|
* @requires XmlHandler
|
||||||
*
|
*
|
||||||
@ -312,7 +313,7 @@ class ModuleManager {
|
|||||||
// Read module config for metadata
|
// Read module config for metadata
|
||||||
try {
|
try {
|
||||||
const configContent = await fs.readFile(configPath, 'utf8');
|
const configContent = await fs.readFile(configPath, 'utf8');
|
||||||
const config = yaml.load(configContent);
|
const config = yaml.parse(configContent);
|
||||||
|
|
||||||
// Use the code property as the id if available
|
// Use the code property as the id if available
|
||||||
if (config.code) {
|
if (config.code) {
|
||||||
@ -387,7 +388,7 @@ class ModuleManager {
|
|||||||
if (configPath) {
|
if (configPath) {
|
||||||
try {
|
try {
|
||||||
const configContent = await fs.readFile(configPath, 'utf8');
|
const configContent = await fs.readFile(configPath, 'utf8');
|
||||||
const config = yaml.load(configContent);
|
const config = yaml.parse(configContent);
|
||||||
if (config.code === moduleName) {
|
if (config.code === moduleName) {
|
||||||
return modulePath;
|
return modulePath;
|
||||||
}
|
}
|
||||||
@ -427,14 +428,14 @@ class ModuleManager {
|
|||||||
if (await fs.pathExists(rootCustomConfigPath)) {
|
if (await fs.pathExists(rootCustomConfigPath)) {
|
||||||
try {
|
try {
|
||||||
const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
|
const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
|
||||||
customConfig = yaml.load(customContent);
|
customConfig = yaml.parse(customContent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
||||||
}
|
}
|
||||||
} else if (await fs.pathExists(moduleInstallerCustomPath)) {
|
} else if (await fs.pathExists(moduleInstallerCustomPath)) {
|
||||||
try {
|
try {
|
||||||
const customContent = await fs.readFile(moduleInstallerCustomPath, 'utf8');
|
const customContent = await fs.readFile(moduleInstallerCustomPath, 'utf8');
|
||||||
customConfig = yaml.load(customContent);
|
customConfig = yaml.parse(customContent);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
||||||
}
|
}
|
||||||
@ -569,7 +570,7 @@ class ModuleManager {
|
|||||||
if (await fs.pathExists(configPath)) {
|
if (await fs.pathExists(configPath)) {
|
||||||
try {
|
try {
|
||||||
const configContent = await fs.readFile(configPath, 'utf8');
|
const configContent = await fs.readFile(configPath, 'utf8');
|
||||||
const config = yaml.load(configContent);
|
const config = yaml.parse(configContent);
|
||||||
Object.assign(moduleInfo, config);
|
Object.assign(moduleInfo, config);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to read installed module config:`, error.message);
|
console.warn(`Failed to read installed module config:`, error.message);
|
||||||
@ -700,7 +701,7 @@ class ModuleManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// First check if web_bundle exists by parsing
|
// First check if web_bundle exists by parsing
|
||||||
const workflowConfig = yaml.load(yamlContent);
|
const workflowConfig = yaml.parse(yamlContent);
|
||||||
|
|
||||||
if (workflowConfig.web_bundle === undefined) {
|
if (workflowConfig.web_bundle === undefined) {
|
||||||
// No web_bundle section, just write (placeholders already replaced above)
|
// No web_bundle section, just write (placeholders already replaced above)
|
||||||
@ -827,20 +828,23 @@ class ModuleManager {
|
|||||||
let answers = {};
|
let answers = {};
|
||||||
if (await fs.pathExists(customizePath)) {
|
if (await fs.pathExists(customizePath)) {
|
||||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||||
const customizeData = yaml.load(customizeContent);
|
const customizeData = yaml.parse(customizeContent);
|
||||||
customizedFields = customizeData.customized_fields || [];
|
customizedFields = customizeData.customized_fields || [];
|
||||||
|
|
||||||
// Build answers object from customizations
|
// Build answers object from customizations (filter empty values)
|
||||||
if (customizeData.persona) {
|
if (customizeData.persona) {
|
||||||
Object.assign(answers, customizeData.persona);
|
Object.assign(answers, filterCustomizationData(customizeData.persona));
|
||||||
}
|
}
|
||||||
if (customizeData.agent?.metadata) {
|
if (customizeData.agent?.metadata) {
|
||||||
Object.assign(answers, { metadata: customizeData.agent.metadata });
|
const filteredMetadata = filterCustomizationData(customizeData.agent.metadata);
|
||||||
|
if (Object.keys(filteredMetadata).length > 0) {
|
||||||
|
Object.assign(answers, { metadata: filteredMetadata });
|
||||||
}
|
}
|
||||||
if (customizeData.critical_actions) {
|
}
|
||||||
|
if (customizeData.critical_actions && customizeData.critical_actions.length > 0) {
|
||||||
answers.critical_actions = customizeData.critical_actions;
|
answers.critical_actions = customizeData.critical_actions;
|
||||||
}
|
}
|
||||||
if (customizeData.memories) {
|
if (customizeData.memories && customizeData.memories.length > 0) {
|
||||||
answers.memories = customizeData.memories;
|
answers.memories = customizeData.memories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -852,7 +856,7 @@ class ModuleManager {
|
|||||||
if (await fs.pathExists(coreConfigPath)) {
|
if (await fs.pathExists(coreConfigPath)) {
|
||||||
const yaml = require('yaml');
|
const yaml = require('yaml');
|
||||||
const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
|
const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||||
coreConfig = yaml.load(coreConfigContent);
|
coreConfig = yaml.parse(coreConfigContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if agent has sidecar
|
// Check if agent has sidecar
|
||||||
@ -1017,7 +1021,7 @@ class ModuleManager {
|
|||||||
|
|
||||||
for (const agentFile of yamlFiles) {
|
for (const agentFile of yamlFiles) {
|
||||||
const agentPath = path.join(sourceAgentsPath, agentFile);
|
const agentPath = path.join(sourceAgentsPath, agentFile);
|
||||||
const agentYaml = yaml.load(await fs.readFile(agentPath, 'utf8'));
|
const agentYaml = yaml.parse(await fs.readFile(agentPath, 'utf8'));
|
||||||
|
|
||||||
// Check if agent has menu items with workflow-install
|
// Check if agent has menu items with workflow-install
|
||||||
const menuItems = agentYaml?.agent?.menu || [];
|
const menuItems = agentYaml?.agent?.menu || [];
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +91,7 @@ class AgentAnalyzer {
|
|||||||
*/
|
*/
|
||||||
async analyzeAgentFile(filePath) {
|
async analyzeAgentFile(filePath) {
|
||||||
const content = await fs.readFile(filePath, 'utf8');
|
const content = await fs.readFile(filePath, 'utf8');
|
||||||
const agentYaml = yaml.load(content);
|
const agentYaml = yaml.parse(content);
|
||||||
return this.analyzeAgentObject(agentYaml);
|
return this.analyzeAgentObject(agentYaml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -313,7 +313,11 @@ async function compileAgent(yamlContent, answers = {}, agentName = '', targetPat
|
|||||||
// Apply customization merges before template processing
|
// Apply customization merges before template processing
|
||||||
// Handle metadata overrides (like name)
|
// Handle metadata overrides (like name)
|
||||||
if (answers.metadata) {
|
if (answers.metadata) {
|
||||||
agentYaml.agent.metadata = { ...agentYaml.agent.metadata, ...answers.metadata };
|
// Filter out empty values from metadata
|
||||||
|
const filteredMetadata = filterCustomizationData(answers.metadata);
|
||||||
|
if (Object.keys(filteredMetadata).length > 0) {
|
||||||
|
agentYaml.agent.metadata = { ...agentYaml.agent.metadata, ...filteredMetadata };
|
||||||
|
}
|
||||||
// Remove from answers so it doesn't get processed as template variables
|
// Remove from answers so it doesn't get processed as template variables
|
||||||
const { metadata, ...templateAnswers } = answers;
|
const { metadata, ...templateAnswers } = answers;
|
||||||
answers = templateAnswers;
|
answers = templateAnswers;
|
||||||
@ -353,6 +357,36 @@ async function compileAgent(yamlContent, answers = {}, agentName = '', targetPat
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter customization data to remove empty/null values
|
||||||
|
* @param {Object} data - Raw customization data
|
||||||
|
* @returns {Object} Filtered customization data
|
||||||
|
*/
|
||||||
|
function filterCustomizationData(data) {
|
||||||
|
const filtered = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(data)) {
|
||||||
|
if (value === null || value === undefined || value === '') {
|
||||||
|
continue; // Skip null/undefined/empty values
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (value.length > 0) {
|
||||||
|
filtered[key] = value;
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
const nested = filterCustomizationData(value);
|
||||||
|
if (Object.keys(nested).length > 0) {
|
||||||
|
filtered[key] = nested;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filtered[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process TTS injection markers in content
|
* Process TTS injection markers in content
|
||||||
* @param {string} content - Content to process
|
* @param {string} content - Content to process
|
||||||
@ -431,4 +465,5 @@ module.exports = {
|
|||||||
buildPersonaXml,
|
buildPersonaXml,
|
||||||
buildPromptsXml,
|
buildPromptsXml,
|
||||||
buildMenuXml,
|
buildMenuXml,
|
||||||
|
filterCustomizationData,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const packageJson = require('../../../package.json');
|
const packageJson = require('../../../package.json');
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const content = await fs.readFile(configPath, 'utf8');
|
const content = await fs.readFile(configPath, 'utf8');
|
||||||
return yaml.load(content);
|
return yaml.parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { getProjectRoot } = require('./project-root');
|
const { getProjectRoot } = require('./project-root');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ class PlatformCodes {
|
|||||||
try {
|
try {
|
||||||
if (fs.existsSync(this.configPath)) {
|
if (fs.existsSync(this.configPath)) {
|
||||||
const content = fs.readFileSync(this.configPath, 'utf8');
|
const content = fs.readFileSync(this.configPath, 'utf8');
|
||||||
this.config = yaml.load(content);
|
this.config = yaml.parse(content);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Platform codes config not found at ${this.configPath}`);
|
console.warn(`Platform codes config not found at ${this.configPath}`);
|
||||||
this.config = { platforms: {} };
|
this.config = { platforms: {} };
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const { execSync } = require('node:child_process');
|
const { execSync } = require('node:child_process');
|
||||||
|
|
||||||
// Dynamic import for ES module
|
// Dynamic import for ES module
|
||||||
@ -57,11 +57,10 @@ async function formatYamlContent(content, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse and re-dump YAML to format it
|
// Parse and re-dump YAML to format it
|
||||||
const parsed = yaml.load(fixedContent);
|
const parsed = yaml.parse(fixedContent);
|
||||||
const formatted = yaml.dump(parsed, {
|
const formatted = yaml.stringify(parsed, {
|
||||||
indent: 2,
|
indent: 2,
|
||||||
lineWidth: -1, // Disable line wrapping
|
lineWidth: 0, // Disable line wrapping
|
||||||
noRefs: true,
|
|
||||||
sortKeys: false, // Preserve key order
|
sortKeys: false, // Preserve key order
|
||||||
});
|
});
|
||||||
// Ensure POSIX-compliant final newline
|
// Ensure POSIX-compliant final newline
|
||||||
@ -96,7 +95,6 @@ async function processMarkdownFile(filePath) {
|
|||||||
const [fullMatch, yamlContent] = match;
|
const [fullMatch, yamlContent] = match;
|
||||||
const formatted = await formatYamlContent(yamlContent, filePath);
|
const formatted = await formatYamlContent(yamlContent, filePath);
|
||||||
if (formatted !== null) {
|
if (formatted !== null) {
|
||||||
// Remove trailing newline that js-yaml adds
|
|
||||||
const trimmedFormatted = formatted.replace(/\n$/, '');
|
const trimmedFormatted = formatted.replace(/\n$/, '');
|
||||||
|
|
||||||
if (trimmedFormatted !== yamlContent) {
|
if (trimmedFormatted !== yamlContent) {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const crypto = require('node:crypto');
|
const crypto = require('node:crypto');
|
||||||
@ -64,13 +64,13 @@ class YamlXmlBuilder {
|
|||||||
async loadAndMergeAgent(agentYamlPath, customizeYamlPath = null) {
|
async loadAndMergeAgent(agentYamlPath, customizeYamlPath = null) {
|
||||||
// Load base agent
|
// Load base agent
|
||||||
const agentContent = await fs.readFile(agentYamlPath, 'utf8');
|
const agentContent = await fs.readFile(agentYamlPath, 'utf8');
|
||||||
const agentYaml = yaml.load(agentContent);
|
const agentYaml = yaml.parse(agentContent);
|
||||||
|
|
||||||
// Load customization if exists
|
// Load customization if exists
|
||||||
let merged = agentYaml;
|
let merged = agentYaml;
|
||||||
if (customizeYamlPath && (await fs.pathExists(customizeYamlPath))) {
|
if (customizeYamlPath && (await fs.pathExists(customizeYamlPath))) {
|
||||||
const customizeContent = await fs.readFile(customizeYamlPath, 'utf8');
|
const customizeContent = await fs.readFile(customizeYamlPath, 'utf8');
|
||||||
const customizeYaml = yaml.load(customizeContent);
|
const customizeYaml = yaml.parse(customizeContent);
|
||||||
|
|
||||||
if (customizeYaml) {
|
if (customizeYaml) {
|
||||||
// Special handling: persona fields are merged, but only non-empty values override
|
// Special handling: persona fields are merged, but only non-empty values override
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { glob } = require('glob');
|
const { glob } = require('glob');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('yaml');
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { validateAgentFile } = require('./schema/agent.js');
|
const { validateAgentFile } = require('./schema/agent.js');
|
||||||
@ -49,7 +49,7 @@ async function main(customProjectRoot) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||||
const agentData = yaml.load(fileContent);
|
const agentData = yaml.parse(fileContent);
|
||||||
|
|
||||||
// Convert absolute path to relative src/ path for module detection
|
// Convert absolute path to relative src/ path for module detection
|
||||||
const srcRelativePath = relativePath.startsWith('src/') ? relativePath : path.relative(project_root, filePath).replaceAll('\\', '/');
|
const srcRelativePath = relativePath.startsWith('src/') ? relativePath : path.relative(project_root, filePath).replaceAll('\\', '/');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user