session

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2026 License: MIT Imports: 13 Imported by: 1

Documentation

Overview

Package session manages Claude Code sessions and their git worktrees.

Overview

Each session in Plural runs in its own git worktree, allowing multiple parallel Claude Code conversations to work on the same repository without conflicts. This package handles the creation and validation of these sessions.

Session Lifecycle

1. Create: When a new session is created:

  • A UUID is generated for the session ID
  • A new git branch is created: plural-<UUID>
  • A worktree is created under the centralized data directory (~/.plural/worktrees/<UUID> or XDG_DATA_HOME/plural/worktrees/<UUID>)
  • The session is registered in the config

2. Resume: When resuming an existing session:

  • The session's worktree path and branch are retrieved from config
  • Claude CLI is started with --resume flag to continue the conversation

3. Delete: When a session is deleted:

  • The session is removed from config
  • Message history file is deleted
  • The git worktree remains (allowing manual recovery if needed)

Worktree Structure

Session worktrees are stored in a centralized location:

~/.plural/worktrees/<session-uuid>/

Or when using XDG Base Directory Specification:

$XDG_DATA_HOME/plural/worktrees/<session-uuid>/

This centralized location avoids scattering .plural-worktrees directories across the filesystem. Legacy worktrees from the old sibling-directory layout are automatically migrated on startup.

Git Operations

The package uses git commands for:

  • Creating worktrees: git worktree add -b <branch> <path>
  • Validating repos: git rev-parse --git-dir
  • Finding repo root: git rev-parse --show-toplevel

Functions

Create: Creates a new session with a git worktree for the given repo path.

ValidateRepo: Checks if a path is a valid git repository.

GetGitRoot: Returns the git root directory for a path.

GetCurrentDirGitRoot: Returns the git root of the current working directory.

MigrateWorktrees: Migrates legacy worktrees to the centralized directory.

Index

Constants

View Source
const MaxBranchNameValidation = 100

MaxBranchNameValidation is the maximum length for user-provided branch names. This is more permissive than git.MaxBranchNameLength which is for auto-generated names.

Variables

This section is empty.

Functions

func ValidateBranchName

func ValidateBranchName(branch string) error

ValidateBranchName checks if a branch name is valid for git

Types

type BasePoint

type BasePoint string

BasePoint specifies where to branch from when creating a new session

const (
	// BasePointOrigin branches from origin's default branch (after fetching)
	BasePointOrigin BasePoint = "origin"
	// BasePointHead branches from the current local HEAD
	BasePointHead BasePoint = "head"
	// BasePointLocalDefault branches from the local default branch (e.g., main) without fetching
	BasePointLocalDefault BasePoint = "local-default"
)

type OrphanedWorktree

type OrphanedWorktree struct {
	Path     string // Full path to the worktree
	RepoPath string // Parent repo path (derived from .plural-worktrees location)
	ID       string // Session ID (directory name)
}

OrphanedWorktree represents a worktree that has no matching session

func FindOrphanedWorktrees

func FindOrphanedWorktrees(cfg *config.Config) ([]OrphanedWorktree, error)

FindOrphanedWorktrees finds all worktrees in .plural-worktrees directories that don't have a matching session in config. Directory scans are parallelized for better performance with many repos.

type SessionService

type SessionService struct {
	// contains filtered or unexported fields
}

SessionService provides session operations with explicit dependency injection. Instead of using a package-level executor variable, each SessionService instance holds its own executor, enabling proper testing and avoiding global state.

func NewSessionService

func NewSessionService() *SessionService

NewSessionService creates a new SessionService with the default real executor.

func NewSessionServiceWithExecutor

func NewSessionServiceWithExecutor(exec pexec.CommandExecutor) *SessionService

NewSessionServiceWithExecutor creates a new SessionService with a custom executor. This is primarily used for testing where a mock executor is needed.

func (*SessionService) BranchExists

func (s *SessionService) BranchExists(ctx context.Context, repoPath, branch string) bool

BranchExists checks if a branch already exists in the repo

func (*SessionService) Create

func (s *SessionService) Create(ctx context.Context, repoPath string, customBranch string, branchPrefix string, basePoint BasePoint) (*config.Session, error)

Create creates a new session with a git worktree for the given repo path. If customBranch is provided, it will be used as the branch name; otherwise a branch named "plural-<UUID>" will be created. The branchPrefix is prepended to auto-generated branch names (e.g., "zhubert/"). The basePoint specifies where to branch from:

  • BasePointOrigin: fetches from origin and branches from origin's default branch
  • BasePointHead: branches from the current local HEAD

func (*SessionService) CreateFromBranch

func (s *SessionService) CreateFromBranch(ctx context.Context, repoPath string, sourceBranch string, customBranch string, branchPrefix string) (*config.Session, error)

CreateFromBranch creates a new session forked from a specific branch. This is used when forking an existing session - the new worktree is created from the source branch's current state rather than from origin/main. If customBranch is provided, it will be used as the new branch name; otherwise a branch named "plural-<UUID>" will be created.

func (*SessionService) Delete

func (s *SessionService) Delete(ctx context.Context, sess *config.Session) error

Delete removes a session's git worktree and branch

func (*SessionService) FetchOrigin

func (s *SessionService) FetchOrigin(ctx context.Context, repoPath string) error

FetchOrigin fetches the latest changes from origin Returns nil if successful, or if there's no remote (local-only repo)

func (*SessionService) GetCurrentDirGitRoot

func (s *SessionService) GetCurrentDirGitRoot(ctx context.Context) string

GetCurrentDirGitRoot returns the git root of the current working directory

func (*SessionService) GetDefaultBranch

func (s *SessionService) GetDefaultBranch(ctx context.Context, repoPath string) string

GetDefaultBranch returns the default branch name for the remote (e.g., "main" or "master") Returns "main" as fallback if it cannot be determined

func (*SessionService) GetGitRoot

func (s *SessionService) GetGitRoot(ctx context.Context, path string) string

GetGitRoot returns the git root directory for a path, or empty string if not a git repo

func (*SessionService) MigrateWorktrees

func (s *SessionService) MigrateWorktrees(ctx context.Context, cfg *config.Config) error

MigrateWorktrees moves worktrees from old .plural-worktrees sibling directories to the centralized worktrees directory (~/.plural/worktrees/ or XDG equivalent). This is safe to call on every startup — it only acts when old-style worktrees exist.

func (*SessionService) PruneOrphanedWorktrees

func (s *SessionService) PruneOrphanedWorktrees(ctx context.Context, cfg *config.Config) (int, error)

PruneOrphanedWorktrees removes all orphaned worktrees and their branches. Pruning operations are parallelized across repos, but serialized within each repo to avoid concurrent git operations on the same repository.

func (*SessionService) ValidateRepo

func (s *SessionService) ValidateRepo(ctx context.Context, path string) error

ValidateRepo checks if a path is a valid git repository

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL