feat: adopt active sessions across repos and worktrees#1472
Conversation
Entire-Checkpoint: 7fb3d4d78c7f
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6add2ba. Configure here.
| adopted.PromptWindowResetPending = false | ||
| adopted.AttachedManually = true | ||
|
|
||
| return &adopted, filesTouched, nil |
There was a problem hiding this comment.
Stale transcript offsets block trailers
High Severity
buildAdoptedSessionState clears target-local checkpoint IDs but keeps source CheckpointTranscriptStart and CheckpointTranscriptSize. After adoption, prepare-commit-msg often uses the live-transcript path (no shadow branch on the target repo). That path calls hasNewTranscriptWork before considering seeded FilesTouched, so when the transcript position has not moved past the copied offset, the hook treats the session as having no new content and skips the Entire-Checkpoint trailer despite staged overlap.
Reviewed by Cursor Bugbot for commit 6add2ba. Configure here.
| } | ||
|
|
||
| cmd := exec.CommandContext(ctx, "git", "-C", absWorktree, "rev-parse", "--show-toplevel", "--git-common-dir") | ||
| output, err := cmd.CombinedOutput() |
There was a problem hiding this comment.
Git rev-parse uses CombinedOutput
Low Severity
stateStoreForWorktree resolves --show-toplevel and --git-common-dir with cmd.CombinedOutput() and then splits stdout into paths. Git may write advice or warnings to stderr on success; merging streams can prepend that text to the parsed lines and break common-dir resolution for the source session store.
Triggered by learned rule: Use cmd.Output() with separate stderr buffer for git CLI commands that parse stdout
Reviewed by Cursor Bugbot for commit 6add2ba. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit entire session adopt subcommand to copy (“adopt”) an in-progress agent session that’s currently tracked under a different repo/worktree into the current repo/worktree so the commit hooks can find local session state and reliably add an Entire-Checkpoint trailer.
Changes:
- Add
entire session adopt [session-id] --from <source-worktree>command wiring under thesessiongroup. - Implement adoption logic that locates the source worktree’s
.git/entire-sessions, selects an adoptable session, and writes a target-local session state seeded with current file changes. - Add unit tests covering cross-repo adoption, source resolution from a nested path, and
PrepareCommitMsgtrailer insertion after adoption.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| cmd/entire/cli/sessions.go | Adds the adopt subcommand to session help text and registers the command. |
| cmd/entire/cli/session_adopt.go | Implements the adopt command, source store resolution, session selection, and target-local state writing. |
| cmd/entire/cli/session_adopt_test.go | Adds tests for adoption behavior and hook trailer behavior after adoption. |
| if sourceState.Phase == session.PhaseEnded || sourceState.FullyCondensed { | ||
| return nil, fmt.Errorf("session %s is ended or fully condensed and cannot be adopted", sessionID) | ||
| } |
| func isRecentAdoptCandidate(state *session.State) bool { | ||
| if state == nil || state.Phase == session.PhaseEnded || state.FullyCondensed { | ||
| return false | ||
| } |
| now := time.Now() | ||
| adopted := *source | ||
| adopted.CLIVersion = versioninfo.Version | ||
| adopted.BaseCommit = head.Hash().String() | ||
| adopted.AttributionBaseCommit = head.Hash().String() | ||
| adopted.WorktreePath = worktreeRoot | ||
| adopted.WorktreeID = worktreeID | ||
| adopted.Branch = branch | ||
| adopted.LastInteractionTime = &now | ||
| adopted.FilesTouched = filesTouched | ||
| adopted.TurnCheckpointIDs = nil | ||
| adopted.LastCheckpointID = id.EmptyCheckpointID | ||
| adopted.LastCheckpointCommitHash = "" | ||
| adopted.FullyCondensed = false | ||
| adopted.DivergenceNoticeShown = false | ||
| adopted.UntrackedFilesAtStart = nil | ||
| adopted.PromptAttributions = nil | ||
| adopted.PendingPromptAttribution = nil | ||
| adopted.PromptWindowBase = 0 | ||
| adopted.PromptWindowResetPending = false | ||
| adopted.AttachedManually = true | ||
|
|
Entire-Checkpoint: b7f863b91041
Entire-Checkpoint: 0d316d428771


Trail: https://entire.io/gh/entireio/cli/trails/613/adopt-active-sessions-across-repos-and-worktrees
Summary
Adds
entire session adopt [session-id] --from <source-worktree>so a user can explicitly anchor an active agent session into the repo/worktree where the commit is about to happen.This addresses the case we hit where an agent session was tracked under one repo/worktree, but the agent made and committed changes in another repo. The target repo hooks can fire correctly, but without target-local session state the commit has no session to link and can miss the
Entire-Checkpointtrailer.What changed
session adoptsubcommand underentire session..git/entire-sessions.FilesTouchedfrom current target repo changes.AttachedManuallyfalse because adoption is notentire session attach.This lets the target repo commit hooks find the adopted session by target worktree, pass the staged-file overlap check, add an
Entire-Checkpointtrailer, and condense normally on post-commit.Review fixes
Addressed the four trail findings in follow-up commit
aae06c4e100bf091dd305b222df469ee9cab4228:AttachedManuallyfor adopted active sessions.Follow-up trailer:
Entire-Checkpoint: b7f863b91041After that, a new transcript-path finding was opened. The suggested behavior was not correct for cross-repo adoption, because the live transcript belongs to the continuing source agent session, not the target repo. Commit
9ffec38cf2fad2c962d48267aa9a1738358f0070documents that intent in code.Clarification trailer:
Entire-Checkpoint: 0d316d428771Commit and checkpoint verification
The original feature commit was created through the real hooks and has:
6add2bae652a5983fe0ffe9171e92710051714c5Entire-Checkpoint: 7fb3d4d78c7fThe review-fix commit was also created through the real hooks and has:
aae06c4e100bf091dd305b222df469ee9cab4228Entire-Checkpoint: b7f863b91041The transcript-path clarification commit was also created through the real hooks and has:
9ffec38cf2fad2c962d48267aa9a1738358f0070Entire-Checkpoint: 0d316d428771Push output confirmed
entire/checkpoints/v1synced to the checkpoint remote.Real smoke test
Ran a disposable cross-repository smoke test with two separate temp git repos.
Flow:
src/feature.gostaged.entire session adopt smoke-adopt-session-001 --from <source> --forcein the target repo.src/feature.go.hooks git prepare-commit-msghandler.Entire-Checkpoint: 08f656dbcb95.hooks git post-commit.Smoke result:
Tests
go test ./cmd/entire/cli -run TestSessionAdopt_CopiesExternalSessionIntoCurrentWorktree -count=1go test ./cmd/entire/cli -run TestSessionAdopt -count=1go test ./cmd/entire/cli -count=1mise run lintmise run checkCaveats
This is explicit adoption, not automatic discovery. Users should run it from the target repo/worktree before committing, and the source transcript path must still be readable on the same machine.