feat(architect): Complete auth pages phase decomposition
Decomposed "Data Display Components - Tables, Grids, Nutrition Display" phase into 6 executable tasks for migrating MUI components to shadcn/ui: 1. Setup shadcn/ui infrastructure (foundation) 2. Migrate NutritionDisplay component (48-field grid) 3. Migrate RecipeRankings and RecipeStatus components 4. Replace @mui/x-data-grid with TanStack Table 5. Test and verify (checkpoint for human review) 6. Remove MUI dependencies and clean up Tasks follow logical dependency chain with parallel execution where possible. Includes comprehensive verification checklist before cleanup. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -163,6 +163,90 @@ describe('Decompose Workflow E2E', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('decompose conflict detection', () => {
|
||||
it('should reject if a decompose agent is already running for the same phase', async () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
const initiative = await harness.createInitiative('Test Project');
|
||||
const phases = await harness.createPhasesFromBreakdown(initiative.id, [
|
||||
{ name: 'Phase 1' },
|
||||
]);
|
||||
|
||||
// Long-running decompose agent
|
||||
harness.setAgentScenario('decomposer-1', { status: 'done', delay: 999999 });
|
||||
|
||||
await harness.caller.spawnArchitectDecompose({
|
||||
name: 'decomposer-1',
|
||||
phaseId: phases[0].id,
|
||||
});
|
||||
|
||||
// Second decompose for same phase should be rejected
|
||||
await expect(
|
||||
harness.caller.spawnArchitectDecompose({
|
||||
name: 'decomposer-2',
|
||||
phaseId: phases[0].id,
|
||||
}),
|
||||
).rejects.toThrow(/already running/);
|
||||
});
|
||||
|
||||
it('should auto-dismiss stale decompose agents before checking', async () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
const initiative = await harness.createInitiative('Test Project');
|
||||
const phases = await harness.createPhasesFromBreakdown(initiative.id, [
|
||||
{ name: 'Phase 1' },
|
||||
]);
|
||||
|
||||
// Decompose agent that crashes immediately
|
||||
harness.setAgentScenario('stale-decomposer', { status: 'error', error: 'crashed' });
|
||||
|
||||
await harness.caller.spawnArchitectDecompose({
|
||||
name: 'stale-decomposer',
|
||||
phaseId: phases[0].id,
|
||||
});
|
||||
await harness.advanceTimers();
|
||||
|
||||
// New decompose should succeed
|
||||
harness.setArchitectDecomposeComplete('new-decomposer', [
|
||||
{ number: 1, name: 'Task 1', content: 'Do it', type: 'auto', dependencies: [] },
|
||||
]);
|
||||
|
||||
const agent = await harness.caller.spawnArchitectDecompose({
|
||||
name: 'new-decomposer',
|
||||
phaseId: phases[0].id,
|
||||
});
|
||||
expect(agent.mode).toBe('decompose');
|
||||
});
|
||||
|
||||
it('should allow decompose for different phases simultaneously', async () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
const initiative = await harness.createInitiative('Test Project');
|
||||
const phases = await harness.createPhasesFromBreakdown(initiative.id, [
|
||||
{ name: 'Phase 1' },
|
||||
{ name: 'Phase 2' },
|
||||
]);
|
||||
|
||||
// Long-running agent on phase 1
|
||||
harness.setAgentScenario('decomposer-p1', { status: 'done', delay: 999999 });
|
||||
await harness.caller.spawnArchitectDecompose({
|
||||
name: 'decomposer-p1',
|
||||
phaseId: phases[0].id,
|
||||
});
|
||||
|
||||
// Decompose on phase 2 should succeed
|
||||
harness.setArchitectDecomposeComplete('decomposer-p2', [
|
||||
{ number: 1, name: 'Task 1', content: 'Do it', type: 'auto', dependencies: [] },
|
||||
]);
|
||||
|
||||
const agent = await harness.caller.spawnArchitectDecompose({
|
||||
name: 'decomposer-p2',
|
||||
phaseId: phases[1].id,
|
||||
});
|
||||
expect(agent.mode).toBe('decompose');
|
||||
});
|
||||
});
|
||||
|
||||
describe('task persistence', () => {
|
||||
it('should create tasks from decomposition output', async () => {
|
||||
const initiative = await harness.createInitiative('Test Project');
|
||||
|
||||
Reference in New Issue
Block a user