Compare commits
1 Commits
56c0aa0993
...
44f06c4bbb
| Author | SHA1 | Date |
|---|---|---|
|
|
44f06c4bbb |
|
|
@ -27,21 +27,10 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Determine Node version
|
|
||||||
id: node-version
|
|
||||||
run: |
|
|
||||||
if [ -f .nvmrc ]; then
|
|
||||||
echo "value=$(cat .nvmrc)" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using Node from .nvmrc"
|
|
||||||
else
|
|
||||||
echo "value=24" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using default Node 24 (current LTS)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.node-version.outputs.value }}
|
node-version-file: ".nvmrc"
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -65,21 +54,10 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Determine Node version
|
|
||||||
id: node-version
|
|
||||||
run: |
|
|
||||||
if [ -f .nvmrc ]; then
|
|
||||||
echo "value=$(cat .nvmrc)" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using Node from .nvmrc"
|
|
||||||
else
|
|
||||||
echo "value=22" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using default Node 22 (current LTS)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.node-version.outputs.value }}
|
node-version-file: ".nvmrc"
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
|
||||||
- name: Cache Playwright browsers
|
- name: Cache Playwright browsers
|
||||||
|
|
@ -121,21 +99,10 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Determine Node version
|
|
||||||
id: node-version
|
|
||||||
run: |
|
|
||||||
if [ -f .nvmrc ]; then
|
|
||||||
echo "value=$(cat .nvmrc)" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using Node from .nvmrc"
|
|
||||||
else
|
|
||||||
echo "value=22" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "Using default Node 22 (current LTS)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.node-version.outputs.value }}
|
node-version-file: ".nvmrc"
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
|
||||||
- name: Cache Playwright browsers
|
- name: Cache Playwright browsers
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ variables:
|
||||||
npm_config_cache: "$CI_PROJECT_DIR/.npm"
|
npm_config_cache: "$CI_PROJECT_DIR/.npm"
|
||||||
# Playwright browser cache
|
# Playwright browser cache
|
||||||
PLAYWRIGHT_BROWSERS_PATH: "$CI_PROJECT_DIR/.cache/ms-playwright"
|
PLAYWRIGHT_BROWSERS_PATH: "$CI_PROJECT_DIR/.cache/ms-playwright"
|
||||||
# Default Node version when .nvmrc is missing
|
|
||||||
DEFAULT_NODE_VERSION: "24"
|
|
||||||
|
|
||||||
# Caching configuration
|
# Caching configuration
|
||||||
cache:
|
cache:
|
||||||
|
|
@ -31,32 +29,19 @@ cache:
|
||||||
# Lint stage - Code quality checks
|
# Lint stage - Code quality checks
|
||||||
lint:
|
lint:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: node:$DEFAULT_NODE_VERSION
|
image: node:20
|
||||||
before_script:
|
|
||||||
- |
|
|
||||||
NODE_VERSION=$(cat .nvmrc 2>/dev/null || echo "$DEFAULT_NODE_VERSION")
|
|
||||||
echo "Using Node $NODE_VERSION"
|
|
||||||
npm install -g n
|
|
||||||
n "$NODE_VERSION"
|
|
||||||
node -v
|
|
||||||
- npm ci
|
|
||||||
script:
|
script:
|
||||||
|
- npm ci
|
||||||
- npm run lint
|
- npm run lint
|
||||||
timeout: 5 minutes
|
timeout: 5 minutes
|
||||||
|
|
||||||
# Test stage - Parallel execution with sharding
|
# Test stage - Parallel execution with sharding
|
||||||
.test-template: &test-template
|
.test-template: &test-template
|
||||||
stage: test
|
stage: test
|
||||||
image: node:$DEFAULT_NODE_VERSION
|
image: node:20
|
||||||
needs:
|
needs:
|
||||||
- lint
|
- lint
|
||||||
before_script:
|
before_script:
|
||||||
- |
|
|
||||||
NODE_VERSION=$(cat .nvmrc 2>/dev/null || echo "$DEFAULT_NODE_VERSION")
|
|
||||||
echo "Using Node $NODE_VERSION"
|
|
||||||
npm install -g n
|
|
||||||
n "$NODE_VERSION"
|
|
||||||
node -v
|
|
||||||
- npm ci
|
- npm ci
|
||||||
- npx playwright install --with-deps chromium
|
- npx playwright install --with-deps chromium
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
@ -90,7 +75,7 @@ test:shard-4:
|
||||||
# Burn-in stage - Flaky test detection
|
# Burn-in stage - Flaky test detection
|
||||||
burn-in:
|
burn-in:
|
||||||
stage: burn-in
|
stage: burn-in
|
||||||
image: node:$DEFAULT_NODE_VERSION
|
image: node:20
|
||||||
needs:
|
needs:
|
||||||
- test:shard-1
|
- test:shard-1
|
||||||
- test:shard-2
|
- test:shard-2
|
||||||
|
|
@ -101,12 +86,6 @@ burn-in:
|
||||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||||
before_script:
|
before_script:
|
||||||
- |
|
|
||||||
NODE_VERSION=$(cat .nvmrc 2>/dev/null || echo "$DEFAULT_NODE_VERSION")
|
|
||||||
echo "Using Node $NODE_VERSION"
|
|
||||||
npm install -g n
|
|
||||||
n "$NODE_VERSION"
|
|
||||||
node -v
|
|
||||||
- npm ci
|
- npm ci
|
||||||
- npx playwright install --with-deps chromium
|
- npx playwright install --with-deps chromium
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ Scaffolds a production-ready CI/CD quality pipeline with test execution, burn-in
|
||||||
- Ask user if unable to auto-detect
|
- Ask user if unable to auto-detect
|
||||||
|
|
||||||
5. **Read Environment Configuration**
|
5. **Read Environment Configuration**
|
||||||
- Use `.nvmrc` for Node version if present
|
- Check for `.nvmrc` to determine Node version
|
||||||
- If missing, default to a current LTS (Node 24) or newer instead of a fixed old version
|
- Default to Node 20 LTS if not found
|
||||||
- Read `package.json` to identify dependencies (affects caching strategy)
|
- Read `package.json` to identify dependencies (affects caching strategy)
|
||||||
|
|
||||||
**Halt Condition:** If preflight checks fail, stop immediately and report which requirement failed.
|
**Halt Condition:** If preflight checks fail, stop immediately and report which requirement failed.
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ class Installer {
|
||||||
this.configCollector = new ConfigCollector();
|
this.configCollector = new ConfigCollector();
|
||||||
this.ideConfigManager = new IdeConfigManager();
|
this.ideConfigManager = new IdeConfigManager();
|
||||||
this.installedFiles = []; // Track all installed files
|
this.installedFiles = []; // Track all installed files
|
||||||
this.ttsInjectedFiles = []; // Track files with TTS injection applied
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -147,8 +146,8 @@ class Installer {
|
||||||
content = content.replaceAll('{*bmad_folder*}', '{bmad_folder}');
|
content = content.replaceAll('{*bmad_folder*}', '{bmad_folder}');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process AgentVibes injection points (pass targetPath for tracking)
|
// Process AgentVibes injection points
|
||||||
content = this.processTTSInjectionPoints(content, targetPath);
|
content = this.processTTSInjectionPoints(content);
|
||||||
|
|
||||||
// Write to target with replaced content
|
// Write to target with replaced content
|
||||||
await fs.ensureDir(path.dirname(targetPath));
|
await fs.ensureDir(path.dirname(targetPath));
|
||||||
|
|
@ -227,14 +226,10 @@ class Installer {
|
||||||
* - src/modules/bmm/agents/*.md (rules sections)
|
* - src/modules/bmm/agents/*.md (rules sections)
|
||||||
* - TTS Hook: .claude/hooks/bmad-speak.sh (in AgentVibes repo)
|
* - TTS Hook: .claude/hooks/bmad-speak.sh (in AgentVibes repo)
|
||||||
*/
|
*/
|
||||||
processTTSInjectionPoints(content, targetPath = null) {
|
processTTSInjectionPoints(content) {
|
||||||
// Check if AgentVibes is enabled (set during installation configuration)
|
// Check if AgentVibes is enabled (set during installation configuration)
|
||||||
const enableAgentVibes = this.enableAgentVibes || false;
|
const enableAgentVibes = this.enableAgentVibes || false;
|
||||||
|
|
||||||
// Check if content contains any TTS injection markers
|
|
||||||
const hasPartyMode = content.includes('<!-- TTS_INJECTION:party-mode -->');
|
|
||||||
const hasAgentTTS = content.includes('<!-- TTS_INJECTION:agent-tts -->');
|
|
||||||
|
|
||||||
if (enableAgentVibes) {
|
if (enableAgentVibes) {
|
||||||
// Replace party-mode injection marker with actual TTS call
|
// Replace party-mode injection marker with actual TTS call
|
||||||
// Use single quotes to prevent shell expansion of special chars like !
|
// Use single quotes to prevent shell expansion of special chars like !
|
||||||
|
|
@ -258,12 +253,6 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||||
IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
|
IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
|
||||||
Run in background (&) to avoid blocking`,
|
Run in background (&) to avoid blocking`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Track files that had TTS injection applied
|
|
||||||
if (targetPath && (hasPartyMode || hasAgentTTS)) {
|
|
||||||
const injectionType = hasPartyMode ? 'party-mode' : 'agent-tts';
|
|
||||||
this.ttsInjectedFiles.push({ path: targetPath, type: injectionType });
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Strip injection markers cleanly when AgentVibes is disabled
|
// Strip injection markers cleanly when AgentVibes is disabled
|
||||||
content = content.replaceAll(/<!-- TTS_INJECTION:party-mode -->\n?/g, '');
|
content = content.replaceAll(/<!-- TTS_INJECTION:party-mode -->\n?/g, '');
|
||||||
|
|
@ -1032,8 +1021,6 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||||
modules: config.modules,
|
modules: config.modules,
|
||||||
ides: config.ides,
|
ides: config.ides,
|
||||||
customFiles: customFiles.length > 0 ? customFiles : undefined,
|
customFiles: customFiles.length > 0 ? customFiles : undefined,
|
||||||
ttsInjectedFiles: this.enableAgentVibes && this.ttsInjectedFiles.length > 0 ? this.ttsInjectedFiles : undefined,
|
|
||||||
agentVibesEnabled: this.enableAgentVibes || false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Offer cleanup for legacy files (only for updates, not fresh installs, and only if not skipped)
|
// Offer cleanup for legacy files (only for updates, not fresh installs, and only if not skipped)
|
||||||
|
|
@ -1539,16 +1526,13 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||||
|
|
||||||
// Build YAML + customize to .md
|
// Build YAML + customize to .md
|
||||||
const customizeExists = await fs.pathExists(customizePath);
|
const customizeExists = await fs.pathExists(customizePath);
|
||||||
let xmlContent = await this.xmlHandler.buildFromYaml(yamlPath, customizeExists ? customizePath : null, {
|
const xmlContent = await this.xmlHandler.buildFromYaml(yamlPath, customizeExists ? customizePath : null, {
|
||||||
includeMetadata: true,
|
includeMetadata: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
||||||
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
||||||
|
|
||||||
// Process TTS injection points (pass targetPath for tracking)
|
|
||||||
xmlContent = this.processTTSInjectionPoints(xmlContent, mdPath);
|
|
||||||
|
|
||||||
// Write the built .md file to bmad/{module}/agents/ with POSIX-compliant final newline
|
// Write the built .md file to bmad/{module}/agents/ with POSIX-compliant final newline
|
||||||
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
||||||
await fs.writeFile(mdPath, content, 'utf8');
|
await fs.writeFile(mdPath, content, 'utf8');
|
||||||
|
|
@ -1644,16 +1628,13 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build YAML to XML .md
|
// Build YAML to XML .md
|
||||||
let xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
const xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
||||||
includeMetadata: true,
|
includeMetadata: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
||||||
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
||||||
|
|
||||||
// Process TTS injection points (pass targetPath for tracking)
|
|
||||||
xmlContent = this.processTTSInjectionPoints(xmlContent, targetMdPath);
|
|
||||||
|
|
||||||
// Write the built .md file with POSIX-compliant final newline
|
// Write the built .md file with POSIX-compliant final newline
|
||||||
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
||||||
await fs.writeFile(targetMdPath, content, 'utf8');
|
await fs.writeFile(targetMdPath, content, 'utf8');
|
||||||
|
|
@ -1741,16 +1722,13 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build YAML + customize to .md
|
// Build YAML + customize to .md
|
||||||
let xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
const xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
||||||
includeMetadata: true,
|
includeMetadata: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
||||||
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
||||||
|
|
||||||
// Process TTS injection points (pass targetPath for tracking)
|
|
||||||
xmlContent = this.processTTSInjectionPoints(xmlContent, targetMdPath);
|
|
||||||
|
|
||||||
// Write the rebuilt .md file with POSIX-compliant final newline
|
// Write the rebuilt .md file with POSIX-compliant final newline
|
||||||
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
||||||
await fs.writeFile(targetMdPath, content, 'utf8');
|
await fs.writeFile(targetMdPath, content, 'utf8');
|
||||||
|
|
|
||||||
|
|
@ -482,39 +482,10 @@ function compileAgent(yamlContent, answers = {}, agentName = '', targetPath = ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Process TTS injection markers in content
|
|
||||||
* @param {string} content - Content to process
|
|
||||||
* @param {boolean} enableAgentVibes - Whether AgentVibes is enabled
|
|
||||||
* @returns {Object} { content: string, hadInjection: boolean }
|
|
||||||
*/
|
|
||||||
function processTTSInjectionPoints(content, enableAgentVibes) {
|
|
||||||
const hasAgentTTS = content.includes('<!-- TTS_INJECTION:agent-tts -->');
|
|
||||||
|
|
||||||
if (enableAgentVibes && hasAgentTTS) {
|
|
||||||
// Replace agent-tts injection marker with TTS rule
|
|
||||||
content = content.replaceAll(
|
|
||||||
'<!-- TTS_INJECTION:agent-tts -->',
|
|
||||||
`- When responding to user messages, speak your responses using TTS:
|
|
||||||
Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response
|
|
||||||
Replace {agent-id} with YOUR agent ID from <agent id="..."> tag at top of this file
|
|
||||||
Replace {response-text} with the text you just output to the user
|
|
||||||
IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
|
|
||||||
Run in background (&) to avoid blocking`,
|
|
||||||
);
|
|
||||||
return { content, hadInjection: true };
|
|
||||||
} else if (!enableAgentVibes && hasAgentTTS) {
|
|
||||||
// Strip injection markers when disabled
|
|
||||||
content = content.replaceAll(/<!-- TTS_INJECTION:agent-tts -->\n?/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return { content, hadInjection: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile agent file to .md
|
* Compile agent file to .md
|
||||||
* @param {string} yamlPath - Path to agent YAML file
|
* @param {string} yamlPath - Path to agent YAML file
|
||||||
* @param {Object} options - { answers: {}, outputPath: string, enableAgentVibes: boolean }
|
* @param {Object} options - { answers: {}, outputPath: string }
|
||||||
* @returns {Object} Compilation result
|
* @returns {Object} Compilation result
|
||||||
*/
|
*/
|
||||||
function compileAgentFile(yamlPath, options = {}) {
|
function compileAgentFile(yamlPath, options = {}) {
|
||||||
|
|
@ -530,24 +501,13 @@ function compileAgentFile(yamlPath, options = {}) {
|
||||||
outputPath = path.join(dir, `${basename}.md`);
|
outputPath = path.join(dir, `${basename}.md`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process TTS injection points if enableAgentVibes option is provided
|
|
||||||
let xml = result.xml;
|
|
||||||
let ttsInjected = false;
|
|
||||||
if (options.enableAgentVibes !== undefined) {
|
|
||||||
const ttsResult = processTTSInjectionPoints(xml, options.enableAgentVibes);
|
|
||||||
xml = ttsResult.content;
|
|
||||||
ttsInjected = ttsResult.hadInjection;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write compiled XML
|
// Write compiled XML
|
||||||
fs.writeFileSync(outputPath, xml, 'utf8');
|
fs.writeFileSync(outputPath, result.xml, 'utf8');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
xml,
|
|
||||||
outputPath,
|
outputPath,
|
||||||
sourcePath: yamlPath,
|
sourcePath: yamlPath,
|
||||||
ttsInjected,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -363,60 +363,11 @@ class UI {
|
||||||
`🔧 Tools Configured: ${result.ides?.length > 0 ? result.ides.join(', ') : 'none'}`,
|
`🔧 Tools Configured: ${result.ides?.length > 0 ? result.ides.join(', ') : 'none'}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add AgentVibes TTS info if enabled
|
|
||||||
if (result.agentVibesEnabled) {
|
|
||||||
summary.push(`🎤 AgentVibes TTS: Enabled`);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLIUtils.displayBox(summary.join('\n\n'), {
|
CLIUtils.displayBox(summary.join('\n\n'), {
|
||||||
borderColor: 'green',
|
borderColor: 'green',
|
||||||
borderStyle: 'round',
|
borderStyle: 'round',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Display TTS injection details if present
|
|
||||||
if (result.ttsInjectedFiles && result.ttsInjectedFiles.length > 0) {
|
|
||||||
console.log('\n' + chalk.cyan.bold('═══════════════════════════════════════════════════'));
|
|
||||||
console.log(chalk.cyan.bold(' AgentVibes TTS Injection Summary'));
|
|
||||||
console.log(chalk.cyan.bold('═══════════════════════════════════════════════════\n'));
|
|
||||||
|
|
||||||
// Explain what TTS injection is
|
|
||||||
console.log(chalk.white.bold('What is TTS Injection?\n'));
|
|
||||||
console.log(chalk.dim(' TTS (Text-to-Speech) injection adds voice instructions to BMAD agents,'));
|
|
||||||
console.log(chalk.dim(' enabling them to speak their responses aloud using AgentVibes.\n'));
|
|
||||||
console.log(chalk.dim(' Example: When you activate the PM agent, it will greet you with'));
|
|
||||||
console.log(chalk.dim(' spoken audio like "Hey! I\'m your Project Manager. How can I help?"\n'));
|
|
||||||
|
|
||||||
console.log(chalk.green(`✅ TTS injection applied to ${result.ttsInjectedFiles.length} file(s):\n`));
|
|
||||||
|
|
||||||
// Group by type
|
|
||||||
const partyModeFiles = result.ttsInjectedFiles.filter((f) => f.type === 'party-mode');
|
|
||||||
const agentTTSFiles = result.ttsInjectedFiles.filter((f) => f.type === 'agent-tts');
|
|
||||||
|
|
||||||
if (partyModeFiles.length > 0) {
|
|
||||||
console.log(chalk.yellow(' Party Mode (multi-agent conversations):'));
|
|
||||||
for (const file of partyModeFiles) {
|
|
||||||
console.log(chalk.dim(` • ${file.path}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (agentTTSFiles.length > 0) {
|
|
||||||
console.log(chalk.yellow(' Agent TTS (individual agent voices):'));
|
|
||||||
for (const file of agentTTSFiles) {
|
|
||||||
console.log(chalk.dim(` • ${file.path}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show backup info and restore command
|
|
||||||
console.log('\n' + chalk.white.bold('Backups & Recovery:\n'));
|
|
||||||
console.log(chalk.dim(' Pre-injection backups are stored in:'));
|
|
||||||
console.log(chalk.cyan(' ~/.bmad-tts-backups/\n'));
|
|
||||||
console.log(chalk.dim(' To restore original files (removes TTS instructions):'));
|
|
||||||
console.log(chalk.cyan(` bmad-tts-injector.sh --restore ${result.path}\n`));
|
|
||||||
|
|
||||||
console.log(chalk.cyan('💡 BMAD agents will now speak when activated!'));
|
|
||||||
console.log(chalk.dim(' Ensure AgentVibes is installed: https://agentvibes.org'));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\n' + chalk.green.bold('✨ BMAD is ready to use!'));
|
console.log('\n' + chalk.green.bold('✨ BMAD is ready to use!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue