@@ -17,38 +17,16 @@ export interface LayoutTasksResult {
1717 readonly nodeH : number
1818}
1919
20- /**
21- * OMA often omits dependsOn on final task records. When no task declares deps,
22- * infer a simple chain in plan order so the DAG still renders edges.
23- */
24- export function resolveTaskDependencies < T extends LayoutTaskInput > (
25- taskList : readonly T [ ] ,
26- ) : readonly ( T & { readonly dependsOn : readonly string [ ] } ) [ ] {
27- const hasExplicit = taskList . some ( ( task ) => ( task . dependsOn ?. length ?? 0 ) > 0 )
28- if ( hasExplicit || taskList . length < 2 ) {
29- return taskList . map ( ( task ) => ( {
30- ...task ,
31- dependsOn : task . dependsOn ?? [ ] ,
32- } ) )
33- }
34-
35- return taskList . map ( ( task , index ) => ( {
36- ...task ,
37- dependsOn : index === 0 ? [ ] : [ taskList [ index - 1 ] ! . id ] ,
38- } ) )
39- }
40-
41- /** Topological column layout for the team-run DAG canvas. */
20+ /** Topological column layout for the team-run DAG canvas (matches oma-core layout). */
4221export function layoutTasks < T extends LayoutTaskInput > (
4322 taskList : readonly T [ ] ,
4423) : LayoutTasksResult {
45- const normalized = resolveTaskDependencies ( taskList )
46- const byId = new Map ( normalized . map ( ( task ) => [ task . id , task ] ) )
47- const children = new Map < string , string [ ] > ( normalized . map ( ( task ) => [ task . id , [ ] ] ) )
24+ const byId = new Map ( taskList . map ( ( task ) => [ task . id , task ] ) )
25+ const children = new Map < string , string [ ] > ( taskList . map ( ( task ) => [ task . id , [ ] ] ) )
4826 const indegree = new Map < string , number > ( )
4927
50- for ( const task of normalized ) {
51- const deps = task . dependsOn . filter ( ( dep ) => byId . has ( dep ) )
28+ for ( const task of taskList ) {
29+ const deps = ( task . dependsOn ?? [ ] ) . filter ( ( dep ) => byId . has ( dep ) )
5230 indegree . set ( task . id , deps . length )
5331 for ( const depId of deps ) {
5432 children . get ( depId ) ! . push ( task . id )
@@ -58,7 +36,7 @@ export function layoutTasks<T extends LayoutTaskInput>(
5836 const levels = new Map < string , number > ( )
5937 const queue : string [ ] = [ ]
6038 let processed = 0
61- for ( const task of normalized ) {
39+ for ( const task of taskList ) {
6240 if ( ( indegree . get ( task . id ) ?? 0 ) === 0 ) {
6341 levels . set ( task . id , 0 )
6442 queue . push ( task . id )
@@ -79,16 +57,16 @@ export function layoutTasks<T extends LayoutTaskInput>(
7957 }
8058 }
8159
82- if ( processed !== normalized . length ) {
60+ if ( processed !== taskList . length ) {
8361 throw new Error ( 'Task dependency graph contains a cycle' )
8462 }
8563
86- for ( const task of normalized ) {
64+ for ( const task of taskList ) {
8765 if ( ! levels . has ( task . id ) ) levels . set ( task . id , 0 )
8866 }
8967
90- const cols = new Map < number , ( typeof normalized ) [ number ] [ ] > ( )
91- for ( const task of normalized ) {
68+ const cols = new Map < number , T [ ] > ( )
69+ for ( const task of taskList ) {
9270 const level = levels . get ( task . id ) ?? 0
9371 if ( ! cols . has ( level ) ) cols . set ( level , [ ] )
9472 cols . get ( level ) ! . push ( task )
@@ -116,8 +94,8 @@ export function layoutTasks<T extends LayoutTaskInput>(
11694 }
11795
11896 const edges : LayoutEdge [ ] = [ ]
119- for ( const task of normalized ) {
120- for ( const depId of task . dependsOn ) {
97+ for ( const task of taskList ) {
98+ for ( const depId of task . dependsOn ?? [ ] ) {
12199 if ( byId . has ( depId ) ) edges . push ( { fromId : depId , toId : task . id } )
122100 }
123101 }
0 commit comments