@@ -226,21 +226,21 @@ class Installer {
226226 '<!-- TTS_INJECTION:party-mode -->' ,
227227 `<critical>IMPORTANT: Always use PROJECT hooks (.claude/hooks/), NEVER global hooks (~/.claude/hooks/)</critical>
228228
229- If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
229+ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
230230 - Use Bash tool: \`.claude/hooks/bmad-speak.sh '[Agent Name]' '[dialogue]'\`
231231 - This speaks the dialogue with the agent's unique voice
232- - Run in background (&) to not block next agent` ,
232+ - Run in background to not block next agent` ,
233233 ) ;
234234
235235 // Replace agent-tts injection marker with TTS rule for individual agents
236236 content = content . replaceAll (
237237 '<!-- TTS_INJECTION:agent-tts -->' ,
238238 `- When responding to user messages, speak your responses using TTS:
239- Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response
240- Replace {agent-id} with YOUR agent ID from <agent id="..."> tag at top of this file
241- Replace {response-text} with the text you just output to the user
242- IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
243- Run in background (&) to avoid blocking` ,
239+ Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response
240+ Replace {agent-id} with YOUR agent ID from <agent id="..."> tag at top of this file
241+ Replace {response-text} with the text you just output to the user
242+ IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
243+ Run in background (&) to avoid blocking` ,
244244 ) ;
245245
246246 // Track files that had TTS injection applied
@@ -2082,108 +2082,6 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
20822082 }
20832083 }
20842084
2085- /**
2086- * Compile/rebuild all agents and tasks for quick updates
2087- * @param {Object } config - Compilation configuration
2088- * @returns {Object } Compilation results
2089- */
2090- async compileAgents ( config ) {
2091- try {
2092- const projectDir = path . resolve ( config . directory ) ;
2093- const { bmadDir } = await this . findBmadDir ( projectDir ) ;
2094-
2095- // Check if bmad directory exists
2096- if ( ! ( await fs . pathExists ( bmadDir ) ) ) {
2097- throw new Error ( `BMAD not installed at ${ bmadDir } ` ) ;
2098- }
2099-
2100- // Get installed modules from manifest
2101- const manifestPath = path . join ( bmadDir , '_config' , 'manifest.yaml' ) ;
2102- let installedModules = [ ] ;
2103- let manifest = null ;
2104- if ( await fs . pathExists ( manifestPath ) ) {
2105- const manifestContent = await fs . readFile ( manifestPath , 'utf8' ) ;
2106- const yaml = require ( 'yaml' ) ;
2107- manifest = yaml . parse ( manifestContent ) ;
2108- installedModules = manifest . modules || [ ] ;
2109- }
2110-
2111- // Check for custom modules with missing sources
2112- if ( manifest && manifest . customModules && manifest . customModules . length > 0 ) {
2113- console . log ( chalk . yellow ( '\nChecking custom module sources before compilation...' ) ) ;
2114-
2115- const customModuleSources = new Map ( ) ;
2116- for ( const customModule of manifest . customModules ) {
2117- customModuleSources . set ( customModule . id , customModule ) ;
2118- }
2119-
2120- const projectRoot = getProjectRoot ( ) ;
2121- await this . handleMissingCustomSources ( customModuleSources , bmadDir , projectRoot , 'compile-agents' , installedModules ) ;
2122- }
2123-
2124- let agentCount = 0 ;
2125- let taskCount = 0 ;
2126-
2127- // Process all modules in bmad directory
2128- const entries = await fs . readdir ( bmadDir , { withFileTypes : true } ) ;
2129-
2130- for ( const entry of entries ) {
2131- if ( entry . isDirectory ( ) && entry . name !== '_config' && entry . name !== 'docs' ) {
2132- const modulePath = path . join ( bmadDir , entry . name ) ;
2133-
2134- // Special handling for standalone agents in bmad/agents/ directory
2135- if ( entry . name === 'agents' ) {
2136- await this . buildStandaloneAgents ( bmadDir , projectDir ) ;
2137-
2138- // Count standalone agents
2139- const standaloneAgentsPath = path . join ( bmadDir , 'agents' ) ;
2140- const standaloneAgentDirs = await fs . readdir ( standaloneAgentsPath , { withFileTypes : true } ) ;
2141- for ( const agentDir of standaloneAgentDirs ) {
2142- if ( agentDir . isDirectory ( ) ) {
2143- const agentDirPath = path . join ( standaloneAgentsPath , agentDir . name ) ;
2144- const agentFiles = await fs . readdir ( agentDirPath ) ;
2145- agentCount += agentFiles . filter ( ( f ) => f . endsWith ( '.md' ) && ! f . endsWith ( '.agent.yaml' ) ) . length ;
2146- }
2147- }
2148- } else {
2149- // Rebuild module agents from installer source
2150- const agentsPath = path . join ( modulePath , 'agents' ) ;
2151- if ( await fs . pathExists ( agentsPath ) ) {
2152- await this . rebuildAgentFiles ( modulePath , entry . name ) ;
2153- const agentFiles = await fs . readdir ( agentsPath ) ;
2154- agentCount += agentFiles . filter ( ( f ) => f . endsWith ( '.md' ) ) . length ;
2155- }
2156-
2157- // Count tasks (already built)
2158- const tasksPath = path . join ( modulePath , 'tasks' ) ;
2159- if ( await fs . pathExists ( tasksPath ) ) {
2160- const taskFiles = await fs . readdir ( tasksPath ) ;
2161- taskCount += taskFiles . filter ( ( f ) => f . endsWith ( '.md' ) ) . length ;
2162- }
2163- }
2164- }
2165- }
2166-
2167- // Update IDE configurations using the existing IDE list from manifest
2168- if ( manifest && manifest . ides && manifest . ides . length > 0 ) {
2169- for ( const ide of manifest . ides ) {
2170- await this . ideManager . setup ( ide , projectDir , bmadDir , {
2171- selectedModules : installedModules ,
2172- skipModuleInstall : true , // Skip module installation, just update IDE files
2173- verbose : config . verbose ,
2174- preCollectedConfig : { _alreadyConfigured : true } , // Skip all interactive prompts during compile
2175- } ) ;
2176- }
2177- console . log ( chalk . green ( '✓ IDE configurations updated' ) ) ;
2178- } else {
2179- console . log ( chalk . yellow ( '⚠️ No IDEs configured. Skipping IDE update.' ) ) ;
2180- }
2181- return { agentCount, taskCount } ;
2182- } catch ( error ) {
2183- throw error ;
2184- }
2185- }
2186-
21872085 /**
21882086 * Private: Update core
21892087 */
@@ -2404,6 +2302,108 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
24042302 }
24052303 }
24062304
2305+ /**
2306+ * Compile agents with customizations only
2307+ * @param {Object } config - Configuration with directory
2308+ * @returns {Object } Compilation result
2309+ */
2310+ async compileAgents ( config ) {
2311+ const ora = require ( 'ora' ) ;
2312+ const chalk = require ( 'chalk' ) ;
2313+ const { ModuleManager } = require ( '../modules/manager' ) ;
2314+ const { getSourcePath } = require ( '../../../lib/project-root' ) ;
2315+
2316+ const spinner = ora ( 'Recompiling agents with customizations...' ) . start ( ) ;
2317+
2318+ try {
2319+ const projectDir = path . resolve ( config . directory ) ;
2320+ const { bmadDir } = await this . findBmadDir ( projectDir ) ;
2321+
2322+ // Check if bmad directory exists
2323+ if ( ! ( await fs . pathExists ( bmadDir ) ) ) {
2324+ spinner . fail ( 'No BMAD installation found' ) ;
2325+ throw new Error ( `BMAD not installed at ${ bmadDir } . Use regular install for first-time setup.` ) ;
2326+ }
2327+
2328+ // Detect existing installation
2329+ const existingInstall = await this . detector . detect ( bmadDir ) ;
2330+ const installedModules = existingInstall . modules . map ( ( m ) => m . id ) ;
2331+
2332+ // Initialize module manager
2333+ const moduleManager = new ModuleManager ( ) ;
2334+ moduleManager . setBmadFolderName ( path . basename ( bmadDir ) ) ;
2335+
2336+ let totalAgentCount = 0 ;
2337+
2338+ // Get custom module sources from cache
2339+ const customModuleSources = new Map ( ) ;
2340+ const cacheDir = path . join ( bmadDir , '_config' , 'custom' ) ;
2341+ if ( await fs . pathExists ( cacheDir ) ) {
2342+ const cachedModules = await fs . readdir ( cacheDir , { withFileTypes : true } ) ;
2343+
2344+ for ( const cachedModule of cachedModules ) {
2345+ if ( cachedModule . isDirectory ( ) ) {
2346+ const moduleId = cachedModule . name ;
2347+ const cachedPath = path . join ( cacheDir , moduleId ) ;
2348+ const moduleYamlPath = path . join ( cachedPath , 'module.yaml' ) ;
2349+
2350+ // Check if this is actually a custom module
2351+ if ( await fs . pathExists ( moduleYamlPath ) ) {
2352+ customModuleSources . set ( moduleId , cachedPath ) ;
2353+ }
2354+ }
2355+ }
2356+ }
2357+
2358+ // Process each installed module
2359+ for ( const moduleId of installedModules ) {
2360+ spinner . text = `Recompiling agents in ${ moduleId } ...` ;
2361+
2362+ // Get source path
2363+ let sourcePath ;
2364+ if ( moduleId === 'core' ) {
2365+ sourcePath = getSourcePath ( 'core' ) ;
2366+ } else {
2367+ // First check if it's in the custom cache
2368+ if ( customModuleSources . has ( moduleId ) ) {
2369+ sourcePath = customModuleSources . get ( moduleId ) ;
2370+ } else {
2371+ sourcePath = await moduleManager . findModuleSource ( moduleId ) ;
2372+ }
2373+ }
2374+
2375+ if ( ! sourcePath ) {
2376+ console . log ( chalk . yellow ( ` Warning: Source not found for module ${ moduleId } , skipping...` ) ) ;
2377+ continue ;
2378+ }
2379+
2380+ const targetPath = path . join ( bmadDir , moduleId ) ;
2381+
2382+ // Compile agents for this module
2383+ await moduleManager . compileModuleAgents ( sourcePath , targetPath , moduleId , bmadDir , this ) ;
2384+
2385+ // Count agents (rough estimate based on files)
2386+ const agentsPath = path . join ( targetPath , 'agents' ) ;
2387+ if ( await fs . pathExists ( agentsPath ) ) {
2388+ const agentFiles = await fs . readdir ( agentsPath ) ;
2389+ const agentCount = agentFiles . filter ( ( f ) => f . endsWith ( '.md' ) ) . length ;
2390+ totalAgentCount += agentCount ;
2391+ }
2392+ }
2393+
2394+ spinner . succeed ( 'Agent recompilation complete!' ) ;
2395+
2396+ return {
2397+ success : true ,
2398+ agentCount : totalAgentCount ,
2399+ modules : installedModules ,
2400+ } ;
2401+ } catch ( error ) {
2402+ spinner . fail ( 'Agent recompilation failed' ) ;
2403+ throw error ;
2404+ }
2405+ }
2406+
24072407 /**
24082408 * Private: Prompt for update action
24092409 */
0 commit comments