mirror-magi-meta-agent
Version:
AI-powered development planning and execution system with Supabase integration
164 lines (140 loc) ⢠4.79 kB
JavaScript
const ClaudeResponseManager = require('./claude-response-manager');
/**
* Generate commit message based on task type
*/
function generateCommitMessage(task, options = {}) {
const { customMessage, claudeSummary, includeTaskId = true } = options;
if (customMessage) return customMessage;
const typeMap = {
'supabase_migration': 'feat(db)',
'supabase_rls': 'feat(security)',
'supabase_function': 'feat(functions)',
'component_creation': 'feat(ui)',
'api_integration': 'feat(api)',
'configuration': 'chore(config)',
'testing': 'test',
'testing_implementation': 'test',
'bug_fix': 'fix',
'documentation': 'docs',
'styling': 'style',
'styling_implementation': 'style(ui)',
'refactoring': 'refactor',
'feature_development': 'feat',
'data_modeling': 'feat(data)',
'performance': 'perf',
'build': 'build',
'ci': 'ci',
'revert': 'revert'
};
const prefix = typeMap[task.type] || 'feat';
// Use Claude's summary if available and it's good
let description = task.description;
if (claudeSummary && claudeSummary.length > 20) {
// Clean up Claude's summary to be commit-friendly
description = claudeSummary
.replace(/^I've |^I have |^Successfully |^This /i, '')
.replace(/\.$/, '')
.toLowerCase()
.replace(/^\w/, c => c.toUpperCase());
}
const taskRef = includeTaskId ? ` (${task.id})` : '';
return `${prefix}: ${description}${taskRef}`;
}
/**
* Generate detailed commit body from task details and Claude's response
*/
function generateCommitBody(task, claudeSummary, changes) {
const body = [];
// Add Claude's summary if it's different from the main description
if (claudeSummary && claudeSummary.length > 50) {
body.push(claudeSummary);
body.push('');
}
// Add task details
if (task.specifics) {
body.push('Task Details:');
Object.entries(task.specifics).forEach(([key, value]) => {
if (typeof value === 'string' && value.length < 100) {
body.push(`- ${key}: ${value}`);
} else if (Array.isArray(value) && value.length > 0) {
body.push(`- ${key}: ${value.join(', ')}`);
}
});
body.push('');
}
// Add file changes
if (changes && changes.length > 0) {
body.push('Files changed:');
changes.forEach(change => {
const [status, ...fileParts] = change.split(/\s+/);
const file = fileParts.join(' ');
const statusMap = {
'M': 'Modified',
'A': 'Added',
'D': 'Deleted',
'R': 'Renamed',
'C': 'Copied'
};
body.push(`- ${statusMap[status] || status}: ${file}`);
});
}
return body.join('\n');
}
/**
* Interactive commit message builder
*/
async function buildInteractiveCommitMessage(task, claudeResponse, changes) {
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const question = (prompt) => new Promise(resolve => readline.question(prompt, resolve));
console.log('\nš Task:', task.description);
console.log('š Type:', task.type);
if (changes && changes.length > 0) {
console.log('\nš Changed files:');
changes.forEach(change => console.log(` ${change}`));
}
// Show Claude's summary if available
let claudeSummary = null;
if (claudeResponse && claudeResponse.summary) {
console.log('\nš¤ Claude\'s summary:');
console.log(` "${claudeResponse.summary}"`);
claudeSummary = claudeResponse.summary;
}
console.log('\nš¬ Suggested commit message:');
const suggested = generateCommitMessage(task, { claudeSummary });
console.log(` ${suggested}`);
const choice = await question('\nOptions:\n1. Use suggested message\n2. Use Claude\'s summary\n3. Custom message\n4. Skip commit\n> ');
let message = null;
let body = '';
if (choice === '1') {
message = suggested;
body = generateCommitBody(task, claudeSummary, changes);
} else if (choice === '2' && claudeSummary) {
message = generateCommitMessage(task, { claudeSummary, includeTaskId: true });
body = generateCommitBody(task, null, changes);
} else if (choice === '3') {
message = await question('Enter commit message: ');
const addBody = await question('Add detailed body? (y/n): ');
if (addBody.toLowerCase() === 'y') {
console.log('Enter commit body (empty line to finish):');
const bodyLines = [];
let line;
while ((line = await question('')) !== '') {
bodyLines.push(line);
}
body = bodyLines.join('\n');
}
}
readline.close();
if (message && body) {
return `${message}\n\n${body}`;
}
return message;
}
module.exports = {
generateCommitMessage,
generateCommitBody,
buildInteractiveCommitMessage
};