@@ -828,6 +828,57 @@ function makeCardsFromKanban(kanban?: KanbanState): Card[] {
828828 ) ;
829829}
830830
831+ function upsertMovementRunIntoKanban ( kanban : KanbanState | undefined , rawRun : unknown ) : KanbanState {
832+ const parsed = KanbanCardSchema . safeParse ( rawRun ) ;
833+ const run = parsed . success ? parsed . data : ( rawRun || { } ) as z . infer < typeof KanbanCardSchema > ;
834+ const key = String ( run . issue_id || run . id || run . linear_identifier || run . identifier || '' ) ;
835+ const targetId = kanbanColumnIdForRun ( run ) ;
836+ const generatedAt = new Date ( ) . toISOString ( ) ;
837+ const baseColumns = kanban ?. columns ?. length
838+ ? kanban . columns
839+ : [
840+ { id : 'running' , title : 'Running' , count : 0 , cards : [ ] } ,
841+ { id : 'retrying' , title : 'Retrying' , count : 0 , cards : [ ] } ,
842+ { id : 'completed' , title : 'Completed' , count : 0 , cards : [ ] }
843+ ] ;
844+
845+ const columns = baseColumns . map ( column => ( {
846+ ...column ,
847+ cards : column . cards . filter ( card => {
848+ const cardKey = String ( card . issue_id || card . id || card . linear_identifier || card . identifier || '' ) ;
849+ return ! key || cardKey !== key ;
850+ } )
851+ } ) ) ;
852+
853+ const targetIndex = columns . findIndex ( column => column . id === targetId ) ;
854+ const targetColumn = targetIndex >= 0
855+ ? columns [ targetIndex ]
856+ : { id : targetId , title : kanbanColumnTitle ( targetId ) , count : 0 , cards : [ ] } ;
857+ const updatedTarget = { ...targetColumn , cards : [ run , ...targetColumn . cards ] , count : targetColumn . cards . length + 1 } ;
858+ const updatedColumns = targetIndex >= 0
859+ ? columns . map ( ( column , index ) => index === targetIndex ? updatedTarget : { ...column , count : column . cards . length } )
860+ : [ ...columns . map ( column => ( { ...column , count : column . cards . length } ) ) , updatedTarget ] ;
861+
862+ return {
863+ ...( kanban || { } ) ,
864+ generated_at : generatedAt ,
865+ columns : updatedColumns
866+ } ;
867+ }
868+
869+ function kanbanColumnIdForRun ( run : z . infer < typeof KanbanCardSchema > ) {
870+ const status = String ( run . operator_status || run . status || run . state || run . stage || run . phase || '' ) . toLowerCase ( ) ;
871+ if ( status . includes ( 'retry' ) ) return 'retrying' ;
872+ if ( status . includes ( 'complete' ) || status . includes ( 'done' ) ) return 'completed' ;
873+ return 'running' ;
874+ }
875+
876+ function kanbanColumnTitle ( id : string ) {
877+ if ( id === 'retrying' ) return 'Retrying' ;
878+ if ( id === 'completed' ) return 'Completed' ;
879+ return 'Running' ;
880+ }
881+
831882function agentProfileFromCard ( raw : z . infer < typeof KanbanCardSchema > ) {
832883 const profile = raw . agent_profile ;
833884 if ( ! profile || typeof profile !== 'object' || Array . isArray ( profile ) ) return null ;
@@ -1248,7 +1299,11 @@ function App() {
12481299 const createMovement = useMutation ( {
12491300 mutationFn : ( payload : ManualMovementPayload ) =>
12501301 api < Record < string , unknown > > ( base , '/api/movements' , { method : 'POST' , body : JSON . stringify ( payload ) } , 12_000 ) ,
1251- onSuccess : ( ) => {
1302+ onSuccess : data => {
1303+ const run = data && typeof data === 'object' ? data . run : undefined ;
1304+ if ( run && typeof run === 'object' ) {
1305+ queryClient . setQueryData < KanbanState > ( [ 'kanban' , base ] , current => upsertMovementRunIntoKanban ( current , run ) ) ;
1306+ }
12521307 invalidateLiveData ( ) ;
12531308 queryClient . invalidateQueries ( { queryKey : [ 'rehearsalCheck' , base ] } ) ;
12541309 }
0 commit comments