Documentation
¶
Overview ¶
Package workspace manages git worktrees and tmux sessions for parallel development workflows, with AI agent orchestration, PR fetching, and interactive shell access.
Index ¶
- Variables
- func ApplyEnvOverrides(baseEnv []string, overrides map[string]string) []string
- func BuildEnvOverrides(mainRepoPath string) map[string]string
- func EnsureDefaultPrompts(globalConfigDir string) bool
- func ExpandPromptTemplate(body, taskID string) string
- func ExtractFallback(body string) string
- func GenerateExportCommands(overrides map[string]string) []string
- func GenerateSingleEnvCommand(overrides map[string]string) string
- func HasTicketPlaceholder(body string) bool
- func MapKeyToTmux(msg tea.KeyMsg) (key string, useLiteral bool)
- func SanitizeBranchName(name string) string
- func ValidateBranchName(name string) (bool, []string, string)
- func WriteDefaultPromptsToConfig(globalConfigDir string) bool
- type Agent
- type AgentOutputMsg
- type AgentPollUnchangedMsg
- type AgentStartedMsg
- type AgentStatus
- type AgentStoppedMsg
- type AgentType
- type ApproveResultMsg
- type AsyncCaptureResultMsg
- type AsyncShellCaptureResultMsg
- type BranchListMsg
- type CheckPRMergedMsg
- type CleanupDoneMsg
- type CleanupResults
- type CommitStatusInfo
- type CommitStatusLoadedMsg
- type Conflict
- type ConflictsDetectedMsg
- type CreateDoneMsg
- type CreateWorktreeMsg
- type DeleteDoneMsg
- type DeleteWorktreeMsg
- type DiffErrorMsg
- type DiffLoadedMsg
- type DiffViewMode
- type DirectMergeDoneMsg
- type FetchPRDoneMsg
- type FetchPRListMsg
- type FocusPane
- type GitStats
- type InteractivePasteResultMsg
- type InteractiveSessionDeadMsg
- type InteractiveState
- type LocalBranchesMsg
- type MergeCommitDoneMsg
- type MergeCommitState
- type MergeResolutionMsg
- type MergeStepCompleteMsg
- type MergeWorkflowState
- type MergeWorkflowStep
- type OpenCreateModalWithTaskMsg
- type OutputBuffer
- func (b *OutputBuffer) Clear()
- func (b *OutputBuffer) Len() int
- func (b *OutputBuffer) LineCount() int
- func (b *OutputBuffer) Lines() []string
- func (b *OutputBuffer) LinesRange(start, end int) []string
- func (b *OutputBuffer) String() string
- func (b *OutputBuffer) Update(content string) bool
- func (b *OutputBuffer) Write(content string)
- type PRListItem
- type Plugin
- func (p *Plugin) Approve(wt *Worktree) tea.Cmd
- func (p *Plugin) ApproveAll() tea.Cmd
- func (p *Plugin) AttachToSession(wt *Worktree) tea.Cmd
- func (p *Plugin) AttachToWorktreeDir(wt *Worktree) tea.Cmd
- func (p *Plugin) Cleanup(removeSessions bool) error
- func (p *Plugin) CleanupOrphanedSessions() error
- func (p *Plugin) Commands() []plugin.Command
- func (p *Plugin) ConsumesTextInput() bool
- func (p *Plugin) FocusContext() string
- func (p *Plugin) ID() string
- func (p *Plugin) Icon() string
- func (p *Plugin) Init(ctx *plugin.Context) error
- func (p *Plugin) IsFocused() bool
- func (p *Plugin) Name() string
- func (p *Plugin) Reject(wt *Worktree) tea.Cmd
- func (p *Plugin) SendText(wt *Worktree, text string) tea.Cmd
- func (p *Plugin) SetFocused(f bool)
- func (p *Plugin) Start() tea.Cmd
- func (p *Plugin) StartAgent(wt *Worktree, agentType AgentType) tea.Cmd
- func (p *Plugin) StartAgentWithOptions(wt *Worktree, agentType AgentType, skipPerms bool, prompt *Prompt) tea.Cmd
- func (p *Plugin) Stop()
- func (p *Plugin) StopAgent(wt *Worktree) tea.Cmd
- func (p *Plugin) Update(msg tea.Msg) (plugin.Plugin, tea.Cmd)
- func (p *Plugin) View(width, height int) string
- type PreviewTab
- type Prompt
- type PromptCancelledMsg
- type PromptInstallDefaultsMsg
- type PromptPicker
- type PromptSelectedMsg
- type PullAfterMergeMsg
- type PushDoneMsg
- type PushMsg
- type RebaseResolutionMsg
- type RefreshDoneMsg
- type RefreshMsg
- type RejectResultMsg
- type RemoteBranchDeleteMsg
- type RemoteCheckDoneMsg
- type RenameShellDoneMsg
- type ResumeConversationMsg
- type SendTextResultMsg
- type SetupConfig
- type ShellAgentErrorMsg
- type ShellAgentStartedMsg
- type ShellCreatedMsg
- type ShellDefinition
- type ShellDetachedMsg
- type ShellKilledMsg
- type ShellManifest
- func (m *ShellManifest) AddShell(def ShellDefinition) error
- func (m *ShellManifest) FindShell(tmuxName string) *ShellDefinition
- func (m *ShellManifest) Path() string
- func (m *ShellManifest) RemoveShell(tmuxName string) error
- func (m *ShellManifest) Save() error
- func (m *ShellManifest) UpdateShell(def ShellDefinition) error
- type ShellManifestChangedMsg
- type ShellOutputMsg
- type ShellSession
- type ShellSessionDeadMsg
- type ShellWatcher
- type StatsErrorMsg
- type StatsLoadedMsg
- type Task
- type TaskDetails
- type TaskDetailsLoadedMsg
- type TaskLinkedMsg
- type TaskSearchResultsMsg
- type TicketMode
- type TmuxAttachFinishedMsg
- type UncommittedChangesCheckMsg
- type ViewMode
- type WatchEventMsg
- type WatcherErrorMsg
- type WatcherStartedMsg
- type WorkDirDeletedMsg
- type Worktree
- type WorktreeStatus
Constants ¶
This section is empty.
Variables ¶
var AgentCommands = map[AgentType]string{ AgentClaude: "claude", AgentCodex: "codex", AgentAider: "aider", AgentGemini: "gemini", AgentCursor: "cursor-agent", AgentOpenCode: "opencode", AgentPi: "pi", }
AgentCommands maps agent types to their CLI commands.
var AgentDisplayNames = map[AgentType]string{ AgentNone: "None (attach only)", AgentClaude: "Claude Code", AgentCodex: "Codex CLI", AgentGemini: "Gemini CLI", AgentCursor: "Cursor Agent", AgentOpenCode: "OpenCode", AgentPi: "Pi Agent", AgentShell: "Project Shell", }
AgentDisplayNames provides human-readable names for agent types.
var AgentTypeOrder = []AgentType{ AgentClaude, AgentCodex, AgentGemini, AgentCursor, AgentOpenCode, AgentPi, AgentNone, }
AgentTypeOrder defines the order of agents in selection UI.
var DefaultEnvOverrides = map[string]string{
"GOWORK": "off",
"GOFLAGS": "",
"NODE_OPTIONS": "",
"NODE_PATH": "",
"PYTHONPATH": "",
"VIRTUAL_ENV": "",
}
DefaultEnvOverrides contains environment variables to clear/override for worktree isolation. These prevent common issues when running commands in worktrees.
var ShellAgentOrder = []AgentType{ AgentNone, AgentClaude, AgentCodex, AgentGemini, AgentCursor, AgentOpenCode, AgentPi, }
ShellAgentOrder defines agent order for shell creation (None first as default). td-a902fe: shells default to no agent, so "None" is first.
var SkipPermissionsFlags = map[AgentType]string{ AgentClaude: "--dangerously-skip-permissions", AgentCodex: "--dangerously-bypass-approvals-and-sandbox", AgentAider: "--yes", AgentGemini: "--yolo", AgentCursor: "-f", AgentOpenCode: "", AgentPi: "", }
SkipPermissionsFlags maps agent types to their skip-permissions CLI flags.
Functions ¶
func ApplyEnvOverrides ¶
ApplyEnvOverrides applies overrides to an existing environment slice. Returns a new slice with overrides applied.
func BuildEnvOverrides ¶
BuildEnvOverrides returns the combined environment overrides for a worktree. User overrides from .worktree-env take precedence over defaults.
func EnsureDefaultPrompts ¶
EnsureDefaultPrompts creates the global config with default prompts if no config exists. Returns true if defaults were created.
func ExpandPromptTemplate ¶
ExpandPromptTemplate expands template variables in a prompt body. - {{ticket}} expands to taskID (returns empty if taskID is empty) - {{ticket || 'default'}} expands to taskID, or 'default' if taskID is empty
func ExtractFallback ¶
ExtractFallback extracts the fallback value from a prompt body. Returns the first fallback found, or empty string if none.
func GenerateExportCommands ¶
GenerateExportCommands generates shell commands to apply environment overrides. Empty values generate unset commands, non-empty generate export commands.
func GenerateSingleEnvCommand ¶
GenerateSingleEnvCommand returns a single shell command that applies all env overrides. This is less noisy than sending multiple commands individually.
func HasTicketPlaceholder ¶
HasTicketPlaceholder returns true if the body contains {{ticket}} or {{ticket || '...'}}
func MapKeyToTmux ¶
MapKeyToTmux is a wrapper around tty.MapKeyToTmux for backward compatibility. See tty.MapKeyToTmux for documentation.
func SanitizeBranchName ¶
SanitizeBranchName converts a string to a valid git branch name. The output should always pass ValidateBranchName.
func ValidateBranchName ¶
ValidateBranchName validates a git branch name and returns validation state. Returns: (valid, errors, sanitized suggestion) Based on git-check-ref-format rules.
func WriteDefaultPromptsToConfig ¶
WriteDefaultPromptsToConfig merges default prompts into the global config. If config.json exists, it preserves other fields and adds/replaces the prompts key. If config.json does not exist, it creates one with default prompts. Returns true on success.
Types ¶
type Agent ¶
type Agent struct {
Type AgentType // claude, codex, aider, gemini
TmuxSession string // tmux session name
TmuxPane string // Pane identifier (e.g., "%12" - globally unique)
PID int // Process ID (if available)
StartedAt time.Time
LastOutput time.Time // Last time output was detected
OutputBuf *OutputBuffer // Last N lines of output
Status AgentStatus
WaitingFor string // Prompt text if waiting
// Runaway detection fields (td-018f25)
// Track recent poll times to detect continuous output that would cause CPU spikes.
RecentPollTimes []time.Time // Last N poll times for runaway detection
PollsThrottled bool // True if this agent is throttled due to continuous output
UnchangedPollCount int // Consecutive unchanged polls (for throttle reset)
}
Agent represents an AI coding agent process.
func (*Agent) CheckRunaway ¶
CheckRunaway checks if this agent should be throttled (td-018f25). Returns true and sets PollsThrottled if runaway condition is detected.
func (*Agent) RecordPollTime ¶
func (a *Agent) RecordPollTime()
RecordPollTime records a poll time for runaway detection (td-018f25). Should be called when an AgentOutputMsg (content changed) is received.
func (*Agent) RecordUnchangedPoll ¶
func (a *Agent) RecordUnchangedPoll()
RecordUnchangedPoll records an unchanged poll for throttle reset (td-018f25). Should be called when an AgentPollUnchangedMsg is received.
type AgentOutputMsg ¶
type AgentOutputMsg struct {
WorkspaceName string
Output string
Status WorktreeStatus
WaitingFor string
// Cursor position captured atomically with output (only set in interactive mode)
CursorRow int
CursorCol int
CursorVisible bool
HasCursor bool // True if cursor position was captured
PaneHeight int // Tmux pane height for cursor offset calculation
PaneWidth int // Tmux pane width for display alignment
}
AgentOutputMsg delivers new agent output.
type AgentPollUnchangedMsg ¶
type AgentPollUnchangedMsg struct {
WorkspaceName string
CurrentStatus WorktreeStatus // Status including session file re-check
WaitingFor string // Prompt text if waiting
// Cursor position captured atomically (even when content unchanged)
CursorRow int
CursorCol int
CursorVisible bool
HasCursor bool
PaneHeight int // Tmux pane height for cursor offset calculation
PaneWidth int // Tmux pane width for display alignment
}
AgentPollUnchangedMsg signals content unchanged, schedule next poll.
type AgentStartedMsg ¶
type AgentStartedMsg struct {
Epoch uint64 // Epoch when request was issued (for stale detection)
WorkspaceName string
SessionName string
PaneID string // tmux pane ID (e.g., "%12") for interactive mode
AgentType AgentType
Reconnected bool // True if we reconnected to an existing session
Err error
}
AgentStartedMsg signals an agent has been started in a worktree.
func (AgentStartedMsg) GetEpoch ¶
func (m AgentStartedMsg) GetEpoch() uint64
GetEpoch implements plugin.EpochMessage.
type AgentStatus ¶
type AgentStatus int
AgentStatus represents the current status of an agent.
const ( AgentStatusIdle AgentStatus = iota AgentStatusRunning AgentStatusWaiting AgentStatusDone AgentStatusError )
type AgentStoppedMsg ¶
AgentStoppedMsg signals an agent has stopped.
type AgentType ¶
type AgentType string
AgentType represents the type of AI coding agent.
const ( AgentNone AgentType = "" // No agent (attach only) AgentClaude AgentType = "claude" // Claude Code AgentCodex AgentType = "codex" // Codex CLI AgentAider AgentType = "aider" // Aider AgentGemini AgentType = "gemini" // Gemini CLI AgentCursor AgentType = "cursor" // Cursor Agent AgentOpenCode AgentType = "opencode" // OpenCode AgentPi AgentType = "pi" // Pi Agent AgentCustom AgentType = "custom" // Custom command AgentShell AgentType = "shell" // Project shell (not an AI agent) )
type ApproveResultMsg ¶
ApproveResultMsg signals the result of an approve action.
type AsyncCaptureResultMsg ¶
type AsyncCaptureResultMsg struct {
WorkspaceName string // Worktree this capture is for
SessionName string // tmux session name
Output string // Captured output (empty on error)
Err error // Non-nil if capture failed
}
AsyncCaptureResultMsg delivers async tmux capture results. Used to avoid blocking the UI thread on tmux subprocess calls (td-c2961e).
type AsyncShellCaptureResultMsg ¶
type AsyncShellCaptureResultMsg struct {
TmuxName string // Shell session tmux name
Output string // Captured output (empty on error)
Err error // Non-nil if capture failed
}
AsyncShellCaptureResultMsg delivers async shell capture results.
type BranchListMsg ¶
BranchListMsg delivers available branches.
type CheckPRMergedMsg ¶
CheckPRMergedMsg signals the result of checking if a PR was merged.
type CleanupDoneMsg ¶
type CleanupDoneMsg struct {
WorkspaceName string
Results *CleanupResults
}
CleanupDoneMsg signals that cleanup operations completed.
type CleanupResults ¶
type CleanupResults struct {
LocalWorktreeDeleted bool
LocalBranchDeleted bool
RemoteBranchDeleted bool
PullAttempted bool
PullSuccess bool
PullError error
Errors []string
// Error detail expansion state (for UX improvements)
ShowErrorDetails bool // Toggle for expanded error view
PullErrorSummary string // Concise 1-line summary
PullErrorFull string // Full git output for details view
BranchDiverged bool // Enables rebase/merge resolution actions
BaseBranch string // Branch name for resolution commands
}
CleanupResults holds the results of cleanup operations for display in summary.
type CommitStatusInfo ¶
type CommitStatusInfo struct {
Hash string // Short commit hash
Subject string // Commit subject line
Pushed bool // Is commit pushed to remote?
Merged bool // Is commit merged to base branch?
}
CommitStatusInfo holds commit information with merge/push status.
type CommitStatusLoadedMsg ¶
type CommitStatusLoadedMsg struct {
Epoch uint64 // Epoch when request was issued (for stale detection)
WorkspaceName string
Commits []CommitStatusInfo
Err error
}
CommitStatusLoadedMsg delivers commit status info for the diff view header.
func (CommitStatusLoadedMsg) GetEpoch ¶
func (m CommitStatusLoadedMsg) GetEpoch() uint64
GetEpoch implements plugin.EpochMessage.
type Conflict ¶
type Conflict struct {
Worktrees []string // Names of worktrees with conflicting changes
Files []string // List of conflicting files
}
Conflict represents a file conflict between worktrees.
type ConflictsDetectedMsg ¶
ConflictsDetectedMsg signals that conflicts have been detected.
type CreateDoneMsg ¶
type CreateDoneMsg struct {
Worktree *Worktree
AgentType AgentType // Agent selected at creation
SkipPerms bool // Whether to skip permissions
Prompt *Prompt // Selected prompt template (nil if none)
Err error
}
CreateDoneMsg signals worktree creation completed.
type CreateWorktreeMsg ¶
CreateWorktreeMsg requests worktree creation.
type DeleteDoneMsg ¶
type DeleteDoneMsg struct {
Name string
Err error
Warnings []string // Non-fatal warnings (e.g., branch deletion failures)
}
DeleteDoneMsg signals worktree deletion completed.
type DeleteWorktreeMsg ¶
DeleteWorktreeMsg requests worktree deletion.
type DiffErrorMsg ¶
DiffErrorMsg signals diff loading failed.
type DiffLoadedMsg ¶
type DiffLoadedMsg struct {
Epoch uint64 // Epoch when request was issued (for stale detection)
WorkspaceName string
Content string
Raw string
}
DiffLoadedMsg delivers diff content for a worktree.
func (DiffLoadedMsg) GetEpoch ¶
func (m DiffLoadedMsg) GetEpoch() uint64
GetEpoch implements plugin.EpochMessage.
type DiffViewMode ¶
type DiffViewMode int
DiffViewMode specifies the diff rendering mode.
const ( DiffViewUnified DiffViewMode = iota // Line-by-line unified view DiffViewSideBySide // Side-by-side split view )
type DirectMergeDoneMsg ¶
DirectMergeDoneMsg signals that direct merge completed.
type FetchPRDoneMsg ¶
type FetchPRDoneMsg struct {
Worktree *Worktree
AlreadyLocal bool // branch already existed locally
Branch string // for finding existing worktree when Worktree is nil
Err error
}
FetchPRDoneMsg signals that a PR branch was fetched and worktree created.
type FetchPRListMsg ¶
type FetchPRListMsg struct {
PRs []PRListItem
Err error
}
FetchPRListMsg delivers the list of open PRs from gh CLI.
type GitStats ¶
type GitStats struct {
Additions int
Deletions int
FilesChanged int
Ahead int // Commits ahead of base branch
Behind int // Commits behind base branch
}
GitStats holds file change statistics.
type InteractivePasteResultMsg ¶
InteractivePasteResultMsg reports clipboard paste results for interactive mode.
type InteractiveSessionDeadMsg ¶
type InteractiveSessionDeadMsg struct{}
InteractiveSessionDeadMsg indicates the tmux session has ended. Sent when send-keys or capture fails with a session/pane not found error.
type InteractiveState ¶
type InteractiveState struct {
// Active indicates whether interactive mode is currently active.
Active bool
// TargetPane is the tmux pane ID (e.g., "%12") receiving input.
TargetPane string
// TargetSession is the tmux session name for the active pane.
TargetSession string
// LastKeyTime tracks when the last key was sent for polling decay.
LastKeyTime time.Time
// EscapePressed tracks if a single Escape was recently pressed
// (for double-escape exit detection with 150ms delay).
EscapePressed bool
// EscapeTime is when the first Escape was pressed.
EscapeTime time.Time
// CursorRow and CursorCol track the cached cursor position for overlay rendering.
// Updated asynchronously via cursorPositionMsg from poll handler (td-648af4).
CursorRow int
CursorCol int
// CursorVisible indicates if the cursor should be rendered.
// Updated asynchronously via cursorPositionMsg from poll handler (td-648af4).
CursorVisible bool
// PaneHeight tracks the tmux pane height for cursor offset calculation.
// Used to adjust cursor_y when display height differs from pane height.
PaneHeight int
// PaneWidth tracks the tmux pane width for display width alignment.
PaneWidth int
// VisibleStart and VisibleEnd track the buffer line range currently visible.
// Used for interactive selection mapping.
VisibleStart int
VisibleEnd int
// ContentRowOffset is the number of preview content rows before output lines.
// Used to map mouse coordinates to buffer lines.
ContentRowOffset int
// BracketedPasteEnabled tracks whether the target app has enabled
// bracketed paste mode (ESC[?2004h). Updated from captured output.
BracketedPasteEnabled bool
// MouseReportingEnabled tracks whether the target app has enabled
// mouse reporting (1000/1002/1003/1006/1015). Updated from captured output.
MouseReportingEnabled bool
// EscapeTimerPending tracks if an escape timer is already in flight.
// Prevents duplicate timers from accumulating (td-83dc22).
EscapeTimerPending bool
// LastResizeAt tracks the last time we attempted to resize the tmux pane.
LastResizeAt time.Time
}
InteractiveState tracks state for interactive mode (tmux input passthrough). Feature-gated behind tmux_interactive_input feature flag.
type LocalBranchesMsg ¶
LocalBranchesMsg returns available local branches for target selection.
type MergeCommitDoneMsg ¶
MergeCommitDoneMsg signals that the commit before merge completed.
type MergeCommitState ¶
type MergeCommitState struct {
Worktree *Worktree
StagedCount int
ModifiedCount int
UntrackedCount int
CommitMessage string
Error string
}
MergeCommitState holds state for the commit-before-merge modal.
type MergeResolutionMsg ¶
MergeResolutionMsg signals result of merge resolution attempt.
type MergeStepCompleteMsg ¶
type MergeStepCompleteMsg struct {
WorkspaceName string
Step MergeWorkflowStep
Data string // Step-specific data (e.g., PR URL)
Err error
ExistingPRFound bool // True if PR already existed (vs newly created)
}
MergeStepCompleteMsg signals a merge workflow step completed.
type MergeWorkflowState ¶
type MergeWorkflowState struct {
Worktree *Worktree
Step MergeWorkflowStep
DiffSummary string
PRTitle string
PRBody string
PRURL string
ExistingPR bool // True if using an existing PR (vs newly created)
Error error
ErrorTitle string // Short title for error display (e.g. "Direct Merge Failed")
ErrorDetail string // Full error text for display and clipboard copy
ErrorFromStep MergeWorkflowStep // Which step produced the error
StepStatus map[MergeWorkflowStep]string // "pending", "running", "done", "error", "skipped"
DeleteAfterMerge bool // true = delete worktree after merge (default)
// Target branch selection
TargetBranch string // Resolved target branch for merge/PR
TargetBranchOption int // Selected index in branch list
TargetBranches []string // Available branches for selection
// Merge method selection
UseDirectMerge bool // true = direct merge to base, false = PR workflow
MergeMethodOption int // 0 = Create PR (default), 1 = Direct merge
// Post-merge confirmation options
DeleteLocalWorktree bool // Checkbox: delete local worktree (default: true)
DeleteLocalBranch bool // Checkbox: delete local branch (default: true)
DeleteRemoteBranch bool // Checkbox: delete remote branch (default: false)
PullAfterMerge bool // Checkbox: pull changes to current branch after merge
CurrentBranch string // Branch user was on before merge (for pull)
ConfirmationFocus int // 0-3=checkboxes, 4=confirm btn, 5=skip btn
ConfirmationHover int // Mouse hover state
// Cleanup results for summary display
CleanupResults *CleanupResults
PendingCleanupOps int // Counter for parallel cleanup operations in flight
}
MergeWorkflowState holds the state for the merge workflow modal.
type MergeWorkflowStep ¶
type MergeWorkflowStep int
MergeWorkflowStep represents the current step in the merge workflow.
const ( MergeStepReviewDiff MergeWorkflowStep = iota MergeStepTargetBranch // Choose target branch for merge/PR MergeStepMergeMethod // Choose: PR workflow or direct merge MergeStepPush MergeStepCreatePR MergeStepWaitingMerge MergeStepDirectMerge // Performing direct merge (no PR) MergeStepPostMergeConfirmation // User confirms cleanup options after PR merge MergeStepCleanup MergeStepDone MergeStepError // Error display step (strategy-agnostic) )
func (MergeWorkflowStep) String ¶
func (s MergeWorkflowStep) String() string
String returns a display name for the merge step.
type OpenCreateModalWithTaskMsg ¶
OpenCreateModalWithTaskMsg opens create modal pre-filled with task data. Sent from td-monitor plugin when user presses send-to-worktree hotkey.
type OutputBuffer ¶
type OutputBuffer struct {
// contains filtered or unexported fields
}
OutputBuffer is a thread-safe bounded buffer for agent output. Uses SHA256 hashing to detect content changes and avoid duplicate processing.
func NewOutputBuffer ¶
func NewOutputBuffer(capacity int) *OutputBuffer
NewOutputBuffer creates a new output buffer with the given capacity.
func (*OutputBuffer) Clear ¶
func (b *OutputBuffer) Clear()
Clear removes all lines from the buffer.
func (*OutputBuffer) Len ¶
func (b *OutputBuffer) Len() int
Len returns the number of lines in the buffer.
func (*OutputBuffer) LineCount ¶
func (b *OutputBuffer) LineCount() int
LineCount returns the number of lines without copying.
func (*OutputBuffer) Lines ¶
func (b *OutputBuffer) Lines() []string
Lines returns a copy of all lines in the buffer.
func (*OutputBuffer) LinesRange ¶
func (b *OutputBuffer) LinesRange(start, end int) []string
LinesRange returns a copy of lines in the specified range [start, end). This is more efficient than Lines() when only a portion is needed.
func (*OutputBuffer) String ¶
func (b *OutputBuffer) String() string
String returns the buffer contents as a single string.
func (*OutputBuffer) Update ¶
func (b *OutputBuffer) Update(content string) bool
Update replaces buffer content if it has changed (detected via SHA256 hash). Returns true if content was updated, false if content was unchanged.
func (*OutputBuffer) Write ¶
func (b *OutputBuffer) Write(content string)
Write replaces content in the buffer (for backward compatibility). Prefer Update() for change detection.
type PRListItem ¶
type PRListItem struct {
Number int `json:"number"`
Title string `json:"title"`
Branch string `json:"headRefName"`
Author prAuthor `json:"author"`
URL string `json:"url"`
CreatedAt string `json:"createdAt"`
IsDraft bool `json:"isDraft"`
}
PRListItem represents an open pull request for the fetch modal.
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin implements the worktree manager plugin.
func (*Plugin) ApproveAll ¶
ApproveAll approves all worktrees with pending prompts.
func (*Plugin) AttachToSession ¶
AttachToSession attaches to a tmux session using tea.ExecProcess.
func (*Plugin) AttachToWorktreeDir ¶
AttachToWorktreeDir creates a tmux session in the worktree directory and attaches to it.
func (*Plugin) CleanupOrphanedSessions ¶
CleanupOrphanedSessions removes sessions that no longer have worktrees.
func (*Plugin) ConsumesTextInput ¶
ConsumesTextInput reports whether the workspace plugin is currently in a mode that expects typed text input.
func (*Plugin) FocusContext ¶
FocusContext returns the current focus context for keybinding dispatch.
func (*Plugin) StartAgent ¶
StartAgent creates a tmux session and starts an agent for a worktree. If a session already exists, it reconnects to it instead of failing.
func (*Plugin) StartAgentWithOptions ¶
func (p *Plugin) StartAgentWithOptions(wt *Worktree, agentType AgentType, skipPerms bool, prompt *Prompt) tea.Cmd
StartAgentWithOptions creates a tmux session and starts an agent with options. If a session already exists, it reconnects to it instead of failing.
type PreviewTab ¶
type PreviewTab int
PreviewTab represents the active tab in the preview pane.
const ( PreviewTabOutput PreviewTab = iota // Agent output PreviewTabDiff // Git diff PreviewTabTask // TD task info )
type Prompt ¶
type Prompt struct {
Name string `json:"name"`
TicketMode TicketMode `json:"ticketMode"`
Body string `json:"body"`
Source string `json:"-"` // "global" or "project" (set at load time)
}
Prompt represents a configurable prompt template.
func DefaultPrompts ¶
func DefaultPrompts() []Prompt
DefaultPrompts returns the built-in default prompts. These serve as examples users can modify.
func LoadPrompts ¶
LoadPrompts loads and merges prompts from global and project config directories. Project prompts override global prompts with the same name. If no config exists, creates global config with default prompts. Returns sorted list by name.
type PromptCancelledMsg ¶
type PromptCancelledMsg struct{}
PromptCancelledMsg is sent when the picker is cancelled.
type PromptInstallDefaultsMsg ¶
type PromptInstallDefaultsMsg struct{}
PromptInstallDefaultsMsg is sent when user requests installing default prompts.
type PromptPicker ¶
type PromptPicker struct {
// contains filtered or unexported fields
}
PromptPicker is a modal for selecting a prompt template.
func NewPromptPicker ¶
func NewPromptPicker(prompts []Prompt, width, height int) *PromptPicker
NewPromptPicker creates a new prompt picker.
func (*PromptPicker) ClearHover ¶
func (pp *PromptPicker) ClearHover()
ClearHover clears the hover state.
func (*PromptPicker) FocusFilter ¶
func (pp *PromptPicker) FocusFilter()
FocusFilter focuses the filter input field.
func (*PromptPicker) SetHover ¶
func (pp *PromptPicker) SetHover(idx int)
SetHover sets the hover index for visual feedback.
func (*PromptPicker) Update ¶
func (pp *PromptPicker) Update(msg tea.Msg) (*PromptPicker, tea.Cmd)
Update handles input for the prompt picker.
func (*PromptPicker) View ¶
func (pp *PromptPicker) View() string
View renders the prompt picker modal.
type PromptSelectedMsg ¶
type PromptSelectedMsg struct {
Prompt *Prompt // nil means "none" was selected
}
PromptSelectedMsg is sent when a prompt is selected.
type PullAfterMergeMsg ¶
PullAfterMergeMsg signals that pull after merge completed.
type PushDoneMsg ¶
PushDoneMsg signals push operation completed.
type RebaseResolutionMsg ¶
RebaseResolutionMsg signals result of rebase resolution attempt.
type RefreshDoneMsg ¶
type RefreshDoneMsg struct {
Epoch uint64 // Epoch when request was issued (for stale detection)
Worktrees []*Worktree
Err error
}
RefreshDoneMsg signals that refresh has completed.
func (RefreshDoneMsg) GetEpoch ¶
func (m RefreshDoneMsg) GetEpoch() uint64
GetEpoch implements plugin.EpochMessage.
type RejectResultMsg ¶
RejectResultMsg signals the result of a reject action.
type RemoteBranchDeleteMsg ¶
RemoteBranchDeleteMsg signals the result of deleting a remote branch.
type RemoteCheckDoneMsg ¶
RemoteCheckDoneMsg signals remote branch existence check completed.
type RenameShellDoneMsg ¶
type RenameShellDoneMsg struct {
TmuxName string // Session name (stable identifier)
NewName string // New display name
Err error // Non-nil if rename failed
}
RenameShellDoneMsg signals shell rename operation completed
type ResumeConversationMsg ¶
type ResumeConversationMsg struct {
SessionID string // Adapter session ID for resume command
AdapterID string // Adapter type (claude-code, codex, etc.)
ResumeCmd string // Full resume command (e.g., "claude --resume xyz")
Type string // "shell" or "worktree"
// Worktree-specific fields (only used when Type == "worktree")
WorktreeName string // Branch name for new worktree
BaseBranch string // Base branch to create from
AgentType AgentType // Agent to start (matches adapter or user selection)
SkipPerms bool // Whether to auto-approve agent actions
}
ResumeConversationMsg requests resuming a conversation in a new shell or worktree. Sent from conversations plugin when user presses O key.
type SendTextResultMsg ¶
SendTextResultMsg signals the result of sending text to an agent.
type SetupConfig ¶
type SetupConfig struct {
CopyEnv bool // Whether to copy env files (default: true)
EnvFiles []string // List of env files to copy
SymlinkDirs []string // Directories to symlink (default: empty, opt-in)
RunSetupScript bool // Whether to run .worktree-setup.sh (default: true)
}
SetupConfig holds worktree setup configuration.
func DefaultSetupConfig ¶
func DefaultSetupConfig() *SetupConfig
DefaultSetupConfig returns the default setup configuration.
type ShellAgentErrorMsg ¶
type ShellAgentErrorMsg struct {
TmuxName string // Shell's tmux session name
Err error // Error that occurred
}
ShellAgentErrorMsg signals agent failed to start in a shell session. td-21a2d8: Sent when agent command fails to execute.
type ShellAgentStartedMsg ¶
type ShellAgentStartedMsg struct {
TmuxName string // Shell's tmux session name
AgentType AgentType // Agent type that was started
SkipPerms bool // Whether skip permissions was enabled
}
ShellAgentStartedMsg signals agent was started in a shell session. td-21a2d8: Sent after agent command is sent to tmux.
type ShellCreatedMsg ¶
type ShellCreatedMsg struct {
SessionName string // tmux session name
DisplayName string // Display name (e.g., "Shell 1")
PaneID string // tmux pane ID (e.g., "%12") for interactive mode
Err error // Non-nil if creation failed
AgentType AgentType // td-16b2b5: Agent to start (AgentNone if plain shell)
SkipPerms bool // td-16b2b5: Whether to skip permissions for agent
}
ShellCreatedMsg signals shell session was created
type ShellDefinition ¶
type ShellDefinition struct {
TmuxName string `json:"tmuxName"`
DisplayName string `json:"displayName"`
CreatedAt time.Time `json:"createdAt"`
AgentType string `json:"agentType,omitempty"`
SkipPerms bool `json:"skipPerms,omitempty"`
}
ShellDefinition contains all info needed to recreate a shell session.
type ShellDetachedMsg ¶
type ShellDetachedMsg struct {
Err error
}
ShellDetachedMsg signals user detached from shell session
type ShellKilledMsg ¶
type ShellKilledMsg struct {
SessionName string // tmux session name that was killed
}
ShellKilledMsg signals shell session was terminated
type ShellManifest ¶
type ShellManifest struct {
Version int `json:"version"`
Shells []ShellDefinition `json:"shells"`
// contains filtered or unexported fields
}
ShellManifest stores persistent shell definitions for cross-instance sync and reboot survival. Stored in {project}/.sidecar/shells.json.
func LoadShellManifest ¶
func LoadShellManifest(path string) (*ShellManifest, error)
LoadShellManifest loads the shell manifest from disk. Returns an empty manifest (not error) if file doesn't exist or is corrupted.
func (*ShellManifest) AddShell ¶
func (m *ShellManifest) AddShell(def ShellDefinition) error
AddShell adds a shell definition and saves.
func (*ShellManifest) FindShell ¶
func (m *ShellManifest) FindShell(tmuxName string) *ShellDefinition
FindShell returns a shell definition by tmuxName, or nil if not found.
func (*ShellManifest) Path ¶
func (m *ShellManifest) Path() string
Path returns the manifest file path.
func (*ShellManifest) RemoveShell ¶
func (m *ShellManifest) RemoveShell(tmuxName string) error
RemoveShell removes a shell by tmuxName and saves.
func (*ShellManifest) Save ¶
func (m *ShellManifest) Save() error
Save writes the manifest to disk atomically with file locking.
func (*ShellManifest) UpdateShell ¶
func (m *ShellManifest) UpdateShell(def ShellDefinition) error
UpdateShell updates an existing shell definition and saves.
type ShellManifestChangedMsg ¶
type ShellManifestChangedMsg struct{}
ShellManifestChangedMsg is emitted when the manifest file changes. This can be triggered by another sidecar instance modifying the manifest.
type ShellOutputMsg ¶
type ShellOutputMsg struct {
TmuxName string // Session name (stable identifier)
Output string
Changed bool
// Cursor position captured atomically with output (only set in interactive mode)
CursorRow int
CursorCol int
CursorVisible bool
HasCursor bool // True if cursor position was captured
PaneHeight int // Tmux pane height for cursor offset calculation
PaneWidth int // Tmux pane width for display alignment
}
ShellOutputMsg signals shell output was captured (for polling)
type ShellSession ¶
type ShellSession struct {
Name string // Display name (e.g., "Shell 1")
TmuxName string // tmux session name (e.g., "sidecar-sh-project-1")
Agent *Agent // Reuses Agent struct for tmux state
CreatedAt time.Time
ChosenAgent AgentType // td-317b64: Agent type selected at creation (AgentNone for plain shell)
SkipPerms bool // td-317b64: Whether skip permissions was enabled
IsOrphaned bool // td-f88fdd: True if manifest entry exists but tmux session is gone
}
ShellSession represents a tmux shell session (not tied to a git worktree).
type ShellSessionDeadMsg ¶
type ShellSessionDeadMsg struct {
TmuxName string // Session name for cleanup (stable identifier)
}
ShellSessionDeadMsg signals shell session was externally terminated (e.g., user typed 'exit' in the shell)
type ShellWatcher ¶
type ShellWatcher struct {
// contains filtered or unexported fields
}
ShellWatcher monitors the shell manifest file for changes. When changes are detected, it emits ShellManifestChangedMsg for cross-instance sync.
func NewShellWatcher ¶
func NewShellWatcher(manifestPath string) (*ShellWatcher, error)
NewShellWatcher creates a watcher for the shell manifest file.
func (*ShellWatcher) Start ¶
func (w *ShellWatcher) Start() <-chan tea.Msg
Start begins watching and returns a channel for receiving messages. The channel emits ShellManifestChangedMsg when the manifest changes.
func (*ShellWatcher) Stop ¶
func (w *ShellWatcher) Stop()
Stop stops the watcher and closes channels.
type StatsErrorMsg ¶
StatsErrorMsg signals stats loading failed.
type StatsLoadedMsg ¶
type StatsLoadedMsg struct {
Epoch uint64 // Epoch when request was issued (for stale detection)
WorkspaceName string
Stats *GitStats
}
StatsLoadedMsg delivers git stats for a worktree.
func (StatsLoadedMsg) GetEpoch ¶
func (m StatsLoadedMsg) GetEpoch() uint64
GetEpoch implements plugin.EpochMessage.
type Task ¶
type Task struct {
ID string
Title string
Status string
Description string
EpicTitle string // Parent epic title for search
}
Task represents a TD task for linking.
type TaskDetails ¶
type TaskDetails struct {
ID string
Title string
Status string
Priority string
Type string
Description string
Acceptance string
CreatedAt string
UpdatedAt string
}
TaskDetails contains full task information for preview pane.
type TaskDetailsLoadedMsg ¶
type TaskDetailsLoadedMsg struct {
TaskID string
Details *TaskDetails
Err error
}
TaskDetailsLoadedMsg delivers task details for the preview pane.
type TaskLinkedMsg ¶
TaskLinkedMsg signals a task was linked to a worktree.
type TaskSearchResultsMsg ¶
TaskSearchResultsMsg delivers task search results.
type TicketMode ¶
type TicketMode string
TicketMode defines how the task field behaves with a prompt.
const ( TicketRequired TicketMode = "required" // Task must be selected TicketOptional TicketMode = "optional" // Task is optional (may have fallback) TicketNone TicketMode = "none" // Task field is hidden )
type TmuxAttachFinishedMsg ¶
TmuxAttachFinishedMsg signals return from tmux attach.
type UncommittedChangesCheckMsg ¶
type UncommittedChangesCheckMsg struct {
WorkspaceName string
HasChanges bool
StagedCount int
ModifiedCount int
UntrackedCount int
Err error
}
UncommittedChangesCheckMsg signals the result of checking for uncommitted changes.
type ViewMode ¶
type ViewMode int
ViewMode represents the current view state.
const ( ViewModeList ViewMode = iota // List view (default) ViewModeKanban // Kanban board view ViewModeCreate // New worktree modal ViewModeTaskLink // Task link modal (for existing worktrees) ViewModeMerge // Merge workflow modal ViewModeAgentChoice // Agent action choice modal (attach/restart) ViewModeConfirmDelete // Delete confirmation modal ViewModeConfirmDeleteShell // Shell delete confirmation modal ViewModeCommitForMerge // Commit modal before merge workflow ViewModePromptPicker // Prompt template picker modal ViewModeTypeSelector // Type selector modal (shell vs worktree) ViewModeRenameShell // Rename shell modal ViewModeFilePicker // Diff file picker modal ViewModeInteractive // Interactive mode (tmux input passthrough) ViewModeFetchPR // Fetch remote PR modal )
type WatchEventMsg ¶
type WatchEventMsg struct {
Path string
}
WatchEventMsg signals a filesystem change was detected.
type WatcherErrorMsg ¶
type WatcherErrorMsg struct {
Err error
}
WatcherErrorMsg signals a file watcher error.
type WatcherStartedMsg ¶
type WatcherStartedMsg struct{}
WatcherStartedMsg signals the file watcher is running.
type WorkDirDeletedMsg ¶
type WorkDirDeletedMsg struct {
MainWorktreePath string
}
WorkDirDeletedMsg signals that the current working directory was deleted. This happens when sidecar is running inside a worktree that gets deleted.
type Worktree ¶
type Worktree struct {
Name string // e.g., "auth-oauth-flow"
Path string // Absolute path
Branch string // Git branch name
BaseBranch string // Branch worktree was created from
TaskID string // Linked td task (e.g., "td-a1b2")
TaskTitle string // Task title (used as fallback if td show fails)
PRURL string // URL of open PR (if any)
ChosenAgentType AgentType // Agent selected at creation (persists even when agent not running)
Agent *Agent // nil if no agent running
Status WorktreeStatus // Derived from agent state
Stats *GitStats // +/- line counts
CreatedAt time.Time
UpdatedAt time.Time
IsOrphaned bool // True if agent file exists but tmux session is gone
IsMain bool // True if this is the primary/main worktree (project root)
IsMissing bool // True if worktree directory no longer exists (detected via os.Stat or git prunable)
}
Worktree represents a git worktree with optional agent.
type WorktreeStatus ¶
type WorktreeStatus int
WorktreeStatus represents the current state of a worktree.
const ( StatusPaused WorktreeStatus = iota // No agent, worktree exists StatusActive // Agent running, recent output StatusThinking // Agent is processing/thinking StatusWaiting // Agent waiting for input StatusDone // Agent completed task StatusError // Agent crashed or errored )
func (WorktreeStatus) Icon ¶
func (s WorktreeStatus) Icon() string
Icon returns the status indicator icon for display.
func (WorktreeStatus) String ¶
func (s WorktreeStatus) String() string
String returns the display string for a WorktreeStatus.
Source Files
¶
- agent.go
- agent_session.go
- browser.go
- commands.go
- conflicts.go
- constants.go
- create_modal.go
- diff.go
- doc.go
- env.go
- fetch_pr.go
- fetch_pr_view.go
- interactive.go
- interactive_selection.go
- kanban.go
- keys.go
- merge.go
- messages.go
- mouse.go
- plugin.go
- prompt_picker.go
- prompt_picker_modal.go
- prompts.go
- setup.go
- shell.go
- shell_manifest.go
- shell_watcher.go
- stats.go
- template.go
- types.go
- update.go
- view_diff.go
- view_helpers.go
- view_kanban.go
- view_list.go
- view_modals.go
- view_preview.go
- worktree.go