/** * Wave computation and dependency graph operations. * @task T4784 */ import type { Task, TaskPriority, TaskRef } from '@cleocode/contracts'; import type { DataAccessor } from '../store/data-accessor.js'; /** Basic execution wave: task IDs grouped by dependency depth. */ export interface Wave { /** 1-based wave number. */ waveNumber: number; /** Task IDs belonging to this wave. */ tasks: string[]; /** Computed lifecycle status of this wave. */ status: 'pending' | 'in_progress' | 'completed'; } /** * Enriched task reference within a wave. * * Carries all fields needed by the wave renderer so callers do not need a * secondary lookup. `blockedBy` lists open (non-terminal) dependency IDs; * `ready` is `true` when the task is immediately actionable. */ export interface EnrichedWaveTask extends TaskRef { /** Task priority level. */ priority: TaskPriority; /** * All declared dependency IDs for this task. * * Empty array when the task has no dependencies. */ depends: string[]; /** * Open (non-terminal) dependency IDs that are currently blocking this task. * * A dependency is open when its status is not `'done'` or `'cancelled'`. */ blockedBy: string[]; /** * Whether this task is immediately actionable. * * `true` when `blockedBy` is empty AND `status` is `'pending'` or `'active'`. */ ready: boolean; } /** * Enriched execution wave carrying per-task metadata for rendering. * * All tasks within the wave are sorted by priority (critical → high → medium → * low) descending, then by open-dependency count ascending, then by ID for * deterministic stability. */ export interface EnrichedWave { /** 1-based wave number. */ waveNumber: number; /** Enriched, priority-sorted tasks for this wave. */ tasks: EnrichedWaveTask[]; /** * Plain task ID list — convenience alias for `tasks.map(t => t.id)`. * * Orchestrators and scripts that only need the IDs (e.g. to spawn agents or * log wave membership) can read this field directly without mapping over * the enriched task objects. Always populated when `tasks` is non-empty. */ taskIds: string[]; /** Computed lifecycle status of this wave. */ status: 'pending' | 'in_progress' | 'completed'; /** * ISO timestamp of the latest `completedAt` among wave tasks. * * Present only when `status === 'completed'` and at least one task carries a * `completedAt` value. */ completedAt?: string; } /** * Compute execution waves using topological sort. * * Tasks that are already done/cancelled are pre-seeded into the `completed` set * so their dependants can be scheduled in wave 1. Wave status is derived from * the live `task.status` field rather than the local `completed` set (which * excludes non-terminal tasks and would always yield `false` for in-flight work). * * @param tasks - All tasks to partition into dependency waves. * @returns Ordered waves where each wave's tasks can execute in parallel. */ export declare function computeWaves(tasks: Task[]): Wave[]; /** * Get enriched wave data for an epic. * * Resolves the epic's direct children, computes topological waves, enriches * each wave's task list with dependency metadata, sorts tasks within each wave * by priority descending then open-dep count ascending, and attaches a * `completedAt` timestamp to completed waves. * * @param epicId - The epic task ID to compute waves for. * @param cwd - Optional project root (falls back to `getTaskAccessor` default). * @param accessor - Optional pre-constructed data accessor (useful in tests). */ export declare function getEnrichedWaves(epicId: string, cwd?: string, accessor?: DataAccessor): Promise<{ epicId: string; waves: EnrichedWave[]; totalWaves: number; totalTasks: number; }>; //# sourceMappingURL=waves.d.ts.map