feat(import): union imported checkpoints into list/explain/tokens with label · Entire

feat(import): union imported checkpoints into list/explain/tokens with label

c3b4197→main·

computermode·3w ago·6 files·+191 added/-10 removed

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Sessions

132601907855View transcript

[?
Implement Claude History Import FeatureClaude Code·Opus 4.8·3 steps](/content/gh/entireio/cli/session/897809d4-ecab-4dc6-aa21-97661cb62607#timeline-132601907855/index.html)

Changes

6

2149 unmodified lines

2150
2151
2152
2153
2154
2155
2156
2157
2158
7 unmodified lines

2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
465 unmodified lines

2670
2671
2672
2673
2674
2675
2676
34 unmodified lines

2711
2712
2713
2714
2715
2716
2717
70 unmodified lines

2788
2789
2790
2791
2792
2793
2794
2795
2796

2149 unmodified lines

tempPoints := getReachableTemporaryCheckpoints(ctx, repo, stores.Ephemeral(), head.Hash(), isOnDefault, limit)
    points = append(points, tempPoints...)

// Add imported (read-only, commit-less) checkpoints from entire/imports/v1.
    points = append(points, getImportedRewindPoints(ctx, repo)...)\n
    // Sort by date, most recent first
    sort.Slice(points, func(i, j int) bool {
        return points[i].Date.After(points[j].Date)
7 unmodified lines

return points, nil
}

// getImportedRewindPoints returns read-only imported checkpoints from
// entire/imports/v1 as RewindPoint entries (flagged Imported, not rewindable).
// Best-effort: returns nil when the imports ref is absent or unreadable.
func getImportedRewindPoints(ctx context.Context, repo *git.Repository) []strategy.RewindPoint {
    importsRefs := checkpoint.ImportsRefs()
    stores, err := checkpoint.Open(ctx, repo, checkpoint.OpenOptions{Refs: &importsRefs})
    if err != nil {
        return nil
    }
    infos, err := stores.Persistent.List(ctx)
    if err != nil {
        return nil
    }
    points := make([]strategy.RewindPoint, 0, len(infos))
    for _, info := range infos {
        point := strategy.RewindPoint{
            ID:           info.CheckpointID.String(),
            Message:      readLatestCommittedSessionPrompt(ctx, stores.Persistent, info.CheckpointID, info.SessionCount),
            Date:         info.CreatedAt,
            IsLogsOnly:   true,
            Imported:     true,
            CheckpointID: info.CheckpointID,
            SessionID:    info.SessionID,
            SessionCount: info.SessionCount,
            SessionIDs:   info.SessionIDs,
            Agent:        info.Agent,
        }
        point.SessionPrompt = point.Message
        points = append(points, point)
    }
    return points
}

func readLatestCommittedSessionPrompt(ctx context.Context, store checkpoint.SessionReader, cpID id.CheckpointID, sessionCount int) string {
    if sessionCount <= 0 {
        return ""
465 unmodified lines

prompt       string
    isTemporary  bool // true if any commit is not logs-only (can be rewound)
    isTask       bool // true if this is a task checkpoint
    imported     bool // true for read-only imported (commit-less) checkpoints
    commits      []commitEntry
}

34 unmodified lines

prompt:       point.SessionPrompt,
        isTemporary:  !point.IsLogsOnly,
        isTask:       point.IsTaskCheckpoint,
        imported:     point.Imported,
        }
        groupMap[cpID] = group
        order = append(order, cpID)
70 unmodified lines

if group.isTemporary && cpID != "temporary" {
        indicators = append(indicators, "[temporary]")
    }
    if group.imported {
        indicators = append(indicators, "[imported]")
    }

// Prompt cascade: SessionPrompt → latest commit message → dimmed placeholder.
    // Quote user prompts; commit subjects render bare.

Mcmd/entire/cli/explain.go+41

329 unmodified lines

330
331
332
333
334
335
336
2 unmodified lines

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

329 unmodified lines

ToolUseID:        c.ToolUseID,
        SessionCount:     c.SessionCount,
        SessionIDs:       c.SessionIDs,
        Imported:         c.Imported,
    })
}
sort.Slice(result, func(i, j int) bool {
2 unmodified lines

return result
}

// ListCheckpointsWithImports returns committed v1 checkpoints plus imported
// (local-only) checkpoints from entire/imports/v1, the latter flagged
// Imported=true. Use this in read/inspect commands that should surface imported
// history; lifecycle/cleanup paths keep using ListCheckpoints (v1 only).
func ListCheckpointsWithImports(ctx context.Context) ([]CheckpointInfo, error) {
    base, err := ListCheckpoints(ctx)
    if err != nil {
        return nil, err
    }
    repo, err := OpenRepository(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed to open git repository: %w", err)
    }
    defer repo.Close()

importsRefs := checkpoint.ImportsRefs()
    imports, err := checkpoint.Open(ctx, repo, checkpoint.OpenOptions{Refs: &importsRefs})
    if err != nil {
        return base, nil //nolint:nilerr // imports are best-effort; v1 results stay valid
    }
    committed, err := imports.Persistent.List(ctx)
    if err != nil {
        return base, nil //nolint:nilerr // imports are best-effort
    }
    imp := checkpointInfosFromCommitted(committed)
    for i := range imp {
        imp[i].Imported = true
    }
    all := append(base, imp...)
    sort.Slice(all, func(i, j int) bool { return all[i].CreatedAt.After(all[j].CreatedAt) })
    return all, nil
}

const (
    entireGitignore    = ".entire/.gitignore"
    entireDir          = ".entire"

Mcmd/entire/cli/strategy/common.go+34

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

package strategy

import (
    "context"
    "testing"

"github.com/go-git/go-git/v6"
    "github.com/go-git/go-git/v6/plumbing/object"

"github.com/entireio/cli/cmd/entire/cli/checkpoint"
    "github.com/entireio/cli/cmd/entire/cli/checkpoint/id"
    "github.com/entireio/cli/cmd/entire/cli/testutil"
    "github.com/entireio/cli/redact"
)

func TestListCheckpointsWithImports_UnionsAndFlags(t *testing.T) {
    // Not parallel: uses t.Chdir for CWD-based repo resolution.
    repoDir := t.TempDir()
    testutil.InitRepo(t, repoDir)
    repo, err := git.PlainOpen(repoDir)
    if err != nil {
        t.Fatal(err)
    }
    wt, err := repo.Worktree()
    if err != nil {
        t.Fatal(err)
    }
    testutil.WriteFile(t, repoDir, "f.txt", "x")
    if _, err := wt.Add("f.txt"); err != nil {
        t.Fatal(err)
    }
    if _, err := wt.Commit("init", &git.CommitOptions{
        Author: &object.Signature{Name: "Test", Email: "test@test.com"},
    }); err != nil {
        t.Fatal(err)
    }
    \tChdir(repoDir)

// Write one imported checkpoint directly to the imports ref.
    store := checkpoint.NewGitStore(repo, checkpoint.ImportsRefs())
    red, err := redact.JSONLBytes([]byte(`{"type":"user","uuid":"u1","message":{"role":"user","content":"hi"}}` + "\n"))
    if err != nil {
        t.Fatal(err)
    }
    if err := store.Write(context.Background(), checkpoint.Session(checkpoint.WriteOptions{
        CheckpointID: id.MustCheckpointID("aabbccddeeff"), SessionID: "s",
        Strategy: "import", Kind: "imported", Transcript: red, Prompts: []string{"hi"}, CheckpointsCount: 1,
    })); err != nil {
        t.Fatal(err)
    }

infos, err := ListCheckpointsWithImports(context.Background())
    if err != nil {
        t.Fatal(err)
    }
    var importedCount int
    for _, in := range infos {
        if in.Imported {
            importedCount++
        }
    }
    if importedCount != 1 {
        t.Fatalf("want 1 imported in union, got %d (total %d)", importedCount, len(infos))
    }

// Default ListCheckpoints (v1 only) must NOT include imports.
    v1, err := ListCheckpoints(context.Background())
    if err != nil {
        t.Fatal(err)
    }
    for _, in := range v1 {
        if in.Imported {
            t.Fatal("imports leaked into v1-only ListCheckpoints")
        }
    }
}

Acmd/entire/cli/strategy/common_imports_test.go+76

43 unmodified lines

44
45
46
47
48
49
50

43 unmodified lines

ToolUseID        string          `json:"tool_use_id,omitempty"`
    SessionCount     int             `json:"session_count,omitempty"` // Number of sessions (1 if omitted)
    SessionIDs       []string        `json:"session_ids,omitempty"`   // All session IDs in this checkpoint
    Imported         bool            `json:"imported,omitempty"`      // True for read-only imported (commit-less) checkpoints
}

// CondenseResult contains the result of a session condensation operation.

Mcmd/entire/cli/strategy/manual_commit_types.go+1

95 unmodified lines

96
97
98
99
100
101
102
103
104
105

95 unmodified lines

// SessionPrompts contains the first prompt for each session (parallel to SessionIDs).
    // Used to display context when showing resume commands for multi-session checkpoints.
    SessionPrompts []string

// Imported indicates this point is a read-only imported (commit-less)
    // checkpoint from entire/imports/v1. Imported points are not rewindable.
    Imported bool
// RewindPreview describes what will happen when rewinding to a checkpoint.

Mcmd/entire/cli/strategy/strategy.go+4

119 unmodified lines

120
121
122
123
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
5 unmodified lines

148
149
150
135
136
137
151
152
153
154
155
156
157
158
159
160
161
162
163
164
142
165
166
167
168
169
147
170
171
172
173
174
175
34 unmodified lines

210
211
212
188
189
190
213
214
215
216
192
217
218
219
220

119 unmodified lines

return fmt.Errorf("failed to list checkpoints: %w", err)
    
    report, err := buildTokensProfileReport(ctx, store, infos, limit)
    refs := make([]tokensCheckpointRef, 0, len(infos))
    for _, info := range infos {
        refs = append(refs, tokensCheckpointRef{store: store, info: info})
    }
    // Include read-only imported checkpoints from entire/imports/v1, read from
    // their own store. Best-effort: skipped when the ref is absent.
    importsRefs := checkpoint.ImportsRefs()
    if importsStore := checkpoint.NewGitStore(repo, importsRefs); importsStore != nil {
        importsStore.SetBlobFetcher(FetchBlobsByHash)
        if importInfos, listErr := importsStore.List(ctx); listErr == nil {
            for _, info := range importInfos {
                refs = append(refs, tokensCheckpointRef{store: importsStore, info: info})
            }
        }
    }

report, err := buildTokensProfileReport(ctx, refs, limit)
    if err != nil {
        return err
    }
5 unmodified lines

return nil
}

