# feat(session): surface imported sessions as read-only in list/info

`ffbe263`→[main](/content/gh/entireio/cli/commits/main/index.html)·

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

```go
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

```go
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

```go
436 unmodified lines

...
```

Mcmd/entire/cli/sessions.go+12/-1

```go
973 unmodified lines

...
```

Mcmd/entire/cli/sessions\_test.go+71

```go
{...}
```
