@@ -12,6 +12,8 @@ import type { paths, components } from "../api/opencode-types";
1212import { parseNetworkError } from "../lib/opencode-errors" ;
1313import { showToast } from "../lib/toast" ;
1414import { useSendErrorStore } from "../stores/sendErrorStore" ;
15+ import { beginOptimisticBusy , rollbackOptimisticBusy } from "../stores/sessionStatusStore" ;
16+ import type { SessionStatusType } from "../stores/sessionStatusStore" ;
1517import { invalidateSessionListCaches , messagesQueryKey } from "../lib/queryInvalidation" ;
1618
1719type AssistantMessage = components [ "schemas" ] [ "AssistantMessage" ] ;
@@ -22,6 +24,8 @@ type SendPromptRequest = NonNullable<
2224
2325type SendCommandResponse = paths [ "/session/{sessionID}/command" ] [ "post" ] [ "responses" ] [ "200" ] [ "content" ] [ "application/json" ] ;
2426
27+ type OptimisticBusyContext = { previousBusyStatus : SessionStatusType } ;
28+
2529const parseModelString = ( model : string ) => {
2630 const [ providerID , ...rest ] = model . split ( "/" ) ;
2731 const modelID = rest . join ( "/" ) ;
@@ -477,8 +481,13 @@ export const useSendPrompt = (opcodeUrl: string | null | undefined, directory?:
477481
478482 return { optimisticUserID, response, queued : false } ;
479483 } ,
480- onError : ( error , variables ) => {
484+ onMutate : ( { sessionID } ) : OptimisticBusyContext => ( {
485+ previousBusyStatus : beginOptimisticBusy ( sessionID ) ,
486+ } ) ,
487+ onError : ( error , variables , context : OptimisticBusyContext | undefined ) => {
481488 const { sessionID } = variables ;
489+ rollbackOptimisticBusy ( sessionID , context ?. previousBusyStatus ?? { type : 'idle' } ) ;
490+
482491 const queryKey = messagesQueryKey ( opcodeUrl , sessionID , directory ) ;
483492
484493 queryClient . setQueryData < MessageWithParts [ ] > (
@@ -726,8 +735,12 @@ export const useSendShell = (opcodeUrl: string | null | undefined, directory?: s
726735
727736 return { optimisticUserID, response } ;
728737 } ,
729- onError : ( _ , variables ) => {
738+ onMutate : ( { sessionID } ) : OptimisticBusyContext => ( {
739+ previousBusyStatus : beginOptimisticBusy ( sessionID ) ,
740+ } ) ,
741+ onError : ( _error , variables , context : OptimisticBusyContext | undefined ) => {
730742 const { sessionID } = variables ;
743+ rollbackOptimisticBusy ( sessionID , context ?. previousBusyStatus ?? { type : 'idle' } ) ;
731744 queryClient . setQueryData < MessageWithParts [ ] > (
732745 messagesQueryKey ( opcodeUrl , sessionID , directory ) ,
733746 ( old ) => {
@@ -788,7 +801,8 @@ export const useLoadSkill = (
788801 return useMutation <
789802 { optimisticUserID : string ; response : SendCommandResponse } ,
790803 Error ,
791- { skillName : string }
804+ { skillName : string } ,
805+ OptimisticBusyContext | undefined
792806 > ( {
793807 mutationFn : async ( { skillName } : { skillName : string } ) => {
794808 if ( ! client ) throw new Error ( "No OpenCode client available" ) ;
@@ -817,7 +831,14 @@ export const useLoadSkill = (
817831 const response = await client . sendCommand ( sessionID , { command : skillName , arguments : "" } ) ;
818832 return { optimisticUserID, response } ;
819833 } ,
820- onError : ( error ) => {
834+ onMutate : ( ) => {
835+ if ( ! sessionID ) return undefined ;
836+ return { previousBusyStatus : beginOptimisticBusy ( sessionID ) } ;
837+ } ,
838+ onError : ( error , _variables , context : OptimisticBusyContext | undefined ) => {
839+ if ( sessionID && context ?. previousBusyStatus ) {
840+ rollbackOptimisticBusy ( sessionID , context . previousBusyStatus ) ;
841+ }
821842 if ( sessionID ) {
822843 const queryKey = messagesQueryKey ( opcodeUrl , sessionID , directory ) ;
823844 queryClient . setQueryData < MessageWithParts [ ] > (
0 commit comments