@@ -44,6 +44,8 @@ const (
4444
4545const providerAddSelectTimeout = 10 * time .Second
4646
47+ const sessionSwitchBusyMessage = "cannot switch sessions while run or compact is active"
48+
4749var panelOrder = []panel {panelTranscript , panelActivity , panelInput }
4850var persistProviderUserEnvVar = config .PersistUserEnvVar
4951var deleteProviderUserEnvVar = config .DeleteUserEnvVar
@@ -378,6 +380,12 @@ func (a App) updateInputPanel(msg tea.Msg, typed tea.KeyMsg, cmds []tea.Cmd) (te
378380 }
379381 return a , tea .Batch (cmds ... )
380382 case slashCommandSession :
383+ if err := a .ensureSessionSwitchAllowed ("" ); err != nil {
384+ a .state .ExecutionError = err .Error ()
385+ a .state .StatusText = err .Error ()
386+ a .appendActivity ("session" , "Failed to open session picker" , err .Error (), true )
387+ return a , tea .Batch (cmds ... )
388+ }
381389 if err := a .refreshSessionPicker (); err != nil {
382390 a .state .ExecutionError = err .Error ()
383391 a .state .StatusText = err .Error ()
@@ -774,6 +782,9 @@ func (a *App) activateSelectedSession() error {
774782 if ! ok {
775783 return nil
776784 }
785+ if err := a .ensureSessionSwitchAllowed (item .Summary .ID ); err != nil {
786+ return err
787+ }
777788
778789 a .state .ActiveSessionID = item .Summary .ID
779790 a .state .ActiveSessionTitle = item .Summary .Title
@@ -784,6 +795,9 @@ func (a *App) activateSelectedSession() error {
784795}
785796
786797func (a * App ) activateSessionByID (sessionID string ) error {
798+ if err := a .ensureSessionSwitchAllowed (sessionID ); err != nil {
799+ return err
800+ }
787801 for _ , s := range a .state .Sessions {
788802 if s .ID == sessionID {
789803 a .state .ActiveSessionID = s .ID
@@ -796,6 +810,16 @@ func (a *App) activateSessionByID(sessionID string) error {
796810 return fmt .Errorf ("session not found: %s" , sessionID )
797811}
798812
813+ // ensureSessionSwitchAllowed 统一阻止运行中切换到其他会话,避免 UI 脱离仍在执行的 run 上下文。
814+ func (a * App ) ensureSessionSwitchAllowed (targetSessionID string ) error {
815+ targetSessionID = strings .TrimSpace (targetSessionID )
816+ activeSessionID := strings .TrimSpace (a .state .ActiveSessionID )
817+ if ! a .isBusy () || (targetSessionID != "" && strings .EqualFold (targetSessionID , activeSessionID )) {
818+ return nil
819+ }
820+ return fmt .Errorf (sessionSwitchBusyMessage )
821+ }
822+
799823func (a * App ) syncActiveSessionTitle () {
800824 if strings .TrimSpace (a .state .ActiveSessionID ) == "" {
801825 if strings .TrimSpace (a .state .ActiveSessionTitle ) == "" {
@@ -1894,6 +1918,12 @@ func (a *App) handleImmediateSlashCommand(input string) (bool, tea.Cmd) {
18941918 case slashCommandForget :
18951919 return true , a .handleForgetCommand (rest )
18961920 case slashCommandSession :
1921+ if err := a .ensureSessionSwitchAllowed ("" ); err != nil {
1922+ a .state .ExecutionError = err .Error ()
1923+ a .state .StatusText = err .Error ()
1924+ a .appendActivity ("session" , "Failed to open session picker" , err .Error (), true )
1925+ return true , nil
1926+ }
18971927 if err := a .refreshSessionPicker (); err != nil {
18981928 a .state .ExecutionError = err .Error ()
18991929 a .state .StatusText = err .Error ()
0 commit comments