UNPKG

ai-sprint

Version:

AI-powered sprint management and SDLC tracking with automatic IDE integration

605 lines (525 loc) • 19.3 kB
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