/** * Initiative Activity — derives current activity state from initiative + phases. */ import type { Initiative, Phase } from '../../db/schema.js'; import type { InitiativeActivity, InitiativeActivityState } from '@codewalk-district/shared'; export interface ActiveArchitectAgent { initiativeId: string; mode: string; status: string; } const MODE_TO_STATE: Record = { discuss: 'discussing', plan: 'detailing', detail: 'detailing', refine: 'refining', }; export function deriveInitiativeActivity( initiative: Initiative, phases: Phase[], activeArchitectAgents?: ActiveArchitectAgent[], ): InitiativeActivity { const phasesTotal = phases.length; const phasesCompleted = phases.filter(p => p.status === 'completed').length; const base = { phasesTotal, phasesCompleted }; if (initiative.status === 'archived') { return { ...base, state: 'archived' }; } if (initiative.status === 'pending_review') { return { ...base, state: 'pending_review' }; } if (initiative.status === 'completed') { return { ...base, state: 'complete' }; } // Check for active architect agents BEFORE zero-phases check // so architect agents (discuss/plan/detail/refine) surface activity const activeAgent = activeArchitectAgents?.find( a => a.initiativeId === initiative.id && (a.status === 'running' || a.status === 'waiting_for_input'), ); if (activeAgent) { const state = MODE_TO_STATE[activeAgent.mode] ?? 'detailing'; return { ...base, state }; } if (phasesTotal === 0) { return { ...base, state: 'idle' }; } // Priority-ordered state detection (first match wins) const priorities: Array<{ status: Phase['status']; state: InitiativeActivityState }> = [ { status: 'pending_review', state: 'pending_review' }, { status: 'in_progress', state: 'executing' }, { status: 'blocked', state: 'blocked' }, ]; for (const { status, state } of priorities) { const match = phases.find(p => p.status === status); if (match) { return { ...base, state, activePhase: { id: match.id, name: match.name } }; } } if (phasesCompleted === phasesTotal) { return { ...base, state: 'complete' }; } const approved = phases.find(p => p.status === 'approved'); if (approved) { return { ...base, state: 'ready', activePhase: { id: approved.id, name: approved.name } }; } return { ...base, state: 'planning' }; }