ai-sprint
Version:
AI-powered sprint management and SDLC tracking with automatic IDE integration
605 lines (525 loc) ⢠19.3 kB
JavaScript
import { promises as fs } from 'fs';
import path from 'path';
import { IDEDetector } from './ide-detector.js';
import { simpleGit } from 'simple-git';
export class Configurator {
detector;
git = simpleGit();
constructor(projectPath = process.cwd()) {
this.detector = new IDEDetector(projectPath);
}
/**
* Auto-configure AI Sprint for the current environment
*/
async setup(options = {}) {
console.log('š Detecting IDE environment...');
// Detect all available IDEs
const detectedIDEs = await this.detector.detectAll();
if (detectedIDEs.length === 0) {
console.log('ā ļø No supported IDE detected. Using generic MCP configuration.');
const genericIDE = await this.detector.detect();
detectedIDEs.push(genericIDE);
}
console.log(`ā
Detected ${detectedIDEs.length} IDE(s): ${detectedIDEs.map(ide => ide.name).join(', ')}`);
// Get project information
const projectInfo = await this.getProjectInfo(options);
// Configure each detected IDE
for (const ide of detectedIDEs) {
console.log(`\nš Configuring ${ide.name}...`);
// Generate and save MCP configuration
const mcpConfig = await this.generateMCPConfig(ide, projectInfo);
await this.saveMCPConfig(ide, mcpConfig);
// Generate command files for IDEs that support them
if (this.detector.hasCommandSupport(ide)) {
console.log(`š Generating command files for ${ide.name}...`);
await this.generateCommandFiles(ide, projectInfo);
}
}
// Update .gitignore if needed
await this.updateGitIgnore();
// Save local project configuration
await this.saveProjectConfig(projectInfo);
console.log('\n⨠Setup complete! Your SDLC tracker is ready to use.');
console.log('\nš Next steps:');
console.log(' 1. Restart your IDE to load the new configuration');
console.log(' 2. Use the SDLC tracker tools or commands');
if (detectedIDEs.some(ide => ide.type === 'claude')) {
console.log('\nš Claude Code users can use:');
console.log(' - Commands: /session-start, /session-update, /sprint-create');
console.log(' - MCP Tools: configure, sync_sessions, watch');
}
}
/**
* Generate MCP configuration for a specific IDE
*/
async generateMCPConfig(ide, projectInfo) {
const serverConfig = {
command: 'npx',
args: ['ai-sprint'],
env: {
PROJECT_ID: projectInfo.projectId,
PROJECT_PATH: projectInfo.projectPath,
API_ENDPOINT: projectInfo.apiEndpoint,
NEON_BRANCH_ID: projectInfo.neonBranchId || '',
WATCH_PATTERNS: projectInfo.watchPatterns.join(','),
IDE_TYPE: ide.type,
AUTO_CONFIGURED: 'true'
}
};
if (projectInfo.apiKey) {
serverConfig.env.API_KEY = projectInfo.apiKey;
}
// Use appropriate config format based on IDE
const config = {};
if (ide.configFormat === 'mcpServers') {
config.mcpServers = {
'ai-sprint': serverConfig
};
}
else {
config.servers = {
'ai-sprint': serverConfig
};
}
return config;
}
/**
* Save MCP configuration to the appropriate location
*/
async saveMCPConfig(ide, config) {
const configPath = ide.configPath;
const configDir = path.dirname(configPath);
// Ensure directory exists
await fs.mkdir(configDir, { recursive: true });
// Check if config file already exists
let existingConfig = {};
try {
const existingContent = await fs.readFile(configPath, 'utf-8');
existingConfig = JSON.parse(existingContent);
}
catch {
// File doesn't exist or is invalid, start fresh
}
// Merge configurations
const mergedConfig = this.mergeConfigs(existingConfig, config);
// Save the configuration
await fs.writeFile(configPath, JSON.stringify(mergedConfig, null, 2));
console.log(` ā
Saved MCP configuration to ${configPath}`);
}
/**
* Generate command files for Claude Code
*/
async generateCommandFiles(ide, projectInfo) {
if (!ide.commandPath)
return;
const commandsDir = ide.commandPath;
await fs.mkdir(commandsDir, { recursive: true });
// Generate session-start command
await this.generateSessionStartCommand(commandsDir);
// Generate session-update command
await this.generateSessionUpdateCommand(commandsDir);
// Generate session-end command
await this.generateSessionEndCommand(commandsDir);
// Generate sprint-create command
await this.generateSprintCreateCommand(commandsDir);
// Generate test-report command
await this.generateTestReportCommand(commandsDir);
console.log(` ā
Generated 5 command files in ${commandsDir}`);
}
async generateSessionStartCommand(commandsDir) {
const content = `Start a new SDLC tracking session with automatic Portal synchronization.
## Usage
\`/session-start [type] [name]\`
### Arguments
- **type**: Session type (feature, bug, maintenance, research, emergency)
- **name**: Descriptive name for the session
### Examples
- \`/session-start feature user-authentication\`
- \`/session-start bug fix-login-redirect\`
- \`/session-start maintenance update-dependencies\`
## What This Command Does
1. **Creates Session File**: Generates a new session file in \`sessions/\` directory
2. **Configures Tracking**: Sets up MCP SDLC tracker for the project
3. **Starts Synchronization**: Begins real-time sync with BizOps Portal
4. **Enables Git Tracking**: Automatically links commits to this session
5. **Activates File Watching**: Monitors session files for changes
## Session File Format
The command creates a file named:
\`sessions/YYYY-MM-DD-HHMM-[type]-[name].md\`
With this initial structure:
- Session metadata and timestamps
- Goals and objectives sections
- Acceptance criteria checklist
- Test results placeholder
- Performance metrics tracking
## Portal Integration
Your session will be:
- Visible in the BizOps Portal dashboard
- Linked to git commits automatically
- Updated in real-time as you work
- Tracked for velocity and metrics
## Related Commands
- \`/session-update\` - Update session progress
- \`/session-end\` - Complete the session
- \`/sprint-create\` - Create a new sprint
- \`/test-report\` - Submit test results
---
*This command uses AI Sprint to provide seamless integration between your IDE and the BizOps Portal.*`;
await fs.writeFile(path.join(commandsDir, 'session-start.md'), content);
}
async generateSessionUpdateCommand(commandsDir) {
const content = `Update the current SDLC session with progress, notes, or checkpoints.
## Usage
\`/session-update [checkpoint-type] [notes]\`
### Arguments
- **checkpoint-type** (optional): Type of update (milestone, daily, debug, blocker, integration, review, deployment)
- **notes** (optional): Additional notes or context for the update
### Examples
- \`/session-update milestone "Completed user authentication backend"\`
- \`/session-update blocker "Waiting for API documentation"\`
- \`/session-update daily\` (auto-generates summary)
## What This Command Does
1. **Identifies Active Session**: Finds the current session file
2. **Adds Timestamped Update**: Appends a checkpoint to the session
3. **Syncs Progress**: Updates Portal with latest information
4. **Tracks Metrics**: Records time spent and progress made
5. **Git Integration**: Links recent commits to the update
## Update Structure
Each update includes:
- Timestamp and checkpoint type
- Git status and changes summary
- Todo progress tracking
- Test results (if available)
- Environment status
- Architecture decisions
- Next steps
## Automatic Context Gathering
When no notes are provided, the command automatically captures:
- Recent git activity and commits
- Changed files and statistics
- Test execution results
- Build status
- Current branch information
## Portal Synchronization
Updates are immediately reflected in:
- Session timeline view
- Sprint progress tracking
- Team velocity metrics
- Quality dashboards
## Related Commands
- \`/session-start\` - Start a new session
- \`/session-end\` - Complete the session
- \`/test-report\` - Add test results
---
*This command ensures comprehensive progress tracking throughout your development session.*`;
await fs.writeFile(path.join(commandsDir, 'session-update.md'), content);
}
async generateSessionEndCommand(commandsDir) {
const content = `Complete the current SDLC session with comprehensive metrics and documentation.
## Usage
\`/session-end [--commit] [--no-sync]\`
### Options
- **--commit**: Automatically create a git commit with session summary
- **--no-sync**: Skip final synchronization with Portal
### Examples
- \`/session-end\` - Standard session completion
- \`/session-end --commit\` - Complete and commit changes
- \`/session-end --no-sync\` - Local completion only
## What This Command Does
1. **Finalizes Session**: Marks session as completed with end timestamp
2. **Generates Summary**: Creates comprehensive completion report
3. **Calculates Metrics**: Duration, velocity, quality scores
4. **Syncs to Portal**: Final synchronization of all session data
5. **Archives Session**: Moves to completed sessions
## Completion Report Includes
### Session Metrics
- Total duration and active time
- Goals completed vs planned
- Code changes (files, lines, commits)
- Test results and coverage
- Performance benchmarks
### Deliverables
- Features implemented
- Bugs fixed
- Documentation created
- Tests added
- Technical debt addressed
### Knowledge Transfer
- Key decisions made
- Lessons learned
- Blockers encountered
- Solutions implemented
### Next Steps
- Follow-up tasks
- Technical debt items
- Improvement suggestions
## Portal Updates
Upon completion, the Portal will:
- Update sprint progress
- Calculate velocity metrics
- Generate insights
- Update team dashboards
- Trigger notifications
## Post-Completion
After ending a session:
- Session file is preserved for reference
- Metrics contribute to team analytics
- Insights feed into AI recommendations
- Knowledge is indexed for search
## Related Commands
- \`/session-start\` - Start a new session
- \`/session-update\` - Update progress
- \`/sprint-create\` - Plan next sprint
---
*This command ensures proper closure and documentation of your development work.*`;
await fs.writeFile(path.join(commandsDir, 'session-end.md'), content);
}
async generateSprintCreateCommand(commandsDir) {
const content = `Create a new sprint with goals, tasks, and tracking setup.
## Usage
\`/sprint-create [sprint-type] [name] [duration]\`
### Arguments
- **sprint-type**: Type of sprint (feature, infrastructure, bugfix, research, maintenance, emergency)
- **name**: Sprint name/title
- **duration**: Duration (e.g., "1 week", "2 weeks", "3 days")
### Examples
- \`/sprint-create feature authentication-system "2 weeks"\`
- \`/sprint-create bugfix critical-fixes "3 days"\`
- \`/sprint-create research ai-integration "1 week"\`
## What This Command Does
1. **Creates Sprint File**: Generates sprint planning document
2. **Sets Up Tracking**: Configures sprint-level metrics
3. **Portal Integration**: Creates sprint in BizOps Portal
4. **Team Notification**: Notifies team members
5. **Initializes Backlog**: Sets up task tracking
## Sprint Structure
Creates a file: \`sprints/[type]-YYYY-MM-DD-[name].md\`
With sections for:
- Sprint goals and objectives
- Success metrics
- Task backlog (prioritized)
- Technical architecture
- Risk assessment
- Team assignments
- Timeline and milestones
## Sprint Types
### Feature Sprint (1.x)
- New functionality development
- User-facing features
- API additions
### Infrastructure Sprint (2.x)
- DevOps improvements
- Architecture changes
- Performance optimization
### Bugfix Sprint (3.x)
- Critical bug fixes
- Regression fixes
- Hotfix deployments
### Research Sprint (4.x)
- Technical spikes
- Proof of concepts
- Technology evaluation
### Maintenance Sprint (5.x)
- Dependency updates
- Code refactoring
- Technical debt
### Emergency Sprint (9.x)
- Critical production issues
- Security patches
- Urgent fixes
## Portal Features
Your sprint will have:
- Real-time progress tracking
- Burndown charts
- Velocity metrics
- Team collaboration
- Automated reporting
## Related Commands
- \`/session-start\` - Start work on sprint tasks
- \`/session-update\` - Update task progress
- \`/test-report\` - Report sprint test results
---
*Sprints provide structured planning and tracking for team development efforts.*`;
await fs.writeFile(path.join(commandsDir, 'sprint-create.md'), content);
}
async generateTestReportCommand(commandsDir) {
const content = `Submit test results to track quality metrics and coverage.
## Usage
\`/test-report [test-type] [passed] [failed] [coverage]\`
### Arguments
- **test-type**: Type of tests (unit, integration, e2e, smoke, visual, performance)
- **passed**: Number of passed tests
- **failed**: Number of failed tests
- **coverage**: Coverage percentage (optional)
### Examples
- \`/test-report unit 245 3 87.5\`
- \`/test-report e2e 18 0 0\`
- \`/test-report integration 52 2 76.3\`
## What This Command Does
1. **Records Results**: Saves test execution results
2. **Updates Session**: Links results to active session
3. **Syncs to Portal**: Real-time quality metrics update
4. **Tracks Trends**: Contributes to quality analytics
5. **Triggers Alerts**: Notifies on failures or coverage drops
## Test Types
### Unit Tests
- Individual function/method tests
- Fast execution
- High coverage expected
### Integration Tests
- Component interaction tests
- API endpoint testing
- Database operations
### E2E Tests
- Full user journey tests
- Browser automation
- Critical path validation
### Smoke Tests
- Basic functionality checks
- Quick validation
- Deployment verification
### Visual Tests
- UI regression testing
- Screenshot comparison
- Style validation
### Performance Tests
- Load testing results
- Response time metrics
- Resource usage
## Portal Analytics
Test results contribute to:
- Quality dashboards
- Coverage trends
- Failure analysis
- Sprint metrics
- Team KPIs
## Additional Options
Include extra details:
- \`--duration 12340\` - Test execution time in ms
- \`--skipped 5\` - Number of skipped tests
- \`--session-id xyz\` - Link to specific session
## Quality Gates
Results are evaluated against:
- Minimum coverage thresholds
- Maximum failure rates
- Performance benchmarks
- Regression checks
## Related Commands
- \`/session-update\` - Include test results in session
- \`/session-end\` - Finalize with test summary
- \`/sprint-create\` - Set sprint quality goals
---
*Continuous test reporting ensures quality visibility throughout development.*`;
await fs.writeFile(path.join(commandsDir, 'test-report.md'), content);
}
/**
* Get project information from options or git
*/
async getProjectInfo(options) {
const projectPath = options.projectPath || process.cwd();
// Generate or use provided project ID
const projectId = options.projectId || this.generateProjectId();
// Get git remote URL for default API endpoint
let gitRemote = '';
try {
const remotes = await this.git.getRemotes(true);
gitRemote = remotes[0]?.refs?.fetch || '';
}
catch {
// Git not initialized
}
// Default values
const apiEndpoint = options.apiEndpoint || process.env.BIZOPS_API_ENDPOINT || 'https://portal.unblockd.com';
const watchPatterns = options.watchPatterns || [
'sessions/*.md',
'sprints/*.md',
'delivery/*.md',
'docs/sprint-*.md'
];
return {
projectId,
projectPath,
apiEndpoint,
apiKey: options.apiKey || process.env.BIZOPS_API_KEY || '',
watchPatterns,
gitRemote,
neonBranchId: process.env.NEON_BRANCH_ID || ''
};
}
/**
* Generate a UUID for the project
*/
generateProjectId() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/**
* Merge two configuration objects
*/
mergeConfigs(existing, newConfig) {
const merged = { ...existing };
// Merge mcpServers or servers
if (newConfig.mcpServers) {
merged.mcpServers = { ...(merged.mcpServers || {}), ...newConfig.mcpServers };
}
if (newConfig.servers) {
merged.servers = { ...(merged.servers || {}), ...newConfig.servers };
}
return merged;
}
/**
* Update .gitignore to exclude local configuration
*/
async updateGitIgnore() {
const gitignorePath = path.join(process.cwd(), '.gitignore');
const entriesToAdd = [
'.ai-sprint.json',
'.ai-sprint.local.json',
'sessions/.current-session'
];
try {
let content = '';
try {
content = await fs.readFile(gitignorePath, 'utf-8');
}
catch {
// .gitignore doesn't exist
}
const lines = content.split('\n');
let modified = false;
for (const entry of entriesToAdd) {
if (!lines.includes(entry)) {
lines.push(entry);
modified = true;
}
}
if (modified) {
await fs.writeFile(gitignorePath, lines.join('\n'));
console.log(' ā
Updated .gitignore');
}
}
catch (error) {
console.warn(' ā ļø Could not update .gitignore:', error);
}
}
/**
* Save project configuration locally
*/
async saveProjectConfig(projectInfo) {
const configPath = path.join(process.cwd(), '.ai-sprint.json');
const config = {
projectId: projectInfo.projectId,
projectPath: projectInfo.projectPath,
apiEndpoint: projectInfo.apiEndpoint,
watchPatterns: projectInfo.watchPatterns,
configuredAt: new Date().toISOString(),
version: '1.0.0'
};
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
console.log(` ā
Saved project configuration to ${configPath}`);
}
}
//# sourceMappingURL=configurator.js.map