2025-09-28 23:17:07 -05:00
const path = require ( 'node:path' ) ;
const { BaseIdeSetup } = require ( './_base-ide' ) ;
const chalk = require ( 'chalk' ) ;
2025-11-09 20:24:56 -06:00
const { AgentCommandGenerator } = require ( './shared/agent-command-generator' ) ;
2025-09-28 23:17:07 -05:00
/ * *
* KiloCode IDE setup handler
* Creates custom modes in . kilocodemodes file ( similar to Roo )
* /
class KiloSetup extends BaseIdeSetup {
constructor ( ) {
super ( 'kilo' , 'Kilo Code' ) ;
this . configFile = '.kilocodemodes' ;
}
/ * *
* Setup KiloCode IDE configuration
* @ param { string } projectDir - Project directory
* @ param { string } bmadDir - BMAD installation directory
* @ param { Object } options - Setup options
* /
async setup ( projectDir , bmadDir , options = { } ) {
console . log ( chalk . cyan ( ` Setting up ${ this . name } ... ` ) ) ;
// Check for existing .kilocodemodes file
const kiloModesPath = path . join ( projectDir , this . configFile ) ;
let existingModes = [ ] ;
let existingContent = '' ;
if ( await this . pathExists ( kiloModesPath ) ) {
existingContent = await this . readFile ( kiloModesPath ) ;
// Parse existing modes
const modeMatches = existingContent . matchAll ( /- slug: ([\w-]+)/g ) ;
for ( const match of modeMatches ) {
existingModes . push ( match [ 1 ] ) ;
}
console . log ( chalk . yellow ( ` Found existing .kilocodemodes file with ${ existingModes . length } modes ` ) ) ;
}
2025-11-09 20:24:56 -06:00
// Generate agent launchers
const agentGen = new AgentCommandGenerator ( this . bmadFolderName ) ;
const { artifacts : agentArtifacts } = await agentGen . collectAgentArtifacts ( bmadDir , options . selectedModules || [ ] ) ;
2025-09-28 23:17:07 -05:00
// Create modes content
let newModesContent = '' ;
let addedCount = 0 ;
let skippedCount = 0 ;
2025-11-09 20:24:56 -06:00
for ( const artifact of agentArtifacts ) {
const slug = ` bmad- ${ artifact . module } - ${ artifact . name } ` ;
2025-09-28 23:17:07 -05:00
// Skip if already exists
if ( existingModes . includes ( slug ) ) {
console . log ( chalk . dim ( ` Skipping ${ slug } - already exists ` ) ) ;
skippedCount ++ ;
continue ;
}
2025-11-09 20:24:56 -06:00
const modeEntry = await this . createModeEntry ( artifact , projectDir ) ;
2025-09-28 23:17:07 -05:00
newModesContent += modeEntry ;
addedCount ++ ;
}
// Build final content
let finalContent = '' ;
if ( existingContent ) {
finalContent = existingContent . trim ( ) + '\n' + newModesContent ;
} else {
finalContent = 'customModes:\n' + newModesContent ;
}
// Write .kilocodemodes file
await this . writeFile ( kiloModesPath , finalContent ) ;
console . log ( chalk . green ( ` ✓ ${ this . name } configured: ` ) ) ;
console . log ( chalk . dim ( ` - ${ addedCount } modes added ` ) ) ;
if ( skippedCount > 0 ) {
console . log ( chalk . dim ( ` - ${ skippedCount } modes skipped (already exist) ` ) ) ;
}
console . log ( chalk . dim ( ` - Configuration file: ${ this . configFile } ` ) ) ;
console . log ( chalk . dim ( '\n Modes will be available when you open this project in KiloCode' ) ) ;
return {
success : true ,
modes : addedCount ,
skipped : skippedCount ,
} ;
}
/ * *
* Create a mode entry for an agent
* /
2025-11-09 20:24:56 -06:00
async createModeEntry ( artifact , projectDir ) {
// Extract metadata from launcher content
const titleMatch = artifact . content . match ( /title="([^"]+)"/ ) ;
const title = titleMatch ? titleMatch [ 1 ] : this . formatTitle ( artifact . name ) ;
2025-09-28 23:17:07 -05:00
2025-11-09 20:24:56 -06:00
const iconMatch = artifact . content . match ( /icon="([^"]+)"/ ) ;
2025-09-28 23:17:07 -05:00
const icon = iconMatch ? iconMatch [ 1 ] : '🤖' ;
2025-11-09 20:24:56 -06:00
const whenToUseMatch = artifact . content . match ( /whenToUse="([^"]+)"/ ) ;
2025-09-28 23:17:07 -05:00
const whenToUse = whenToUseMatch ? whenToUseMatch [ 1 ] : ` Use for ${ title } tasks ` ;
Major Enhancements:
- Installation path is now fully configurable, allowing users to specify custom installation directories during setup
- Default installation location changed to .bmad (hidden directory) for cleaner project root organization
Web Bundle Improvements:
- All web bundles (single agent and team) now include party mode support for multi-agent collaboration!
- Advanced elicitation capabilities integrated into standalone agents
- All bundles enhanced with party mode agent manifests
- Added default-party.csv files to bmm, bmgd, and cis module teams
- The default party file is what will be used with single agent bundles. teams can customize for different party configurations before web bundling through a setting in the team yaml file
- New web bundle outputs for all agents (analyst, architect, dev, pm, sm, tea, tech-writer, ux-designer, game-*, creative-squad)
Phase 4 Workflow Updates (In Progress):
- Initiated shift to separate phase 4 implementation artifacts from documentation
- Phase 4 implementation artifacts (stories, code review, sprint plan, context files) will move to dedicated location outside docs folder
- Installer questions and configuration added for artifact path selection
- Updated workflow.yaml files for code-review, sprint-planning, story-context, epic-tech-context, and retrospective workflows to support this, but still might require some udpates
Additional Changes:
- New agent and action command header models for standardization
- Enhanced web-bundle-activation-steps fragment
- Updated web-bundler.js to support new structure
- VS Code settings updated for new .bmad directory
- Party mode instructions and workflow enhanced for better orchestration
IDE Installer Updates:
- Show version number of installer in cli
- improved Installer UX
- Gemini TOML Improved to have clear loading instructions with @ commands
- All tools agent launcher mds improved to use a central file template critical indication isntead of hardcoding in 2 different locations.
2025-11-09 17:39:05 -06:00
// Get the activation header from central template
const activationHeader = await this . getAgentCommandHeader ( ) ;
2025-11-09 20:24:56 -06:00
const roleDefinitionMatch = artifact . content . match ( /roleDefinition="([^"]+)"/ ) ;
2025-09-28 23:17:07 -05:00
const roleDefinition = roleDefinitionMatch
? roleDefinitionMatch [ 1 ]
: ` You are a ${ title } specializing in ${ title . toLowerCase ( ) } tasks. ` ;
// Get relative path
2025-11-09 20:24:56 -06:00
const relativePath = path . relative ( projectDir , artifact . sourcePath ) . replaceAll ( '\\' , '/' ) ;
2025-09-28 23:17:07 -05:00
// Build mode entry (KiloCode uses same schema as Roo)
2025-11-09 20:24:56 -06:00
const slug = ` bmad- ${ artifact . module } - ${ artifact . name } ` ;
2025-09-28 23:17:07 -05:00
let modeEntry = ` - slug: ${ slug } \n ` ;
modeEntry += ` name: ' ${ icon } ${ title } ' \n ` ;
modeEntry += ` roleDefinition: ${ roleDefinition } \n ` ;
modeEntry += ` whenToUse: ${ whenToUse } \n ` ;
Major Enhancements:
- Installation path is now fully configurable, allowing users to specify custom installation directories during setup
- Default installation location changed to .bmad (hidden directory) for cleaner project root organization
Web Bundle Improvements:
- All web bundles (single agent and team) now include party mode support for multi-agent collaboration!
- Advanced elicitation capabilities integrated into standalone agents
- All bundles enhanced with party mode agent manifests
- Added default-party.csv files to bmm, bmgd, and cis module teams
- The default party file is what will be used with single agent bundles. teams can customize for different party configurations before web bundling through a setting in the team yaml file
- New web bundle outputs for all agents (analyst, architect, dev, pm, sm, tea, tech-writer, ux-designer, game-*, creative-squad)
Phase 4 Workflow Updates (In Progress):
- Initiated shift to separate phase 4 implementation artifacts from documentation
- Phase 4 implementation artifacts (stories, code review, sprint plan, context files) will move to dedicated location outside docs folder
- Installer questions and configuration added for artifact path selection
- Updated workflow.yaml files for code-review, sprint-planning, story-context, epic-tech-context, and retrospective workflows to support this, but still might require some udpates
Additional Changes:
- New agent and action command header models for standardization
- Enhanced web-bundle-activation-steps fragment
- Updated web-bundler.js to support new structure
- VS Code settings updated for new .bmad directory
- Party mode instructions and workflow enhanced for better orchestration
IDE Installer Updates:
- Show version number of installer in cli
- improved Installer UX
- Gemini TOML Improved to have clear loading instructions with @ commands
- All tools agent launcher mds improved to use a central file template critical indication isntead of hardcoding in 2 different locations.
2025-11-09 17:39:05 -06:00
modeEntry += ` customInstructions: ${ activationHeader } Read the full YAML from ${ relativePath } start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode \n ` ;
2025-09-28 23:17:07 -05:00
modeEntry += ` groups: \n ` ;
modeEntry += ` - read \n ` ;
modeEntry += ` - edit \n ` ;
return modeEntry ;
}
/ * *
* Format name as title
* /
formatTitle ( name ) {
return name
. split ( '-' )
. map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) )
. join ( ' ' ) ;
}
/ * *
* Cleanup KiloCode configuration
* /
async cleanup ( projectDir ) {
const fs = require ( 'fs-extra' ) ;
const kiloModesPath = path . join ( projectDir , this . configFile ) ;
if ( await fs . pathExists ( kiloModesPath ) ) {
const content = await fs . readFile ( kiloModesPath , 'utf8' ) ;
// Remove BMAD modes only
const lines = content . split ( '\n' ) ;
const filteredLines = [ ] ;
let skipMode = false ;
let removedCount = 0 ;
for ( const line of lines ) {
if ( /^\s*- slug: bmad-/ . test ( line ) ) {
skipMode = true ;
removedCount ++ ;
} else if ( skipMode && /^\s*- slug: / . test ( line ) ) {
skipMode = false ;
}
if ( ! skipMode ) {
filteredLines . push ( line ) ;
}
}
await fs . writeFile ( kiloModesPath , filteredLines . join ( '\n' ) ) ;
console . log ( chalk . dim ( ` Removed ${ removedCount } BMAD modes from .kilocodemodes ` ) ) ;
}
}
}
module . exports = { KiloSetup } ;