@@ -17,6 +17,8 @@ import { nextNodePosition } from "./node-position";
1717
1818const EVAL_GLOW_DURATION_MS = 2000 ;
1919const DEFAULT_LAYOUT_VIEWPORT = { width : 1200 , height : 800 } ;
20+ const TASK_VERTICAL_OFFSET = 200 ;
21+ const TASK_VERTICAL_STAGGER = 24 ;
2022
2123function mapEngineStatus ( engineStatus : string ) : SessionStatus {
2224 switch ( engineStatus ) {
@@ -96,10 +98,20 @@ function seedBoardFromEngineSnapshot(engine: SwarmOrchestrator): void {
9698 position : agentPositions . get ( agent . id ) ,
9799 } ) ) ;
98100
99- const taskNodes = Object . values ( snapshot . tasks ) . map ( ( task , index ) => {
101+ const seededTaskCounts = new Map < string , number > ( ) ;
102+
103+ const taskNodes = Object . values ( snapshot . tasks ) . map ( ( task ) => {
100104 const agentPosition = task . assignedTo
101105 ? agentPositions . get ( task . assignedTo )
102106 : undefined ;
107+ const taskIndex = task . assignedTo
108+ ? ( seededTaskCounts . get ( task . assignedTo ) ?? 0 )
109+ : 0 ;
110+
111+ if ( task . assignedTo ) {
112+ seededTaskCounts . set ( task . assignedTo , taskIndex + 1 ) ;
113+ }
114+
103115 return {
104116 id : task . id ,
105117 taskId : task . id ,
@@ -115,7 +127,7 @@ function seedBoardFromEngineSnapshot(engine: SwarmOrchestrator): void {
115127 previewLines : task . previewLines ,
116128 } ,
117129 position : agentPosition
118- ? { x : agentPosition . x , y : agentPosition . y + 200 + index * 24 }
130+ ? getStackedTaskPosition ( agentPosition , taskIndex )
119131 : undefined ,
120132 } ;
121133 } ) ;
@@ -177,6 +189,47 @@ function buildTopologyEdges(
177189 } ) ;
178190}
179191
192+ function getStackedTaskPosition (
193+ agentPosition : { x : number ; y : number } ,
194+ taskIndex : number ,
195+ ) : { x : number ; y : number } {
196+ return {
197+ x : agentPosition . x ,
198+ y : agentPosition . y + TASK_VERTICAL_OFFSET + taskIndex * TASK_VERTICAL_STAGGER ,
199+ } ;
200+ }
201+
202+ function getAssignedTaskPosition (
203+ nodes : Node < SwarmBoardNodeData > [ ] ,
204+ agentId : string | null | undefined ,
205+ excludeTaskNodeId ?: string ,
206+ ) : { x : number ; y : number } | undefined {
207+ if ( ! agentId ) {
208+ return undefined ;
209+ }
210+
211+ const agentNode = nodes . find (
212+ ( node ) => node . data . agentId === agentId ,
213+ ) ;
214+
215+ if ( ! agentNode ) {
216+ return undefined ;
217+ }
218+
219+ const siblingTaskCount = nodes . filter ( ( node ) => {
220+ if ( node . id === excludeTaskNodeId ) {
221+ return false ;
222+ }
223+
224+ return (
225+ node . data . nodeType === "terminalTask" &&
226+ node . data . agentId === agentId
227+ ) ;
228+ } ) . length ;
229+
230+ return getStackedTaskPosition ( agentNode . position , siblingTaskCount ) ;
231+ }
232+
180233function getLayoutViewport ( ) : { width : number ; height : number } {
181234 if ( typeof window === "undefined" ) {
182235 return DEFAULT_LAYOUT_VIEWPORT ;
@@ -292,9 +345,10 @@ export function useEngineBoardBridge(engine: SwarmOrchestrator | null): void {
292345 n . data . agentId === event . task . assignedTo ,
293346 ) ;
294347
295- const position = parentNode
296- ? { x : parentNode . position . x , y : parentNode . position . y + 200 }
297- : nextNodePosition ( nodes ) ;
348+ const position = getAssignedTaskPosition (
349+ nodes ,
350+ event . task . assignedTo ,
351+ ) ?? nextNodePosition ( nodes ) ;
298352
299353 const taskNode = {
300354 ...createBoardNode ( {
@@ -363,7 +417,10 @@ export function useEngineBoardBridge(engine: SwarmOrchestrator | null): void {
363417 return {
364418 ...node ,
365419 position : agentNode
366- ? { x : agentNode . position . x , y : agentNode . position . y + 200 }
420+ ? (
421+ getAssignedTaskPosition ( nodes , event . agentId , taskNode . id ) ??
422+ node . position
423+ )
367424 : node . position ,
368425 data : {
369426 ...node . data ,
0 commit comments