99
1010 "github.com/andyrewlee/amux/internal/data"
1111 "github.com/andyrewlee/amux/internal/logging"
12+ "github.com/andyrewlee/amux/internal/tmux"
1213 "github.com/andyrewlee/amux/internal/ui/sidebar"
1314)
1415
@@ -144,11 +145,13 @@ func (a *App) discoverSidebarTerminalsFromTmux(ws *data.Workspace) tea.Cmd {
144145 logging .Warn ("tmux sidebar discovery failed: %v" , err )
145146 return tmuxSidebarDiscoverResult {WorkspaceID : wsID }
146147 }
148+ seen := make (map [string ]struct {}, len (rows ))
147149 sessions := make ([]sidebarSessionInfo , 0 , len (rows ))
148150 for _ , row := range rows {
149151 if row .Name == "" {
150152 continue
151153 }
154+ seen [row .Name ] = struct {}{}
152155 state , err := svc .SessionStateFor (row .Name , opts )
153156 if err != nil || ! state .Exists || ! state .HasLivePane {
154157 continue
@@ -175,6 +178,9 @@ func (a *App) discoverSidebarTerminalsFromTmux(ws *data.Workspace) tea.Cmd {
175178 hasClients : attached ,
176179 })
177180 }
181+ if fallback := a .discoverLegacySidebarSessions (wsID , opts , svc , seen ); len (fallback ) > 0 {
182+ sessions = append (sessions , fallback ... )
183+ }
178184 if len (sessions ) == 0 {
179185 return tmuxSidebarDiscoverResult {WorkspaceID : wsID }
180186 }
@@ -183,6 +189,91 @@ func (a *App) discoverSidebarTerminalsFromTmux(ws *data.Workspace) tea.Cmd {
183189 }
184190}
185191
192+ // discoverLegacySidebarSessions finds likely terminal sessions created by older
193+ // builds that are missing @amux tags and retags them.
194+ func (a * App ) discoverLegacySidebarSessions (wsID string , opts tmux.Options , svc * tmuxService , seen map [string ]struct {}) []sidebarSessionInfo {
195+ if wsID == "" || svc == nil {
196+ return nil
197+ }
198+ names , err := tmux .ListSessions (opts )
199+ if err != nil {
200+ logging .Warn ("tmux sidebar fallback discovery failed: %v" , err )
201+ return nil
202+ }
203+ sessionPrefix := tmux .SessionName ("amux" , wsID ) + "-"
204+ out := make ([]sidebarSessionInfo , 0 , len (names ))
205+ for _ , raw := range names {
206+ name := strings .TrimSpace (raw )
207+ if name == "" {
208+ continue
209+ }
210+ if _ , ok := seen [name ]; ok {
211+ continue
212+ }
213+ if ! strings .HasPrefix (name , sessionPrefix ) {
214+ continue
215+ }
216+ tabID := strings .TrimPrefix (name , sessionPrefix )
217+ if ! strings .HasPrefix (tabID , "term-tab-" ) {
218+ continue
219+ }
220+ state , err := svc .SessionStateFor (name , opts )
221+ if err != nil || ! state .Exists || ! state .HasLivePane {
222+ continue
223+ }
224+ // Assume clients exist on error to avoid detaching other sessions.
225+ attached := true
226+ if value , err := svc .SessionHasClients (name , opts ); err == nil {
227+ attached = value
228+ }
229+ createdAt , _ := svc .SessionCreatedAt (name , opts )
230+ if err := a .retagSidebarTerminalSession (name , wsID , tabID , createdAt , opts ); err != nil {
231+ logging .Warn ("tmux sidebar fallback retag failed for %s: %v" , name , err )
232+ }
233+ out = append (out , sidebarSessionInfo {
234+ name : name ,
235+ instanceID : a .instanceID ,
236+ createdAt : createdAt ,
237+ hasClients : attached ,
238+ })
239+ }
240+ return out
241+ }
242+
243+ func (a * App ) retagSidebarTerminalSession (sessionName , wsID , tabID string , createdAt int64 , opts tmux.Options ) error {
244+ values := []struct {
245+ key string
246+ val string
247+ }{
248+ {key : "@amux" , val : "1" },
249+ {key : "@amux_workspace" , val : wsID },
250+ {key : "@amux_tab" , val : tabID },
251+ {key : "@amux_type" , val : "terminal" },
252+ {key : "@amux_assistant" , val : "terminal" },
253+ }
254+ if createdAt > 0 {
255+ values = append (values , struct {
256+ key string
257+ val string
258+ }{key : "@amux_created_at" , val : strconv .FormatInt (createdAt , 10 )})
259+ }
260+ if strings .TrimSpace (a .instanceID ) != "" {
261+ values = append (values , struct {
262+ key string
263+ val string
264+ }{key : "@amux_instance" , val : strings .TrimSpace (a .instanceID )})
265+ }
266+ for _ , item := range values {
267+ if strings .TrimSpace (item .val ) == "" {
268+ continue
269+ }
270+ if err := tmux .SetSessionTagValue (sessionName , item .key , item .val , opts ); err != nil {
271+ return err
272+ }
273+ }
274+ return nil
275+ }
276+
186277func buildSidebarSessionAttachInfos (sessions []sidebarSessionInfo ) []sidebar.SessionAttachInfo {
187278 sorted := make ([]sidebarSessionInfo , len (sessions ))
188279 copy (sorted , sessions )
0 commit comments