feat: Task decomposition for Tailwind/Radix/shadcn foundation setup
Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind" phase into 6 executable tasks: 1. Install Tailwind CSS, PostCSS & Autoprefixer 2. Map MUI theme to Tailwind design tokens 3. Setup CSS variables for dynamic theming 4. Install Radix UI primitives 5. Initialize shadcn/ui and setup component directory 6. Move MUI to devDependencies and verify setup Tasks follow logical dependency chain with final human verification checkpoint before proceeding with component migration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,10 @@ import type { AgentManager } from '../agent/types.js';
|
||||
import type { TaskRepository } from '../db/repositories/task-repository.js';
|
||||
import type { MessageRepository } from '../db/repositories/message-repository.js';
|
||||
import type { InitiativeRepository } from '../db/repositories/initiative-repository.js';
|
||||
import type { PhaseRepository } from '../db/repositories/phase-repository.js';
|
||||
import type { Task } from '../db/schema.js';
|
||||
import type { DispatchManager, QueuedTask, DispatchResult } from './types.js';
|
||||
import { initiativeBranchName, phaseBranchName, taskBranchName } from '../git/branch-naming.js';
|
||||
import { createModuleLogger } from '../logger/index.js';
|
||||
|
||||
const log = createModuleLogger('dispatch');
|
||||
@@ -59,7 +61,8 @@ export class DefaultDispatchManager implements DispatchManager {
|
||||
private messageRepository: MessageRepository,
|
||||
private agentManager: AgentManager,
|
||||
private eventBus: EventBus,
|
||||
private initiativeRepository?: InitiativeRepository
|
||||
private initiativeRepository?: InitiativeRepository,
|
||||
private phaseRepository?: PhaseRepository,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -320,10 +323,39 @@ export class DefaultDispatchManager implements DispatchManager {
|
||||
};
|
||||
}
|
||||
|
||||
// Compute branch info for branch-aware spawning
|
||||
let baseBranch: string | undefined;
|
||||
let branchName: string | undefined;
|
||||
|
||||
if (task.phaseId && task.initiativeId && this.initiativeRepository && this.phaseRepository) {
|
||||
try {
|
||||
const initiative = await this.initiativeRepository.findById(task.initiativeId);
|
||||
const phase = await this.phaseRepository.findById(task.phaseId);
|
||||
if (initiative?.mergeTarget && phase) {
|
||||
const initBranch = initiativeBranchName(initiative.mergeTarget);
|
||||
|
||||
if (task.category === 'merge') {
|
||||
// Merge tasks work directly on the phase branch
|
||||
baseBranch = initBranch;
|
||||
branchName = phaseBranchName(initBranch, phase.name);
|
||||
} else {
|
||||
baseBranch = phaseBranchName(initBranch, phase.name);
|
||||
branchName = taskBranchName(initBranch, task.id);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Non-fatal: fall back to default branching
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn agent with task (alias auto-generated by agent manager)
|
||||
const agent = await this.agentManager.spawn({
|
||||
taskId: nextTask.taskId,
|
||||
initiativeId: task.initiativeId ?? undefined,
|
||||
phaseId: task.phaseId ?? undefined,
|
||||
prompt: task.description || task.name,
|
||||
baseBranch,
|
||||
branchName,
|
||||
});
|
||||
|
||||
log.info({ taskId: nextTask.taskId, agentId: agent.id }, 'task dispatched');
|
||||
|
||||
@@ -16,7 +16,15 @@ import type {
|
||||
} from '../events/index.js';
|
||||
import type { PhaseRepository } from '../db/repositories/phase-repository.js';
|
||||
import type { TaskRepository } from '../db/repositories/task-repository.js';
|
||||
import type { InitiativeRepository } from '../db/repositories/initiative-repository.js';
|
||||
import type { ProjectRepository } from '../db/repositories/project-repository.js';
|
||||
import type { BranchManager } from '../git/branch-manager.js';
|
||||
import type { PhaseDispatchManager, DispatchManager, QueuedPhase, PhaseDispatchResult } from './types.js';
|
||||
import { initiativeBranchName, phaseBranchName } from '../git/branch-naming.js';
|
||||
import { ensureProjectClone } from '../git/project-clones.js';
|
||||
import { createModuleLogger } from '../logger/index.js';
|
||||
|
||||
const log = createModuleLogger('phase-dispatch');
|
||||
|
||||
// =============================================================================
|
||||
// Internal Types
|
||||
@@ -51,7 +59,11 @@ export class DefaultPhaseDispatchManager implements PhaseDispatchManager {
|
||||
private phaseRepository: PhaseRepository,
|
||||
private taskRepository: TaskRepository,
|
||||
private dispatchManager: DispatchManager,
|
||||
private eventBus: EventBus
|
||||
private eventBus: EventBus,
|
||||
private initiativeRepository?: InitiativeRepository,
|
||||
private projectRepository?: ProjectRepository,
|
||||
private branchManager?: BranchManager,
|
||||
private workspaceRoot?: string,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -156,6 +168,26 @@ export class DefaultPhaseDispatchManager implements PhaseDispatchManager {
|
||||
// Update phase status to 'in_progress'
|
||||
await this.phaseRepository.update(nextPhase.phaseId, { status: 'in_progress' });
|
||||
|
||||
// Create phase branch in all linked project clones
|
||||
if (this.initiativeRepository && this.projectRepository && this.branchManager && this.workspaceRoot) {
|
||||
try {
|
||||
const initiative = await this.initiativeRepository.findById(phase.initiativeId);
|
||||
if (initiative?.mergeTarget) {
|
||||
const initBranch = initiativeBranchName(initiative.mergeTarget);
|
||||
const phBranch = phaseBranchName(initBranch, phase.name);
|
||||
const projects = await this.projectRepository.findProjectsByInitiativeId(phase.initiativeId);
|
||||
for (const project of projects) {
|
||||
const clonePath = await ensureProjectClone(project, this.workspaceRoot);
|
||||
await this.branchManager.ensureBranch(clonePath, initBranch, 'main');
|
||||
await this.branchManager.ensureBranch(clonePath, phBranch, initBranch);
|
||||
}
|
||||
log.info({ phaseId: nextPhase.phaseId, phBranch, initBranch }, 'phase branch created');
|
||||
}
|
||||
} catch (err) {
|
||||
log.error({ phaseId: nextPhase.phaseId, err: err instanceof Error ? err.message : String(err) }, 'failed to create phase branch');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from queue (now being worked on)
|
||||
this.phaseQueue.delete(nextPhase.phaseId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user