feat(session): surface imported sessions as read-only in list/info · Entire
feat(session): surface imported sessions as read-only in list/info
ffbe263→main·
computermode·1w ago·4 files·+126 added/-1 removed
Imported sessions are read-only (not resumable/rewindable). Label them so users don't mistake unsupported writes for breakage: - session list card shows "imported (read-only)" - session info text adds a read-only note; --json/list --json expose kind + read_only - resume picker explains when the only sessions present are imports
Rewind already refuses imported checkpoints (refuseIfImportedCheckpoint).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Sessions
01KX4B7QPKJ5NFBCE8C0XMW0QMView transcript
[?
Fix Imported Sessions Handling in CLIClaude Code·Opus 4.8·4 steps](/content/gh/entireio/cli/session/91fa7c44-6634-48ab-ae5f-d394502f50d5#timeline-01KX4B7QPKJ5NFBCE8C0XMW0QM/index.html)
Changes
4
cmd/entire/cli
Mresume_picker.go+24
Mresume_picker_test.go+19
Msessions.go+12/-1
Msessions_test.go+71
79 unmodified lines
...
return resumable
}
// countImportedSessions counts read-only imported sessions in the set. Used to
// explain an empty resume picker when the only sessions present are imports
// (which are deliberately filtered out of the resumable list).
func countImportedSessions(states []*strategy.SessionState) int {
n := 0
for _, s := range states {
if s != nil && s.Kind == session.KindImported {
n++
}
}
return n
}
// pluralizeImportedSessions renders the count for the picker hint.
func pluralizeImportedSessions(n int) string {
if n == 1 {
return "1 imported session is"
}
return fmt.Sprintf("%d imported sessions are", n)
}
// sessionLastActiveTime returns the best timestamp to represent when a session
// was last touched: its end time, else last interaction, else start time.
func sessionLastActiveTime(s *strategy.SessionState) time.Time {
Mcmd/entire/cli/resume_picker.go+24
39 unmodified lines
...
}
func TestCountImportedSessions(t *testing.T) {
t.Parallel()
states := []*strategy.SessionState{
{SessionID: "a", Kind: session.KindImported},
{SessionID: "b"},
nil,
{SessionID: "c", Kind: session.KindImported},
}
if got := countImportedSessions(states); got != 2 {
t.Fatalf("countImportedSessions = %d, want 2", got)
}
if got := pluralizeImportedSessions(1); got != "1 imported session is" {
t.Errorf("singular = %q", got)
}
if got := pluralizeImportedSessions(3); got != "3 imported sessions are" {
t.Errorf("plural = %q", got)
}
}
func TestFilterResumableSessions(t *testing.T) {
t.Parallel()
Mcmd/entire/cli/resume_picker_test.go+19
436 unmodified lines
...
Mcmd/entire/cli/sessions.go+12/-1
973 unmodified lines
...
Mcmd/entire/cli/sessions_test.go+71
{...}