func buildTokensProfileReport(ctx context.Context, store *checkpoint.GitStore, infos []checkpoint.CheckpointInfo, limit int) (tokensProfileReport, error) {
    checkpointsAvailable := len(infos)
    infos = limitTokensProfileCheckpoints(infos, limit)
// tokensCheckpointRef binds a checkpoint info to the store that owns it, so the
// profile can read both committed (v1) and imported (entire/imports/v1) sources.
type tokensCheckpointRef struct {
    store *checkpoint.GitStore
    info  checkpoint.CheckpointInfo
}

func buildTokensProfileReport(ctx context.Context, refs []tokensCheckpointRef, limit int) (tokensProfileReport, error) {
    checkpointsAvailable := len(refs)
    refs = limitTokensProfileCheckpoints(refs, limit)
    report := tokensProfileReport{
        Source:               "committed_checkpoints",
        UsageScope:           tokensProfileUsageScopeCheckpointObserved,
        CheckpointsAvailable: checkpointsAvailable,
        CheckpointsAnalyzed:  len(infos),
        CheckpointsAnalyzed:  len(refs),
    }
    signals := make(map[string]*tokensProfileSignal, len(tokensProfileSignalDefinitions))
    var aggregate *agent.TokenUsage

for _, info := range infos {
    for _, ref := range refs {
        store := ref.store
        info := ref.info
        if err := ctx.Err(); err != nil {
            return tokensProfileReport{}, err //nolint:wrapcheck // Propagating context cancellation.
        }
34 unmodified lines

return report, nil
}

func limitTokensProfileCheckpoints(infos []checkpoint.CheckpointInfo, limit int) []checkpoint.CheckpointInfo {
    if limit <= 0 || len(infos) <= limit {
        return infos
    }
func limitTokensProfileCheckpoints(refs []tokensCheckpointRef, limit int) []tokensCheckpointRef {
    if limit <= 0 || len(refs) <= limit {
        return refs
    }
    return infos[:limit]
    return refs[:limit]
}

func tokensProfileCheckpointUsage(ctx context.Context, store *checkpoint.GitStore, checkpointID id.CheckpointID, summary *checkpoint.CheckpointSummary) (*agent.TokenUsage, bool, error) {