mirror-magi-meta-agent
Version:
AI-powered development planning and execution system with Supabase integration
106 lines (91 loc) • 2.92 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
class ClaudeResponseManager {
constructor() {
this.responsePath = path.join(__dirname, '../../state/claude-responses.json');
}
/**
* Save Claude's response for a specific task
*/
async saveResponse(taskId, response) {
let responses = {};
try {
const data = await fs.readFile(this.responsePath, 'utf8');
responses = JSON.parse(data);
} catch {
// File doesn't exist yet
}
responses[taskId] = {
response,
timestamp: new Date().toISOString(),
summary: this.extractSummary(response)
};
await fs.writeFile(this.responsePath, JSON.stringify(responses, null, 2));
}
/**
* Get Claude's response for a specific task
*/
async getResponse(taskId) {
try {
const data = await fs.readFile(this.responsePath, 'utf8');
const responses = JSON.parse(data);
return responses[taskId];
} catch {
return null;
}
}
/**
* Extract summary from Claude's response
* Claude often ends with summaries like "I've successfully created..."
*/
extractSummary(response) {
// Look for common summary patterns in Claude's responses
const summaryPatterns = [
/I've successfully (.*?)\.?$/im,
/I've created (.*?)\.?$/im,
/I've implemented (.*?)\.?$/im,
/I've added (.*?)\.?$/im,
/I've updated (.*?)\.?$/im,
/Successfully (.*?)\.?$/im,
/This (?:creates?|implements?|adds?) (.*?)\.?$/im,
/The .* (?:is|are) now (.*?)\.?$/im
];
// Try to find a summary in the last few paragraphs
const lines = response.split('\n').filter(line => line.trim());
const lastFewLines = lines.slice(-5).join(' ');
for (const pattern of summaryPatterns) {
const match = lastFewLines.match(pattern);
if (match) {
return match[0].trim();
}
}
// If no pattern matches, look for the last substantial sentence
const sentences = response.split(/[.!?]+/).filter(s => s.trim().length > 20);
if (sentences.length > 0) {
const lastSentence = sentences[sentences.length - 1].trim();
// Clean it up and make it commit-message friendly
return lastSentence.substring(0, 100);
}
return null;
}
/**
* Clear responses older than 7 days
*/
async cleanup() {
try {
const data = await fs.readFile(this.responsePath, 'utf8');
const responses = JSON.parse(data);
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const cleaned = {};
for (const [taskId, data] of Object.entries(responses)) {
if (new Date(data.timestamp) > oneWeekAgo) {
cleaned[taskId] = data;
}
}
await fs.writeFile(this.responsePath, JSON.stringify(cleaned, null, 2));
} catch {
// No cleanup needed
}
}
}
module.exports = ClaudeResponseManager;