cli

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2026 License: MIT Imports: 61 Imported by: 0

Documentation

Overview

hook_registry.go provides hook command registration for agents. The lifecycle dispatcher (DispatchLifecycleEvent) handles all lifecycle events. PostTodo is the only hook that's handled directly (not via lifecycle dispatcher).

hooks_claudecode_posttodo.go contains the PostTodo hook handler for Claude Code. This is a Claude-specific hook that creates incremental checkpoints during subagent execution. It's not part of the generic lifecycle dispatcher because it requires special handling: - Only fires for TodoWrite tool invocations - Creates incremental checkpoints (not full checkpoints) - Only activates when in subagent context (pre-task file exists)

lifecycle.go implements the generic lifecycle event dispatcher. It routes normalized events from any agent to the appropriate framework actions.

The dispatcher inverts the current flow from "agent handler calls framework functions" to "framework dispatcher calls agent methods." Agents are passive data providers; the dispatcher handles all orchestration: state transitions, strategy calls, file change detection, metadata generation.

Index

Constants

View Source
const (
	EntireSettingsFile      = settings.EntireSettingsFile
	EntireSettingsLocalFile = settings.EntireSettingsLocalFile
)

Package-level aliases to avoid shadowing the settings package with local variables named "settings".

View Source
const (
	EntireDir         = paths.EntireDir
	EntireTmpDir      = paths.EntireTmpDir
	EntireMetadataDir = paths.EntireMetadataDir
)

Directory paths - re-exported from paths package for convenience

View Source
const DisabledMessage = "Entire is disabled. Run `entire enable` to re-enable."

DisabledMessage is the message shown when Entire is disabled

Variables

This section is empty.

Functions

func AgentTranscriptPath

func AgentTranscriptPath(transcriptDir, agentID string) string

AgentTranscriptPath returns the path to a subagent's transcript file. Subagent transcripts are stored as agent-{agentId}.jsonl in the same directory as the main transcript.

func BranchExistsLocally

func BranchExistsLocally(ctx context.Context, branchName string) (bool, error)

BranchExistsLocally checks if a local branch exists.

func BranchExistsOnRemote

func BranchExistsOnRemote(ctx context.Context, branchName string) (bool, error)

