diff --git a/README.md b/README.md index c6fa7c8..53af321 100644 --- a/README.md +++ b/README.md @@ -186,12 +186,12 @@ echo '{"to":"a3f2b9d1","type":"REVIEW_REQUEST","subject":"...","body":"..."}' | # Create session echo 'new claude /home/user/project' | 9p write agent/ctl -# List sessions (order is non-deterministic) +# List sessions (newest first) 9p read agent/list # Output: -# Use a specific session ID -ID="a1b2c3d4" # Replace with actual ID from list +# Get most recent session ID +ID=$(9p read agent/list | head -1 | awk '{print $1}') # Send prompt via mailbox echo '{"to":"'$ID'","type":"PROMPT_REQUEST","subject":"User prompt","body":"Hello"}' | 9p write user/mail diff --git a/internal/backend/backend.go b/internal/backend/backend.go index 882c6e2..c12470a 100644 --- a/internal/backend/backend.go +++ b/internal/backend/backend.go @@ -78,6 +78,9 @@ type Session interface { // Tasks returns the session tasks (empty if not specified) Tasks() []string + + // CreatedAt returns when the session was created + CreatedAt() time.Time } // SessionMetadata provides information about a session diff --git a/internal/backend/tmux/session.go b/internal/backend/tmux/session.go index c510cde..5c56678 100644 --- a/internal/backend/tmux/session.go +++ b/internal/backend/tmux/session.go @@ -193,6 +193,13 @@ func (s *Session) Tasks() []string { return s.tasks } +// CreatedAt returns when the session was created +func (s *Session) CreatedAt() time.Time { + s.mu.Lock() + defer s.mu.Unlock() + return s.createdAt +} + // GetPid gets the process ID func (s *Session) GetPid() int { s.mu.Lock() diff --git a/internal/session/manager.go b/internal/session/manager.go index 3bda565..beb9da6 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "os" + "sort" "sync" "time" ) @@ -133,14 +134,28 @@ func (m *Manager) GetAlias(id string) string { return sess.Metadata().Alias } -// List returns all session IDs +// List returns all session IDs, sorted by creation time (newest first) func (m *Manager) List() []string { m.mu.RLock() defer m.mu.RUnlock() - ids := make([]string, 0, len(m.sessions)) - for id := range m.sessions { - ids = append(ids, id) + type entry struct { + id string + created time.Time + } + + entries := make([]entry, 0, len(m.sessions)) + for id, sess := range m.sessions { + entries = append(entries, entry{id, sess.CreatedAt()}) + } + + sort.Slice(entries, func(i, j int) bool { + return entries[i].created.After(entries[j].created) // newest first + }) + + ids := make([]string, len(entries)) + for i, e := range entries { + ids[i] = e.id } return ids }