summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-05-08 07:43:31 -0500
committeradamdottv <[email protected]>2025-05-08 07:58:37 -0500
commitbab17d75208ffca043ff85c258ec42507d955a1e (patch)
tree7a497b108ecba5a4a8a82b7ddc727fc2c240c435
parent051d7d7936abbb20a2d165d5a356fc6fe0199a27 (diff)
downloadopencode-bab17d75208ffca043ff85c258ec42507d955a1e.tar.gz
opencode-bab17d75208ffca043ff85c258ec42507d955a1e.zip
feat: session manager
-rw-r--r--internal/app/app.go3
-rw-r--r--internal/session/manager.go88
-rw-r--r--internal/tui/components/dialog/session.go5
-rw-r--r--internal/tui/page/chat.go9
4 files changed, 101 insertions, 4 deletions
diff --git a/internal/app/app.go b/internal/app/app.go
index db2ce7da7..239235134 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -42,6 +42,9 @@ func New(ctx context.Context, conn *sql.DB) (*App, error) {
messages := message.NewService(q)
files := history.NewService(q, conn)
+ // Initialize session manager
+ session.InitManager(sessions)
+
app := &App{
Sessions: sessions,
Messages: messages,
diff --git a/internal/session/manager.go b/internal/session/manager.go
new file mode 100644
index 000000000..8df421bd8
--- /dev/null
+++ b/internal/session/manager.go
@@ -0,0 +1,88 @@
+package session
+
+import (
+ "context"
+ "sync"
+
+ "github.com/opencode-ai/opencode/internal/logging"
+ "github.com/opencode-ai/opencode/internal/pubsub"
+)
+
+// Manager handles session management, tracking the currently active session.
+type Manager struct {
+ currentSessionID string
+ service Service
+ mu sync.RWMutex
+}
+
+// Global instance of the session manager
+var globalManager *Manager
+
+// InitManager initializes the global session manager with the provided service.
+func InitManager(service Service) {
+ globalManager = &Manager{
+ currentSessionID: "",
+ service: service,
+ }
+
+ // Subscribe to session events to handle session deletions
+ go func() {
+ ctx := context.Background()
+ eventCh := service.Subscribe(ctx)
+ for event := range eventCh {
+ if event.Type == pubsub.DeletedEvent && event.Payload.ID == CurrentSessionID() {
+ // If the current session is deleted, clear the current session
+ SetCurrentSession("")
+ }
+ }
+ }()
+}
+
+// SetCurrentSession changes the active session to the one with the specified ID.
+func SetCurrentSession(sessionID string) {
+ if globalManager == nil {
+ logging.Warn("Session manager not initialized")
+ return
+ }
+
+ globalManager.mu.Lock()
+ defer globalManager.mu.Unlock()
+
+ globalManager.currentSessionID = sessionID
+ logging.Debug("Current session changed", "sessionID", sessionID)
+}
+
+// CurrentSessionID returns the ID of the currently active session.
+func CurrentSessionID() string {
+ if globalManager == nil {
+ logging.Warn("Session manager not initialized")
+ return ""
+ }
+
+ globalManager.mu.RLock()
+ defer globalManager.mu.RUnlock()
+
+ return globalManager.currentSessionID
+}
+
+// CurrentSession returns the currently active session.
+// If no session is set or the session cannot be found, it returns nil.
+func CurrentSession() *Session {
+ if globalManager == nil {
+ logging.Warn("Session manager not initialized")
+ return nil
+ }
+
+ sessionID := CurrentSessionID()
+ if sessionID == "" {
+ return nil
+ }
+
+ session, err := globalManager.service.Get(context.Background(), sessionID)
+ if err != nil {
+ logging.Warn("Failed to get current session", "err", err)
+ return nil
+ }
+
+ return &session
+} \ No newline at end of file
diff --git a/internal/tui/components/dialog/session.go b/internal/tui/components/dialog/session.go
index a29fa7131..174e4bed9 100644
--- a/internal/tui/components/dialog/session.go
+++ b/internal/tui/components/dialog/session.go
@@ -91,8 +91,11 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return s, nil
case key.Matches(msg, sessionKeys.Enter):
if len(s.sessions) > 0 {
+ selectedSession := s.sessions[s.selectedIdx]
+ // Update the session manager with the selected session
+ session.SetCurrentSession(selectedSession.ID)
return s, util.CmdHandler(SessionSelectedMsg{
- Session: s.sessions[s.selectedIdx],
+ Session: selectedSession,
})
}
case key.Matches(msg, sessionKeys.Escape):
diff --git a/internal/tui/page/chat.go b/internal/tui/page/chat.go
index 8afd18c22..afb9c8a4c 100644
--- a/internal/tui/page/chat.go
+++ b/internal/tui/page/chat.go
@@ -128,17 +128,20 @@ func (p *chatPage) clearSidebar() tea.Cmd {
func (p *chatPage) sendMessage(text string, attachments []message.Attachment) tea.Cmd {
var cmds []tea.Cmd
if p.session.ID == "" {
- session, err := p.app.Sessions.Create(context.Background(), "New Session")
+ newSession, err := p.app.Sessions.Create(context.Background(), "New Session")
if err != nil {
return util.ReportError(err)
}
- p.session = session
+ p.session = newSession
+ // Update the current session in the session manager
+ session.SetCurrentSession(newSession.ID)
+
cmd := p.setSidebar()
if cmd != nil {
cmds = append(cmds, cmd)
}
- cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(session)))
+ cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(newSession)))
}
_, err := p.app.CoderAgent.Run(context.Background(), p.session.ID, text, attachments...)