Sort session list by creation time (newest first)

Backend changes:
- Add CreatedAt() to Session interface
- Implement CreatedAt() in tmux.Session (field already existed)
- Sort Manager.List() by creation time descending

Benefits:
- Deterministic ordering (no more random map iteration)
- Newest sessions appear first (most useful)
- All clients benefit immediately
- head -1 now reliably gets most recent session

README:
- Update example to use head -1 for newest session
- Document that list is sorted newest first
This commit is contained in:
Levi Neely 2026-02-19 23:51:10 +01:00
parent 17ad0fcafd
commit 536b358006
4 changed files with 32 additions and 7 deletions

View File

@ -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: <id> <backend> <state> <alias> <cwd>
# 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

View File

@ -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

View File

@ -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()

View File

@ -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
}