Merge pull request #1789 from entireio/feat/enable-defaults-git-refs · Entire

Merge pull request #1789 from entireio/feat/enable-defaults-git-refs

7a69e1f→main · peyton-alt · 10h ago · 11 files · +181 added / -55 removed

enable: default new setups to git-refs checkpoint storage (drop wizard question)

Changes

11

// promptCheckpointBackend asks the user to choose a checkpoint storage backend
// during first-time interactive setup. The default is the git-branch backend;
// the git-refs backend is offered as the selectable alternative. It returns the
// canonical backend type, or "" when the user kept the default (or cancelled) so
the caller can skip writing a redundant config block.
func promptCheckpointBackend(ctx context.Context, w io.Writer) (string, error) {
    choice := checkpoint.BackendTypeGitBranch
    form := NewAccessibleForm(
        huh.NewGroup(
            huh.NewSelect[string]().
                Title("Checkpoint storage backend").
                Description("How Entire stores committed session checkpoints in your repo.").
                Options(
                    huh.NewOption("Branch — one shared branch, entire/checkpoints/v1 (default)", checkpoint.BackendTypeGitBranch),
                    huh.NewOption("Refs — one git ref per checkpoint", checkpoint.BackendTypeGitRefs),
                ).
                Value(&choice),
            ),
        )
    if err := form.RunWithContext(ctx); err != nil {
        return "", handleFormCancellation(w, "Checkpoint backend selection", err)
    }
    if choice == checkpoint.BackendTypeGitBranch {
        return "", nil
    }
    return choice, nil
}

Checkpoint version and policy

State primary Behavior
Default (today) git-branch Hex checkpoints on the v1 branch; unchanged legacy behavior
Config-less fallback git-branch Hex checkpoints on the v1 branch; unchanged legacy behavior for repos set up before the git-refs default (new setups get an explicit git-refs primary written by entire enable)
Refs-only git-refs New checkpoints are ULIDs written as per-checkpoint refs; pre-existing hex/v1 checkpoints stay readable via the read-routing fallback

| Persistent (git-branch) | entire/checkpoints/v1 branch, sharded <id[:2]>/<id[2:]>/ | Metadata + commit reference | | Persistent (git-refs) | refs/entire/checkpoints/<shard>/<id>, one ref per checkpoint | Metadata + commit reference |

The persistent store is pluggable: git-branch (the default) stores every committed checkpoint as a subtree of a single entire/checkpoints/v1 branch, while git-refs stores one ref per checkpoint. Both are git-backed and share the same checkpoint tree layout; they differ only in where that tree is committed. This document describes the git-branch layout; for the ref-based backend — its ref naming, sharding, push/fetch model, read routing, and configuration — see Ref-Based Checkpoint Backend.

The persistent store is pluggable: git-branch stores every committed checkpoint as a subtree of a single entire/checkpoints/v1 branch, while git-refs stores one ref per checkpoint. New setups get git-refs written into their settings by entire enable; a repo with no checkpoints config still resolves to git-branch (the config-less fallback), so pre-existing repos keep their behavior. Both are git-backed and share the same checkpoint tree layout; they differ only in where that tree is committed. This document describes the git-branch layout; for the ref-based backend — its ref naming, sharding, push/fetch model, read routing, and configuration — see Ref-Based Checkpoint Backend.

Session State

func TestEnableDefault_GitRefsRoundTrip(t *testing.T) {
    t.Parallel()
    
    env := NewTestEnv(t)
    testutil.InitRepo(t, env.RepoDir)
    env.WriteFile("README.md", "# fresh repo\n")
    gitOutput(t, env.RepoDir, "add", "README.md")
    gitOutput(t, env.RepoDir, "commit", "-m", "initial commit")
    
    env.RunCLI("enable", "--agent", "claude-code", "--telemetry=false")
    
    settings := env.ReadFile(".entire/settings.json")
    if !strings.Contains(settings, `"git-refs"`) {
        t.Fatalf("first-run enable should write the git-refs primary into settings.json, got:\n%s", settings)
    }
    
    initialHead := gitOutput(t, env.RepoDir, "rev-parse", "HEAD")
    sess := env.NewSession()
    prompt := "Create a file"
    if err := env.SimulateUserPromptSubmitWithPromptAndTranscriptPath(sess.ID, prompt, sess.TranscriptPath); err != nil {
        t.Fatalf("user-prompt-submit failed: %v", err)
    }
    const content = "package main\n\nfunc main() {}\n"
    env.WriteFile("main.go", content)
    sess.CreateTranscript(prompt, []FileChange{{Path: "main.go", Content: content}})
    if err := env.SimulateStop(sess.ID, sess.TranscriptPath); err != nil {
        t.Fatalf("stop hook failed: %v", err)
    }
    _ = initialHead
    env.GitCommitWithShadowHooks("Add main", "main.go")
    
    refs := gitOutput(t, env.RepoDir, "for-each-ref", "refs/entire/checkpoints")
    if refs == "" {
        t.Fatal("expected the condensed checkpoint as a per-checkpoint ref under refs/entire/checkpoints (settings-driven git-refs)")
    }
}
func enableReviewAgent(t *testing.T, env *TestEnv, name string) {
    t.Helper()
    env.RunCLI("enable", "--agent", name, "--telemetry=false")
    // Pin the git-branch backend: readCheckpointSummary/readSessionMetadata
    // resolve checkpoint content from the v1 metadata branch, and first-run
    // enable now defaults new setups to git-refs.
    env.RunCLI("enable", "--agent", name, "--telemetry=false", "--checkpoint-backend", "branch")
}
//go:build integration

package integration

import (
    "strings"
    "testing"

"github.com/entireio/cli/cmd/entire/cli/testutil"
)