BranchExistsOnRemote checks if a branch exists on the origin remote. First checks local remote-tracking refs, then queries the actual remote via git ls-remote in case local refs are stale (e.g., after a fresh clone that didn't fetch all branches).

func CapturePrePromptState

func CapturePrePromptState(ctx context.Context, ag agent.Agent, sessionID, sessionRef string) error

CapturePrePromptState captures current untracked files and transcript position before a prompt and saves them to a state file.

The agent parameter is used to determine the transcript position via TranscriptAnalyzer. If the agent does not implement TranscriptAnalyzer, the transcript offset will be 0. The sessionRef parameter is optional — if empty, transcript position won't be captured.

Works correctly from any subdirectory within the repository.

func CapturePreTaskState

func CapturePreTaskState(ctx context.Context, toolUseID string) error

CapturePreTaskState captures current untracked files before a Task execution and saves them to a state file. Works correctly from any subdirectory within the repository.

func CheckoutBranch

func CheckoutBranch(ctx context.Context, ref string) error

CheckoutBranch switches to the specified local branch or commit. Uses git CLI instead of go-git to work around go-git v5 bug where Checkout deletes untracked files (see https://github.com/go-git/go-git/issues/970). Should be switched back to go-git once we upgrade to go-git v6 Returns an error if the ref doesn't exist or checkout fails.

func CleanupPrePromptState

func CleanupPrePromptState(ctx context.Context, sessionID string) error

CleanupPrePromptState removes the state file after use

func CleanupPreTaskState

func CleanupPreTaskState(ctx context.Context, toolUseID string) error

CleanupPreTaskState removes the task state file after use

func CopyAgentTranscript

func CopyAgentTranscript(srcTranscript, taskMetadataDir, agentID string) error

CopyAgentTranscript copies a subagent's transcript to the task metadata directory. If the source transcript doesn't exist, this is a no-op (not an error).

func CountTodosFromToolInput

func CountTodosFromToolInput(toolInput json.RawMessage) int

CountTodosFromToolInput returns the number of todo items in the TodoWrite tool_input. Returns 0 if the JSON is invalid or empty.

This function unwraps the outer tool_input object to extract the todos array, then delegates to strategy.CountTodos for the actual count.

func DispatchLifecycleEvent added in v0.4.6

func DispatchLifecycleEvent(ctx context.Context, ag agent.Agent, event *agent.Event) error

DispatchLifecycleEvent routes a normalized lifecycle event to the appropriate handler. Returns nil if the event was handled successfully.

func ExtractLastCompletedTodoFromToolInput

func ExtractLastCompletedTodoFromToolInput(toolInput json.RawMessage) string

ExtractLastCompletedTodoFromToolInput extracts the content of the last completed todo item. In PostToolUse[TodoWrite], the tool_input contains the NEW todo list where the just-finished work is marked as "completed". The last completed item represents the work that was just done.

Returns empty string if no completed items exist or JSON is invalid.

func ExtractTodoContentFromToolInput

func ExtractTodoContentFromToolInput(toolInput json.RawMessage) string

ExtractTodoContentFromToolInput extracts the content of the in-progress todo item from TodoWrite tool_input. Falls back to the first pending item if no in-progress item is found. Returns empty string if no suitable item is found or JSON is invalid.

This function unwraps the outer tool_input object to extract the todos array, then delegates to strategy.ExtractInProgressTodo for the actual parsing logic.

func FetchAndCheckoutRemoteBranch

func FetchAndCheckoutRemoteBranch(ctx context.Context, branchName string) error

FetchAndCheckoutRemoteBranch fetches a branch from origin and creates a local tracking branch. Uses git CLI instead of go-git for fetch because go-git doesn't use credential helpers, which breaks HTTPS URLs that require authentication.

func FetchBlobsByHash added in v0.5.1

func FetchBlobsByHash(ctx context.Context, hashes []plumbing.Hash) error

FetchBlobsByHash fetches specific blob objects from the remote by their SHA-1 hashes. Uses "git fetch origin <hash>" which goes through normal credential helpers, unlike fetch-pack which bypasses them. Requires the server to support uploadpack.allowReachableSHA1InWant (GitHub, GitLab, Bitbucket all do).

If fetching by hash fails, falls back to a full metadata branch fetch.

func FetchMetadataBranch

func FetchMetadataBranch(ctx context.Context) error

FetchMetadataBranch fetches the entire/checkpoints/v1 branch from origin and creates/updates the local branch. This is used when the metadata branch exists on remote but not locally. Uses git CLI instead of go-git for fetch because go-git doesn't use credential helpers, which breaks HTTPS URLs that require authentication.

func FetchMetadataTreeOnly added in v0.5.1

func FetchMetadataTreeOnly(ctx context.Context) error

FetchMetadataTreeOnly fetches the tip of the entire/checkpoints/v1 branch from origin with --depth=1 --filter=blob:none, downloading only the latest commit and its tree objects (no blobs, no history). After this call, tree navigation via go-git works but blob reads will fail for objects that weren't previously fetched. Uses git CLI for credential helper support.

func FilterAndNormalizePaths

func FilterAndNormalizePaths(files []string, cwd string) []string

FilterAndNormalizePaths converts absolute paths to relative and filters out infrastructure paths and paths outside the repo.

func FindActivePreTaskFile

func FindActivePreTaskFile(ctx context.Context) (taskToolUseID string, found bool)

FindActivePreTaskFile finds an active pre-task file in .entire/tmp/ and returns the parent Task's tool_use_id. Returns ("", false) if no pre-task file exists. When multiple pre-task files exist (nested subagents), returns the most recently modified one. Works correctly from any subdirectory within the repository.

func FindCheckpointUUID

func FindCheckpointUUID(transcript []transcriptLine, toolUseID string) (string, bool)

FindCheckpointUUID finds the UUID of the message containing the tool_result for the given tool_use_id. This is used to find the checkpoint point for transcript truncation when rewinding to a task. Returns the UUID and true if found, empty string and false otherwise.

func GetAgentsWithHooksInstalled

func GetAgentsWithHooksInstalled(ctx context.Context) []types.AgentName

GetAgentsWithHooksInstalled returns names of agents that have hooks installed.

func GetCurrentBranch

func GetCurrentBranch(ctx context.Context) (string, error)

GetCurrentBranch returns the name of the current branch. Returns an error if in detached HEAD state or if not in a git repository.

func GetCurrentHookAgent

func GetCurrentHookAgent() (agent.Agent, error)

GetCurrentHookAgent returns the agent for the currently executing hook. Returns the agent based on the hook command structure (e.g., "entire hooks claude-code ...") rather than guessing from directory presence. Falls back to GetAgent() if not in a hook context.

func GetLogLevel

func GetLogLevel() string

GetLogLevel returns the configured log level from settings. Returns empty string if not configured (caller should use default). Note: ENTIRE_LOG_LEVEL env var takes precedence; check it first.

func GetMergeBase

func GetMergeBase(ctx context.Context, branch1, branch2 string) (*plumbing.Hash, error)

GetMergeBase finds the common ancestor (merge-base) between two branches. Returns the hash of the merge-base commit.

func GetNextCheckpointSequence

func GetNextCheckpointSequence(sessionID, taskToolUseID string) int

GetNextCheckpointSequence returns the next sequence number for incremental checkpoints. It counts existing checkpoint files in the task metadata checkpoints directory. Returns 1 if no checkpoints exist yet.

func GetStrategy

GetStrategy returns the manual-commit strategy instance with blob fetching enabled so that checkpoint reads work after treeless fetches.

func HasUncommittedChanges

func HasUncommittedChanges(ctx context.Context) (bool, error)

HasUncommittedChanges checks if there are any uncommitted changes in the repository. This includes staged changes, unstaged changes, and untracked files. Uses git CLI instead of go-git because go-git doesn't respect global gitignore (core.excludesfile) which can cause false positives for globally ignored files.

func IsAccessibleMode

func IsAccessibleMode() bool

IsAccessibleMode returns true if accessibility mode should be enabled. This checks the ACCESSIBLE environment variable. Set ACCESSIBLE=1 (or any non-empty value) to enable accessible mode, which uses simpler prompts that work better with screen readers.

func IsEnabled

func IsEnabled(ctx context.Context) (bool, error)

IsEnabled returns whether Entire is currently enabled. Returns true by default if settings cannot be loaded.

func IsOnDefaultBranch

func IsOnDefaultBranch(ctx context.Context) (bool, string, error)

IsOnDefaultBranch checks if the repository is currently on the default branch. It determines the default branch by: 1. Checking the remote origin's HEAD reference 2. Falling back to common names (main, master) if remote HEAD is unavailable Returns (isDefault, branchName, error)

func JoinAgentNames

func JoinAgentNames(names []types.AgentName) string

JoinAgentNames joins agent names into a comma-separated string.

func LoadEntireSettings

func LoadEntireSettings(ctx context.Context) (*settings.EntireSettings, error)

LoadEntireSettings loads the Entire settings from .entire/settings.json, then applies any overrides from .entire/settings.local.json if it exists. Returns default settings if neither file exists. Works correctly from any subdirectory within the repository.

func NewAccessibleForm

func NewAccessibleForm(groups ...*huh.Group) *huh.Form

NewAccessibleForm creates a new huh form with accessibility mode enabled if the ACCESSIBLE environment variable is set. Note: WithAccessible() is only available on forms, not individual fields. Always wrap confirmations and other prompts in a form to enable accessibility.

func NewHelpCmd

func NewHelpCmd(rootCmd *cobra.Command) *cobra.Command

NewHelpCmd creates a custom help command that supports a hidden -t flag to display the entire command tree.

func NewRootCmd

func NewRootCmd() *cobra.Command

func ParseSubagentTypeAndDescription

func ParseSubagentTypeAndDescription(toolInput json.RawMessage) (agentType, description string)

ParseSubagentTypeAndDescription extracts subagent_type and description from Task tool_input. Returns empty strings if parsing fails or fields are not present.

func SaveEntireSettings

func SaveEntireSettings(ctx context.Context, s *settings.EntireSettings) error

SaveEntireSettings saves the Entire settings to .entire/settings.json.

func SaveEntireSettingsLocal

func SaveEntireSettingsLocal(ctx context.Context, s *settings.EntireSettings) error

SaveEntireSettingsLocal saves the Entire settings to .entire/settings.local.json.

func ShouldSkipOnDefaultBranch

func ShouldSkipOnDefaultBranch(ctx context.Context) (bool, string)

ShouldSkipOnDefaultBranch checks if we're on the default branch. Returns (shouldSkip, branchName). If shouldSkip is true, the caller should skip the operation to avoid polluting main/master history. If the branch cannot be determined, returns (false, "") to allow the operation.

func TaskMetadataDir

func TaskMetadataDir(sessionMetadataDir, toolUseID string) string

TaskMetadataDir returns the path to a task's metadata directory within the session metadata directory.

func TruncateTranscriptAtUUID

func TruncateTranscriptAtUUID(transcript []transcriptLine, uuid string) []transcriptLine

TruncateTranscriptAtUUID returns transcript lines up to and including the line with the given UUID. If the UUID is not found or is empty, returns the entire transcript.

func ValidateBranchName

func ValidateBranchName(ctx context.Context, branchName string) error

ValidateBranchName checks if a branch name is valid using git check-ref-format. Returns an error if the name is invalid or contains unsafe characters.

func WriteTaskCheckpoint

func WriteTaskCheckpoint(taskMetadataDir string, checkpoint *TaskCheckpoint) error

WriteTaskCheckpoint writes the checkpoint.json file to the task metadata directory. Creates the directory if it doesn't exist. Uses os.Root for traversal-resistant file writes within the metadata directory.

func WriteTaskPrompt

func WriteTaskPrompt(taskMetadataDir, prompt string) error

WriteTaskPrompt writes the task prompt to the task metadata directory. Uses os.Root for traversal-resistant file writes within the metadata directory.

Types

type EnableOptions added in v0.4.9

type EnableOptions struct {
	LocalDev            bool
	UseLocalSettings    bool
	UseProjectSettings  bool
	ForceHooks          bool
	SkipPushSessions    bool
	CheckpointRemote    string
	Telemetry           bool
	AbsoluteGitHookPath bool
}

EnableOptions holds the flags for `entire enable`.

type EntireSettings

type EntireSettings = settings.EntireSettings

EntireSettings is an alias for settings.EntireSettings.

type FileChanges added in v0.4.3

type FileChanges struct {
	Modified []string // Modified or staged files
	New      []string // Untracked files (filtered if previouslyUntracked provided)
	Deleted  []string // Deleted files (staged or unstaged)
}

FileChanges holds categorized file changes from git status.

func DetectFileChanges added in v0.4.3

func DetectFileChanges(ctx context.Context, previouslyUntracked []string) (*FileChanges, error)

DetectFileChanges returns categorized file changes from the current git status.

previouslyUntracked controls new-file detection:

  • nil: all untracked files go into New
  • non-nil: only untracked files NOT in the pre-existing set go into New

Modified includes both worktree and staging modified/added files. Deleted includes both staged and unstaged deletions. All results exclude .entire/ directory.

type GitAuthor

type GitAuthor struct {
	Name  string
	Email string
}

GitAuthor represents the git user configuration

func GetGitAuthor

func GetGitAuthor(ctx context.Context) (*GitAuthor, error)

GetGitAuthor retrieves the git user.name and user.email from the repository config. It checks local config first, then falls back to global config. If go-git can't find the config, it falls back to using the git command. Returns fallback defaults if no user is configured anywhere.

type PostTaskHookInput

type PostTaskHookInput struct {
	TaskHookInput

	AgentID   string          // Extracted from tool_response.agentId
	ToolInput json.RawMessage // Raw tool input for reference
}

PostTaskHookInput represents the parsed input from PostToolUse[Task] hook

type PrePromptState

type PrePromptState struct {
	SessionID      string   `json:"session_id"`
	Timestamp      string   `json:"timestamp"`
	UntrackedFiles []string `json:"untracked_files"`

	// TranscriptOffset is the unified transcript position when this state was captured.
	// For Claude Code (JSONL), this is the line count.
	// For Gemini CLI (JSON), this is the message count.
	// Zero means not set or session just started.
	TranscriptOffset int `json:"transcript_offset,omitempty"`

	// LastTranscriptIdentifier is the agent-specific identifier at the transcript position.
	// UUID for Claude Code, message ID for Gemini CLI. Optional metadata.
	LastTranscriptIdentifier string `json:"last_transcript_identifier,omitempty"`

	// Deprecated: StartMessageIndex is the old Gemini-specific field.
	// Migrated to TranscriptOffset on load.
	StartMessageIndex int `json:"start_message_index,omitempty"`

	// Deprecated: StepTranscriptStart is the old Claude-specific field.
	// Migrated to TranscriptOffset on load.
	StepTranscriptStart int `json:"step_transcript_start,omitempty"`

	// Deprecated: LastTranscriptLineCount is the oldest name for transcript position.
	// Migrated to TranscriptOffset on load.
	LastTranscriptLineCount int `json:"last_transcript_line_count,omitempty"`
}

PrePromptState stores the state captured before a user prompt

func LoadPrePromptState

func LoadPrePromptState(ctx context.Context, sessionID string) (*PrePromptState, error)

LoadPrePromptState loads previously captured state. Returns nil if no state file exists.

func (*PrePromptState) PreUntrackedFiles added in v0.4.3

func (s *PrePromptState) PreUntrackedFiles() []string

PreUntrackedFiles returns the untracked files list, or nil if the receiver is nil. This nil-vs-empty distinction lets DetectFileChanges know whether to skip new-file detection. When the receiver is non-nil but UntrackedFiles is nil (e.g., old state files deserialized with "untracked_files": null), returns an empty non-nil slice so that all current untracked files are correctly treated as new.

type PreTaskState

type PreTaskState struct {
	ToolUseID      string   `json:"tool_use_id"`
	Timestamp      string   `json:"timestamp"`
	UntrackedFiles []string `json:"untracked_files"`
}

PreTaskState stores the state captured before a task execution

func LoadPreTaskState

func LoadPreTaskState(ctx context.Context, toolUseID string) (*PreTaskState, error)

LoadPreTaskState loads previously captured task state. Returns nil if no state file exists.

func (*PreTaskState) PreUntrackedFiles added in v0.4.3

func (s *PreTaskState) PreUntrackedFiles() []string

PreUntrackedFiles returns the untracked files list, or nil if the receiver is nil. See PrePromptState.PreUntrackedFiles for nil-vs-empty semantics.

type SilentError

type SilentError struct {
	Err error
}

SilentError wraps an error to signal that the error message has already been printed to the user. main.go checks for this type to avoid duplicate output.

func NewSilentError

func NewSilentError(err error) *SilentError

NewSilentError creates a SilentError wrapping the given error. Use this when you've already printed a user-friendly error message and don't want main.go to print the error again.

func (*SilentError) Error

func (e *SilentError) Error() string

func (*SilentError) Unwrap

func (e *SilentError) Unwrap() error

type SubagentCheckpointHookInput

type SubagentCheckpointHookInput struct {
	SessionID      string          `json:"session_id"`
	TranscriptPath string          `json:"transcript_path"`
	ToolName       string          `json:"tool_name"`
	ToolUseID      string          `json:"tool_use_id"`
	ToolInput      json.RawMessage `json:"tool_input"`
	ToolResponse   json.RawMessage `json:"tool_response"`
}

SubagentCheckpointHookInput represents the JSON input from PostToolUse hooks for subagent checkpoint creation (TodoWrite, Edit, Write)

type TaskCheckpoint

type TaskCheckpoint struct {
	SessionID      string `json:"session_id"`
	ToolUseID      string `json:"tool_use_id"`
	CheckpointUUID string `json:"checkpoint_uuid"`
	AgentID        string `json:"agent_id,omitempty"`
}

TaskCheckpoint contains the checkpoint information for a task

func ReadTaskCheckpoint

func ReadTaskCheckpoint(taskMetadataDir string) (*TaskCheckpoint, error)

ReadTaskCheckpoint reads the checkpoint file from the task metadata directory. Uses os.Root for traversal-resistant file reads within the metadata directory.

type TaskHookInput

type TaskHookInput struct {
	SessionID      string          `json:"session_id"`
	TranscriptPath string          `json:"transcript_path"`
	ToolUseID      string          `json:"tool_use_id"`
	ToolInput      json.RawMessage `json:"tool_input"`
}

TaskHookInput represents the JSON input from PreToolUse[Task] hook

type TempFileDeleteError added in v0.4.6

type TempFileDeleteError struct {
	File string
	Err  error
}

TempFileDeleteError contains a file name and the error that occurred during deletion.

type TranscriptPosition

type TranscriptPosition struct {
	LastUUID  string // Last non-empty UUID (from user/assistant messages)
	LineCount int    // Total number of lines
}

TranscriptPosition contains the position information for a transcript file.

func GetTranscriptPosition

func GetTranscriptPosition(path string) (TranscriptPosition, error)

GetTranscriptPosition reads a transcript file and returns the last UUID and line count. Returns empty position if file doesn't exist or is empty. Only considers UUIDs from actual messages (user/assistant), not summary rows which use leafUuid.

Directories

Path Synopsis
Package agent provides interfaces and types for integrating with coding agents.
Package agent provides interfaces and types for integrating with coding agents.
claudecode
Package claudecode implements the Agent interface for Claude Code.
Package claudecode implements the Agent interface for Claude Code.
copilotcli
Package copilotcli implements the Agent interface for GitHub Copilot CLI.
Package copilotcli implements the Agent interface for GitHub Copilot CLI.
cursor
Package cursor implements the Agent interface for Cursor.
Package cursor implements the Agent interface for Cursor.
external
Package external provides an adapter that bridges external agent binaries (discovered via PATH as entire-agent-<name>) to the agent.Agent interface.
Package external provides an adapter that bridges external agent binaries (discovered via PATH as entire-agent-<name>) to the agent.Agent interface.
factoryaidroid
Package factoryaidroid implements the Agent interface for Factory AI Droid.
Package factoryaidroid implements the Agent interface for Factory AI Droid.
geminicli
Package geminicli implements the Agent interface for Gemini CLI.
Package geminicli implements the Agent interface for Gemini CLI.
opencode
Package opencode implements the Agent interface for OpenCode.
Package opencode implements the Agent interface for OpenCode.
testutil
Package testutil provides shared test utilities for agent packages.
Package testutil provides shared test utilities for agent packages.
vogon
Package vogon implements the Agent interface for a deterministic test agent used as an E2E canary.
Package vogon implements the Agent interface for a deterministic test agent used as an E2E canary.
Package benchutil provides test fixture helpers for CLI benchmarks.
Package benchutil provides test fixture helpers for CLI benchmarks.
Package checkpoint provides types and interfaces for checkpoint storage.
Package checkpoint provides types and interfaces for checkpoint storage.
id
Package id provides the CheckpointID type for identifying checkpoints.
Package id provides the CheckpointID type for identifying checkpoints.
Package jsonutil provides JSON utilities with consistent formatting.
Package jsonutil provides JSON utilities with consistent formatting.
Package logging provides structured logging for the Entire CLI using slog.
Package logging provides structured logging for the Entire CLI using slog.
Package osroot provides traversal-resistant file I/O helpers built on os.Root (Go 1.24+).
Package osroot provides traversal-resistant file I/O helpers built on os.Root (Go 1.24+).
Package settings provides configuration loading for Entire.
Package settings provides configuration loading for Entire.
Package strategy provides the manual-commit strategy for managing Claude Code session changes via shadow branches and checkpoint condensation.
Package strategy provides the manual-commit strategy for managing Claude Code session changes via shadow branches and checkpoint condensation.
Package stringutil provides UTF-8 safe string manipulation utilities.
Package stringutil provides UTF-8 safe string manipulation utilities.
Package summarize provides AI-powered summarization of development sessions.
Package summarize provides AI-powered summarization of development sessions.
Package testutil provides shared test utilities for both integration and e2e tests.
Package testutil provides shared test utilities for both integration and e2e tests.
Package trail provides types and helpers for managing trail metadata.
Package trail provides types and helpers for managing trail metadata.
Package trailers provides parsing and formatting for Entire commit message trailers.
Package trailers provides parsing and formatting for Entire commit message trailers.
Package transcript provides shared types and utilities for parsing JSONL transcripts.
Package transcript provides shared types and utilities for parsing JSONL transcripts.
Package validation provides input validation functions for the Entire CLI.
Package validation provides input validation functions for the Entire CLI.

Jump to

Keyboard shortcuts

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