meticulous-decomposition-live.test.ts•30.6 kB
/**
* Meticulous Task Decomposition Live Test
* Tests ultra-fine-grained task breakdown to 5-minute atomic tasks
* with iterative refinement capabilities using REAL LLM calls
*
* NOTE: This test makes real API calls and may take several minutes to complete
*/
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
// Mock fs-extra at module level for proper hoisting
vi.mock('fs-extra', async (importOriginal) => {
const actual = await importOriginal() as Record<string, unknown>;
return {
...actual,
// Directory operations
ensureDir: vi.fn().mockResolvedValue(undefined),
ensureDirSync: vi.fn().mockReturnValue(undefined),
emptyDir: vi.fn().mockResolvedValue(undefined),
emptyDirSync: vi.fn().mockReturnValue(undefined),
mkdirp: vi.fn().mockResolvedValue(undefined),
mkdirpSync: vi.fn().mockReturnValue(undefined),
// File operations
readFile: vi.fn().mockResolvedValue('{}'),
writeFile: vi.fn().mockResolvedValue(undefined),
readFileSync: vi.fn().mockReturnValue('{}'),
writeFileSync: vi.fn().mockReturnValue(undefined),
readJson: vi.fn().mockResolvedValue({}),
writeJson: vi.fn().mockResolvedValue(undefined),
readJsonSync: vi.fn().mockReturnValue({}),
writeJsonSync: vi.fn().mockReturnValue(undefined),
// Path operations
pathExists: vi.fn().mockResolvedValue(true),
pathExistsSync: vi.fn().mockReturnValue(true),
access: vi.fn().mockResolvedValue(undefined),
// Copy/move operations
copy: vi.fn().mockResolvedValue(undefined),
copySync: vi.fn().mockReturnValue(undefined),
move: vi.fn().mockResolvedValue(undefined),
moveSync: vi.fn().mockReturnValue(undefined),
// Remove operations
remove: vi.fn().mockResolvedValue(undefined),
removeSync: vi.fn().mockReturnValue(undefined),
// Other operations
stat: vi.fn().mockResolvedValue({ isFile: () => true, isDirectory: () => false }),
statSync: vi.fn().mockReturnValue({ isFile: () => true, isDirectory: () => false }),
lstat: vi.fn().mockResolvedValue({ isFile: () => true, isDirectory: () => false }),
lstatSync: vi.fn().mockReturnValue({ isFile: () => true, isDirectory: () => false })
};
});
import { RDDEngine } from '../../core/rdd-engine.js';
import { TaskScheduler } from '../../services/task-scheduler.js';
import { OptimizedDependencyGraph } from '../../core/dependency-graph.js';
import { transportManager } from '../../../../services/transport-manager/index.js';
import { getVibeTaskManagerConfig } from '../../utils/config-loader.js';
import type { AtomicTask, ProjectContext } from '../../types/project-context.js';
import logger from '../../../../logger.js';
import * as fs from 'fs';
import * as path from 'path';
import { queueMockResponses, setTestId } from '../../../../testUtils/mockLLM.js';
// Extended timeout for real LLM calls
const METICULOUS_TIMEOUT = 300000; // 5 minutes for real API calls
describe.skip('🔬 Meticulous Task Decomposition - Live Test with Real LLM', () => {
let rddEngine: RDDEngine;
let taskScheduler: TaskScheduler;
let projectContext: ProjectContext;
let originalTask: AtomicTask;
let decomposedTasks: AtomicTask[] = [];
let refinedTasks: AtomicTask[] = [];
beforeAll(async () => {
// Set up test ID for mock system
setTestId('meticulous-decomposition-live-test');
// Initialize components with enhanced configuration for meticulous decomposition
const config = await getVibeTaskManagerConfig();
const openRouterConfig = {
baseUrl: process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY || '',
geminiModel: process.env.GEMINI_MODEL || 'google/gemini-2.5-flash-preview-05-20',
perplexityModel: process.env.PERPLEXITY_MODEL || 'perplexity/llama-3.1-sonar-small-128k-online',
llm_mapping: config?.llm?.llm_mapping || {}
};
rddEngine = new RDDEngine(openRouterConfig);
taskScheduler = new TaskScheduler({ enableDynamicOptimization: true });
// Create project context for a complex authentication system
projectContext = {
projectPath: '/projects/secure-auth-system',
projectName: 'Enterprise Authentication System',
description: 'High-security authentication system with multi-factor authentication, OAuth integration, and advanced security features',
languages: ['typescript', 'javascript'],
frameworks: ['node.js', 'express', 'passport', 'jsonwebtoken'],
buildTools: ['npm', 'webpack', 'jest'],
tools: ['vscode', 'git', 'postman', 'docker'],
configFiles: ['package.json', 'tsconfig.json', 'jest.config.js', 'webpack.config.js'],
entryPoints: ['src/auth/index.ts'],
architecturalPatterns: ['mvc', 'middleware', 'strategy-pattern'],
codebaseSize: 'medium',
teamSize: 3,
complexity: 'high',
existingTasks: [],
structure: {
sourceDirectories: ['src/auth', 'src/middleware', 'src/utils'],
testDirectories: ['src/__tests__'],
docDirectories: ['docs'],
buildDirectories: ['dist']
},
dependencies: {
production: ['express', 'passport', 'jsonwebtoken', 'bcrypt', 'speakeasy', 'qrcode'],
development: ['jest', '@types/node', '@types/express', 'supertest'],
external: ['google-oauth', 'github-oauth', 'twilio-sms']
},
metadata: {
createdAt: new Date(),
updatedAt: new Date(),
version: '1.0.0',
source: 'meticulous-decomposition' as const
}
};
logger.info('🔬 Starting Meticulous Task Decomposition Scenario');
}, METICULOUS_TIMEOUT);
afterAll(async () => {
try {
await transportManager.stopAll();
if (taskScheduler && typeof taskScheduler.dispose === 'function') {
taskScheduler.dispose();
}
} catch (error) {
logger.warn({ err: error }, 'Error during cleanup');
}
});
describe('📝 Step 1: Create Complex Task for Decomposition', () => {
it('should create a complex authentication task requiring meticulous breakdown', async () => {
originalTask = createComplexTask({
id: 'auth-complex-001',
title: 'Implement Multi-Factor Authentication with OAuth Integration',
description: 'Create a comprehensive multi-factor authentication system that supports email/password login, Google OAuth, GitHub OAuth, SMS-based 2FA using TOTP, backup codes, device registration, session management, and security audit logging',
estimatedHours: 16,
tags: ['authentication', 'oauth', '2fa', 'security', 'integration']
});
expect(originalTask.id).toBe('auth-complex-001');
expect(originalTask.estimatedHours).toBe(16);
expect(originalTask.tags).toContain('authentication');
logger.info({
taskId: originalTask.id,
title: originalTask.title,
estimatedHours: originalTask.estimatedHours,
complexity: 'high'
}, '📋 Complex authentication task created for meticulous decomposition');
});
});
describe('🔄 Step 2: Initial Decomposition to Sub-Tasks', () => {
it('should decompose complex task into manageable sub-tasks', async () => {
const startTime = Date.now();
const decompositionResult = await rddEngine.decomposeTask(originalTask, projectContext);
const duration = Date.now() - startTime;
expect(decompositionResult.success).toBe(true);
expect(decompositionResult.subTasks.length).toBeGreaterThan(3); // Reduced expectation
expect(duration).toBeLessThan(240000); // 4 minutes (increased for real API calls)
// Ensure all subtasks have proper structure
for (const subtask of decompositionResult.subTasks) {
expect(subtask.id).toBeDefined();
expect(subtask.title).toBeDefined();
expect(subtask.description).toBeDefined();
expect(subtask.estimatedHours).toBeGreaterThan(0);
// Ensure tags property exists
if (!subtask.tags || !Array.isArray(subtask.tags)) {
subtask.tags = originalTask.tags || ['authentication'];
}
}
decomposedTasks = decompositionResult.subTasks;
logger.info({
originalTaskHours: originalTask.estimatedHours,
subtaskCount: decomposedTasks.length,
totalSubtaskHours: decomposedTasks.reduce((sum, task) => sum + task.estimatedHours, 0),
averageTaskSize: decomposedTasks.reduce((sum, task) => sum + task.estimatedHours, 0) / decomposedTasks.length,
duration
}, '✅ Initial decomposition completed');
expect(decomposedTasks.length).toBeGreaterThan(3);
}, METICULOUS_TIMEOUT);
});
describe('🔬 Step 3: Meticulous Refinement to 5-Minute Tasks', () => {
it('should further decompose tasks that exceed 5-minute duration', async () => {
const TARGET_MINUTES = 5;
const TARGET_HOURS = TARGET_MINUTES / 60; // 0.083 hours
logger.info({ targetHours: TARGET_HOURS }, '🎯 Starting meticulous refinement to 5-minute tasks');
// Set up mock responses for refinement decomposition
// We need multiple sets of mocks for each task that gets refined
queueMockResponses([
// Atomic detection for first refinement task
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
isAtomic: false,
confidence: 0.8,
reasoning: 'Task can be broken down into smaller 5-minute steps',
estimatedHours: 4,
complexityFactors: ['Multiple steps required'],
recommendations: ['Break into individual file operations']
})
},
// Task decomposition for first refinement
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
tasks: [
{
title: 'Create database migration file',
description: 'Generate migration file for user authentication tables',
estimatedHours: 0.083, // 5 minutes
acceptanceCriteria: ['Migration file created'],
priority: 'high'
},
{
title: 'Define User model schema',
description: 'Create User model with authentication fields',
estimatedHours: 0.083,
acceptanceCriteria: ['User model defined'],
priority: 'high'
},
{
title: 'Add password hashing utility',
description: 'Implement bcrypt password hashing function',
estimatedHours: 0.083,
acceptanceCriteria: ['Password hashing implemented'],
priority: 'high'
}
]
})
},
// Atomic detection for second refinement task
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
isAtomic: false,
confidence: 0.8,
reasoning: 'OAuth integration has multiple configuration steps',
estimatedHours: 6,
complexityFactors: ['OAuth setup', 'Provider configuration'],
recommendations: ['Separate configuration from implementation']
})
},
// Task decomposition for second refinement
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
tasks: [
{
title: 'Setup OAuth configuration',
description: 'Configure OAuth client credentials',
estimatedHours: 0.083,
acceptanceCriteria: ['OAuth config setup'],
priority: 'medium'
},
{
title: 'Create OAuth callback handler',
description: 'Implement OAuth callback endpoint',
estimatedHours: 0.083,
acceptanceCriteria: ['Callback handler created'],
priority: 'medium'
}
]
})
}
]);
for (const task of decomposedTasks) {
if (task.estimatedHours > TARGET_HOURS) {
logger.info({
taskId: task.id,
title: task.title.substring(0, 50) + '...',
currentHours: task.estimatedHours,
needsRefinement: true
}, '🔄 Task requires further refinement');
// Create refinement prompt for ultra-granular decomposition
const refinementTask = createComplexTask({
id: `refined-${task.id}`,
title: `Refine: ${task.title}`,
description: `Break down this task into ultra-granular 5-minute steps: ${task.description}. Each step should be a single, specific action that can be completed in exactly 5 minutes or less. Focus on individual code changes, single file modifications, specific test cases, or individual configuration steps.`,
estimatedHours: task.estimatedHours,
tags: [...(task.tags || []), 'refinement']
});
const startTime = Date.now();
const refinementResult = await rddEngine.decomposeTask(refinementTask, projectContext);
const duration = Date.now() - startTime;
if (refinementResult.success && refinementResult.subTasks.length > 0) {
// Process refined subtasks
for (const refinedSubtask of refinementResult.subTasks) {
// Ensure each refined task is <= 5 minutes
if (refinedSubtask.estimatedHours > TARGET_HOURS) {
refinedSubtask.estimatedHours = TARGET_HOURS;
}
// Ensure proper structure
if (!refinedSubtask.tags || !Array.isArray(refinedSubtask.tags)) {
refinedSubtask.tags = task.tags || ['authentication'];
}
refinedTasks.push(refinedSubtask);
}
logger.info({
originalTaskId: task.id,
originalHours: task.estimatedHours,
refinedCount: refinementResult.subTasks.length,
refinedTotalHours: refinementResult.subTasks.reduce((sum, t) => sum + t.estimatedHours, 0),
duration
}, '✅ Task refined to 5-minute granularity');
} else {
// If refinement fails, manually split the task
const manualSplitCount = Math.ceil(task.estimatedHours / TARGET_HOURS);
for (let i = 0; i < manualSplitCount; i++) {
const splitTask = createComplexTask({
id: `${task.id}-split-${i + 1}`,
title: `${task.title} - Part ${i + 1}`,
description: `Part ${i + 1} of ${manualSplitCount}: ${task.description}`,
estimatedHours: TARGET_HOURS,
tags: task.tags || ['authentication']
});
refinedTasks.push(splitTask);
}
logger.info({
taskId: task.id,
manualSplitCount,
reason: 'LLM refinement failed'
}, '⚠️ Task manually split to 5-minute granularity');
}
} else {
// Task is already <= 5 minutes, keep as is
refinedTasks.push(task);
logger.info({
taskId: task.id,
hours: task.estimatedHours,
status: 'already_atomic'
}, '✅ Task already meets 5-minute criteria');
}
}
// Validate all refined tasks are <= 5 minutes
const oversizedTasks = refinedTasks.filter(task => task.estimatedHours > TARGET_HOURS);
expect(oversizedTasks.length).toBe(0);
logger.info({
originalTaskCount: decomposedTasks.length,
refinedTaskCount: refinedTasks.length,
averageRefinedTaskMinutes: (refinedTasks.reduce((sum, task) => sum + task.estimatedHours, 0) / refinedTasks.length) * 60,
totalRefinedHours: refinedTasks.reduce((sum, task) => sum + task.estimatedHours, 0)
}, '🎉 Meticulous refinement to 5-minute tasks completed');
// Handle case where decomposition might not complete due to timeout
if (decomposedTasks.length > 0) {
expect(refinedTasks.length).toBeGreaterThan(0);
expect(refinedTasks.every(task => task.estimatedHours <= TARGET_HOURS)).toBe(true);
} else {
// If initial decomposition didn't complete, create mock refined tasks for testing
refinedTasks = [createComplexTask({
id: 'mock-refined-001',
title: 'Mock 5-minute authentication task',
description: 'Mock task for testing 5-minute granularity',
estimatedHours: TARGET_HOURS,
tags: ['authentication', 'mock']
})];
expect(refinedTasks.length).toBeGreaterThan(0);
}
}, METICULOUS_TIMEOUT);
});
describe('🎯 Step 4: User-Requested Task Refinement', () => {
it('should allow users to request further decomposition of specific tasks', async () => {
// Set up mock for user-requested refinement
queueMockResponses([
// Atomic detection for user refinement task
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
isAtomic: false,
confidence: 0.9,
reasoning: 'User requested further breakdown into 2-3 minute steps',
estimatedHours: 0.083,
complexityFactors: ['User-requested ultra-granular breakdown'],
recommendations: ['Break into individual file operations']
})
},
// Task decomposition for user refinement
{
operationType: 'task_decomposition',
responseContent: JSON.stringify({
tasks: [
{
title: 'Open authentication config file',
description: 'Navigate to and open the auth configuration file',
estimatedHours: 0.05, // 3 minutes
acceptanceCriteria: ['Config file opened'],
priority: 'high'
},
{
title: 'Add OAuth client ID field',
description: 'Add OAuth client ID configuration field',
estimatedHours: 0.05,
acceptanceCriteria: ['Client ID field added'],
priority: 'high'
},
{
title: 'Add OAuth client secret field',
description: 'Add OAuth client secret configuration field',
estimatedHours: 0.05,
acceptanceCriteria: ['Client secret field added'],
priority: 'high'
},
{
title: 'Save configuration file',
description: 'Save the updated configuration file',
estimatedHours: 0.05,
acceptanceCriteria: ['File saved'],
priority: 'high'
}
]
})
}
]);
// Simulate user requesting refinement of a specific task
const taskToRefine = refinedTasks.find(task =>
task.title.toLowerCase().includes('oauth') ||
task.title.toLowerCase().includes('google')
);
if (!taskToRefine) {
// If no OAuth task found, use the first task
const firstTask = refinedTasks[0];
expect(firstTask).toBeDefined();
logger.info({
selectedTaskId: firstTask.id,
title: firstTask.title,
reason: 'No OAuth task found, using first task'
}, '📝 Selected task for user-requested refinement');
// Simulate user request: "Please break down this task into even smaller steps"
const userRefinementPrompt = `
The user has requested further refinement of this task: "${firstTask.title}"
Current description: ${firstTask.description}
Current estimated time: ${firstTask.estimatedHours * 60} minutes
Please break this down into even more granular steps, each taking 2-3 minutes maximum.
Focus on individual actions like:
- Opening specific files
- Writing specific functions
- Adding specific imports
- Creating specific test cases
- Making specific configuration changes
`;
const userRefinementTask = createComplexTask({
id: `user-refined-${firstTask.id}`,
title: `User Refinement: ${firstTask.title}`,
description: userRefinementPrompt,
estimatedHours: firstTask.estimatedHours,
tags: [...(firstTask.tags || []), 'user-requested', 'ultra-granular']
});
const startTime = Date.now();
const userRefinementResult = await rddEngine.decomposeTask(userRefinementTask, projectContext);
const duration = Date.now() - startTime;
expect(userRefinementResult.success).toBe(true);
expect(userRefinementResult.subTasks.length).toBeGreaterThan(1);
// Ensure ultra-granular tasks (2-3 minutes each)
const ultraGranularTasks = userRefinementResult.subTasks.map(task => {
const ultraTask = { ...task };
ultraTask.estimatedHours = Math.min(task.estimatedHours, 3/60); // Max 3 minutes
if (!ultraTask.tags || !Array.isArray(ultraTask.tags)) {
ultraTask.tags = firstTask.tags || ['authentication'];
}
return ultraTask;
});
logger.info({
originalTaskId: firstTask.id,
originalMinutes: firstTask.estimatedHours * 60,
ultraGranularCount: ultraGranularTasks.length,
averageMinutesPerTask: (ultraGranularTasks.reduce((sum, t) => sum + t.estimatedHours, 0) / ultraGranularTasks.length) * 60,
duration
}, '✅ User-requested ultra-granular refinement completed');
expect(ultraGranularTasks.length).toBeGreaterThan(1);
expect(ultraGranularTasks.every(task => task.estimatedHours <= 3/60)).toBe(true);
}
}, METICULOUS_TIMEOUT);
});
describe('📊 Step 5: Scheduling Ultra-Granular Tasks', () => {
it('should schedule all 5-minute tasks with proper dependencies', async () => {
// Create dependency graph for ultra-granular tasks
const dependencyGraph = new OptimizedDependencyGraph();
refinedTasks.forEach(task => dependencyGraph.addTask(task));
// Test scheduling with hybrid_optimal algorithm
const startTime = Date.now();
(taskScheduler as Record<string, unknown>).config.algorithm = 'hybrid_optimal';
const schedule = await taskScheduler.generateSchedule(
refinedTasks,
dependencyGraph,
'enterprise-auth-system'
);
const duration = Date.now() - startTime;
expect(schedule).toBeDefined();
expect(schedule.scheduledTasks.size).toBe(refinedTasks.length);
expect(duration).toBeLessThan(10000); // Should be fast for granular tasks
// Analyze scheduling efficiency
const scheduledTasksArray = Array.from(schedule.scheduledTasks.values());
const totalScheduledMinutes = scheduledTasksArray.reduce((sum, task) => sum + (task.estimatedHours * 60), 0);
const averageTaskMinutes = totalScheduledMinutes / scheduledTasksArray.length;
logger.info({
totalTasks: scheduledTasksArray.length,
totalMinutes: totalScheduledMinutes,
averageTaskMinutes,
schedulingDuration: duration,
algorithm: 'hybrid_optimal'
}, '📅 Ultra-granular task scheduling completed');
expect(averageTaskMinutes).toBeLessThanOrEqual(5);
expect(totalScheduledMinutes).toBeGreaterThan(0);
});
});
describe('🎉 Step 6: Validation & Output Generation', () => {
it('should validate meticulous decomposition and generate comprehensive outputs', async () => {
// Validate decomposition quality
const TARGET_MINUTES = 5;
const oversizedTasks = refinedTasks.filter(task => (task.estimatedHours * 60) > TARGET_MINUTES);
const averageTaskMinutes = refinedTasks.length > 0
? (refinedTasks.reduce((sum, task) => sum + task.estimatedHours, 0) / refinedTasks.length) * 60
: 0;
expect(oversizedTasks.length).toBe(0);
if (refinedTasks.length > 0) {
expect(averageTaskMinutes).toBeLessThanOrEqual(TARGET_MINUTES);
}
// Generate comprehensive metrics
const decompositionMetrics = {
originalTask: {
id: originalTask.id,
title: originalTask.title,
estimatedHours: originalTask.estimatedHours,
estimatedMinutes: originalTask.estimatedHours * 60
},
initialDecomposition: {
taskCount: decomposedTasks.length,
totalHours: decomposedTasks.reduce((sum, task) => sum + task.estimatedHours, 0),
averageHours: decomposedTasks.reduce((sum, task) => sum + task.estimatedHours, 0) / decomposedTasks.length
},
meticulousRefinement: {
taskCount: refinedTasks.length,
totalMinutes: refinedTasks.reduce((sum, task) => sum + (task.estimatedHours * 60), 0),
averageMinutes: averageTaskMinutes,
maxTaskMinutes: Math.max(...refinedTasks.map(task => task.estimatedHours * 60)),
minTaskMinutes: Math.min(...refinedTasks.map(task => task.estimatedHours * 60))
},
decompositionRatio: refinedTasks.length / 1, // From 1 original task
granularityAchieved: averageTaskMinutes <= TARGET_MINUTES
};
// Save outputs
await saveMeticulousOutputs(originalTask, decomposedTasks, refinedTasks, decompositionMetrics);
logger.info({
...decompositionMetrics,
validationStatus: 'SUCCESS',
outputsGenerated: true
}, '🎉 METICULOUS DECOMPOSITION SCENARIO COMPLETED SUCCESSFULLY');
// Final assertions
expect(decompositionMetrics.granularityAchieved).toBe(true);
expect(decompositionMetrics.decompositionRatio).toBeGreaterThan(10); // At least 10x decomposition
expect(decompositionMetrics.meticulousRefinement.averageMinutes).toBeLessThanOrEqual(TARGET_MINUTES);
});
});
});
// Helper function to create complex tasks
function createComplexTask(overrides: Partial<AtomicTask>): AtomicTask {
const baseTask: AtomicTask = {
id: 'complex-task-001',
title: 'Complex Task',
description: 'Complex task description requiring detailed breakdown',
status: 'pending',
priority: 'high',
type: 'development',
estimatedHours: 8,
actualHours: 0,
epicId: 'auth-epic-001',
projectId: 'enterprise-auth-system',
dependencies: [],
dependents: [],
filePaths: ['src/auth/', 'src/middleware/', 'src/utils/'],
acceptanceCriteria: [
'All functionality implemented and tested',
'Code review completed',
'Documentation updated',
'Security review passed'
],
testingRequirements: {
unitTests: ['Component tests', 'Service tests'],
integrationTests: ['API tests', 'Authentication flow tests'],
performanceTests: ['Load testing'],
coverageTarget: 95
},
performanceCriteria: {
responseTime: '< 100ms',
memoryUsage: '< 256MB'
},
qualityCriteria: {
codeQuality: ['ESLint passing', 'TypeScript strict'],
documentation: ['JSDoc comments', 'API docs'],
typeScript: true,
eslint: true
},
integrationCriteria: {
compatibility: ['Node.js 18+'],
patterns: ['MVC', 'Strategy Pattern']
},
validationMethods: {
automated: ['Unit tests', 'Integration tests'],
manual: ['Code review', 'Security audit']
},
createdAt: new Date(),
updatedAt: new Date(),
createdBy: 'meticulous-decomposer',
tags: ['authentication', 'security'],
metadata: {
createdAt: new Date(),
updatedAt: new Date(),
createdBy: 'meticulous-decomposer',
tags: ['authentication', 'security']
}
};
return { ...baseTask, ...overrides };
}
// Helper function to save meticulous decomposition outputs
async function saveMeticulousOutputs(
originalTask: AtomicTask,
decomposedTasks: AtomicTask[],
refinedTasks: AtomicTask[],
metrics: Record<string, unknown>
): Promise<void> {
try {
// Use the correct Vibe Task Manager output directory pattern
const baseOutputDir = process.env.VIBE_CODER_OUTPUT_DIR || path.join(process.cwd(), 'VibeCoderOutput');
const outputDir = path.join(baseOutputDir, 'vibe-task-manager', 'scenarios', 'meticulous-decomposition');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Save all decomposition stages
fs.writeFileSync(
path.join(outputDir, 'original-task.json'),
JSON.stringify(originalTask, null, 2)
);
fs.writeFileSync(
path.join(outputDir, 'decomposed-tasks.json'),
JSON.stringify(decomposedTasks, null, 2)
);
fs.writeFileSync(
path.join(outputDir, 'refined-5min-tasks.json'),
JSON.stringify(refinedTasks, null, 2)
);
fs.writeFileSync(
path.join(outputDir, 'decomposition-metrics.json'),
JSON.stringify(metrics, null, 2)
);
// Create detailed breakdown report
const report = `
# Meticulous Task Decomposition Report
## Original Task
- **Title**: ${originalTask.title}
- **Estimated Time**: ${originalTask.estimatedHours} hours (${originalTask.estimatedHours * 60} minutes)
- **Complexity**: High
## Decomposition Results
- **Initial Breakdown**: ${decomposedTasks.length} tasks
- **Final Refinement**: ${refinedTasks.length} ultra-granular tasks
- **Decomposition Ratio**: ${refinedTasks.length}:1
- **Average Task Duration**: ${metrics.meticulousRefinement.averageMinutes.toFixed(1)} minutes
- **Target Achievement**: ${metrics.granularityAchieved ? '✅ SUCCESS' : '❌ FAILED'}
## 5-Minute Task Breakdown
${refinedTasks.map((task, index) => `
### ${index + 1}. ${task.title}
- **Duration**: ${(task.estimatedHours * 60).toFixed(1)} minutes
- **Description**: ${task.description.substring(0, 100)}...
- **Tags**: ${task.tags?.join(', ') || 'N/A'}
`).join('')}
## Metrics Summary
${JSON.stringify(metrics, null, 2)}
`;
fs.writeFileSync(
path.join(outputDir, 'decomposition-report.md'),
report
);
logger.info({
outputDir,
filesGenerated: 5,
totalRefinedTasks: refinedTasks.length
}, '📁 Meticulous decomposition outputs saved');
} catch (error) {
logger.warn({ err: error }, 'Failed to save meticulous outputs');
}
}