Documentation
¶
Overview ¶
PipelineEngine is the seam that WriteSlashCommands, headless-triage prompt construction, review-gate prompt construction, initial-session-prompt construction, and mode-content-hash lookup consult instead of calling the pre-existing hardcoded functions directly.
PipelineEngine is a SIBLING of WorkflowEngine (session/workflow_engine.go), not an extension or wrapper of it. WorkflowEngine governs which backlog *status transitions* are structurally/gate-legal; PipelineEngine governs *what content* (slash commands, prompts) drives an item's pipeline within whatever status it's already in. The two interfaces have disjoint call-site sets and disjoint reasons to change — coupling them (e.g. having PipelineEngine call into WorkflowEngine, or extending WorkflowEngine with pipeline methods) would pull unrelated concerns together for no benefit. Both are held as independent fields by their callers (BacklogService, BacklogLifecycleListener) and composed by the caller, never by each other. See project_plans/backlog-configurable-pipeline/implementation/plan.md's Pattern Decisions table ("PipelineEngine ↔ WorkflowEngine relationship") and research/architecture.md §1 for the full reasoning.
Index ¶
- Constants
- Variables
- func BuildHeadlessRetriagePrompt(item *BacklogItemData, artifactAbsPath string, prior HeadlessTriageResult, ...) string
- func BuildHeadlessReviewPrompt(item *BacklogItemData, acSnapshot []AcCriterion, diff string, ...) string
- func BuildHeadlessTriagePrompt(item *BacklogItemData, artifactAbsPath string) string
- func BuildReviewCallOptions(diff, codebaseWorkDir string) (systemPrompt string, opts headless.CallOptions, callTimeout time.Duration, ...)
- func BuildReviewPrompt(item *BacklogItemData, acSnapshot []AcCriterion, diff string, ...) string
- func BuildSessionInitialPrompt(item *BacklogItemData, priorSessions []ItemSessionSummary) string
- func BuildTokenBudgetedPrompt(item *BacklogItemData, priorSessions []ItemSessionSummary) string
- func CanTransition(from, to Status) bool
- func ClaudeProjectDirName(projectPath string) string
- func CleanupBacklogContextFile(worktreePath string) error
- func CleanupSlashCommands(worktreePath string) error
- func ComputeContentHash(fields ...string) string
- func CreateBacklogWorktree(repoPath, branchSuffix string) (string, error)
- func DecryptToken(key []byte, ciphertext string) (string, error)
- func DegradeIfUnverified(path string, overall ReviewOutcome, verdicts []CriterionVerdict, ...) (ReviewOutcome, []CriterionVerdict, string, string)
- func EncodeTasks(tasks []TaskNode) (string, error)
- func EncryptToken(key []byte, plaintext string) (string, error)
- func EnsureDirectorySessionPath(path string) error
- func ExtractPRURL(sessionOutput string) string
- func FindConversationFilePath(sessionID string) (string, error)
- func FindInstanceByHistoryPath(instances []*Instance, filePath string) (string, bool)
- func ForkClaudeConversation(srcConvPath string, lineCount uint64, dstDir string) (string, error)
- func GetGitDiff(ctx context.Context, worktreePath string, baseSHA string) (diff string, truncated bool, err error)
- func GetGitDiffRef(ctx context.Context, dir string, baseSHA string, headRef string) (diff string, truncated bool, err error)
- func GetGitHeadSHA(repoPath string) (string, error)
- func GetMainRepoPath(path string) (string, error)
- func InstanceInfoSlice(instances []*Instance) []artifacts.InstanceInfo
- func IsGitHubURL(input string) bool
- func IsValidTaskStatus(s string) bool
- func IsWorktreeDirty(ctx context.Context, worktreePath string) (bool, error)
- func ParseHeadlessToolReads(text string) []string
- func ParseHeadlessVerdictResult(text string) (overall ReviewOutcome, verdicts []CriterionVerdict, summary string)
- func PortSessionHistory(ctx context.Context, oldProgram, newProgram string, i *Instance) error
- func ReconcileOrphanedTmuxSessions(instances []*Instance)
- func RecoverBaseCommitSHA(ctx context.Context, repoPath, headRef string) (string, error)
- func RegisterBackendProvider(backend ProcessManagerBackend)
- func ResolveSessionPath(path string) (string, error)
- func ResolvedModeLabel(mode string) string
- func RollbackMigration(backupPath, sqlitePath string) error
- func RunPreGateSecurityCheck(diff string) error
- func SanitizeDiff(diff string) string
- func SanitizeForAgentContext(s string, maxLen int) string
- func StartSessionDriver(inst *Instance, allowedPath string)
- func ValidateEntMigration(jsonPath, entDBPath string) error
- func ValidatePipelineModeContent(fields PipelineModeContentFields) error
- func ValidateTaskDepth(tasks []TaskNode, depth int) error
- func ValidateWorkflowSlug(slug string) error
- func WriteBacklogContextFile(item *BacklogItemData, priorSessions []ItemSessionSummary, worktreePath string) error
- func WriteReviewTranscriptFile(sm *scrollback.ScrollbackManager, sessionUUID, codebaseWorkDir string, ...) (relPath string, cleanup func(), err error)
- func WriteSlashCommands(engine PipelineEngine, item *BacklogItemData, worktreePath string) error
- type AcCriteriaJSON
- type AcCriterion
- type AcStatus
- type ActivityTracking
- type AgyAdapter
- type AnalyticsData
- type ApprovalAutomation
- func (aa *ApprovalAutomation) GetDetector() *detection.ApprovalDetector
- func (aa *ApprovalAutomation) GetPendingApprovals() []*PendingApproval
- func (aa *ApprovalAutomation) GetPolicyEngine() *PolicyEngine
- func (aa *ApprovalAutomation) GetSessionName() string
- func (aa *ApprovalAutomation) IsRunning() bool
- func (aa *ApprovalAutomation) RespondToApproval(requestID string, approved bool, userInput string, ...) error
- func (aa *ApprovalAutomation) Start(ctx context.Context, options ApprovalAutomationOptions) error
- func (aa *ApprovalAutomation) Stop() error
- func (aa *ApprovalAutomation) Subscribe(subscriberID string) <-chan ApprovalEvent
- func (aa *ApprovalAutomation) Unsubscribe(subscriberID string)
- type ApprovalAutomationOptions
- type ApprovalEvent
- type ApprovalEventType
- type ApprovalMetadata
- type ApprovalMetadataProvider
- type ApprovalPolicy
- type ApprovalRuleData
- type AttentionReason
- type AutoReopenSpawner
- type AutonomousDriver
- type AutonomousDriverOutcome
- type AutonomousModeState
- type AvailableTargets
- type BacklogController
- type BacklogItemData
- type BacklogItemFilter
- type BacklogItemPrecondition
- type BacklogItemSummary
- type BacklogItemTransitionInput
- type BacklogItemUpdate
- type BacklogLifecycleListener
- func NewBacklogLifecycleListener(storage *Storage) *BacklogLifecycleListener
- func NewBacklogLifecycleListenerWithPool(storage *Storage, pool *headless.Pool, pipelineEngine PipelineEngine) *BacklogLifecycleListener
- func NewBacklogLifecycleListenerWithSpawner(storage *Storage, spawner ReviewGateSpawner) *BacklogLifecycleListener
- func (l *BacklogLifecycleListener) BackfillStuckStates(ctx context.Context)
- func (l *BacklogLifecycleListener) PipelineEngine() PipelineEngine
- func (l *BacklogLifecycleListener) ReconcilePRPending(ctx context.Context, er *EntRepository)
- func (l *BacklogLifecycleListener) ReconcileStuck(ctx context.Context)
- func (l *BacklogLifecycleListener) SetAutoReopener(r AutoReopenSpawner)
- func (l *BacklogLifecycleListener) SetEnabled(v bool)
- func (l *BacklogLifecycleListener) SetHeadlessPool(p *headless.Pool)
- func (l *BacklogLifecycleListener) SetNotifier(n Notifier)
- func (l *BacklogLifecycleListener) SetPRCreatorFactory(...)
- func (l *BacklogLifecycleListener) SetPRFixSpawner(s PRFixSpawner)
- func (l *BacklogLifecycleListener) SetPRPendingCheckerFactory(f func(repoPath string) prPendingChecker)
- func (l *BacklogLifecycleListener) SetSessionCreator(s ReviewGateSpawner)
- func (l *BacklogLifecycleListener) SetSessionLivenessChecker(f func(sessionUUID string) bool)
- func (l *BacklogLifecycleListener) Shutdown()
- func (l *BacklogLifecycleListener) TriggerReviewForSession(workSessionUUID string)
- func (l *BacklogLifecycleListener) WireToInstance(inst *Instance)
- type BacklogStatus
- type BacklogStatusEventData
- type BookmarkTarget
- type CDPStreamManager
- type CachingPipelineEngine
- func (e *CachingPipelineEngine) ContentHashFor(mode PipelineMode) (string, bool)
- func (e *CachingPipelineEngine) InitialPromptFor(item *BacklogItemData, priorSessions []ItemSessionSummary) string
- func (e *CachingPipelineEngine) InvalidateCache(ctx context.Context) error
- func (e *CachingPipelineEngine) ReviewPromptFor(item *BacklogItemData, acSnapshot []AcCriterion, diff string, ...) string
- func (e *CachingPipelineEngine) SlashCommandSet(item *BacklogItemData) (map[string]string, error)
- func (e *CachingPipelineEngine) TriagePromptFor(item *BacklogItemData, artifactAbsPath string) string
- type CanonicalBlock
- type CanonicalBlockKind
- type CanonicalRole
- type CanonicalTurn
- type Checkpoint
- type CheckpointList
- type CircularBuffer
- func (cb *CircularBuffer) Cap() int
- func (cb *CircularBuffer) Clear()
- func (cb *CircularBuffer) Close() error
- func (cb *CircularBuffer) DisableDiskFallback() error
- func (cb *CircularBuffer) EnableDiskFallback(diskPath string) error
- func (cb *CircularBuffer) GetAll() []byte
- func (cb *CircularBuffer) GetRecent(n int) []byte
- func (cb *CircularBuffer) GetRecentHash(n int) (uint64, bool)
- func (cb *CircularBuffer) GetRecentInto(dst []byte, n int) int
- func (cb *CircularBuffer) Len() int
- func (cb *CircularBuffer) TotalBytesWritten() int64
- func (cb *CircularBuffer) Write(data []byte) (int, error)
- func (cb *CircularBuffer) WriteTo(w io.Writer) (int64, error)
- type ClaudeAdapter
- type ClaudeCommandBuilder
- type ClaudeController
- func (cc *ClaudeController) AddStatusChangeListener(fn StatusChangeListener)
- func (cc *ClaudeController) CancelCommand(commandID string) error
- func (cc *ClaudeController) ClearHistory() error
- func (cc *ClaudeController) ClearQueue() error
- func (cc *ClaudeController) GetCommandHistory(limit int) []*HistoryEntry
- func (cc *ClaudeController) GetCommandStatus(commandID string) (*Command, error)
- func (cc *ClaudeController) GetCurrentCommand() *Command
- func (cc *ClaudeController) GetCurrentStatus() (detection.DetectedStatus, string)
- func (cc *ClaudeController) GetEscapeParser() *analytics.EscapeCodeParser
- func (cc *ClaudeController) GetExecutionOptions() ExecutionOptions
- func (cc *ClaudeController) GetExitContent() []byte
- func (cc *ClaudeController) GetHistoryStatistics() HistoryStatistics
- func (cc *ClaudeController) GetIdleDuration() time.Duration
- func (cc *ClaudeController) GetIdleState() (detection.IdleState, time.Time)
- func (cc *ClaudeController) GetIdleStateInfo() detection.IdleStateInfo
- func (cc *ClaudeController) GetInstance() InstanceContext
- func (cc *ClaudeController) GetQueuedCommands() []*Command
- func (cc *ClaudeController) GetQueuedCommandsCount() int
- func (cc *ClaudeController) GetRateLimitHandler() *ratelimit.PTYConsumer
- func (cc *ClaudeController) GetRateLimitResetTime() time.Time
- func (cc *ClaudeController) GetRateLimitState() ratelimit.RateLimitState
- func (cc *ClaudeController) GetRecentOutput(bytes int) []byte
- func (cc *ClaudeController) GetSessionName() string
- func (cc *ClaudeController) GetStatusAndIdleInfo() (detection.DetectedStatus, string, detection.IdleStateInfo)
- func (cc *ClaudeController) GetStatusDetector() detection.TerminalDetector
- func (cc *ClaudeController) GetTotalBytesWritten() int64
- func (cc *ClaudeController) IsActive() bool
- func (cc *ClaudeController) IsIdle() bool
- func (cc *ClaudeController) IsRateLimitEnabled() bool
- func (cc *ClaudeController) IsStarted() bool
- func (cc *ClaudeController) SearchHistory(query string) []*HistoryEntry
- func (cc *ClaudeController) SendCommand(text string, priority int) (string, error)
- func (cc *ClaudeController) SendCommandImmediate(text string) (*ExecutionResult, error)
- func (cc *ClaudeController) SetExecutionOptions(options ExecutionOptions)
- func (cc *ClaudeController) SetOnEOFCallback(fn func())
- func (cc *ClaudeController) SetRateLimitEnabled(enabled bool)
- func (cc *ClaudeController) SetStatusChangeListener(fn StatusChangeListener)
- func (cc *ClaudeController) Start(ctx context.Context) error
- func (cc *ClaudeController) Stop() error
- func (cc *ClaudeController) Subscribe(subscriberID string) (<-chan ResponseChunk, error)
- func (cc *ClaudeController) Unsubscribe(subscriberID string) error
- type ClaudeConversationMessage
- type ClaudeHistoryEntry
- type ClaudeSession
- type ClaudeSessionData
- type ClaudeSessionHistory
- func (sh *ClaudeSessionHistory) Count() int
- func (sh *ClaudeSessionHistory) GetAll() []ClaudeHistoryEntry
- func (sh *ClaudeSessionHistory) GetByID(id string) (*ClaudeHistoryEntry, error)
- func (sh *ClaudeSessionHistory) GetByProject(projectPath string) []ClaudeHistoryEntry
- func (sh *ClaudeSessionHistory) GetMessagesFromConversationFile(sessionID string, limit int) ([]ClaudeConversationMessage, error)
- func (sh *ClaudeSessionHistory) GetProjects() []string
- func (sh *ClaudeSessionHistory) LastLoadTime() time.Time
- func (sh *ClaudeSessionHistory) Reload() error
- func (sh *ClaudeSessionHistory) Search(query string) []ClaudeHistoryEntry
- type ClaudeSessionManager
- func (csm *ClaudeSessionManager) AttachToSession(sessionID string) error
- func (csm *ClaudeSessionManager) CreateSessionData(session ClaudeSession, settings ClaudeSettings) ClaudeSessionData
- func (csm *ClaudeSessionManager) DetectAvailableSessions() ([]ClaudeSession, error)
- func (csm *ClaudeSessionManager) FindSessionByProject(projectPath string) ([]ClaudeSession, error)
- func (csm *ClaudeSessionManager) GetSessionByID(sessionID string) (*ClaudeSession, error)
- type ClaudeSettings
- type CloudContext
- type Command
- type CommandExecutor
- func (ce *CommandExecutor) ExecuteImmediate(cmd *Command) (*ExecutionResult, error)
- func (ce *CommandExecutor) GetCurrentCommand() *Command
- func (ce *CommandExecutor) GetOptions() ExecutionOptions
- func (ce *CommandExecutor) GetSessionName() string
- func (ce *CommandExecutor) IsExecuting() bool
- func (ce *CommandExecutor) SetOptions(options ExecutionOptions)
- func (ce *CommandExecutor) SetResultCallback(callback func(*ExecutionResult))
- func (ce *CommandExecutor) Start(ctx context.Context) error
- func (ce *CommandExecutor) Stop() error
- type CommandHistory
- func (ch *CommandHistory) Add(entry *HistoryEntry) error
- func (ch *CommandHistory) AddFromResult(result *ExecutionResult) error
- func (ch *CommandHistory) Clear() error
- func (ch *CommandHistory) Count() int
- func (ch *CommandHistory) GetAll() []*HistoryEntry
- func (ch *CommandHistory) GetByCommandID(commandID string) []*HistoryEntry
- func (ch *CommandHistory) GetByStatus(status CommandStatus) []*HistoryEntry
- func (ch *CommandHistory) GetByTimeRange(start, end time.Time) []*HistoryEntry
- func (ch *CommandHistory) GetFailed() []*HistoryEntry
- func (ch *CommandHistory) GetMaxEntries() int
- func (ch *CommandHistory) GetPersistPath() string
- func (ch *CommandHistory) GetRecent(n int) []*HistoryEntry
- func (ch *CommandHistory) GetSessionName() string
- func (ch *CommandHistory) GetStatistics() HistoryStatistics
- func (ch *CommandHistory) GetSuccessful() []*HistoryEntry
- func (ch *CommandHistory) Load() error
- func (ch *CommandHistory) Save() error
- func (ch *CommandHistory) Search(query string) []*HistoryEntry
- func (ch *CommandHistory) SetMaxEntries(max int)
- func (ch *CommandHistory) SetPersistPath(path string)
- type CommandQueue
- func (cq *CommandQueue) Cancel(id string) error
- func (cq *CommandQueue) Clear() error
- func (cq *CommandQueue) Dequeue() *Command
- func (cq *CommandQueue) Enqueue(cmd *Command) error
- func (cq *CommandQueue) Get(id string) (*Command, error)
- func (cq *CommandQueue) GetPersistPath() string
- func (cq *CommandQueue) IsEmpty() bool
- func (cq *CommandQueue) Len() int
- func (cq *CommandQueue) List() []*Command
- func (cq *CommandQueue) ListByStatus(status CommandStatus) []*Command
- func (cq *CommandQueue) Load() error
- func (cq *CommandQueue) NotifyChannel() <-chan struct{}
- func (cq *CommandQueue) Peek() *Command
- func (cq *CommandQueue) Save() error
- func (cq *CommandQueue) SetPersistPath(path string)
- func (cq *CommandQueue) Update(cmd *Command) error
- type CommandStatus
- type CompletionCallback
- type ContentProvider
- type ContextOptions
- func (o ContextOptions) AnyChildDataLoaded() bool
- func (o ContextOptions) AnyContextLoaded() bool
- func (o ContextOptions) Merge(other ContextOptions) ContextOptions
- func (o ContextOptions) String() string
- func (o ContextOptions) ToLoadOptions() LoadOptions
- func (o ContextOptions) WithActivity() ContextOptions
- func (o ContextOptions) WithCloud() ContextOptions
- func (o ContextOptions) WithDiffContent() ContextOptions
- func (o ContextOptions) WithFilesystem() ContextOptions
- func (o ContextOptions) WithGit() ContextOptions
- func (o ContextOptions) WithTags() ContextOptions
- func (o ContextOptions) WithTerminal() ContextOptions
- func (o ContextOptions) WithUI() ContextOptions
- func (o ContextOptions) WithoutDiffContent() ContextOptions
- func (o ContextOptions) WithoutTags() ContextOptions
- type ControllerManager
- func (cm *ControllerManager) GetController() *ClaudeController
- func (cm *ControllerManager) GetStatusManager() *InstanceStatusManager
- func (cm *ControllerManager) HasController() bool
- func (cm *ControllerManager) RegisterController(title string, controller *ClaudeController)
- func (cm *ControllerManager) SetController(c *ClaudeController)
- func (cm *ControllerManager) SetStatusManager(m *InstanceStatusManager)
- func (cm *ControllerManager) StopAndClearController()
- func (cm *ControllerManager) UnregisterController(title string)
- type ConversationID
- type CriterionVerdict
- type DefaultStatusDeterminer
- type DefaultWorkflowEngine
- type DetectionAction
- type DetectionResult
- type DiffStatsData
- type DiscoveryMode
- type DriverOption
- type EntPipelineModeRepository
- func (r *EntPipelineModeRepository) Create(ctx context.Context, m PipelineModeCreateInput) (*ent.PipelineMode, error)
- func (r *EntPipelineModeRepository) Delete(ctx context.Context, id uuid.UUID) error
- func (r *EntPipelineModeRepository) GetByID(ctx context.Context, id uuid.UUID) (*ent.PipelineMode, error)
- func (r *EntPipelineModeRepository) GetBySlug(ctx context.Context, slug string) (*ent.PipelineMode, error)
- func (r *EntPipelineModeRepository) ListAll(ctx context.Context) ([]*ent.PipelineMode, error)
- func (r *EntPipelineModeRepository) ListEnabled(ctx context.Context) ([]*ent.PipelineMode, error)
- func (r *EntPipelineModeRepository) Update(ctx context.Context, id uuid.UUID, m PipelineModeUpdateInput) (*ent.PipelineMode, error)
- type EntRepository
- func (r *EntRepository) AllRules(ctx context.Context) ([]ApprovalRuleData, error)
- func (r *EntRepository) AppendProgressNote(ctx context.Context, itemID string, criterionIndex int, note, status string) error
- func (r *EntRepository) ArchiveBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
- func (r *EntRepository) AssignSessionsToProject(ctx context.Context, projectName string, sessionTitles []string) error
- func (r *EntRepository) BackfillMissingPRNumbers(ctx context.Context) (int, error)
- func (r *EntRepository) Close() error
- func (r *EntRepository) CountReviewCyclesSince(ctx context.Context, itemID string, since time.Time) (int, error)
- func (r *EntRepository) Create(ctx context.Context, data InstanceData) error
- func (r *EntRepository) CreateBacklogItem(ctx context.Context, data BacklogItemData) (*BacklogItemData, error)
- func (r *EntRepository) CreateItemSession(ctx context.Context, data ItemSessionData) (ItemSessionSummary, error)
- func (r *EntRepository) CreateItemSessionWithVerdict(ctx context.Context, isData ItemSessionData, verdict ReviewVerdictData) (ItemSessionSummary, error)
- func (r *EntRepository) CreateItemSource(ctx context.Context, data ItemSourceData) (*ItemSourceData, error)
- func (r *EntRepository) CreateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
- func (r *EntRepository) CreateSession(ctx context.Context, session *Session) error
- func (r *EntRepository) CreateShell(ctx context.Context, sessionTitle string, data ShellData) (*ent.Shell, error)
- func (r *EntRepository) CreateSourceSyncEvent(ctx context.Context, sourceID string, cursorAfter string, ...) error
- func (r *EntRepository) Delete(ctx context.Context, title string) error
- func (r *EntRepository) DeleteBacklogItem(ctx context.Context, id string) error
- func (r *EntRepository) DeleteItemSource(ctx context.Context, id string) error
- func (r *EntRepository) DeleteProject(ctx context.Context, name string) error
- func (r *EntRepository) DeleteRule(ctx context.Context, id string) error
- func (r *EntRepository) DeleteShell(ctx context.Context, shellID string) error
- func (r *EntRepository) FindOpenStuckStates(ctx context.Context) ([]OpenStuckStateData, error)
- func (r *EntRepository) FindPRPendingItems(ctx context.Context) ([]*ent.BacklogItem, error)
- func (r *EntRepository) FindReviewItemsWithoutGate(ctx context.Context) ([]*ent.BacklogItem, error)
- func (r *EntRepository) FindStuckReviewItems(ctx context.Context) ([]*ent.BacklogItem, error)
- func (r *EntRepository) FindZombieReviewItems(ctx context.Context) ([]*ent.BacklogItem, error)
- func (r *EntRepository) FinishSourceSync(ctx context.Context, sourceID string, cursorAfter string, ...) error
- func (r *EntRepository) Get(ctx context.Context, title string) (*InstanceData, error)
- func (r *EntRepository) GetAllItemSessionsWithBacklogInfo(ctx context.Context) ([]ItemSessionBacklogEntry, error)
- func (r *EntRepository) GetAllSessionArtifacts(ctx context.Context) (map[string]string, error)
- func (r *EntRepository) GetBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
- func (r *EntRepository) GetBacklogItemByExternalID(ctx context.Context, sourceID, externalID string) (*ent.BacklogItem, error)
- func (r *EntRepository) GetBaseCommitSHAsForSessions(ctx context.Context, sessionUUIDs []string) (map[string]string, error)
- func (r *EntRepository) GetClaudeConversationUUIDBySessionUUID(ctx context.Context, sessionUUID string) (string, error)
- func (r *EntRepository) GetEntClient() *ent.Client
- func (r *EntRepository) GetItemSession(ctx context.Context, id string) (ItemSessionSummary, error)
- func (r *EntRepository) GetItemSessionBySessionAndItem(ctx context.Context, sessionUUID string, itemID string) (ItemSessionSummary, error)
- func (r *EntRepository) GetItemSessionBySessionUUID(ctx context.Context, sessionUUID string) (ItemSessionSummary, error)
- func (r *EntRepository) GetItemSourceByID(ctx context.Context, id string) (*ent.ItemSource, error)
- func (r *EntRepository) GetMostRecentReviewVerdictForItem(ctx context.Context, itemID string) (ReviewOutcome, error)
- func (r *EntRepository) GetMostRecentStatusEventAt(ctx context.Context, itemID string, toStatus BacklogStatus) (time.Time, bool, error)
- func (r *EntRepository) GetSession(ctx context.Context, title string, opts ContextOptions) (*Session, error)
- func (r *EntRepository) GetSessionArtifacts(ctx context.Context, title string) (string, error)
- func (r *EntRepository) GetSubcommandBreakdown(ctx context.Context, program string, since time.Time) ([]SubcommandDecisionCount, error)
- func (r *EntRepository) GetSubcommandTrend(ctx context.Context, program, subcommand string, since time.Time) ([]AnalyticsData, error)
- func (r *EntRepository) GetWithOptions(ctx context.Context, title string, options LoadOptions) (*InstanceData, error)
- func (r *EntRepository) GetWorktreeDataBySessionUUID(ctx context.Context, sessionUUID string) (GitWorktreeData, error)
- func (r *EntRepository) List(ctx context.Context) ([]InstanceData, error)
- func (r *EntRepository) ListAnalytics(ctx context.Context, limit int) ([]AnalyticsData, error)
- func (r *EntRepository) ListAnalyticsByProgramSince(ctx context.Context, program string, since time.Time, limit int) ([]AnalyticsData, error)
- func (r *EntRepository) ListAnalyticsSince(ctx context.Context, since time.Time, limit int) ([]AnalyticsData, error)
- func (r *EntRepository) ListBacklogItemSummaries(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemSummary, error)
- func (r *EntRepository) ListBacklogItems(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemData, error)
- func (r *EntRepository) ListByStatus(ctx context.Context, status Status) ([]InstanceData, error)
- func (r *EntRepository) ListByStatusWithOptions(ctx context.Context, status Status, options LoadOptions) ([]InstanceData, error)
- func (r *EntRepository) ListByTag(ctx context.Context, tagName string) ([]InstanceData, error)
- func (r *EntRepository) ListByTagWithOptions(ctx context.Context, tag string, options LoadOptions) ([]InstanceData, error)
- func (r *EntRepository) ListItemSessions(ctx context.Context, itemID string) ([]ItemSessionSummary, error)
- func (r *EntRepository) ListItemSources(ctx context.Context) ([]ItemSourceData, error)
- func (r *EntRepository) ListProgressNotesForItem(ctx context.Context, itemID string) ([]ProgressNoteData, error)
- func (r *EntRepository) ListProjects(ctx context.Context) ([]ProjectData, error)
- func (r *EntRepository) ListRecentCommandsByProgram(ctx context.Context, program, subcommand string, since time.Time, n int) ([]string, error)
- func (r *EntRepository) ListSessions(ctx context.Context, opts ContextOptions) ([]*Session, error)
- func (r *EntRepository) ListShells(ctx context.Context, sessionTitle string) ([]*ent.Shell, error)
- func (r *EntRepository) ListSourceSyncEvents(ctx context.Context, sourceID string) ([]SourceSyncEventData, bool, error)
- func (r *EntRepository) ListWithOptions(ctx context.Context, options LoadOptions) ([]InstanceData, error)
- func (r *EntRepository) MarkStuck(ctx context.Context, itemID string, reason domain.StuckReason, ...) (applied bool, err error)
- func (r *EntRepository) MarkStuckNotified(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
- func (r *EntRepository) ReconcileStuckItems(ctx context.Context) (int, error)
- func (r *EntRepository) RecordAnalytics(ctx context.Context, data AnalyticsData) error
- func (r *EntRepository) ResolveStuck(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
- func (r *EntRepository) SaveReviewVerdict(ctx context.Context, itemSessionID string, verdict ReviewVerdictData) error
- func (r *EntRepository) SnoozeStuckState(ctx context.Context, itemID string, reason domain.StuckReason, until time.Time) (bool, error)
- func (r *EntRepository) TransitionBacklogItemStatus(ctx context.Context, id string, toStatus BacklogStatus, ...) (*BacklogItemData, error)
- func (r *EntRepository) Update(ctx context.Context, data InstanceData) error
- func (r *EntRepository) UpdateAcCriterionStatus(ctx context.Context, itemID string, criterionIndex int, status string, ...) error
- func (r *EntRepository) UpdateBacklogItem(ctx context.Context, id string, update BacklogItemUpdate, ...) (*BacklogItemData, error)
- func (r *EntRepository) UpdateGitHubPRNumber(ctx context.Context, title string, prNumber int) error
- func (r *EntRepository) UpdateItemSessionEnded(ctx context.Context, id string, endedAt time.Time) error
- func (r *EntRepository) UpdateItemSessionFileTouch(ctx context.Context, id string, touchAt time.Time) error
- func (r *EntRepository) UpdateItemSessionGitActivity(ctx context.Context, id string, sha, msg string, commitAt time.Time, ...) error
- func (r *EntRepository) UpdateItemSessionSessionUUID(ctx context.Context, id string, sessionUUID string) error
- func (r *EntRepository) UpdateItemSessionStarted(ctx context.Context, id string, startedAt time.Time) error
- func (r *EntRepository) UpdateItemSessionTriageResult(ctx context.Context, id string, triageResult string) error
- func (r *EntRepository) UpdateItemSessionVerificationNotes(ctx context.Context, id string, verificationNotes string) error
- func (r *EntRepository) UpdateItemSource(ctx context.Context, id string, update ItemSourceUpdate) (*ItemSourceData, error)
- func (r *EntRepository) UpdateLastAcknowledged(ctx context.Context, title string, t time.Time) error
- func (r *EntRepository) UpdateLastAddedToQueue(ctx context.Context, title string, t time.Time) error
- func (r *EntRepository) UpdateLastViewed(ctx context.Context, title string, t time.Time) error
- func (r *EntRepository) UpdateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
- func (r *EntRepository) UpdateReviewQueueState(ctx context.Context, title string, ...) error
- func (r *EntRepository) UpdateSession(ctx context.Context, session *Session) error
- func (r *EntRepository) UpdateSessionArtifacts(ctx context.Context, title string, blob string) error
- func (r *EntRepository) UpdateShellStatus(ctx context.Context, shellID, status string, exitCode *int) error
- func (r *EntRepository) UpdateTimestamps(ctx context.Context, title string, ...) error
- func (r *EntRepository) UpsertRule(ctx context.Context, data ApprovalRuleData) error
- type EntWorkflowRepository
- func (r *EntWorkflowRepository) Create(ctx context.Context, w WorkflowCreateInput) (*ent.Workflow, error)
- func (r *EntWorkflowRepository) Delete(ctx context.Context, id uuid.UUID) error
- func (r *EntWorkflowRepository) GetByID(ctx context.Context, id uuid.UUID) (*ent.Workflow, error)
- func (r *EntWorkflowRepository) GetBySlug(ctx context.Context, slug string) (*ent.Workflow, error)
- func (r *EntWorkflowRepository) ListAll(ctx context.Context) ([]*ent.Workflow, error)
- func (r *EntWorkflowRepository) ListEnabled(ctx context.Context) ([]*ent.Workflow, error)
- func (r *EntWorkflowRepository) Update(ctx context.Context, id uuid.UUID, w WorkflowUpdateInput) (*ent.Workflow, error)
- type ErrDuplicateTag
- type ErrInvalidTransition
- type ErrTagTooLong
- type ErrTooManyTags
- type ExecutionOptions
- type ExecutionResult
- type ExternalApprovalCallback
- type ExternalApprovalEvent
- type ExternalApprovalMonitor
- func (m *ExternalApprovalMonitor) GetAllPendingApprovals() map[string][]*detection.ApprovalRequest
- func (m *ExternalApprovalMonitor) GetDetector() *detection.ApprovalDetector
- func (m *ExternalApprovalMonitor) GetMonitoredSessions() []string
- func (m *ExternalApprovalMonitor) GetPendingApprovals(socketPath string) []*detection.ApprovalRequest
- func (m *ExternalApprovalMonitor) IntegrateWithDiscovery(discovery *ExternalSessionDiscovery, streamerManager *ExternalStreamerManager)
- func (m *ExternalApprovalMonitor) IntegrateWithDiscoveryTmux(discovery *ExternalSessionDiscovery, ...)
- func (m *ExternalApprovalMonitor) MarkApprovalHandled(socketPath, requestID string, approved bool) error
- func (m *ExternalApprovalMonitor) MonitorSession(streamer *ExternalStreamer, title string, source ExternalApprovalSource) error
- func (m *ExternalApprovalMonitor) MonitorSessionTmux(streamer *ExternalTmuxStreamer, tmuxSessionName string, title string, ...) error
- func (m *ExternalApprovalMonitor) OnApproval(callback ExternalApprovalCallback)
- func (m *ExternalApprovalMonitor) Start()
- func (m *ExternalApprovalMonitor) Stop()
- func (m *ExternalApprovalMonitor) StopMonitoringSession(socketPath string)
- type ExternalApprovalSource
- type ExternalInstanceMetadata
- type ExternalItem
- type ExternalSessionDiscovery
- func (e *ExternalSessionDiscovery) GetSession(socketPath string) *Instance
- func (e *ExternalSessionDiscovery) GetSessionByTmux(tmuxSessionName string) *Instance
- func (e *ExternalSessionDiscovery) GetSessions() []*Instance
- func (e *ExternalSessionDiscovery) OnSessionAdded(callback func(*Instance))
- func (e *ExternalSessionDiscovery) OnSessionRemoved(callback func(*Instance))
- func (e *ExternalSessionDiscovery) Start(interval time.Duration)
- func (e *ExternalSessionDiscovery) Stop()
- type ExternalStreamer
- func (s *ExternalStreamer) AddConsumer(consumer OutputConsumer, catchUp bool) string
- func (s *ExternalStreamer) ConsumerCount() int
- func (s *ExternalStreamer) GetMetadata() *mux.SessionMetadata
- func (s *ExternalStreamer) GetRecentOutput() []byte
- func (s *ExternalStreamer) GetSnapshot() ([]byte, error)
- func (s *ExternalStreamer) IsConnected() bool
- func (s *ExternalStreamer) RemoveConsumer(key string)
- func (s *ExternalStreamer) SendInput(data []byte) error
- func (s *ExternalStreamer) SendResize(cols, rows uint16) error
- func (s *ExternalStreamer) SocketPath() string
- func (s *ExternalStreamer) Start() error
- func (s *ExternalStreamer) Stop()
- type ExternalStreamerManager
- func (m *ExternalStreamerManager) Count() int
- func (m *ExternalStreamerManager) Get(socketPath string) *ExternalStreamer
- func (m *ExternalStreamerManager) GetOrCreate(socketPath string) (*ExternalStreamer, error)
- func (m *ExternalStreamerManager) Remove(socketPath string)
- func (m *ExternalStreamerManager) StopAll()
- type ExternalTmuxStreamer
- func (s *ExternalTmuxStreamer) AddConsumer(consumer func(content string)) string
- func (s *ExternalTmuxStreamer) ConsumerCount() int
- func (s *ExternalTmuxStreamer) GetContent() string
- func (s *ExternalTmuxStreamer) IsRunning() bool
- func (s *ExternalTmuxStreamer) RemoveConsumer(key string)
- func (s *ExternalTmuxStreamer) Start() error
- func (s *ExternalTmuxStreamer) Stop()
- type ExternalTmuxStreamerManager
- func (m *ExternalTmuxStreamerManager) Count() int
- func (m *ExternalTmuxStreamerManager) Get(tmuxSessionName string) *ExternalTmuxStreamer
- func (m *ExternalTmuxStreamerManager) GetOrCreate(tmuxSessionName string) (*ExternalTmuxStreamer, error)
- func (m *ExternalTmuxStreamerManager) Remove(tmuxSessionName string)
- func (m *ExternalTmuxStreamerManager) StopAll()
- type FilesystemContext
- type ForceReleaseFunc
- type GitContext
- type GitHubIntegration
- type GitHubIssuesPlugin
- type GitHubMetadataView
- type GitHubPRsPlugin
- type GitHubRef
- type GitHubRefType
- type GitManager
- type GitWorktreeData
- type GitWorktreeManager
- func (gm *GitWorktreeManager) Cleanup() error
- func (gm *GitWorktreeManager) ClearDiffStats()
- func (gm *GitWorktreeManager) CommitChanges(commitMsg string) error
- func (gm *GitWorktreeManager) ComputeDiff() *git.DiffStats
- func (gm *GitWorktreeManager) ComputeDiffIfReady() (stats *git.DiffStats, needsPause bool)
- func (gm *GitWorktreeManager) GetBaseCommitSHA() string
- func (gm *GitWorktreeManager) GetBranchName() string
- func (gm *GitWorktreeManager) GetCurrentCommitSHA() (string, error)
- func (gm *GitWorktreeManager) GetDiffStats() *git.DiffStats
- func (gm *GitWorktreeManager) GetDirBaseSHA() string
- func (gm *GitWorktreeManager) GetRepoName() string
- func (gm *GitWorktreeManager) GetRepoPath() string
- func (gm *GitWorktreeManager) GetWorktree() *git.GitWorktree
- func (gm *GitWorktreeManager) GetWorktreePath() string
- func (gm *GitWorktreeManager) HasWorktree() bool
- func (gm *GitWorktreeManager) InvalidateDirtyCache()
- func (gm *GitWorktreeManager) IsBranchCheckedOut() (bool, error)
- func (gm *GitWorktreeManager) IsDirty() (bool, error)
- func (gm *GitWorktreeManager) OpenBranchURL() error
- func (gm *GitWorktreeManager) PrimeDirtyCacheJitter()
- func (gm *GitWorktreeManager) Prune() error
- func (gm *GitWorktreeManager) PushChanges(commitMsg string, open bool) error
- func (gm *GitWorktreeManager) Remove() error
- func (gm *GitWorktreeManager) SetDiffStats(stats *git.DiffStats)
- func (gm *GitWorktreeManager) SetDirBaseSHA(sha string)
- func (gm *GitWorktreeManager) SetWorktree(wt *git.GitWorktree)
- func (gm *GitWorktreeManager) Setup() error
- func (gm *GitWorktreeManager) UpdateDiffStats()
- type HeadlessPoolClient
- type HeadlessTriageResult
- type HealthCheckResult
- type HibernationSweeper
- type HistoryAdapter
- type HistoryEntry
- type HistoryFileDetector
- type HistoryFileInfo
- type HistoryFileWatcher
- type HistoryLinker
- func (hl *HistoryLinker) AddInstance(instance *Instance)
- func (hl *HistoryLinker) Instances() []*Instance
- func (hl *HistoryLinker) RegisterFileCallback(cb func(filePath string))
- func (hl *HistoryLinker) RemoveInstance(title string)
- func (hl *HistoryLinker) ScanAll()
- func (hl *HistoryLinker) SetInstances(instances []*Instance)
- func (hl *HistoryLinker) Start(ctx context.Context)
- type HistoryStatistics
- type Instance
- func (i *Instance) AddShellInMemory(sh *Shell)
- func (i *Instance) AddTag(tag string) error
- func (i *Instance) Approve() error
- func (i *Instance) Attach() (chan struct{}, error)
- func (i *Instance) CDPDisplayEnv() []string
- func (i *Instance) CDPManager() CDPStreamManager
- func (i *Instance) CaptureCurrentState() error
- func (i *Instance) CapturePaneContent() (string, error)
- func (i *Instance) CapturePaneContentRaw() (string, error)
- func (i *Instance) CleanupWorktree() error
- func (i *Instance) ClearConversationState()
- func (i *Instance) ClosePR() error
- func (i *Instance) CreateCheckpoint(label string, scrollbackSeq uint64) (*Checkpoint, error)
- func (i *Instance) CurrentBranch() string
- func (i *Instance) DeleteShell(ctx context.Context, shellID string) error
- func (i *Instance) Deny() error
- func (i *Instance) Destroy() error
- func (i *Instance) DetectAndPopulateWorktreeInfo() error
- func (i *Instance) FireLifecycleEventForTest(event LifecycleEvent, reason string)
- func (i *Instance) ForceStatus(s Status)
- func (i *Instance) ForkFromCheckpoint(checkpointID, newTitle string, configDir string) (*Instance, error)
- func (i *Instance) GeneratePRContextPrompt() (string, error)
- func (i *Instance) GetCategoryPath() []string
- func (i *Instance) GetCheckpoints() CheckpointList
- func (i *Instance) GetClaudeConversationUUID() string
- func (i *Instance) GetClaudeSession() *ClaudeSessionData
- func (i *Instance) GetController() *ClaudeController
- func (i *Instance) GetConversationUUID() string
- func (i *Instance) GetCreatedAt() time.Time
- func (i *Instance) GetCurrentPaneContent(lines int) (string, error)
- func (i *Instance) GetDetectedContext() string
- func (i *Instance) GetDetectedStatus() detection.DetectedStatus
- func (i *Instance) GetDiffStats() *git.DiffStats
- func (i *Instance) GetEffectiveRootDir() string
- func (i *Instance) GetEffectiveStatus() Status
- func (i *Instance) GetEscapeParser() *analytics.EscapeCodeParser
- func (i *Instance) GetExitContent() []byte
- func (i *Instance) GetGitHubRepoFullName() string
- func (i *Instance) GetGitWorktree() (*git.GitWorktree, error)
- func (i *Instance) GetLifecycleStatus() Status
- func (i *Instance) GetPRComments() ([]github.PRComment, error)
- func (i *Instance) GetPRDiff() (string, error)
- func (i *Instance) GetPRDisplayInfo() string
- func (i *Instance) GetPTYReader() (*os.File, error)
- func (i *Instance) GetPaneCursorPosition() (x, y int, err error)
- func (i *Instance) GetPaneDimensions() (width, height int, err error)
- func (i *Instance) GetPanePID() (int32, error)
- func (i *Instance) GetPermissions() InstancePermissions
- func (i *Instance) GetRateLimitResetTime() time.Time
- func (i *Instance) GetRateLimitState() int
- func (i *Instance) GetReviewItem() (*ReviewItem, bool)
- func (i *Instance) GetReviewQueue() *ReviewQueue
- func (i *Instance) GetScrollbackHistory(startLine, endLine string) (string, error)
- func (i *Instance) GetSessionGoal() *SessionGoalData
- func (i *Instance) GetShellExitCh(shellID string) (<-chan struct{}, bool)
- func (i *Instance) GetShellPTYReader(shellID string) (*os.File, error)
- func (i *Instance) GetStableID() string
- func (i *Instance) GetStatus() int
- func (i *Instance) GetStatusIconForType() string
- func (i *Instance) GetStatusManager() *InstanceStatusManager
- func (i *Instance) GetTags() []string
- func (i *Instance) GetTimeSinceLastMeaningfulOutput() time.Duration
- func (i *Instance) GetTimeSinceLastTerminalUpdate() time.Duration
- func (i *Instance) GetTitle() string
- func (i *Instance) GetTmuxSession() *tmux.TmuxSession
- func (i *Instance) GetTmuxSessionName() string
- func (i *Instance) GetTotalBytesWritten() int64
- func (i *Instance) GetVCSInfo() (*VCSInfo, error)
- func (i *Instance) GetWorkingDirectory() string
- func (i *Instance) GitHub() GitHubMetadataView
- func (i *Instance) HasClaudeSession() bool
- func (i *Instance) HasGitHubPR() bool
- func (i *Instance) HasGitWorktree() bool
- func (i *Instance) HasTag(tag string) bool
- func (i *Instance) HasUpdated() (updated bool, hasPrompt bool)
- func (i *Instance) Hibernate(ctx context.Context) error
- func (i *Instance) Hibernated() bool
- func (i *Instance) IsActive() bool
- func (i *Instance) IsCreating() bool
- func (i *Instance) IsGitHubSession() bool
- func (i *Instance) IsHibernated() bool
- func (i *Instance) IsPRSession() bool
- func (i *Instance) IsPaused() bool
- func (i *Instance) IsRateLimitEnabled() bool
- func (i *Instance) IsStopped() bool
- func (i *Instance) Kill() error
- func (i *Instance) KillExternalSession() error
- func (i *Instance) KillSession() error
- func (i *Instance) KillSessionKeepWorktree() error
- func (i *Instance) LastMeaningfulOutputTime() time.Time
- func (i *Instance) ListAvailableTargets() (*AvailableTargets, error)
- func (i *Instance) ListShellsInMemory() []*Shell
- func (i *Instance) MarkAcknowledged()
- func (i *Instance) MarkNeedsApproval() error
- func (i *Instance) MarkUserResponded() time.Time
- func (i *Instance) MarkViewed()
- func (i *Instance) MatchesID(id string) bool
- func (i *Instance) MergePR(method string) error
- func (i *Instance) NeedsReview() bool
- func (i *Instance) PaneProcessDead() bool
- func (i *Instance) Pause() error
- func (i *Instance) Paused() bool
- func (i *Instance) PostComment(body string) error
- func (i *Instance) Preview() (string, error)
- func (i *Instance) PreviewFullHistory() (string, error)
- func (i *Instance) ReconcileShells(ctx context.Context)
- func (i *Instance) RecoverFromStopped()
- func (i *Instance) RefreshPRInfo() (*github.PRInfo, error)
- func (i *Instance) RefreshTmuxClient() error
- func (i *Instance) RegisterLifecycleListener(l LifecycleListener)
- func (i *Instance) RegisterStatusChangeCallback(fn func(detection.DetectedStatus, string))
- func (i *Instance) RemoveTag(tag string)
- func (i *Instance) Rename(newTitle string) error
- func (i *Instance) RepoName() (string, error)
- func (i *Instance) ResizePTY(cols, rows int) error
- func (i *Instance) Restart(preserveOutput bool) error
- func (i *Instance) RestartShell(ctx context.Context, shellID string) error
- func (i *Instance) Resume() error
- func (i *Instance) ResumeFromHibernation(ctx context.Context) error
- func (i *Instance) RunWithResume(ctx context.Context, message string) (string, error)
- func (i *Instance) SendInputViaControlMode(ctx context.Context, data []byte) error
- func (i *Instance) SendKeys(keys string) error
- func (i *Instance) SendPrompt(prompt string) error
- func (i *Instance) SetArchivedAt(t *time.Time)
- func (i *Instance) SetArchivedAtIfNil(t time.Time) bool
- func (i *Instance) SetArtifacts(blob *artifacts.SessionArtifactsBlob)
- func (i *Instance) SetAutoYes(v bool)
- func (i *Instance) SetAutonomousComplete(done bool)
- func (i *Instance) SetAutonomousMode(mode bool, outcome string)
- func (i *Instance) SetAutonomousTurn(turn, maxTurns int32)
- func (i *Instance) SetCategory(category string)
- func (i *Instance) SetClaudeConversationUUID(uuid string)
- func (i *Instance) SetClaudeSession(sessionData *ClaudeSessionData)
- func (i *Instance) SetClaudeSessionIDSavedCallback(fn func())
- func (i *Instance) SetCreationProgress(msg string)
- func (i *Instance) SetDirBaseSHA(sha string)
- func (i *Instance) SetGitHubPR(prURL string, prNumber int)
- func (i *Instance) SetGitHubPRNumber(n int)
- func (i *Instance) SetGitWorktree(worktree *git.GitWorktree)
- func (i *Instance) SetHibernateReason(reason string)
- func (i *Instance) SetHistoryInfo(conversationUUID, historyFilePath string)
- func (i *Instance) SetLastAddedToQueue(t time.Time)
- func (i *Instance) SetLastMeaningfulOutput(t time.Time)
- func (i *Instance) SetLastPRStatusCheck(t time.Time)
- func (i *Instance) SetMCPServerURL(url string)
- func (i *Instance) SetPauseReason(reason string)
- func (i *Instance) SetPreviewSize(width, height int) error
- func (i *Instance) SetProgram(program string)
- func (i *Instance) SetRateLimitCallbacks(onDetected func(sessionID string, resetTime time.Time), ...)
- func (i *Instance) SetRateLimitEnabled(enabled bool)
- func (i *Instance) SetReviewQueue(queue *ReviewQueue)
- func (i *Instance) SetSessionGoalCached(g *SessionGoalData)
- func (i *Instance) SetShellRepository(repo ShellRepository)
- func (i *Instance) SetStatusChangeCallback(fn func(detection.DetectedStatus, string))
- func (i *Instance) SetStatusManager(manager *InstanceStatusManager)
- func (i *Instance) SetTags(tags []string) error
- func (i *Instance) SetTitle(title string) error
- func (i *Instance) SetTitleDirect(title string)
- func (i *Instance) SetTmuxSession(session *tmux.TmuxSession)
- func (i *Instance) SetWindowSize(cols, rows int) error
- func (i *Instance) SetWorkingDir(dir string)
- func (i *Instance) Snapshot() *InstanceSnapshot
- func (i *Instance) SpawnShell(ctx context.Context, req SpawnShellRequest) (*Shell, error)
- func (i *Instance) Start(firstTimeSetup bool) error
- func (i *Instance) StartControlMode() error
- func (i *Instance) StartController() error
- func (i *Instance) StartWithCleanup(firstTimeSetup bool) (tmux.CleanupFunc, error)
- func (i *Instance) Started() bool
- func (i *Instance) StopControlMode() error
- func (i *Instance) StopController()
- func (i *Instance) StopShell(ctx context.Context, shellID string) error
- func (i *Instance) SubscribeControlModeUpdates() (string, <-chan []byte)
- func (i *Instance) SwitchProgram(ctx context.Context, rawProgram string, persist func() error) (changed bool, resolvedProgram string, err error)
- func (i *Instance) SwitchWorkspace(req WorkspaceSwitchRequest) (*WorkspaceSwitchResult, error)
- func (i *Instance) TapEnter()
- func (i *Instance) TmuxAlive() bool
- func (i *Instance) TmuxSessionExists() bool
- func (i *Instance) ToInstanceData() InstanceData
- func (i *Instance) ToSession() *Session
- func (i *Instance) UnsubscribeControlModeUpdates(id string)
- func (i *Instance) UpdateDiffStats() error
- func (i *Instance) UpdatePRStatus(state, priority, checkConclusion string, approvedCount, changesReqCount int, ...) prUpdateResult
- func (i *Instance) UpdateTerminalTimestamps(content string, forceUpdate bool)
- func (i *Instance) VNCDisplayEnv() string
- func (i *Instance) VNCManager() VNCProcessManager
- func (i *Instance) Workspace() Workspace
- func (i *Instance) WriteToPTY(data []byte) (int, error)
- type InstanceAcquirer
- type InstanceContext
- type InstanceData
- type InstanceOptions
- type InstancePermissions
- type InstanceReader
- type InstanceSnapshot
- type InstanceStatusInfo
- func (info InstanceStatusInfo) GetColorCode() string
- func (info InstanceStatusInfo) GetStatusDescription() string
- func (info InstanceStatusInfo) GetStatusIcon() string
- func (info InstanceStatusInfo) HasPendingWork() bool
- func (info InstanceStatusInfo) IsWaitingForUser() bool
- func (info InstanceStatusInfo) NeedsAttention() bool
- type InstanceStatusManager
- func (ism *InstanceStatusManager) GetAllControllers() map[string]*ClaudeController
- func (ism *InstanceStatusManager) GetController(instanceTitle string) (*ClaudeController, bool)
- func (ism *InstanceStatusManager) GetStatus(instance *Instance) InstanceStatusInfo
- func (ism *InstanceStatusManager) RegisterController(instanceTitle string, controller *ClaudeController)
- func (ism *InstanceStatusManager) UnregisterController(instanceTitle string)
- type InstanceStore
- type InstanceType
- type ItemSessionBacklogEntry
- type ItemSessionData
- type ItemSessionSummary
- type ItemSourceData
- type ItemSourcePlugin
- type ItemSourceUpdate
- type LifecycleEvent
- type LifecycleListener
- type LiveInstance
- type LiveInstancesProvider
- type LoadOptions
- type Locked
- type MemoryCacheReader
- type MigrationOptions
- type MigrationResult
- type NativeProcessManager
- func (n *NativeProcessManager) Attach() (chan struct{}, error)
- func (n *NativeProcessManager) CapturePaneContent() (string, error)
- func (n *NativeProcessManager) CapturePaneContentRaw() (string, error)
- func (n *NativeProcessManager) CapturePaneContentWithOptions(_, _ string) (string, error)
- func (n *NativeProcessManager) CaptureViewport(_ int) (string, error)
- func (n *NativeProcessManager) Close() error
- func (n *NativeProcessManager) DetachSafely() error
- func (n *NativeProcessManager) FilterBanners(content string) (string, int)
- func (n *NativeProcessManager) GetCurrentWorkingDirectory() (string, error)
- func (n *NativeProcessManager) GetCursorPosition() (x, y int, err error)
- func (n *NativeProcessManager) GetPTY() (*os.File, error)
- func (n *NativeProcessManager) GetPaneDimensions() (width, height int, err error)
- func (n *NativeProcessManager) GetPanePID() (int32, error)
- func (n *NativeProcessManager) GetSessionIdentifier() string
- func (n *NativeProcessManager) HasMeaningfulContent(_ string) bool
- func (n *NativeProcessManager) HasSession() bool
- func (n *NativeProcessManager) HasUpdated() (updated bool, hasPrompt bool, content string)
- func (n *NativeProcessManager) IsAlive() bool
- func (n *NativeProcessManager) RefreshClient() error
- func (n *NativeProcessManager) ResetExitOnce()
- func (n *NativeProcessManager) RestoreWithWorkDir(_ string) error
- func (n *NativeProcessManager) SendInputViaControlMode(_ context.Context, data []byte) error
- func (n *NativeProcessManager) SendKeys(keys string) (int, error)
- func (n *NativeProcessManager) SendPromptWithEnter(prompt string) error
- func (n *NativeProcessManager) SetDetachedSize(width, height int, _ string) error
- func (n *NativeProcessManager) SetOnExitCallback(fn func(string))
- func (n *NativeProcessManager) SetWindowSize(cols, rows int) error
- func (n *NativeProcessManager) Start(dir string) error
- func (n *NativeProcessManager) StartControlMode() error
- func (n *NativeProcessManager) StopControlMode() error
- func (n *NativeProcessManager) SubscribeToControlModeUpdates() (string, chan []byte)
- func (n *NativeProcessManager) TapEnter() error
- func (n *NativeProcessManager) UnsubscribeFromControlModeUpdates(id string)
- type Notifier
- type OpenStuckStateData
- type OutputConsumer
- type PRFixSpawner
- type PRStatusPoller
- func (p *PRStatusPoller) AddInstance(inst *Instance)
- func (p *PRStatusPoller) GetInstances() []*Instance
- func (p *PRStatusPoller) RemoveInstance(title string)
- func (p *PRStatusPoller) SetInstances(instances []*Instance)
- func (p *PRStatusPoller) SetOnUpdated(fn func(*Instance))
- func (p *PRStatusPoller) Start(ctx context.Context)
- func (p *PRStatusPoller) Stop()
- type PRStatusPollerConfig
- type PTYAccess
- func (p *PTYAccess) Close() error
- func (p *PTYAccess) GetBuffer() []byte
- func (p *PTYAccess) GetFile() (*os.File, bool)
- func (p *PTYAccess) GetRecentHash(n int) (uint64, bool)
- func (p *PTYAccess) GetRecentOutput(n int) []byte
- func (p *PTYAccess) GetRecentOutputInto(dst []byte, n int) int
- func (p *PTYAccess) GetSessionName() string
- func (p *PTYAccess) IsClosed() bool
- func (p *PTYAccess) Read(buf []byte) (int, error)
- func (p *PTYAccess) UpdatePTY(pty *os.File) error
- func (p *PTYAccess) Write(data []byte) (int, error)
- type PTYCategory
- type PTYConnection
- type PTYDiscovery
- func (pd *PTYDiscovery) GetConnection(path string) *PTYConnection
- func (pd *PTYDiscovery) GetConnections() []*PTYConnection
- func (pd *PTYDiscovery) GetConnectionsByCategory() map[PTYCategory][]*PTYConnection
- func (pd *PTYDiscovery) Refresh() error
- func (pd *PTYDiscovery) SetSessions(sessions []*Instance)
- func (pd *PTYDiscovery) Start()
- func (pd *PTYDiscovery) Stop()
- type PTYDiscoveryConfig
- type PTYDiscoveryOption
- type PTYStatus
- type PTYSubscriber
- type PendingApproval
- type PendingApprovalStatus
- type PipelineEngine
- type PipelineMode
- type PipelineModeContentFields
- type PipelineModeCreateInput
- type PipelineModeRepository
- type PipelineModeUpdateInput
- type PluginConfig
- type PluginRegistry
- type PolicyAction
- type PolicyAuditEntry
- type PolicyCondition
- type PolicyDecision
- type PolicyEngine
- func (pe *PolicyEngine) AddPolicy(policy *ApprovalPolicy) error
- func (pe *PolicyEngine) ClearAuditLog()
- func (pe *PolicyEngine) Evaluate(request *detection.ApprovalRequest) (*PolicyDecision, error)
- func (pe *PolicyEngine) GetAuditLog(limit int) []PolicyAuditEntry
- func (pe *PolicyEngine) GetPolicy(id string) *ApprovalPolicy
- func (pe *PolicyEngine) GetStatistics() PolicyStatistics
- func (pe *PolicyEngine) ListPolicies() []*ApprovalPolicy
- func (pe *PolicyEngine) RemovePolicy(id string) bool
- func (pe *PolicyEngine) SetMaxAuditLog(max int)
- func (pe *PolicyEngine) UpdatePolicy(updated *ApprovalPolicy) error
- type PolicyStatistics
- type Priority
- type ProcessFileInspector
- type ProcessManager
- type ProcessManagerBackend
- type ProcessManagerOptions
- type ProgressNoteData
- type ProjectData
- type Registry
- func (r *Registry) Acquire(sessionID string) (*LiveInstance, ReleaseFunc, error)
- func (r *Registry) AcquireAll() ([]*LiveInstance, ReleaseFunc, error)
- func (r *Registry) Count() int
- func (r *Registry) ForceRelease(sessionID string)
- func (r *Registry) List() []*LiveInstance
- func (r *Registry) Register(instance *LiveInstance) (ReleaseFunc, error)
- func (r *Registry) Shutdown()
- func (r *Registry) Storage() *Storage
- func (r *Registry) WithInstance(ctx context.Context, sessionID string, fn func(*LiveInstance) error) error
- type RegistryInspector
- type ReleaseFunc
- type RepoPathManager
- func (m *RepoPathManager) EnsureRepoCloned(ref *GitHubRef) (string, error)
- func (m *RepoPathManager) GetCloneURL(ref *GitHubRef) string
- func (m *RepoPathManager) GetRepoPath(ref *GitHubRef) string
- func (m *RepoPathManager) ResolveGitHubInput(input string) (localPath string, ref *GitHubRef, err error)
- type Repository
- type RepositoryOption
- type ResponseChunk
- type ResponseStream
- func (rs *ResponseStream) GetBufferSize() int
- func (rs *ResponseStream) GetEscapeParser() *analytics.EscapeCodeParser
- func (rs *ResponseStream) GetExitTail() []byte
- func (rs *ResponseStream) GetSubscriberCount() int
- func (rs *ResponseStream) GetSubscriberIDs() []string
- func (rs *ResponseStream) GetSubscriberInfo(subscriberID string) (created time.Time, exists bool)
- func (rs *ResponseStream) GetTotalBytesWritten() int64
- func (rs *ResponseStream) IsStarted() bool
- func (rs *ResponseStream) SetBufferSize(size int)
- func (rs *ResponseStream) SetOnOutput(fn func())
- func (rs *ResponseStream) SetStableSessionID(id string)
- func (rs *ResponseStream) Start(ctx context.Context) error
- func (rs *ResponseStream) Stop() error
- func (rs *ResponseStream) Subscribe(subscriberID string) (<-chan ResponseChunk, error)
- func (rs *ResponseStream) Unsubscribe(subscriberID string) error
- type RestartState
- type ReviewContextExtras
- type ReviewGateRunner
- type ReviewGateSpawner
- type ReviewItem
- type ReviewOutcome
- type ReviewQueue
- type ReviewQueueObserver
- type ReviewQueuePoller
- func (rqp *ReviewQueuePoller) AddInstance(instance *Instance)
- func (rqp *ReviewQueuePoller) CheckSession(inst *Instance)
- func (rqp *ReviewQueuePoller) FindInstance(sessionID string) *Instance
- func (rqp *ReviewQueuePoller) ForceReconcile()
- func (rqp *ReviewQueuePoller) GetConfig() ReviewQueuePollerConfig
- func (rqp *ReviewQueuePoller) GetInstances() []*Instance
- func (rqp *ReviewQueuePoller) GetMonitoredCount() int
- func (rqp *ReviewQueuePoller) IsRunning() bool
- func (rqp *ReviewQueuePoller) RemoveInstance(instanceTitle string)
- func (rqp *ReviewQueuePoller) SetActivityChannel(ch <-chan struct{})
- func (rqp *ReviewQueuePoller) SetApprovalProvider(provider ApprovalMetadataProvider)
- func (rqp *ReviewQueuePoller) SetInstances(instances []*Instance)
- func (rqp *ReviewQueuePoller) Start(ctx context.Context)
- func (rqp *ReviewQueuePoller) Stop()
- func (rqp *ReviewQueuePoller) UpdateConfig(config ReviewQueuePollerConfig)
- type ReviewQueuePollerConfig
- type ReviewQueueStatistics
- type ReviewQueueWriter
- type ReviewState
- func (rs *ReviewState) ComputePromptSignature(content string) string
- func (rs *ReviewState) DetectAndTrackPrompt(content string, statusInfo InstanceStatusInfo, sessionTitle string) bool
- func (rs *ReviewState) IsAcknowledgedAfterOutput() bool
- func (rs *ReviewState) IsInProcessingGracePeriod() bool
- func (rs *ReviewState) SyncAtomicTimestamps()
- func (rs *ReviewState) TimeSinceLastMeaningfulOutput(createdAt time.Time) time.Duration
- func (rs *ReviewState) TimeSinceLastTerminalUpdate(createdAt time.Time) time.Duration
- func (rs *ReviewState) UpdateTimestamps(rawContent, filteredContent string, shouldUpdateMeaningful bool, ...) bool
- func (rs *ReviewState) UserRespondedAfterPrompt() bool
- type ReviewVerdictData
- type ReviewVerdictSummary
- type RevisionTarget
- type Session
- func (s *Session) GetBranch() string
- func (s *Session) GetCategory() string
- func (s *Session) GetLastMeaningfulOutput() time.Time
- func (s *Session) GetLastViewed() time.Time
- func (s *Session) GetPath() string
- func (s *Session) GetTags() []string
- func (s *Session) GetTerminalDimensions() (width, height int)
- func (s *Session) GetTmuxSessionName() string
- func (s *Session) GetWorkingDir() string
- func (s *Session) HasActivityTracking() bool
- func (s *Session) HasCloudContext() bool
- func (s *Session) HasFilesystemContext() bool
- func (s *Session) HasGitContext() bool
- func (s *Session) HasTerminalContext() bool
- func (s *Session) HasUIPreferences() bool
- func (s *Session) IsCloudConfigured() bool
- func (s *Session) NeedsReviewQueueAttention() bool
- func (s *Session) WithActivityTracking(activity *ActivityTracking) *Session
- func (s *Session) WithCloudContext(cloud *CloudContext) *Session
- func (s *Session) WithFilesystemContext(fs *FilesystemContext) *Session
- func (s *Session) WithGitContext(git *GitContext) *Session
- func (s *Session) WithTerminalContext(terminal *TerminalContext) *Session
- func (s *Session) WithUIPreferences(ui *UIPreferences) *Session
- type SessionGoalData
- type SessionHealthChecker
- type SessionType
- type Shell
- type ShellData
- type ShellHandle
- type ShellRegistry
- func (r *ShellRegistry) Add(sh *Shell, handle *tmux.ShellTmuxHandle)
- func (r *ShellRegistry) AddStopped(sh *Shell)
- func (r *ShellRegistry) Get(shellID string) (*Shell, bool)
- func (r *ShellRegistry) GetBoth(shellID string) (*Shell, *tmux.ShellTmuxHandle, bool)
- func (r *ShellRegistry) GetHandle(shellID string) (*tmux.ShellTmuxHandle, bool)
- func (r *ShellRegistry) Len() int
- func (r *ShellRegistry) List() []*Shell
- func (r *ShellRegistry) Remove(shellID string)
- func (r *ShellRegistry) SetHandle(shellID string, handle *tmux.ShellTmuxHandle)
- func (r *ShellRegistry) UpdateForRestart(shellID string, newHandle *tmux.ShellTmuxHandle, newSessionName string, ...)
- func (r *ShellRegistry) UpdateStatus(shellID string, status ShellStatus, exitCode *int) bool
- type ShellRepository
- type ShellStatus
- type SourceSyncEventData
- type SpawnShellRequest
- type StartupScanner
- type Status
- type StatusChange
- type StatusChangeListener
- type StatusDeterminer
- type StatusProvider
- type Storage
- func (s *Storage) AddInstance(instance *Instance) error
- func (s *Storage) AllRules(ctx context.Context) ([]ApprovalRuleData, error)
- func (s *Storage) AppendProgressNote(ctx context.Context, itemID string, criterionIndex int, note, status string) error
- func (s *Storage) ArchiveBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
- func (s *Storage) AssignSessionsToProject(ctx context.Context, projectName string, sessionTitles []string) error
- func (s *Storage) Close() error
- func (s *Storage) CreateBacklogItem(ctx context.Context, data BacklogItemData) (*BacklogItemData, error)
- func (s *Storage) CreateItemSession(ctx context.Context, data ItemSessionData) (ItemSessionSummary, error)
- func (s *Storage) CreateItemSessionWithVerdict(ctx context.Context, isData ItemSessionData, verdict ReviewVerdictData) (ItemSessionSummary, error)
- func (s *Storage) CreateItemSource(ctx context.Context, data ItemSourceData) (*ItemSourceData, error)
- func (s *Storage) CreateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
- func (s *Storage) CreateSourceSyncEvent(ctx context.Context, sourceID, cursorAfter string, ...) error
- func (s *Storage) DeleteAllInstances() error
- func (s *Storage) DeleteBacklogItem(ctx context.Context, id string) error
- func (s *Storage) DeleteInstance(title string) error
- func (s *Storage) DeleteItemSource(ctx context.Context, id string) error
- func (s *Storage) DeleteProject(ctx context.Context, name string) error
- func (s *Storage) DeleteRule(ctx context.Context, id string) error
- func (s *Storage) FindInstanceDataByID(id string) (*InstanceData, error)
- func (s *Storage) FindOpenStuckStates(ctx context.Context) ([]OpenStuckStateData, error)
- func (s *Storage) GetAllInstanceArtifacts() (map[string]string, error)
- func (s *Storage) GetAllItemSessionsWithBacklogInfo(ctx context.Context) ([]ItemSessionBacklogEntry, error)
- func (s *Storage) GetBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
- func (s *Storage) GetBaseCommitSHAsForSessions(ctx context.Context, uuids []string) (map[string]string, error)
- func (s *Storage) GetClaudeConversationUUIDBySessionUUID(ctx context.Context, sessionUUID string) (string, error)
- func (s *Storage) GetEntClient() *ent.Client
- func (s *Storage) GetInstanceArtifacts(title string) (string, error)
- func (s *Storage) GetItemSession(ctx context.Context, id string) (ItemSessionSummary, error)
- func (s *Storage) GetItemSessionBySessionAndItem(ctx context.Context, sessionUUID string, itemID string) (ItemSessionSummary, error)
- func (s *Storage) GetItemSessionBySessionUUID(ctx context.Context, sessionUUID string) (ItemSessionSummary, error)
- func (s *Storage) GetMostRecentReviewVerdictForItem(ctx context.Context, itemID string) (ReviewOutcome, error)
- func (s *Storage) GetSession(ctx context.Context, title string, opts ContextOptions) (*Session, error)
- func (s *Storage) GetSessionGoal(ctx context.Context, sessionUUID string) (*SessionGoalData, error)
- func (s *Storage) GetSubcommandBreakdown(ctx context.Context, program string, since time.Time) ([]SubcommandDecisionCount, error)
- func (s *Storage) GetSubcommandTrend(ctx context.Context, program, subcommand string, since time.Time) ([]AnalyticsData, error)
- func (s *Storage) GetWorktreeDataBySessionUUID(ctx context.Context, sessionUUID string) (GitWorktreeData, error)
- func (s *Storage) ListAnalytics(ctx context.Context, limit int) ([]AnalyticsData, error)
- func (s *Storage) ListAnalyticsByProgramSince(ctx context.Context, program string, since time.Time, limit int) ([]AnalyticsData, error)
- func (s *Storage) ListAnalyticsSince(ctx context.Context, since time.Time, limit int) ([]AnalyticsData, error)
- func (s *Storage) ListBacklogItemSummaries(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemSummary, error)
- func (s *Storage) ListBacklogItems(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemData, error)
- func (s *Storage) ListInstanceData() ([]InstanceData, error)
- func (s *Storage) ListInstanceIDs() ([]string, error)
- func (s *Storage) ListItemSessions(ctx context.Context, itemID string) ([]ItemSessionSummary, error)
- func (s *Storage) ListItemSources(ctx context.Context) ([]ItemSourceData, error)
- func (s *Storage) ListProgressNotesForItem(ctx context.Context, itemID string) ([]ProgressNoteData, error)
- func (s *Storage) ListProjects(ctx context.Context) ([]ProjectData, error)
- func (s *Storage) ListRecentCommandsByProgram(ctx context.Context, program, subcommand string, since time.Time, n int) ([]string, error)
- func (s *Storage) ListSessionRecords() []tokens.SessionRecord
- func (s *Storage) ListSessions(ctx context.Context, opts ContextOptions) ([]*Session, error)
- func (s *Storage) ListSourceSyncEvents(ctx context.Context, sourceID string) ([]SourceSyncEventData, bool, error)
- func (s *Storage) LoadInstances() ([]*Instance, error)
- func (s *Storage) MarkStuck(ctx context.Context, itemID string, reason domain.StuckReason, ...) (bool, error)
- func (s *Storage) MarkStuckNotified(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
- func (s *Storage) RecordAnalytics(ctx context.Context, data AnalyticsData) error
- func (s *Storage) ResolveStuck(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
- func (s *Storage) SaveInstances(instances []*Instance) error
- func (s *Storage) SaveInstancesSync(instances []*Instance) error
- func (s *Storage) SaveReviewVerdict(ctx context.Context, itemSessionID string, verdict ReviewVerdictData) error
- func (s *Storage) SaveSession(ctx context.Context, session *Session) error
- func (s *Storage) SetSessionGoal(ctx context.Context, sessionUUID string, goal string, status string, ...) (*SessionGoalData, error)
- func (s *Storage) SnoozeStuckState(ctx context.Context, itemID string, reason domain.StuckReason, until time.Time) (bool, error)
- func (s *Storage) TransitionBacklogItemStatus(ctx context.Context, id string, toStatus BacklogStatus, ...) (*BacklogItemData, error)
- func (s *Storage) UpdateAcCriterionStatus(ctx context.Context, itemID string, criterionIndex int, status string, ...) error
- func (s *Storage) UpdateBacklogItem(ctx context.Context, id string, update BacklogItemUpdate, ...) (*BacklogItemData, error)
- func (s *Storage) UpdateInstance(instance *Instance) error
- func (s *Storage) UpdateInstanceAcknowledged(title string) error
- func (s *Storage) UpdateInstanceArtifacts(title string, blob string) error
- func (s *Storage) UpdateInstanceForkFlag(_ string, _ bool) error
- func (s *Storage) UpdateInstanceLastAddedToQueue(title string, lastAddedToQueue time.Time) error
- func (s *Storage) UpdateInstanceLastUserResponse(title string, lastUserResponse time.Time) error
- func (s *Storage) UpdateInstancePRNumber(title string, prNumber int) error
- func (s *Storage) UpdateInstancePRStatus(_, _, _, _ string, _, _ int, _, _ bool) error
- func (s *Storage) UpdateInstanceProcessingGrace(title string, processingGraceUntil time.Time) error
- func (s *Storage) UpdateInstanceTimestampsOnly(title string, lastTerminalUpdate, lastMeaningfulOutput time.Time, ...) error
- func (s *Storage) UpdateItemSessionEnded(ctx context.Context, id string, endedAt time.Time) error
- func (s *Storage) UpdateItemSessionGitActivity(ctx context.Context, id string, sha, msg string, commitAt time.Time, ...) error
- func (s *Storage) UpdateItemSessionSessionUUID(ctx context.Context, id string, sessionUUID string) error
- func (s *Storage) UpdateItemSessionStarted(ctx context.Context, id string, startedAt time.Time) error
- func (s *Storage) UpdateItemSessionTriageResult(ctx context.Context, id string, triageResult string) error
- func (s *Storage) UpdateItemSessionVerificationNotes(ctx context.Context, id string, verificationNotes string) error
- func (s *Storage) UpdateItemSource(ctx context.Context, id string, update ItemSourceUpdate) (*ItemSourceData, error)
- func (s *Storage) UpdateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
- func (s *Storage) UpdateSessionTaskStatus(ctx context.Context, sessionUUID string, taskID string, newStatus string) (*SessionGoalData, error)
- func (s *Storage) UpsertRule(ctx context.Context, rule ApprovalRuleData) error
- type SubcommandDecisionCount
- type Subscriber
- type SyncLoop
- type TagManager
- type TaskNode
- type TerminalContext
- type TimeRestriction
- type TmuxBackend
- func (b *TmuxBackend) Attach() (chan struct{}, error)
- func (b *TmuxBackend) CapturePaneContent() (string, error)
- func (b *TmuxBackend) CapturePaneContentRaw() (string, error)
- func (b *TmuxBackend) CapturePaneContentWithOptions(start, end string) (string, error)
- func (b *TmuxBackend) CaptureViewport(lines int) (string, error)
- func (b *TmuxBackend) Close() error
- func (b *TmuxBackend) DetachSafely() error
- func (b *TmuxBackend) FilterBanners(content string) (string, int)
- func (b *TmuxBackend) GetCurrentWorkingDirectory() (string, error)
- func (b *TmuxBackend) GetCursorPosition() (x, y int, err error)
- func (b *TmuxBackend) GetPTY() (*os.File, error)
- func (b *TmuxBackend) GetPaneDimensions() (width, height int, err error)
- func (b *TmuxBackend) GetPanePID() (int32, error)
- func (b *TmuxBackend) GetSessionIdentifier() string
- func (b *TmuxBackend) HasMeaningfulContent(content string) bool
- func (b *TmuxBackend) HasSession() bool
- func (b *TmuxBackend) HasUpdated() (updated bool, hasPrompt bool, content string)
- func (b *TmuxBackend) IsAlive() bool
- func (b *TmuxBackend) RefreshClient() error
- func (b *TmuxBackend) ResetExitOnce()
- func (b *TmuxBackend) RestoreWithWorkDir(w string) error
- func (b *TmuxBackend) SendInputViaControlMode(ctx context.Context, data []byte) error
- func (b *TmuxBackend) SendKeys(keys string) (int, error)
- func (b *TmuxBackend) SendPromptWithEnter(p string) error
- func (b *TmuxBackend) SetDetachedSize(w, h int, title string) error
- func (b *TmuxBackend) SetOnExitCallback(fn func(string))
- func (b *TmuxBackend) SetWindowSize(cols, rows int) error
- func (b *TmuxBackend) Start(dir string) error
- func (b *TmuxBackend) StartControlMode() error
- func (b *TmuxBackend) StopControlMode() error
- func (b *TmuxBackend) SubscribeToControlModeUpdates() (string, chan []byte)
- func (b *TmuxBackend) TapEnter() error
- func (b *TmuxBackend) TmuxManager() TmuxManager
- func (b *TmuxBackend) UnsubscribeFromControlModeUpdates(id string)
- type TmuxManager
- type TmuxProcessManager
- func (tm *TmuxProcessManager) Attach() (chan struct{}, error)
- func (tm *TmuxProcessManager) CapturePaneContent() (string, error)
- func (tm *TmuxProcessManager) CapturePaneContentRaw() (string, error)
- func (tm *TmuxProcessManager) CapturePaneContentWithOptions(startLine, endLine string) (string, error)
- func (tm *TmuxProcessManager) CaptureViewport(lines int) (string, error)
- func (tm *TmuxProcessManager) Close() error
- func (tm *TmuxProcessManager) DetachSafely() error
- func (tm *TmuxProcessManager) DoesSessionExist() bool
- func (tm *TmuxProcessManager) FilterBanners(content string) (string, int)
- func (tm *TmuxProcessManager) GetCursorPosition() (x, y int, err error)
- func (tm *TmuxProcessManager) GetPTY() (*os.File, error)
- func (tm *TmuxProcessManager) GetPaneDimensions() (width, height int, err error)
- func (tm *TmuxProcessManager) GetPanePID() (int32, error)
- func (tm *TmuxProcessManager) GetTmuxSessionName() string
- func (tm *TmuxProcessManager) HasMeaningfulContent(content string) bool
- func (tm *TmuxProcessManager) HasSession() bool
- func (tm *TmuxProcessManager) HasUpdated() (updated bool, hasPrompt bool, content string)
- func (tm *TmuxProcessManager) IsAlive() bool
- func (tm *TmuxProcessManager) PaneExitStatus() (code int, signal string, dead bool)
- func (tm *TmuxProcessManager) RefreshClient() error
- func (tm *TmuxProcessManager) ResetExitOnce()
- func (tm *TmuxProcessManager) RestoreWithWorkDir(workDir string) error
- func (tm *TmuxProcessManager) SendInputViaControlMode(ctx context.Context, data []byte) error
- func (tm *TmuxProcessManager) SendKeys(keys string) (int, error)
- func (tm *TmuxProcessManager) SendPromptWithEnter(prompt string) error
- func (tm *TmuxProcessManager) Session() *tmux.TmuxSession
- func (tm *TmuxProcessManager) SetDetachedSize(width, height int, instanceTitle string) error
- func (tm *TmuxProcessManager) SetOnExitCallback(fn func(string))
- func (tm *TmuxProcessManager) SetSession(s *tmux.TmuxSession)
- func (tm *TmuxProcessManager) SetWindowSize(cols, rows int) error
- func (tm *TmuxProcessManager) Start(dir string) error
- func (tm *TmuxProcessManager) StartControlMode() error
- func (tm *TmuxProcessManager) StopControlMode() error
- func (tm *TmuxProcessManager) SubscribeToControlModeUpdates() (string, chan []byte)
- func (tm *TmuxProcessManager) TapEnter() error
- func (tm *TmuxProcessManager) UnsubscribeFromControlModeUpdates(id string)
- type TmuxSocketQuerier
- type TransitionDef
- type TriageSuggestion
- type TriageTask
- type TurnCallback
- type UIPreferences
- type UsageLimit
- type VCSInfo
- type VNCProcessManager
- type WorkflowCreateInput
- type WorkflowEngine
- type WorkflowRepository
- type WorkflowUpdateInput
- type Workspace
- type WorkspacePath
- type WorkspaceSwitchRequest
- type WorkspaceSwitchResult
- type WorkspaceSwitchType
- type WorktreeInfo
- type WorktreePRPoller
- func (p *WorktreePRPoller) GetPRData(repoPath, branch string) *github.PRInfo
- func (p *WorktreePRPoller) SetOnUpdated(fn func(repoPath, branch string, info *github.PRInfo))
- func (p *WorktreePRPoller) SetSource(src WorktreeSource)
- func (p *WorktreePRPoller) Start(ctx context.Context)
- func (p *WorktreePRPoller) Stop()
- type WorktreePRPollerConfig
- type WorktreeScanItem
- type WorktreeSource
- type WorktreeTarget
Constants ¶
const ( BacklogStatusIdea = domain.BacklogStatusIdea BacklogStatusRefining = domain.BacklogStatusRefining BacklogStatusReady = domain.BacklogStatusReady BacklogStatusInProgress = domain.BacklogStatusInProgress BacklogStatusReview = domain.BacklogStatusReview BacklogStatusPRPending = domain.BacklogStatusPRPending BacklogStatusDone = domain.BacklogStatusDone BacklogStatusArchived = domain.BacklogStatusArchived )
const ( SessionRoleWork = "work" SessionRoleTriage = "triage" SessionRoleReview = "review" )
Session role constants.
const ( TagBacklogWork = "backlog:work" TagBacklogRevision = "backlog:revision" TagAutonomous = "autonomous" )
Session tag constants for backlog-spawned sessions.
const ( TriggeredByUser = "user" TriggeredBySystem = "system" )
TriggeredBy values for BacklogStatusEvent records.
const ( AcStatusPending = domain.AcStatusPending AcStatusInProgress = domain.AcStatusInProgress AcStatusDone = domain.AcStatusDone AcStatusFail = domain.AcStatusFail )
const ( ReviewOutcomePass = domain.ReviewOutcomePass ReviewOutcomeFail = domain.ReviewOutcomeFail ReviewOutcomePartial = domain.ReviewOutcomePartial ReviewOutcomeUnverifiable = domain.ReviewOutcomeUnverifiable )
const ( ReviewVerdictPass = domain.ReviewVerdictPass ReviewVerdictFail = domain.ReviewVerdictFail ReviewVerdictPartial = domain.ReviewVerdictPartial ReviewVerdictUnverifiable = domain.ReviewVerdictUnverifiable )
Backward-compatible aliases so callers can be migrated incrementally. Prefer ReviewOutcome* constants in new code.
const ( PauseReasonManual = "manual" PauseReasonAutoInactivity = "auto:inactivity" PauseReasonAutoLimit = "auto:session_limit" PauseReasonAutoResource = "auto:resource" )
SessionType indicates the type of session workflow to use Pause reason constants. Use these instead of bare string literals.
const ( PermissionModeAuto = "auto" PermissionModeBypassPermissions = "bypassPermissions" PermissionModeAcceptEdits = "acceptEdits" PermissionModeManual = "manual" )
PermissionMode constants for the --permission-mode Claude Code flag.
const ( // SessionTypeDirectory creates a simple directory session without git worktree SessionTypeDirectory = config.SessionTypeDirectory // SessionTypeNewWorktree creates a new git worktree for the session SessionTypeNewWorktree = config.SessionTypeNewWorktree // SessionTypeExistingWorktree uses an existing git worktree SessionTypeExistingWorktree = config.SessionTypeExistingWorktree // SessionTypeNewProject creates a new directory, initializes a git repo with an // initial commit, and opens the session. The directory need not exist beforehand. SessionTypeNewProject = config.SessionTypeNewProject // SessionTypeOneOff generates a fresh temporary directory under one_off_base_dir. SessionTypeOneOff = config.SessionTypeOneOff )
const ( ReasonApprovalPending = queue.ReasonApprovalPending ReasonInputRequired = queue.ReasonInputRequired ReasonErrorState = queue.ReasonErrorState ReasonTestsFailing = queue.ReasonTestsFailing ReasonIdleTimeout = queue.ReasonIdleTimeout ReasonTaskComplete = queue.ReasonTaskComplete ReasonUncommittedChanges = queue.ReasonUncommittedChanges ReasonIdle = queue.ReasonIdle ReasonStale = queue.ReasonStale ReasonWaitingForUser = queue.ReasonWaitingForUser )
const ( PriorityUrgent = queue.PriorityUrgent PriorityHigh = queue.PriorityHigh PriorityMedium = queue.PriorityMedium PriorityLow = queue.PriorityLow )
const ( GoalStatusIdle = "idle" GoalStatusWorking = "working" GoalStatusBlocked = "blocked" GoalStatusDone = "done" TaskStatusPending = "pending" TaskStatusInProgress = "in_progress" TaskStatusDone = "done" TaskStatusBlocked = "blocked" )
Goal and task status constants.
const ( MinTitleLength = 1 MaxTitleLength = 32 )
Title validation constants
const AcCriteriaJSONEmpty = domain.AcCriteriaJSONEmpty
AcCriteriaJSONEmpty is the zero value — an empty criteria list.
const CategoryBacklog = "Backlog"
CategoryBacklog is the Session.Category value assigned to all sessions spawned by BacklogService (work, revision, review-gate, re-review) so they group under a "Backlog" bucket in the session list UI instead of falling into "Uncategorized".
const DefaultBacklogPriority = domain.DefaultBacklogPriority
DefaultBacklogPriority is the default priority assigned to new backlog items when no priority is specified. Lower values indicate higher priority.
const (
// DefaultBufferSize is 10MB of in-memory buffer
DefaultBufferSize = 10 * 1024 * 1024
)
const DefaultReviewTranscriptMaxBytes int64 = 256 * 1024
DefaultReviewTranscriptMaxBytes bounds how much ANSI-stripped scrollback is written to a review transcript file. This is no longer a prompt-embedding budget (the file is searched on demand via the reviewer's Grep/Read tools, not injected into the prompt text), so it can be considerably larger than a typical per-section prompt budget -- 256KB comfortably covers a long session's tail without writing unbounded data into a real repo checkout.
const MaxTagCount = 100
MaxTagCount is the maximum number of tags allowed per session.
const MaxTagLength = 50
MaxTagLength is the maximum allowed length for a single tag.
Variables ¶
var ( ErrACRequired = domain.ErrACRequired ErrPlanRequired = domain.ErrPlanRequired ErrPlanArtifactsRequired = domain.ErrPlanArtifactsRequired ErrVerdictRequired = domain.ErrVerdictRequired ErrPRRequired = domain.ErrPRRequired )
Sentinel errors for transition guards.
var ( ErrInvalidTitleLength = errors.New("title must be 1-32 characters") ErrInvalidTitleChars = errors.New("title contains invalid characters") ErrDuplicateTitle = errors.New("a session with this title already exists") ErrCannotRestart = errors.New("session cannot be restarted in current state") )
Title validation errors
var AggregateOutcome = domain.AggregateOutcome
AggregateOutcome computes the overall outcome from a slice of CriterionVerdicts.
var CanTransitionBacklog = domain.CanTransitionBacklog
CanTransitionBacklog reports whether a transition from one backlog status to another is permitted.
var ContextCloudSession = ContextOptions{ LoadCloud: true, LoadActivity: true, LoadUI: true, LoadTags: true, }
ContextCloudSession loads contexts for cloud/API sessions. Optimized for remote sessions that don't have local git/filesystem context. Memory usage: ~1-2 KB per session
var ContextDetailView = ContextOptions{ LoadGit: true, LoadFilesystem: true, LoadTerminal: true, LoadUI: true, LoadActivity: true, LoadWorktree: true, LoadDiffStats: true, LoadTags: true, LoadClaudeSession: true, }
ContextDetailView loads most contexts for detail panel. Comprehensive data for session detail views, excluding heavy diff content. Memory usage: ~10-20 KB per session
var ContextForReviewQueue = ContextOptions{ LoadGit: true, LoadActivity: true, LoadWorktree: true, LoadDiffStats: true, LoadTags: true, }
ContextForReviewQueue loads data needed for review queue operations. Focused on git context and change indicators. Memory usage: ~3-5 KB per session
var ContextForSearch = ContextOptions{ LoadGit: true, LoadTags: true, LoadActivity: true, }
ContextForSearch loads contexts needed for search operations. Includes tags and basic metadata for efficient filtering. Memory usage: ~1-2 KB per session
var ContextFull = ContextOptions{ LoadGit: true, LoadFilesystem: true, LoadTerminal: true, LoadUI: true, LoadActivity: true, LoadCloud: true, LoadWorktree: true, LoadDiffStats: true, LoadDiffContent: true, LoadTags: true, LoadClaudeSession: true, }
ContextFull loads all contexts and child data (expensive). Complete data including full diff content. Use sparingly. Memory usage: Can be 1-25 MB per session depending on diff size
var ContextMinimal = ContextOptions{}
ContextMinimal loads only core session data with no contexts. Use this for basic operations that only need session metadata. Memory usage: ~500 bytes per session
var ContextTerminalView = ContextOptions{ LoadTerminal: true, LoadGit: true, LoadUI: true, LoadActivity: true, LoadDiffStats: true, }
ContextTerminalView loads contexts needed for terminal preview. Includes terminal output and git diffs for preview panes. Memory usage: ~5-10 KB per session (varies with terminal output size)
var ContextUIView = ContextOptions{ LoadUI: true, LoadActivity: true, LoadGit: true, LoadTags: true, }
ContextUIView loads contexts needed for list/card display. Optimized for responsive UI rendering with essential context only. Memory usage: ~2-3 KB per session
var DefaultRepoPathManager = NewRepoPathManager()
DefaultRepoPathManager is the default instance used for GitHub URL resolution.
var DeterminePriority = queue.DeterminePriority
DeterminePriority re-export
var ErrConflict = errors.New("conflict")
ErrConflict is returned when an operation would violate a uniqueness constraint.
var ErrInstanceDataNotFound = errors.New("instance data not found")
ErrInstanceDataNotFound is returned by FindInstanceDataByID when no match exists.
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a requested entity does not exist.
var ErrPreconditionFailed = errors.New("precondition failed: concurrent modification detected")
ErrPreconditionFailed is returned when an optimistic-locking precondition check fails.
var ErrSessionAlreadyRegistered = errors.New("session: already registered")
ErrSessionAlreadyRegistered is returned by Register when a LiveInstance for the given ID is already present in the registry (duplicate-ID collision guard).
var ErrSessionNotFound = errors.New("session: not found in storage")
ErrSessionNotFound is returned by Acquire when the sessionID is not known to Storage.
var ErrShellStopped = errors.New("shell is stopped")
ErrShellStopped is returned when an operation is attempted on a shell that has been stopped.
var ErrSubscriberFull = errors.New("PTYSubscriber: internal buffer exceeded capacity limit")
ErrSubscriberFull is returned by PTYSubscriber.Push when the internal buffer has exceeded its capacity limit. The caller should close the subscriber.
var LoadDiffOnly = LoadOptions{ LoadWorktree: true, LoadDiffStats: true, LoadDiffContent: true, }
LoadDiffOnly loads only diff-related data, useful for preview panes.
Deprecated: For new code, use ContextTerminalView.WithDiffContent() with GetSession/ListSessions.
var LoadForReviewQueue = LoadOptions{ LoadWorktree: true, LoadDiffStats: true, LoadDiffContent: false, LoadTags: true, LoadClaudeSession: false, }
LoadForReviewQueue loads data needed for review queue operations.
Deprecated: For new code, use ContextForReviewQueue with GetSession/ListSessions.
var LoadFull = LoadOptions{ LoadWorktree: true, LoadDiffStats: true, LoadDiffContent: true, LoadTags: true, LoadClaudeSession: true, }
LoadFull loads all available data including full diff content. Use this for detail views where you need complete information. Memory usage: Can be 1-25 MB per session depending on diff size
Deprecated: For new code, use ContextFull with GetSession/ListSessions.
var LoadMinimal = LoadOptions{}
LoadMinimal loads only the core session fields without any child data. Use this when you only need session metadata (title, path, status, etc.)
Deprecated: For new code, use ContextMinimal with GetSession/ListSessions.
var LoadSummary = LoadOptions{ LoadWorktree: true, LoadDiffStats: true, LoadDiffContent: false, LoadTags: true, LoadClaudeSession: true, }
LoadSummary loads lightweight child data suitable for list views. This includes everything except the heavy diff content. Memory usage: ~1-2 KB per session
Deprecated: For new code, use ContextUIView with GetSession/ListSessions.
var ParseAcCriteria = domain.ParseAcCriteria
ParseAcCriteria deserializes acceptance criteria from a JSON string.
var SerializeAcCriteria = domain.SerializeAcCriteria
SerializeAcCriteria serializes acceptance criteria to an AcCriteriaJSON value.
var TransitionGuard = domain.TransitionGuard
TransitionGuard validates business rules before a status transition.
Functions ¶
func BuildHeadlessRetriagePrompt ¶ added in v1.37.0
func BuildHeadlessRetriagePrompt(item *BacklogItemData, artifactAbsPath string, prior HeadlessTriageResult, feedback string) string
BuildHeadlessRetriagePrompt constructs a JSON-output prompt that refines a prior triage result using free-text user feedback. artifactAbsPath is the same directory used by the original triage run — research/*.md, plan.md, and validation.md already exist there and are treated as valid context unless the feedback indicates otherwise.
func BuildHeadlessReviewPrompt ¶ added in v1.35.0
func BuildHeadlessReviewPrompt(item *BacklogItemData, acSnapshot []AcCriterion, diff string, diffTruncated bool, verificationNotes string, extras ReviewContextExtras) string
BuildHeadlessReviewPrompt constructs a review prompt for headless calls. Unlike BuildReviewPrompt, it asks for JSON output instead of tool invocation because headless claude -p subprocesses do not have tool access.
extras carries the additional context sources available on the empty-diff codebase-read path (prior review attempts, full notes history, item goal/status history, a searchable session transcript file) — see ReviewContextExtras. Its sections are rendered only when diff == "", matching this feature's established "expensive extras only on the hard-to-verify path" posture; pass the zero value when diff != "" or when no such context is available.
func BuildHeadlessTriagePrompt ¶ added in v1.35.0
func BuildHeadlessTriagePrompt(item *BacklogItemData, artifactAbsPath string) string
BuildHeadlessTriagePrompt constructs the JSON-output triage prompt for a backlog item. artifactAbsPath is the absolute path where the LLM should write planning files.
func BuildReviewCallOptions ¶ added in v1.38.0
func BuildReviewCallOptions(diff, codebaseWorkDir string) (systemPrompt string, opts headless.CallOptions, callTimeout time.Duration, path string)
BuildReviewCallOptions decides the headless review call's system prompt, CallOptions, and context timeout for a given diff state. This is the single point of decision for the empty-diff codebase-access branch — both ReviewGateRunner.Run and TriggerReReview must call this instead of independently constructing the same literals (see ADR-001).
The returned path label is one of "diff" (normal, no tool access) or "codebase-read" (empty diff, granted bounded Read/Grep/Glob access under codebaseWorkDir). Callers use the label to decide whether DegradeIfUnverified applies and for logging.
func BuildReviewPrompt ¶ added in v1.35.0
func BuildReviewPrompt(item *BacklogItemData, acSnapshot []AcCriterion, diff string, diffTruncated bool, itemSessionID string, verificationNotes string) string
BuildReviewPrompt constructs the initial prompt for a review gate session.
func BuildSessionInitialPrompt ¶ added in v1.35.0
func BuildSessionInitialPrompt(item *BacklogItemData, priorSessions []ItemSessionSummary) string
BuildSessionInitialPrompt renders the full context prompt for an agent session.
func BuildTokenBudgetedPrompt ¶ added in v1.35.0
func BuildTokenBudgetedPrompt(item *BacklogItemData, priorSessions []ItemSessionSummary) string
BuildTokenBudgetedPrompt wraps BuildSessionInitialPrompt with token budget enforcement. It estimates tokens as len(output)/4, and reduces content in two passes if over 4000.
func CanTransition ¶
CanTransition returns true if transitioning from -> to is a valid state transition.
func ClaudeProjectDirName ¶ added in v1.12.0
ClaudeProjectDirName returns the directory name Claude uses for a given absolute project path. Claude encodes the path by replacing every non-alphanumeric character with '-'. This includes '/', '.', '_', and any other non-word characters. Example: "/Users/alice/myproject" → "-Users-alice-myproject" Example: "/Users/alice/.hidden/my_project" → "-Users-alice--hidden-my-project"
func CleanupBacklogContextFile ¶ added in v1.35.0
CleanupBacklogContextFile removes .backlog-context.md from the worktree root. Logs but does not fail if the file is absent.
func CleanupSlashCommands ¶ added in v1.35.0
CleanupSlashCommands removes the backlog slash command directory. Logs but does not return an error if the directory is absent.
func ComputeContentHash ¶ added in v1.38.0
ComputeContentHash returns a SHA-256 hex digest, truncated to 16 characters, over fields concatenated in the order given by the caller. Used to detect when a PipelineMode's persisted content has changed since a session snapshotted it (see plan.md's ItemSessionSummary.PipelineModeSnapshotHash entry, Epic 1.6). Callers must always pass the 9 content-template fields in the same fixed declaration order so hashes are comparable across loads.
Exported (Epic 2.2) so server/services can compute content_hash for CreatePipelineMode/UpdatePipelineMode/GetPipelineMode/ListPipelineModes RPC responses directly from a row's current field values — including rows for disabled modes, which never enter pipelineModeCache (only ListEnabled-backed modes do) and therefore have no resolvedPipelineMode.ContentHash to reuse.
func CreateBacklogWorktree ¶ added in v1.37.0
CreateBacklogWorktree creates a git worktree for a backlog work session. It creates a branch named "backlog/<branchSuffix>" and returns the on-disk worktree path. The caller is responsible for writing files to the path before spawning the session.
func DecryptToken ¶ added in v1.35.0
DecryptToken decrypts a base64-encoded ciphertext (nonce prepended) using AES-256-GCM.
func DegradeIfUnverified ¶ added in v1.38.0
func DegradeIfUnverified(path string, overall ReviewOutcome, verdicts []CriterionVerdict, summary string, toolReads []string, codebaseWorkDir string) (ReviewOutcome, []CriterionVerdict, string, string)
DegradeIfUnverified force-downgrades overall/verdicts to UNVERIFIABLE when path is "codebase-read" and EITHER toolReads is empty OR any claimed tool_reads path does not actually exist under (or escapes) codebaseWorkDir. Returns the possibly-downgraded outcome, verdicts, an annotated summary, and the refined path label ("codebase-read-verified" or "codebase-read-degraded") for logging. No-op when path != "codebase-read".
func EncodeTasks ¶ added in v1.35.0
EncodeTasks serializes a task tree to a JSON string.
func EncryptToken ¶ added in v1.35.0
EncryptToken encrypts plaintext using AES-256-GCM with the given 32-byte key. Returns base64-encoded ciphertext (nonce prepended).
func EnsureDirectorySessionPath ¶ added in v1.35.0
EnsureDirectorySessionPath creates and git-inits path if it does not already exist — the same directory-creation step SessionTypeDirectory takes when CreateIfMissing is set. Callers that need path to exist before spawning a directory session (e.g. to write files into the worktree ahead of the claude process starting) should call this first so the spawn's own CreateIfMissing check finds the directory already present and correctly git-initialized, rather than skipping git-init because the path merely exists.
func ExtractPRURL ¶ added in v1.35.0
ExtractPRURL scans the last 200 lines of sessionOutput for a GitHub PR URL.
func FindConversationFilePath ¶ added in v1.35.0
FindConversationFilePath is the exported wrapper for findConversationFilePath. It searches ~/.claude/projects/ for the JSONL file containing sessionID.
func FindInstanceByHistoryPath ¶ added in v1.35.0
FindInstanceByHistoryPath returns the title of the session whose JSONL history file matches filePath. Returns ("", false) if not found. HistoryFilePath is a public field set by HistoryLinker; safe to read here since this runs on each HistoryLinker callback, which is the same goroutine that sets the field.
func ForkClaudeConversation ¶
ForkClaudeConversation copies the first lineCount non-empty lines from srcConvPath into a new JSONL file named {newUUID}.jsonl inside dstDir. The new UUID is returned so the caller can set it as the forked session's ResumeId.
If lineCount is 0 an empty file is created and the new UUID is still returned. If lineCount exceeds the number of lines in the source all lines are copied without error. If srcConvPath does not exist an error is returned.
func GetGitDiff ¶ added in v1.35.0
func GetGitDiff(ctx context.Context, worktreePath string, baseSHA string) (diff string, truncated bool, err error)
GetGitDiff returns the diff of changes in worktreePath relative to baseSHA (or HEAD~1 if baseSHA is empty). If the diff exceeds MaxDiffSizeReview bytes it is truncated and truncated=true is returned.
dir's own checked-out HEAD is used as the diff target. That's correct when dir is the session's own worktree (HEAD there is the work branch's tip), but wrong when dir is a fallback directory such as the shared main repo checkout (HEAD there is whatever the main checkout has, not the work branch). Callers diffing from a fallback directory must use GetGitDiffRef with an explicit branch name instead.
func GetGitDiffRef ¶ added in v1.37.0
func GetGitDiffRef(ctx context.Context, dir string, baseSHA string, headRef string) (diff string, truncated bool, err error)
GetGitDiffRef is like GetGitDiff but diffs baseSHA..headRef instead of baseSHA..HEAD (headRef == "" behaves exactly like GetGitDiff). Callers must pass an explicit headRef (typically a branch name) when dir isn't the session's own worktree — e.g. diffing a work session's branch from the shared main repo checkout after the session's own worktree directory has been removed. Worktrees share the same object store, so any ref reachable from any worktree of the repo resolves correctly regardless of dir.
func GetGitHeadSHA ¶ added in v1.37.0
GetGitHeadSHA returns the current HEAD commit SHA in the given directory, or "" on any error. Used to capture a base SHA at work session start.
func GetMainRepoPath ¶
GetMainRepoPath uses git rev-parse --git-common-dir to get the main repo path. This is more reliable than parsing the .git file.
func InstanceInfoSlice ¶ added in v1.35.0
func InstanceInfoSlice(instances []*Instance) []artifacts.InstanceInfo
InstanceInfoSlice converts a slice of live Instances to the lightweight InstanceInfo type used by ArtifactExtractor.SeedOffsets.
func IsGitHubURL ¶
IsGitHubURL returns true if the input looks like a GitHub URL or shorthand.
func IsValidTaskStatus ¶ added in v1.35.0
IsValidTaskStatus returns true if s is a recognized task status value.
func IsWorktreeDirty ¶ added in v1.37.0
IsWorktreeDirty returns true if the git worktree at worktreePath has any uncommitted changes (staged or unstaged). Returns false with no error when the worktree is clean or when it cannot be reached.
func ParseHeadlessToolReads ¶ added in v1.38.0
ParseHeadlessToolReads extracts the tool_reads list from a headless LLM JSON response. Returns nil if the field is absent or the JSON doesn't parse.
func ParseHeadlessVerdictResult ¶ added in v1.35.0
func ParseHeadlessVerdictResult(text string) (overall ReviewOutcome, verdicts []CriterionVerdict, summary string)
ParseHeadlessVerdictResult extracts verdict data from a headless LLM JSON response. It searches for the outermost JSON object in text, tolerating prose around it. Returns ReviewOutcomeFail overall if parsing fails or no verdicts are present.
func PortSessionHistory ¶ added in v1.35.0
PortSessionHistory translates and syncs history between Claude Code and Antigravity CLI.
func ReconcileOrphanedTmuxSessions ¶ added in v1.35.0
func ReconcileOrphanedTmuxSessions(instances []*Instance)
ReconcileOrphanedTmuxSessions kills staplersquad_ tmux sessions that have no corresponding record in the current workspace DB.
Orphans accumulate when DeleteSession removes the DB record but the server is restarted before (or while) the live in-memory instance is available — leaving the Claude process running inside a tmux pane with no owner. This sweep is called once during server startup, after all DB sessions have been loaded and re-adopted (steps 6/6b of BuildRuntimeDeps), so there is no risk of killing a session that is mid-adoption.
Identification strategy (two-tier):
- Tmux session has STAPLER_SESSION_UUID env var → compare against known UUIDs.
- No env var (pre-UUID sessions) → compare the tmux session name against known sanitized titles. If neither matches, the session is an orphan.
The staplersquad_keepalive sentinel is always preserved — it keeps the tmux server alive between sessions and is never tracked in the DB.
func RecoverBaseCommitSHA ¶ added in v1.38.0
RecoverBaseCommitSHA attempts to self-heal a base commit SHA that no longer resolves in the repository's object store — the concrete cause found via manual QA on backlog item ae1e2070-db02-4ad7-8580-633ef9904f31, whose worktrees.base_commit_sha was a stale/corrupted 40-char SHA unreachable from any ref, causing every review attempt to see an empty diff and return a false UNVERIFIABLE verdict even though real, complete work was committed on the branch. Recomputes the merge-base of headRef against repoPath's own checked-out HEAD, which is reachable from any worktree of the same repo (worktrees share one object store). Returns an error if headRef itself doesn't resolve either (e.g. the branch was deleted) — that case is not recoverable here and must surface to a human.
func RegisterBackendProvider ¶ added in v1.35.0
func RegisterBackendProvider(backend ProcessManagerBackend)
RegisterBackendProvider sets the backend used by NewProcessManager. Call once at startup, before any session is created.
func ResolveSessionPath ¶ added in v1.35.0
ResolveSessionPath expands a leading "~" to the current user's home directory and converts the result to an absolute path — the same resolution NewInstance applies to InstanceOptions.Path. Callers that need to act on a session's worktree path *before* calling NewInstance (e.g. writing files into it ahead of spawn) must resolve through this function first, or they risk operating on a different path than the one the spawned Instance actually uses.
func ResolvedModeLabel ¶ added in v1.38.0
ResolvedModeLabel renders a raw BacklogItemData.PipelineMode string for PipelineEngine-prefixed log lines: the empty string (PipelineModeDefault) becomes "default" for log readability, any other slug is passed through unchanged. Exported so both server/services (TriggerTriage) and session (ReviewGateRunner.Run) call sites use one shared rendering — see Story 1.7.2's observability acceptance criteria.
func RollbackMigration ¶
RollbackMigration restores the JSON backup and removes the SQLite database
func RunPreGateSecurityCheck ¶ added in v1.35.0
RunPreGateSecurityCheck scans a git diff for obvious secret patterns before sending to the review LLM. Returns a non-nil error if any pattern matches, blocking the review gate from spawning. This is a best-effort check — it does not replace a full secret scanner.
func SanitizeDiff ¶ added in v1.37.0
SanitizeDiff neutralizes triple-backtick sequences in a diff so they cannot close a markdown code fence when the diff is interpolated into an LLM prompt.
func SanitizeForAgentContext ¶ added in v1.35.0
SanitizeForAgentContext strips HTML tags from s and truncates to maxLen, appending " [truncated]" if truncation occurred.
func StartSessionDriver ¶ added in v1.35.0
StartSessionDriver launches a background goroutine that drives the session through its startup dialogs, fires the initial task prompt, and monitors for approval dialogs throughout the session lifetime.
allowedPath is the session's repo/workspace path — directory-access approval dialogs that mention this path are auto-approved.
Calling StartSessionDriver twice on the same instance is safe: the second call is a no-op (the idempotency guard uses atomic.Bool.CompareAndSwap).
func ValidateEntMigration ¶
ValidateEntMigration verifies that all sessions from JSON were successfully migrated to Ent
func ValidatePipelineModeContent ¶ added in v1.38.0
func ValidatePipelineModeContent(fields PipelineModeContentFields) error
ValidatePipelineModeContent enforces Story 2.3.1's structural-integrity invariants at the RPC write boundary, before any repository write occurs:
- If fields.ValidateSlug, fields.Slug must be non-empty and contain only characters in [a-z0-9-].
- None of the 9 content-template fields may contain a raw shell metacharacter from shellMetacharacters (defense in depth).
- Every {{...}} token in every content-template field must name a placeholder in the recognized allow-list (recognizedPlaceholders, declared in pipeline_engine.go and also used by renderTemplate) — an unrecognized token is rejected, naming both the offending field and the unrecognized token.
Returns nil if fields passes all checks.
func ValidateTaskDepth ¶ added in v1.35.0
ValidateTaskDepth validates that the task tree does not exceed maxTaskDepth (3) and that all task statuses are valid enum values. Total task count is checked separately by validateTaskCount (both are called from validateTasks).
func ValidateWorkflowSlug ¶ added in v1.35.0
ValidateWorkflowSlug validates that slug conforms to the workflow slug format: - 2–64 characters - Lowercase alphanumeric with hyphens - No leading/trailing hyphens - No consecutive hyphens
func WriteBacklogContextFile ¶ added in v1.35.0
func WriteBacklogContextFile(item *BacklogItemData, priorSessions []ItemSessionSummary, worktreePath string) error
WriteBacklogContextFile builds the full context prompt and writes it atomically to .backlog-context.md in the worktree root. Appends a fallback instructions block. priorSessions must match what was passed to the live CLI prompt (BuildTokenBudgetedPrompt) so the on-disk fallback the agent re-reads after context compaction doesn't lose history.
func WriteReviewTranscriptFile ¶ added in v1.38.0
func WriteReviewTranscriptFile(sm *scrollback.ScrollbackManager, sessionUUID, codebaseWorkDir string, maxBytes int64) (relPath string, cleanup func(), err error)
WriteReviewTranscriptFile fetches sessionUUID's most recent scrollback, strips ANSI escape sequences, and writes the result to a file inside codebaseWorkDir so a reviewer LLM can search it on demand with its already-granted Read/Grep/Glob tools -- instead of the orchestrator pre-injecting a text blob into the review prompt, which would bloat the prompt/context window regardless of session length.
The returned relPath is relative to codebaseWorkDir (e.g. ".stapler-squad-review-transcript-<uuid>.txt"), so it can be dropped directly into a reviewer prompt template and is treated consistently by containment-checked tool_reads logic the same way as any other path the reviewer cites. cleanup removes the written file and is always safe to call (including when relPath == "", in which case it is a no-op) -- callers should defer cleanup() immediately after a successful call so the file does not linger in the real repo checkout after the review completes.
Fetching scrollback is treated as best-effort enrichment: if the session has no scrollback (never started, expired, or storage error), WriteReviewTranscriptFile returns ("", no-op cleanup, nil) rather than an error, so a missing/expired session's scrollback never blocks a review. A non-nil error is returned only when scrollback WAS available but writing it to disk failed (e.g. codebaseWorkDir unwritable) -- callers may choose to ignore this error too, given the enrichment-only contract.
maxBytes bounds how much stripped transcript is written; pass <= 0 to use DefaultReviewTranscriptMaxBytes. When the stripped transcript exceeds maxBytes, the HEAD is dropped and the tail is kept (most recent activity is most relevant to a reviewer checking final state), prefixed with a truncation marker.
func WriteSlashCommands ¶ added in v1.35.0
func WriteSlashCommands(engine PipelineEngine, item *BacklogItemData, worktreePath string) error
WriteSlashCommands creates the .claude/commands/backlog/ directory and writes per-item slash command markdown files. Retries directory creation up to 3 times.
Content generation is delegated to engine.SlashCommandSet (Epic 1.5, Story 1.5.2) — this function only owns directory creation and the disk-write loop. engine may be nil, in which case content generation falls back to buildDefaultSlashCommandSet directly, matching CachingPipelineEngine's own default-mode behavior; this keeps tests that don't care about PipelineEngine free to pass nil. Both real callers (server/services/backlog_service_triage.go's SpawnSessionFromItem and backlog_service_sync.go's AttachSessionToItem) must pass the SAME shared engine instance (BacklogService.pipelineEngine) — passing two different engines would reintroduce the "2 independent callers can drift" regression this seam closes.
Types ¶
type AcCriteriaJSON ¶ added in v1.37.0
type AcCriteriaJSON = domain.AcCriteriaJSON
AcCriteriaJSON is the JSON-serialized form of []AcCriterion stored in the DB. Type alias — session.AcCriteriaJSON and domain.AcCriteriaJSON are identical types.
func MergeAcCriteria ¶ added in v1.37.0
func MergeAcCriteria(existing []AcCriterion, incoming []AcCriterion) (AcCriteriaJSON, error)
MergeAcCriteria merges incoming criteria into existing by index. Criteria not mentioned in incoming are preserved unchanged. Returns an error if incoming contains duplicate indices.
type AcCriterion ¶ added in v1.35.0
type AcCriterion = domain.AcCriterion
AcCriterion is a single acceptance criterion for a backlog item. Type alias — session.AcCriterion and domain.AcCriterion are identical types.
func MergeLiveCriterionNotes ¶ added in v1.38.0
func MergeLiveCriterionNotes(snapshot, live []AcCriterion) []AcCriterion
MergeLiveCriterionNotes overlays each criterion's live Note and Status (from item.AcceptanceCriteria) onto a possibly-stale snapshot, matched by Index. Fixes staleness where report_progress writes a Note onto the live item after an ItemSession's AcSnapshot was already captured at spawn time.
type AcStatus ¶ added in v1.37.0
AcStatus represents the status of a single acceptance criterion. Type alias — session.AcStatus and domain.AcStatus are identical types.
type ActivityTracking ¶
type ActivityTracking struct {
// LastTerminalUpdate is when the terminal output was last updated
LastTerminalUpdate time.Time `json:"last_terminal_update,omitempty"`
// LastMeaningfulOutput is when meaningful (non-noise) output was detected
LastMeaningfulOutput time.Time `json:"last_meaningful_output,omitempty"`
// LastViewed is when the session was last viewed by the user
LastViewed time.Time `json:"last_viewed,omitempty"`
// LastAcknowledged is when the user last acknowledged session output
LastAcknowledged time.Time `json:"last_acknowledged,omitempty"`
// LastOutputSignature is a hash/signature of the last output for deduplication
LastOutputSignature string `json:"last_output_signature,omitempty"`
// LastAddedToQueue is when the session was last added to the review queue
LastAddedToQueue time.Time `json:"last_added_to_queue,omitempty"`
}
ActivityTracking represents the activity tracking data for a session. This includes timestamps for various events and output tracking.
func (*ActivityTracking) HasRecentActivity ¶
func (a *ActivityTracking) HasRecentActivity(within time.Duration) bool
HasRecentActivity returns true if there has been activity within the specified duration
func (*ActivityTracking) IsEmpty ¶
func (a *ActivityTracking) IsEmpty() bool
IsEmpty returns true if the ActivityTracking has no meaningful data
type AgyAdapter ¶ added in v1.35.0
type AgyAdapter struct{}
func NewAgyAdapter ¶ added in v1.35.0
func NewAgyAdapter() *AgyAdapter
func (*AgyAdapter) CanHandle ¶ added in v1.35.0
func (a *AgyAdapter) CanHandle(program string) bool
func (*AgyAdapter) Export ¶ added in v1.35.0
func (a *AgyAdapter) Export(ctx context.Context, turns []CanonicalTurn, inst *Instance) error
func (*AgyAdapter) Import ¶ added in v1.35.0
func (a *AgyAdapter) Import(ctx context.Context, inst *Instance) ([]CanonicalTurn, error)
func (*AgyAdapter) Name ¶ added in v1.35.0
func (a *AgyAdapter) Name() string
type AnalyticsData ¶ added in v1.12.0
type AnalyticsData struct {
ID string
SessionID string
ToolName string
CommandPreview string
Cwd string
Decision string
RiskLevel string
RuleID string
RuleName string
Reason string
Alternative string
DurationMs int64
ApprovalID string
CommandProgram string
CommandCategory string
CommandSubcategory string
PythonImports []string
CreatedAt time.Time
}
AnalyticsData is the domain model for classification analytics.
type ApprovalAutomation ¶
type ApprovalAutomation struct {
// contains filtered or unexported fields
}
ApprovalAutomation orchestrates automatic approval handling.
Lock ordering (must always be acquired in this order):
mu > queueMu > subMu
func NewApprovalAutomation ¶
func NewApprovalAutomation(sessionName string, controller *ClaudeController) *ApprovalAutomation
NewApprovalAutomation creates a new approval automation system.
func (*ApprovalAutomation) GetDetector ¶
func (aa *ApprovalAutomation) GetDetector() *detection.ApprovalDetector
GetDetector returns the approval detector for configuration.
func (*ApprovalAutomation) GetPendingApprovals ¶
func (aa *ApprovalAutomation) GetPendingApprovals() []*PendingApproval
GetPendingApprovals returns all approvals awaiting user response.
func (*ApprovalAutomation) GetPolicyEngine ¶
func (aa *ApprovalAutomation) GetPolicyEngine() *PolicyEngine
GetPolicyEngine returns the policy engine for configuration.
func (*ApprovalAutomation) GetSessionName ¶
func (aa *ApprovalAutomation) GetSessionName() string
GetSessionName returns the session name.
func (*ApprovalAutomation) IsRunning ¶
func (aa *ApprovalAutomation) IsRunning() bool
IsRunning returns whether the automation is currently running.
func (*ApprovalAutomation) RespondToApproval ¶
func (aa *ApprovalAutomation) RespondToApproval(requestID string, approved bool, userInput string, options ApprovalAutomationOptions) error
RespondToApproval processes a user response to a pending approval.
func (*ApprovalAutomation) Start ¶
func (aa *ApprovalAutomation) Start(ctx context.Context, options ApprovalAutomationOptions) error
Start begins the approval automation processing loop.
func (*ApprovalAutomation) Stop ¶
func (aa *ApprovalAutomation) Stop() error
Stop halts the approval automation system.
func (*ApprovalAutomation) Subscribe ¶
func (aa *ApprovalAutomation) Subscribe(subscriberID string) <-chan ApprovalEvent
Subscribe creates a subscription for approval events.
func (*ApprovalAutomation) Unsubscribe ¶
func (aa *ApprovalAutomation) Unsubscribe(subscriberID string)
Unsubscribe removes a subscription.
type ApprovalAutomationOptions ¶
type ApprovalAutomationOptions struct {
AutoExecute bool // Automatically execute approved commands
UserTimeout time.Duration // Time to wait for user response
ProcessingDelay time.Duration // Delay between processing approvals
MaxQueueSize int // Maximum pending approvals
EnableAuditLog bool // Log all approval actions
}
ApprovalAutomationOptions configures approval automation behavior.
func DefaultApprovalAutomationOptions ¶
func DefaultApprovalAutomationOptions() ApprovalAutomationOptions
DefaultApprovalAutomationOptions returns sensible defaults.
type ApprovalEvent ¶
type ApprovalEvent struct {
Type ApprovalEventType
Request *detection.ApprovalRequest
Decision *PolicyDecision
Timestamp time.Time
Details string
}
ApprovalEvent represents an event in the approval automation system.
type ApprovalEventType ¶
type ApprovalEventType string
ApprovalEventType categorizes approval events.
const ( EventDetected ApprovalEventType = "detected" EventAutoApproved ApprovalEventType = "auto_approved" EventAutoRejected ApprovalEventType = "auto_rejected" EventAwaitingUser ApprovalEventType = "awaiting_user" EventUserApproved ApprovalEventType = "user_approved" EventUserRejected ApprovalEventType = "user_rejected" EventExpired ApprovalEventType = "expired" EventExecuted ApprovalEventType = "executed" EventExecutionFail ApprovalEventType = "execution_failed" )
type ApprovalMetadata ¶
type ApprovalMetadata struct {
ApprovalID string
ToolName string
ToolInput map[string]interface{}
Cwd string
Orphaned bool
}
ApprovalMetadata holds metadata about a pending approval for enriching review queue items.
type ApprovalMetadataProvider ¶
type ApprovalMetadataProvider interface {
// GetApprovalMetadataBySession returns approval metadata for the given session ID.
// Returns nil if no approvals exist for the session.
GetApprovalMetadataBySession(sessionID string) []ApprovalMetadata
}
ApprovalMetadataProvider provides approval metadata for enriching review queue items. This interface decouples the poller (session package) from the ApprovalStore (services package).
type ApprovalPolicy ¶
type ApprovalPolicy struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
ApprovalTypes []detection.ApprovalType `json:"approval_types"` // Types this policy applies to
Enabled bool `json:"enabled"`
Priority int `json:"priority"` // Higher priority policies checked first
Conditions []PolicyCondition `json:"conditions"` // All must match
Action PolicyAction `json:"action"` // What to do when matched
TimeRestriction *TimeRestriction `json:"time_restriction,omitempty"`
UsageLimit *UsageLimit `json:"usage_limit,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// contains filtered or unexported fields
}
ApprovalPolicy defines a rule for automatic approval.
func CreateBusinessHoursPolicy ¶
func CreateBusinessHoursPolicy() *ApprovalPolicy
CreateBusinessHoursPolicy creates a policy that only applies during business hours.
func CreateNoDestructivePolicy ¶
func CreateNoDestructivePolicy() *ApprovalPolicy
CreateNoDestructivePolicy creates a policy for rejecting destructive commands.
func CreateSafeCommandPolicy ¶
func CreateSafeCommandPolicy() *ApprovalPolicy
CreateSafeCommandPolicy creates a policy for automatically approving safe commands.
type ApprovalRuleData ¶ added in v1.12.0
type ApprovalRuleData struct {
ID string
Name string
ToolName string
ToolPattern string
ToolCategory string
CommandPattern string
FilePattern string
Decision int
RiskLevel int
Reason string
Alternative string
Priority int
Enabled bool
Source string
CreatedAt time.Time
UpdatedAt time.Time
// Structured CommandCriteria fields — correspond to classifier.CommandCriteria.
Programs []string
Subcommands []string
BlockedSubcommands []string
RequiredFlags []string
ForbiddenFlags []string
RequiredFlagPrefixes []string
PythonModes []string
SafePythonImportsOnly bool
}
ApprovalRuleData is the domain model for an auto-approval rule.
type AttentionReason ¶
type AttentionReason = queue.AttentionReason
AttentionReason re-export
func AttentionReasonFromDetected ¶
func AttentionReasonFromDetected(detected detection.DetectedStatus) AttentionReason
AttentionReasonFromDetected maps a DetectedStatus to the AttentionReason that should be used when adding the session to the review queue. Returns the zero AttentionReason (empty string) when no attention is needed for that status.
type AutoReopenSpawner ¶ added in v1.37.0
type AutoReopenSpawner interface {
AutoReopenAfterFailedReview(ctx context.Context, itemID string) error
}
AutoReopenSpawner can automatically reopen a backlog item for rework after a failed review verdict (FAIL or PARTIAL). It transitions the item back to in_progress and spawns a new work session so the review→rework cycle is fully automated.
type AutonomousDriver ¶ added in v1.35.0
type AutonomousDriver struct {
// contains filtered or unexported fields
}
AutonomousDriver monitors a session and injects orchestrator prompts when idle.
func NewAutonomousDriver ¶ added in v1.35.0
func NewAutonomousDriver(inst *Instance, pool HeadlessPoolClient, goal string, maxTurns int, opts ...DriverOption) *AutonomousDriver
NewAutonomousDriver creates an AutonomousDriver for inst. pool must not be nil; maxTurns ≤ 0 defaults to 20. Use functional options (e.g. WithStartupTimeout) to override defaults.
func (*AutonomousDriver) RegisterCompletionCallback ¶ added in v1.35.0
func (d *AutonomousDriver) RegisterCompletionCallback(cb CompletionCallback)
RegisterCompletionCallback sets the function called when the driver exits.
func (*AutonomousDriver) RegisterTurnCallback ¶ added in v1.35.0
func (d *AutonomousDriver) RegisterTurnCallback(cb TurnCallback)
RegisterTurnCallback sets the function called after each prompt injection.
func (*AutonomousDriver) Start ¶ added in v1.35.0
func (d *AutonomousDriver) Start(ctx context.Context) error
Start begins the autonomous driver goroutine. The second call is a no-op.
func (*AutonomousDriver) Stop ¶ added in v1.35.0
func (d *AutonomousDriver) Stop()
Stop cancels the driver goroutine. Context cancellation propagates into CallBlocking: the headless pool passes ctx to runner.Run (which kills the subprocess) and the stream reader selects on ctx.Done, so Stop returns control to the caller nearly immediately — no blocking LLM call delay.
type AutonomousDriverOutcome ¶ added in v1.35.0
type AutonomousDriverOutcome struct {
Done bool
Reason string
PRUrl string
Turns int
Stuck bool // true if exited via maxTurns without DONE signal
}
AutonomousDriverOutcome describes how an autonomous driver run concluded.
type AutonomousModeState ¶ added in v1.35.0
type AutonomousModeState struct {
AutonomousMode bool
AutonomousTurn int32
AutonomousMaxTurns int32
AutonomousOutcome string
}
AutonomousModeState groups all autonomous-mode fields within InstanceSnapshot (CDD Epic 3, Task 3.1b). Access via snap.Autonomous.AutonomousMode etc.
type AvailableTargets ¶
type AvailableTargets struct {
VCSType string
Bookmarks []BookmarkTarget
RecentRevisions []RevisionTarget
Worktrees []WorktreeTarget
}
AvailableTargets contains the available workspace switch targets
type BacklogController ¶ added in v1.35.0
type BacklogController struct {
// contains filtered or unexported fields
}
BacklogController implements services.FeatureController for the backlog feature. It enables/disables the BacklogLifecycleListener and SyncLoop at runtime without requiring a server restart.
Enable/Disable are safe to call concurrently.
func NewBacklogController ¶ added in v1.35.0
func NewBacklogController( listener *BacklogLifecycleListener, storage *Storage, registry *PluginRegistry, keyFunc func() ([]byte, error), ) *BacklogController
NewBacklogController creates a controller that manages the given listener. storage, registry, and keyFunc are used to create a new SyncLoop on Enable.
func (*BacklogController) Disable ¶ added in v1.35.0
func (c *BacklogController) Disable() error
Disable deactivates the backlog feature: sets listener disabled and stops the sync loop. Idempotent — calling Disable when already disabled is a no-op.
func (*BacklogController) Enable ¶ added in v1.35.0
func (c *BacklogController) Enable(_ context.Context) error
Enable activates the backlog feature: sets listener enabled and starts the sync loop. Idempotent — calling Enable when already enabled is a no-op.
func (*BacklogController) IsEnabled ¶ added in v1.35.0
func (c *BacklogController) IsEnabled() bool
IsEnabled reports whether the backlog feature is currently active.
type BacklogItemData ¶ added in v1.35.0
type BacklogItemData struct {
ID string
Title string
Description string
AcceptanceCriteria AcCriteriaJSON
Priority int
Status string
RepoPath string
SkipReviewGate bool
SkipPlanning bool
AutoSpawnSession bool
// PipelineMode is the slug of the PipelineMode this item uses to drive
// triage/work/review content (see session/pipeline_engine.go). Empty
// string (PipelineModeDefault) means the built-in, hardcoded pipeline.
//
// Scope note: this field is introduced in Epic 1.3 (backlog-configurable-
// pipeline) solely so PipelineEngine's mode-resolution/fail-closed
// behavior is exercisable against this struct per Story 1.3.3's own
// acceptance criteria. It is NOT yet wired to ent/proto/the repository
// persistence layer or any RPC handler — every BacklogItemData produced
// by the current storage layer has PipelineMode == "" today. That full
// wiring (ent schema field, proto optional field, repository Create/
// Update mapping, RPC handler presence-gating) is Epic 1.4's scope.
PipelineMode string
PlanApproved bool
PlanApprovedAt *time.Time
PlanArtifactsPath string
Notes string
ExternalID string
ArchivedAt *time.Time
SourceID string
PrURL string
PrNumber int
CreatedAt time.Time
UpdatedAt time.Time
// ItemSessions holds the eagerly-loaded item sessions for this backlog item.
// Only populated when explicitly loaded by the caller (e.g. GetBacklogItem).
ItemSessions []ItemSessionSummary
// StatusEvents holds the eagerly-loaded status transition history.
// Only populated when explicitly loaded by the caller (e.g. GetBacklogItem).
StatusEvents []BacklogStatusEventData
}
BacklogItemData is the domain model for a backlog item.
type BacklogItemFilter ¶ added in v1.35.0
type BacklogItemFilter struct {
// Statuses restricts results to these statuses. Empty means no restriction.
Statuses []string
// Priorities restricts results to these priority values. Empty means no restriction.
Priorities []int
// SortBy controls ordering ("priority", "updated_at"). Empty means default ordering.
SortBy string
// ExcludeTerminal, when true, excludes items with status "done" or "archived".
ExcludeTerminal bool
// Limit caps the number of results returned. 0 means use the default safety cap (1000).
Limit int
// Offset skips the first N results (for pagination). Only applied when Limit > 0.
Offset int
}
BacklogItemFilter controls which items ListBacklogItems returns.
type BacklogItemPrecondition ¶ added in v1.35.0
type BacklogItemPrecondition struct {
// ExpectedStatus, if non-empty, requires the item's current status to match.
ExpectedStatus string
// ExpectedUpdatedAt, if non-zero, requires the item's updated_at to match.
ExpectedUpdatedAt *time.Time
// Note, if non-empty, is stored in the status event audit log alongside this
// transition. Use it to record why the transition happened (e.g. "auto-reopened
// after FAIL verdict").
Note string
}
BacklogItemPrecondition is used for optimistic locking on update/transition.
type BacklogItemSummary ¶ added in v1.37.0
type BacklogItemSummary struct {
ID string `json:"id"`
ExternalID string `json:"external_id"`
Title string `json:"title"`
Status BacklogStatus `json:"status"`
Priority int `json:"priority"`
RepoPath string `json:"repo_path"`
AcceptanceCriteria AcCriteriaJSON `json:"acceptance_criteria"`
Notes string `json:"notes"`
PrURL string `json:"pr_url"`
PrNumber int `json:"pr_number"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ArchivedAt *time.Time `json:"archived_at"`
ItemSessions []ItemSessionSummary `json:"-"`
}
BacklogItemSummary is a lightweight projection of BacklogItemData for list views. It omits large text fields (Description, plan artifacts) and status-event history, but eagerly includes ItemSessions (with ReviewVerdict) for cost/status display.
type BacklogItemTransitionInput ¶ added in v1.35.0
type BacklogItemTransitionInput = domain.BacklogItemTransitionInput
BacklogItemTransitionInput carries the fields needed by TransitionGuard. Type alias — session.BacklogItemTransitionInput and domain.BacklogItemTransitionInput are identical types.
type BacklogItemUpdate ¶ added in v1.35.0
type BacklogItemUpdate struct {
Title *string
Description *string
AcceptanceCriteria *AcCriteriaJSON
Priority *int
RepoPath *string
SkipReviewGate *bool
SkipPlanning *bool
AutoSpawnSession *bool
// PipelineMode is a pointer for partial-update presence: nil means "leave
// the item's stored pipeline_mode untouched", while a non-nil pointer
// (including one pointing at "") explicitly sets/resets it. See
// BacklogItemData.PipelineMode for the field's semantics.
PipelineMode *string
Notes *string
PlanApproved *bool
PlanApprovedAt *time.Time
PlanArtifactsPath *string
PrURL *string
PrNumber *int
}
BacklogItemUpdate carries the mutable fields for UpdateBacklogItem.
type BacklogLifecycleListener ¶ added in v1.35.0
type BacklogLifecycleListener struct {
// contains filtered or unexported fields
}
BacklogLifecycleListener drives backlog item state transitions in response to session lifecycle events. It must be registered via Instance.RegisterLifecycleListener.
OnLifecycleEvent is non-blocking; all DB work is dispatched to a goroutine. Call SetEnabled(false) to make all callbacks no-ops without unwiring.
func NewBacklogLifecycleListener ¶ added in v1.35.0
func NewBacklogLifecycleListener(storage *Storage) *BacklogLifecycleListener
NewBacklogLifecycleListener creates a listener backed by the given storage. The review gate is disabled (sessionCreator=nil, headlessPool=nil). No PipelineEngine is wired (nil) — callers needing one should use NewBacklogLifecycleListenerWithPool.
func NewBacklogLifecycleListenerWithPool ¶ added in v1.35.0
func NewBacklogLifecycleListenerWithPool(storage *Storage, pool *headless.Pool, pipelineEngine PipelineEngine) *BacklogLifecycleListener
NewBacklogLifecycleListenerWithPool creates a listener that uses a headless.Pool for review gate calls instead of spawning a tmux session. pipelineEngine is the shared PipelineEngine instance (Epic 1.5, Story 1.5.1) — pass nil to fall back to the built-in default pipeline for every item.
func NewBacklogLifecycleListenerWithSpawner ¶ added in v1.35.0
func NewBacklogLifecycleListenerWithSpawner(storage *Storage, spawner ReviewGateSpawner) *BacklogLifecycleListener
NewBacklogLifecycleListenerWithSpawner creates a listener that will spawn a review gate session when a work session exits and SkipReviewGate is false.
func (*BacklogLifecycleListener) BackfillStuckStates ¶ added in v1.38.0
func (l *BacklogLifecycleListener) BackfillStuckStates(ctx context.Context)
BackfillStuckStates seeds durable BacklogStuckState rows for items that are already stuck at startup, with notified_at pre-set, so the first genuine reconcile tick after a restart/deploy does not re-notify for conditions that were already known (and already surfaced) before the restart. Intended to be called once, before the reconcile ticker goroutine starts. Idempotent via MarkStuck's (item_id, reason) unique-constraint upsert — safe to call on every startup, not just the first one. Best-effort throughout: query/write failures are logged, never returned — backfill must never block startup.
Scope note: only the two DB-derivable reasons that already have a queryable detection surface as of this Epic are seeded — abandoned_review (via the existing FindStuckReviewItems query) and stale_work (mirroring reconcileStaleWorkSessions' maxWorkSessionStaleness check, without modifying that function). rework_cap, bouncing, and push_failed are deliberately NOT seeded here: their detection logic is introduced by Phase 2 (Stories 2.1.2, 2.1.4, 2.1.6 respectively) and does not exist yet in this Epic — seeding them now would mean fabricating that not-yet-built detection logic ahead of schedule. Once Phase 2 ships those detectors, their own MarkStuck/MarkStuckNotified notify-once dedup naturally covers the "first tick after shipping" storm-suppression case for those three reasons at that time, the same way this backfill does for the two reasons seeded today.
pr_ready_unmerged is excluded for a different reason: detecting it needs a GetPRStatus/IsPRMerged GitHub call per pr_pending item, which would burst the GitHub API on every one of the 15+ daily boots. The first genuine tick after startup surfaces it via its own notified_at IS NULL + 30-min gate — a one-tick delay, not a startup API burst.
func (*BacklogLifecycleListener) PipelineEngine ¶ added in v1.38.0
func (l *BacklogLifecycleListener) PipelineEngine() PipelineEngine
PipelineEngine returns the PipelineEngine injected at construction (nil if none was wired). Exported for the pointer-equality integration test proving BacklogService and BacklogLifecycleListener share a single PipelineEngine instance (Story 1.5.1).
func (*BacklogLifecycleListener) ReconcilePRPending ¶ added in v1.37.0
func (l *BacklogLifecycleListener) ReconcilePRPending(ctx context.Context, er *EntRepository)
ReconcilePRPending polls items in pr_pending status. It transitions to done when the PR is merged, and spawns a fix session when CI fails or reviewers request changes.
func (*BacklogLifecycleListener) ReconcileStuck ¶ added in v1.35.0
func (l *BacklogLifecycleListener) ReconcileStuck(ctx context.Context)
ReconcileStuck calls ReconcileStuckItems and logs the result. Intended to be called on a periodic ticker as a safety net for abnormal session exits. No-op when the listener is disabled.
func (*BacklogLifecycleListener) SetAutoReopener ¶ added in v1.37.0
func (l *BacklogLifecycleListener) SetAutoReopener(r AutoReopenSpawner)
SetAutoReopener wires in the spawner used to automatically reopen items for rework when a review verdict is FAIL or PARTIAL.
func (*BacklogLifecycleListener) SetEnabled ¶ added in v1.35.0
func (l *BacklogLifecycleListener) SetEnabled(v bool)
SetEnabled toggles whether this listener processes lifecycle events. Safe to call concurrently.
func (*BacklogLifecycleListener) SetHeadlessPool ¶ added in v1.35.0
func (l *BacklogLifecycleListener) SetHeadlessPool(p *headless.Pool)
SetHeadlessPool wires in the headless LLM pool after construction. Calling this enables the headless review gate path even when the listener was created via NewBacklogLifecycleListenerWithSpawner.
func (*BacklogLifecycleListener) SetNotifier ¶ added in v1.37.0
func (l *BacklogLifecycleListener) SetNotifier(n Notifier)
SetNotifier wires in the notifier used to publish operator-facing notifications (PR creation failures, security blocks, stale work sessions, rework-cap hits). Optional — nil means notifications are disabled.
func (*BacklogLifecycleListener) SetPRCreatorFactory ¶ added in v1.37.0
func (l *BacklogLifecycleListener) SetPRCreatorFactory(f func(repoPath, worktreePath, sessionName, branchName, baseCommitSHA string) prCreator)
SetPRCreatorFactory overrides the factory used to construct the push/PR-creation client for pushAndCreatePR. Overridable in tests; production code never needs to call this, since newListenerBase installs defaultPRCreatorFactory.
func (*BacklogLifecycleListener) SetPRFixSpawner ¶ added in v1.37.0
func (l *BacklogLifecycleListener) SetPRFixSpawner(s PRFixSpawner)
SetPRFixSpawner wires in the spawner used to automatically reopen pr_pending items for rework when CI checks fail or reviewers request changes.
func (*BacklogLifecycleListener) SetPRPendingCheckerFactory ¶ added in v1.37.0
func (l *BacklogLifecycleListener) SetPRPendingCheckerFactory(f func(repoPath string) prPendingChecker)
SetPRPendingCheckerFactory overrides the factory used to construct the PR-status checker for ReconcilePRPending. Overridable in tests (mirrors the timeNow seam in instance_workspace.go:581); production code never needs to call this, since newListenerBase installs defaultPRPendingCheckerFactory.
func (*BacklogLifecycleListener) SetSessionCreator ¶ added in v1.38.0
func (l *BacklogLifecycleListener) SetSessionCreator(s ReviewGateSpawner)
SetSessionCreator wires in the spawner used to create review-gate sessions after construction. Needed because production wiring (server/dependencies.go) constructs this listener before SessionService exists.
func (*BacklogLifecycleListener) SetSessionLivenessChecker ¶ added in v1.38.0
func (l *BacklogLifecycleListener) SetSessionLivenessChecker(f func(sessionUUID string) bool)
SetSessionLivenessChecker wires the function used by the zombie-session review detector (pre-mortem F3) to confirm whether a session's underlying tmux/CLI process is actually still alive, rather than trusting the DB's EndedAt IS NULL row alone. Optional — nil means the zombie detector never flags (conservative: unknown liveness is treated as "assume alive").
func (*BacklogLifecycleListener) Shutdown ¶ added in v1.35.0
func (l *BacklogLifecycleListener) Shutdown()
Shutdown cancels in-flight review gate calls. Safe to call concurrently.
func (*BacklogLifecycleListener) TriggerReviewForSession ¶ added in v1.37.0
func (l *BacklogLifecycleListener) TriggerReviewForSession(workSessionUUID string)
TriggerReviewForSession immediately spawns a review gate for the work session identified by workSessionUUID. Used by the autonomous driver to trigger review as soon as the driver signals DONE, rather than waiting for ReconcileStuck. No-op if the listener is disabled or no review mechanism is configured.
func (*BacklogLifecycleListener) WireToInstance ¶ added in v1.35.0
func (l *BacklogLifecycleListener) WireToInstance(inst *Instance)
WireToInstance creates a per-instance listener shim and registers it on inst. Call this for every Instance that should participate in backlog lifecycle tracking.
type BacklogStatus ¶ added in v1.35.0
type BacklogStatus = domain.BacklogStatus
BacklogStatus represents the lifecycle state of a backlog item. Type alias — session.BacklogStatus and domain.BacklogStatus are identical types; all existing callers continue to work without any import changes.
type BacklogStatusEventData ¶ added in v1.37.0
type BacklogStatusEventData struct {
ID string
FromStatus string
ToStatus string
TriggeredBy string
Note *string
CreatedAt time.Time
}
BacklogStatusEventData is the domain DTO replacing *ent.BacklogStatusEvent in Storage returns.
type BookmarkTarget ¶
BookmarkTarget represents a bookmark/branch as a switch target
type CDPStreamManager ¶ added in v1.35.0
type CDPStreamManager = cdp.CDPStreamManager
CDPStreamManager is a local alias for the cdp package interface so that files within the session package can reference it without importing cdp directly.
type CachingPipelineEngine ¶ added in v1.38.0
type CachingPipelineEngine struct {
// contains filtered or unexported fields
}
CachingPipelineEngine is the single concrete implementation of PipelineEngine. PipelineModeDefault resolves for free (no cache/DB touch); any other slug resolves via pipelineModeCache; any unresolvable/malformed slug falls back to the default behavior and emits exactly one PipelineEngine-prefixed Warn log line naming the item and the unresolved slug (never a silent no-op, never a panic) — see Story 1.3.3's fail-closed acceptance criteria.
func NewPipelineEngine ¶ added in v1.38.0
func NewPipelineEngine(repo PipelineModeRepository) (*CachingPipelineEngine, error)
NewPipelineEngine constructs a CachingPipelineEngine backed by repo, doing one synchronous cache.Load at construction time.
Unlike NewDefaultWorkflowEngine's zero-arg, infallible, pure in-memory construction, this constructor performs a real DB call and can fail (DB unavailable, migration race, transient connection error). Per plan.md's Risk Control section ("NewPipelineEngine startup-failure behavior"), a cache.Load failure here NEVER aborts construction: it is logged at Warn and NewPipelineEngine returns a valid, usable engine backed by an empty cache. The signature still returns an error for future-proofing (e.g. a future validation error genuinely worth failing construction on), but this Phase 1 implementation never returns a non-nil error for a cache.Load failure specifically — PipelineEngine is purely additive/opt-in, so a transient DB hiccup at boot must never crash the whole server for a feature most items don't use yet.
func (*CachingPipelineEngine) ContentHashFor ¶ added in v1.38.0
func (e *CachingPipelineEngine) ContentHashFor(mode PipelineMode) (string, bool)
ContentHashFor implements PipelineEngine.
No Warn log is emitted for an unresolved slug here — documented exemption: this method is only ever called from the Epic 1.6 snapshot-write path immediately after a successful resolution already logged its own outcome via one of the 4 methods above; a caller invoking ContentHashFor for an already-unresolved slug independently of that flow would be a pre-existing bug elsewhere, not a new failure mode worth logging again here.
func (*CachingPipelineEngine) InitialPromptFor ¶ added in v1.38.0
func (e *CachingPipelineEngine) InitialPromptFor(item *BacklogItemData, priorSessions []ItemSessionSummary) string
InitialPromptFor implements PipelineEngine.
func (*CachingPipelineEngine) InvalidateCache ¶ added in v1.38.0
func (e *CachingPipelineEngine) InvalidateCache(ctx context.Context) error
InvalidateCache re-fetches enabled pipeline modes from the repository and swaps the cache wholesale. Exported for the RPC write handlers (Epic 2.2) that must invalidate the cache after every Create/Update/Delete/Enable/ Disable of a PipelineMode. Not yet called by any production code path in this epic — added now because it is cheap and Epic 2.2 needs it.
func (*CachingPipelineEngine) ReviewPromptFor ¶ added in v1.38.0
func (e *CachingPipelineEngine) ReviewPromptFor(item *BacklogItemData, acSnapshot []AcCriterion, diff string, diffTruncated bool, verificationNotes string, extras ReviewContextExtras) string
ReviewPromptFor implements PipelineEngine.
Deviation from plan.md's Story 1.3.1 interface text: an extras ReviewContextExtras parameter was added. BuildHeadlessReviewPrompt requires it (PriorSessions/ProgressNotes/ItemDescription), and the real call sites this engine replaces (session/review_gate.go, backlog_service_triage.go's TriggerReReview) always populate it — dropping it silently would have been a real behavior regression on the default path, not just an interface nicety. Epic 1.5's call sites should pass their real extras value here.
func (*CachingPipelineEngine) SlashCommandSet ¶ added in v1.38.0
func (e *CachingPipelineEngine) SlashCommandSet(item *BacklogItemData) (map[string]string, error)
SlashCommandSet implements PipelineEngine.
func (*CachingPipelineEngine) TriagePromptFor ¶ added in v1.38.0
func (e *CachingPipelineEngine) TriagePromptFor(item *BacklogItemData, artifactAbsPath string) string
TriagePromptFor implements PipelineEngine.
type CanonicalBlock ¶ added in v1.35.0
type CanonicalBlock struct {
Kind CanonicalBlockKind `json:"kind"`
Text string `json:"text,omitempty"`
ToolID string `json:"tool_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
ToolArgs json.RawMessage `json:"tool_args,omitempty"`
ToolResultID string `json:"tool_result_id,omitempty"`
ToolResultContent string `json:"tool_result_content,omitempty"`
ToolResultIsError bool `json:"tool_result_is_error,omitempty"`
}
func NewTextBlock ¶ added in v1.35.0
func NewTextBlock(text string) CanonicalBlock
NewTextBlock constructs a valid CanonicalBlock of text kind.
func NewThinkingBlock ¶ added in v1.35.0
func NewThinkingBlock(text string) CanonicalBlock
NewThinkingBlock constructs a valid CanonicalBlock of thinking kind.
func NewToolResultBlock ¶ added in v1.35.0
func NewToolResultBlock(id, name, content string, isError bool) CanonicalBlock
NewToolResultBlock constructs a valid CanonicalBlock of tool_result kind.
func NewToolUseBlock ¶ added in v1.35.0
func NewToolUseBlock(id, name string, args json.RawMessage) CanonicalBlock
NewToolUseBlock constructs a valid CanonicalBlock of tool_use kind.
func (CanonicalBlock) Validate ¶ added in v1.35.0
func (b CanonicalBlock) Validate() error
Validate checks if the block is in a valid state.
type CanonicalBlockKind ¶ added in v1.35.0
type CanonicalBlockKind string
const ( BlockKindText CanonicalBlockKind = "text" BlockKindThinking CanonicalBlockKind = "thinking" BlockKindToolUse CanonicalBlockKind = "tool_use" BlockKindToolResult CanonicalBlockKind = "tool_result" BlockKindImage CanonicalBlockKind = "image" )
type CanonicalRole ¶ added in v1.35.0
type CanonicalRole string
const ( RoleUser CanonicalRole = "user" RoleAssistant CanonicalRole = "assistant" )
type CanonicalTurn ¶ added in v1.35.0
type CanonicalTurn struct {
Role CanonicalRole `json:"role"`
Blocks []CanonicalBlock `json:"blocks"`
Timestamp time.Time `json:"timestamp"`
TurnIndex int `json:"turn_index"`
Model string `json:"model,omitempty"`
}
func (CanonicalTurn) Validate ¶ added in v1.35.0
func (t CanonicalTurn) Validate() error
Validate checks if the turn and all of its blocks are in a valid state.
type Checkpoint ¶
type Checkpoint struct {
ID string `json:"id"`
SessionID string `json:"session_id"`
ParentID string `json:"parent_id,omitempty"`
Label string `json:"label"`
ScrollbackSeq uint64 `json:"scrollback_seq"`
ScrollbackPath string `json:"scrollback_path,omitempty"`
ClaudeConvUUID string `json:"claude_conv_uuid,omitempty"`
// ConvLineCount is the number of JSONL lines in the Claude conversation file at
// checkpoint time. Used by ForkClaudeConversation to truncate the fork correctly.
ConvLineCount uint64 `json:"conv_line_count,omitempty"`
GitCommitSHA string `json:"git_commit_sha,omitempty"`
Timestamp time.Time `json:"timestamp"`
// New: CLI-agnostic checkpoint details.
CanonicalTurnIndex int `json:"canonical_turn_index,omitempty"`
CanonicalPath string `json:"canonical_path,omitempty"`
}
Checkpoint represents a named bookmark of a session's state at a point in time. It captures the scrollback position, git SHA, and conversation UUID so that the session can later be forked or restored from this exact state.
type CheckpointList ¶
type CheckpointList []Checkpoint
CheckpointList is a slice of Checkpoints with helper methods.
func (CheckpointList) FindByID ¶
func (cl CheckpointList) FindByID(id string) *Checkpoint
FindByID returns the Checkpoint with the given ID, or nil if not found.
func (CheckpointList) FindByLabel ¶
func (cl CheckpointList) FindByLabel(label string) *Checkpoint
FindByLabel returns the first Checkpoint with the given label, or nil if not found.
func (CheckpointList) Latest ¶
func (cl CheckpointList) Latest() *Checkpoint
Latest returns the Checkpoint with the most recent Timestamp, or nil if empty.
type CircularBuffer ¶
type CircularBuffer struct {
// contains filtered or unexported fields
}
CircularBuffer is a thread-safe circular buffer with automatic disk fallback when the in-memory buffer fills up. This prevents memory overflow while maintaining a history of PTY output for status detection and debugging.
func NewCircularBuffer ¶
func NewCircularBuffer(size int) *CircularBuffer
NewCircularBuffer creates a new circular buffer with the specified size in bytes. When the buffer fills up, old data is automatically overwritten (circular behavior).
func (*CircularBuffer) Cap ¶
func (cb *CircularBuffer) Cap() int
Cap returns the total capacity of the buffer.
func (*CircularBuffer) Clear ¶
func (cb *CircularBuffer) Clear()
Clear resets the buffer to empty state.
func (*CircularBuffer) Close ¶
func (cb *CircularBuffer) Close() error
Close releases resources used by the circular buffer. If disk fallback is enabled, it removes the disk file.
func (*CircularBuffer) DisableDiskFallback ¶
func (cb *CircularBuffer) DisableDiskFallback() error
DisableDiskFallback disables disk fallback and removes the disk file.
func (*CircularBuffer) EnableDiskFallback ¶
func (cb *CircularBuffer) EnableDiskFallback(diskPath string) error
EnableDiskFallback enables automatic disk fallback when buffer is full. The diskPath parameter specifies where to store overflow data. This feature is currently a placeholder for future implementation.
func (*CircularBuffer) GetAll ¶
func (cb *CircularBuffer) GetAll() []byte
GetAll returns all data currently in the buffer. Returns a copy to prevent concurrent modification issues.
func (*CircularBuffer) GetRecent ¶
func (cb *CircularBuffer) GetRecent(n int) []byte
GetRecent returns the last n bytes from the buffer. If n is larger than the buffer size or the available data, returns all available data.
func (*CircularBuffer) GetRecentHash ¶ added in v1.37.0
func (cb *CircularBuffer) GetRecentHash(n int) (uint64, bool)
GetRecentHash returns the murmur3-64 hash of the last n bytes without allocating a copy. Returns (0, false) when the buffer has no data. In the common case (contiguous tail segment), this is allocation-free. Only the rare wrapped case allocates via murmur3.New64().
func (*CircularBuffer) GetRecentInto ¶ added in v1.37.0
func (cb *CircularBuffer) GetRecentInto(dst []byte, n int) int
GetRecentInto copies the last n bytes into dst and returns the number of bytes written. dst must have length >= n. Returns 0 when the buffer is empty. Prefer over GetRecent when the caller can provide a pooled buffer.
func (*CircularBuffer) Len ¶
func (cb *CircularBuffer) Len() int
Len returns the number of bytes currently in the buffer.
func (*CircularBuffer) TotalBytesWritten ¶ added in v1.35.0
func (cb *CircularBuffer) TotalBytesWritten() int64
TotalBytesWritten returns the total bytes ever written to this buffer (monotonically increasing).
type ClaudeAdapter ¶ added in v1.35.0
type ClaudeAdapter struct{}
func NewClaudeAdapter ¶ added in v1.35.0
func NewClaudeAdapter() *ClaudeAdapter
func (*ClaudeAdapter) CanHandle ¶ added in v1.35.0
func (a *ClaudeAdapter) CanHandle(program string) bool
func (*ClaudeAdapter) Export ¶ added in v1.35.0
func (a *ClaudeAdapter) Export(ctx context.Context, turns []CanonicalTurn, inst *Instance) error
func (*ClaudeAdapter) Import ¶ added in v1.35.0
func (a *ClaudeAdapter) Import(ctx context.Context, inst *Instance) ([]CanonicalTurn, error)
func (*ClaudeAdapter) Name ¶ added in v1.35.0
func (a *ClaudeAdapter) Name() string
type ClaudeCommandBuilder ¶
type ClaudeCommandBuilder struct {
// contains filtered or unexported fields
}
ClaudeCommandBuilder constructs Claude CLI commands with session resumption support. This builder intelligently adds the --resume flag when appropriate to maintain conversation continuity across session restarts.
func NewClaudeCommandBuilder ¶
func NewClaudeCommandBuilder(baseProgram string, claudeSession *ClaudeSessionData) *ClaudeCommandBuilder
NewClaudeCommandBuilder creates a new command builder for constructing Claude CLI commands. Parameters:
- baseProgram: The base command string (e.g., "claude", "claude --model sonnet", "aider")
- claudeSession: Optional session data for resumption support (can be nil)
func (*ClaudeCommandBuilder) Build ¶
func (b *ClaudeCommandBuilder) Build() string
Build constructs the final command string with session resumption if applicable. The method follows these rules:
- If not a Claude command, returns baseProgram unchanged
- If no session data exists, returns baseProgram unchanged
- If session ID is invalid UUID, returns baseProgram unchanged with warning
- If all conditions met, returns "baseProgram --resume <sessionId>"
type ClaudeController ¶
type ClaudeController struct {
// contains filtered or unexported fields
}
ClaudeController provides a high-level API for controlling Claude instances. It orchestrates all the underlying components (queue, executor, history, streams).
Locking discipline:
- lifecycle (Locked[controllerLifecycle]): write-locked briefly at the boundary of Start/Stop transitions. Slow cleanup in Stop() runs OUTSIDE this lock so that status reads are never blocked by goroutine joins or disk I/O.
- Sub-components (atomic.Pointer[T]): set once in Start(), cleared in Stop(). Readers call .Load() — a nil result means not yet initialized. Atomic access means GetCurrentStatus, GetRecentOutput, Subscribe, etc. never contend with Stop().
- listeners (Locked[[]StatusChangeListener]): fan-out callbacks.
- cache (Locked[cacheState]): tail-hash result cache for status/idle detection.
Cache-line layout: lifecycle.mu (a sync.RWMutex) and the atomic.Pointer fields are separated by [64]byte padding so that write operations on the mutex do not invalidate the cache line read by atomic.Load() calls (Go issue #67764).
func NewClaudeController ¶
func NewClaudeController(instance InstanceContext) (*ClaudeController, error)
NewClaudeController creates a new controller for the given instance.
func (*ClaudeController) AddStatusChangeListener ¶ added in v1.35.0
func (cc *ClaudeController) AddStatusChangeListener(fn StatusChangeListener)
AddStatusChangeListener appends fn to the fan-out set of status-change listeners. All registered listeners fire on every status transition. Safe to call before or after Start().
func (*ClaudeController) CancelCommand ¶
func (cc *ClaudeController) CancelCommand(commandID string) error
CancelCommand cancels a pending command in the queue.
func (*ClaudeController) ClearHistory ¶
func (cc *ClaudeController) ClearHistory() error
ClearHistory removes all command history entries.
func (*ClaudeController) ClearQueue ¶
func (cc *ClaudeController) ClearQueue() error
ClearQueue removes all pending commands from the queue.
func (*ClaudeController) GetCommandHistory ¶
func (cc *ClaudeController) GetCommandHistory(limit int) []*HistoryEntry
GetCommandHistory returns recent command history.
func (*ClaudeController) GetCommandStatus ¶
func (cc *ClaudeController) GetCommandStatus(commandID string) (*Command, error)
GetCommandStatus retrieves the current status of a command.
func (*ClaudeController) GetCurrentCommand ¶
func (cc *ClaudeController) GetCurrentCommand() *Command
GetCurrentCommand returns the currently executing command, if any.
func (*ClaudeController) GetCurrentStatus ¶
func (cc *ClaudeController) GetCurrentStatus() (detection.DetectedStatus, string)
GetCurrentStatus detects the current status of the Claude instance.
Two optimisations are applied on every call:
- Tail slicing — only the last statusDetectionTailBytes bytes of the terminal content are examined. Status indicators (◇ Ready, Thinking…, esc to interrupt) always appear near the current cursor position, so scanning the full scrollback is unnecessary.
- Content hash cache — a FNV-64a hash of the tail is compared against the previous call. If the tail is unchanged the cached result is returned immediately with zero allocations.
This function holds no lifecycle lock — it reads ptyAccess and statusDetector via atomic.Pointer, and the status/idle caches via atomic.Pointer. It therefore never blocks when Stop() is running its slow cleanup.
func (*ClaudeController) GetEscapeParser ¶ added in v1.35.0
func (cc *ClaudeController) GetEscapeParser() *analytics.EscapeCodeParser
GetEscapeParser returns the escape code parser from the response stream. Returns nil if the controller is not started or has no response stream.
func (*ClaudeController) GetExecutionOptions ¶
func (cc *ClaudeController) GetExecutionOptions() ExecutionOptions
GetExecutionOptions returns current execution options.
func (*ClaudeController) GetExitContent ¶ added in v1.15.0
func (cc *ClaudeController) GetExitContent() []byte
GetExitContent returns the last bytes captured before the PTY exited. Returns nil if the controller has no response stream or no exit content was recorded.
func (*ClaudeController) GetHistoryStatistics ¶
func (cc *ClaudeController) GetHistoryStatistics() HistoryStatistics
GetHistoryStatistics returns statistics about command execution.
func (*ClaudeController) GetIdleDuration ¶
func (cc *ClaudeController) GetIdleDuration() time.Duration
GetIdleDuration returns how long the session has been idle.
func (*ClaudeController) GetIdleState ¶
func (cc *ClaudeController) GetIdleState() (detection.IdleState, time.Time)
GetIdleState returns the current idle state with timing information. Returns the state and the timestamp of last activity.
Applies the same tail-slice + hash-cache optimisations as GetCurrentStatus so that polling the idle state on an unchanged terminal is essentially free.
Holds no lifecycle lock — reads ptyAccess and idleDetector via atomic.Pointer. This also fixes the re-entrant RWMutex bug that existed when calling cc.instance.Preview() → GetRecentOutput() → cc.mu.RLock() while already holding cc.mu.RLock(); with atomic pointers there is no lock to re-enter.
func (*ClaudeController) GetIdleStateInfo ¶
func (cc *ClaudeController) GetIdleStateInfo() detection.IdleStateInfo
GetIdleStateInfo returns comprehensive idle state information.
func (*ClaudeController) GetInstance ¶
func (cc *ClaudeController) GetInstance() InstanceContext
GetInstance returns the InstanceContext backing this controller.
func (*ClaudeController) GetQueuedCommands ¶
func (cc *ClaudeController) GetQueuedCommands() []*Command
GetQueuedCommands returns all commands currently in the queue.
func (*ClaudeController) GetQueuedCommandsCount ¶ added in v1.37.0
func (cc *ClaudeController) GetQueuedCommandsCount() int
GetQueuedCommandsCount returns the number of commands in the queue without allocating a slice. Use this instead of len(GetQueuedCommands()) on hot paths.
func (*ClaudeController) GetRateLimitHandler ¶ added in v1.35.0
func (cc *ClaudeController) GetRateLimitHandler() *ratelimit.PTYConsumer
GetRateLimitHandler returns the rate limit PTY consumer (for callback wiring). Returns nil if the controller has not been started yet.
func (*ClaudeController) GetRateLimitResetTime ¶ added in v1.35.0
func (cc *ClaudeController) GetRateLimitResetTime() time.Time
GetRateLimitResetTime returns the reset time from the rate limit handler. Returns zero time if no handler is active or no reset time is known.
func (*ClaudeController) GetRateLimitState ¶ added in v1.12.0
func (cc *ClaudeController) GetRateLimitState() ratelimit.RateLimitState
GetRateLimitState returns the current rate limit detection state.
func (*ClaudeController) GetRecentOutput ¶
func (cc *ClaudeController) GetRecentOutput(bytes int) []byte
GetRecentOutput returns recent output from the PTY buffer. Holds no lifecycle lock; returns nil if the controller is not started.
func (*ClaudeController) GetSessionName ¶
func (cc *ClaudeController) GetSessionName() string
GetSessionName returns the session name for this controller.
func (*ClaudeController) GetStatusAndIdleInfo ¶ added in v1.37.0
func (cc *ClaudeController) GetStatusAndIdleInfo() (detection.DetectedStatus, string, detection.IdleStateInfo)
GetStatusAndIdleInfo returns both the detected status and idle state info in one call. Saves one GetRecentHash (murmur3 over 4KB) and one cache.Read on every poll tick compared to calling GetCurrentStatus + GetIdleStateInfo separately.
func (*ClaudeController) GetStatusDetector ¶ added in v1.35.0
func (cc *ClaudeController) GetStatusDetector() detection.TerminalDetector
GetStatusDetector returns the status detector used by this controller. Used by GetDetectionEvents RPC to retrieve recent detection events for debugging.
func (*ClaudeController) GetTotalBytesWritten ¶ added in v1.35.0
func (cc *ClaudeController) GetTotalBytesWritten() int64
GetTotalBytesWritten returns the monotonic PTY byte offset from the response stream's circular buffer. Returns 0 if the controller is not started or has no response stream.
func (*ClaudeController) IsActive ¶
func (cc *ClaudeController) IsActive() bool
IsActive returns whether the Claude instance is actively processing commands.
func (*ClaudeController) IsIdle ¶
func (cc *ClaudeController) IsIdle() bool
IsIdle returns whether the Claude instance is currently idle (waiting for input). This uses pattern-based detection on terminal content.
func (*ClaudeController) IsRateLimitEnabled ¶ added in v1.12.0
func (cc *ClaudeController) IsRateLimitEnabled() bool
IsRateLimitEnabled returns whether rate limit detection is enabled.
func (*ClaudeController) IsStarted ¶
func (cc *ClaudeController) IsStarted() bool
IsStarted returns whether the controller is currently started.
func (*ClaudeController) SearchHistory ¶
func (cc *ClaudeController) SearchHistory(query string) []*HistoryEntry
SearchHistory searches command history by text.
func (*ClaudeController) SendCommand ¶
func (cc *ClaudeController) SendCommand(text string, priority int) (string, error)
SendCommand sends a command to the Claude instance (queued execution).
func (*ClaudeController) SendCommandImmediate ¶
func (cc *ClaudeController) SendCommandImmediate(text string) (*ExecutionResult, error)
SendCommandImmediate sends a command for immediate execution (bypasses queue).
func (*ClaudeController) SetExecutionOptions ¶
func (cc *ClaudeController) SetExecutionOptions(options ExecutionOptions)
SetExecutionOptions updates command execution options.
func (*ClaudeController) SetOnEOFCallback ¶ added in v1.15.0
func (cc *ClaudeController) SetOnEOFCallback(fn func())
SetOnEOFCallback registers a function called when the PTY backing this controller exits unexpectedly (program exit, not an explicit Stop() call). Must be called before Start().
func (*ClaudeController) SetRateLimitEnabled ¶ added in v1.12.0
func (cc *ClaudeController) SetRateLimitEnabled(enabled bool)
SetRateLimitEnabled enables or disables rate limit detection.
func (*ClaudeController) SetStatusChangeListener ¶ added in v1.35.0
func (cc *ClaudeController) SetStatusChangeListener(fn StatusChangeListener)
SetStatusChangeListener registers fn as the sole status-change listener, replacing any previously registered listeners. Kept for backward compatibility; prefer AddStatusChangeListener.
func (*ClaudeController) Start ¶
func (cc *ClaudeController) Start(ctx context.Context) error
Start initializes all components and begins background operations (streaming, command execution). This is the single entry point for starting the controller — no separate Initialize() call needed.
The lifecycle write lock is held for the duration of initialization to prevent concurrent Start() calls. Read-only operations (GetCurrentStatus, etc.) do not use this lock and are therefore unblocked — they simply see nil atomic pointers until initialization completes.
func (*ClaudeController) Stop ¶
func (cc *ClaudeController) Stop() error
Stop stops all background operations and cleans up resources.
The lifecycle write lock is held only to cancel the context and clear the lifecycle fields. All slow cleanup (goroutine joins via executor.Stop/responseStream.Stop, disk I/O via queue.Save/history.Save) runs OUTSIDE the lock, so concurrent callers of GetCurrentStatus, GetRecentOutput, Subscribe, etc. are never blocked.
func (*ClaudeController) Subscribe ¶
func (cc *ClaudeController) Subscribe(subscriberID string) (<-chan ResponseChunk, error)
Subscribe creates a new subscription to the response stream.
func (*ClaudeController) Unsubscribe ¶
func (cc *ClaudeController) Unsubscribe(subscriberID string) error
Unsubscribe removes a subscription from the response stream.
type ClaudeConversationMessage ¶
type ClaudeConversationMessage struct {
Role string
Content string
Timestamp time.Time
Model string
}
ClaudeConversationMessage represents a message in a conversation
type ClaudeHistoryEntry ¶
type ClaudeHistoryEntry struct {
// ID is the unique identifier for this conversation
ID string `json:"id"`
// Name is the conversation title
Name string `json:"name"`
// Project is the project/directory path
Project string `json:"project"`
// CreatedAt is when the conversation started
CreatedAt time.Time `json:"created_at"`
// UpdatedAt is when the conversation was last updated
UpdatedAt time.Time `json:"updated_at"`
// Model is the Claude model used (e.g., "claude-sonnet-4")
Model string `json:"model"`
// MessageCount is the number of messages in the conversation
MessageCount int `json:"message_count"`
}
ClaudeHistoryEntry represents a single entry from Claude's history.jsonl file
type ClaudeSession ¶
type ClaudeSession struct {
ID string `json:"id"`
ConversationID string `json:"conversation_id"`
ProjectName string `json:"project_name"`
LastActive time.Time `json:"last_active"`
WorkingDir string `json:"working_dir"`
IsActive bool `json:"is_active"`
}
ClaudeSession represents a Claude Code session
type ClaudeSessionData ¶
type ClaudeSessionData struct {
ConversationUUID string `json:"session_id,omitempty"` // Claude Code conversation UUID (used for --resume)
SquadSessionID string `json:"squad_session_id,omitempty"` // claude-squad's own session identifier (= Instance.UUID)
ProjectName string `json:"project_name,omitempty"` // Project name in Claude Code
LastAttached time.Time `json:"last_attached,omitempty"` // When this session was last used
Settings ClaudeSettings `json:"settings,omitempty"` // User preferences for Claude Code
Metadata map[string]string `json:"metadata,omitempty"` // Additional session metadata
}
ClaudeSessionData represents Claude Code session information
func (*ClaudeSessionData) UnmarshalJSON ¶ added in v1.35.0
func (c *ClaudeSessionData) UnmarshalJSON(data []byte) error
UnmarshalJSON keeps backward compatibility with persisted state written before SquadSessionID was renamed from ConversationID. The legacy "conversation_id" key is read as a fallback when "squad_session_id" is absent, so existing JSON state files continue to hydrate the field on load.
type ClaudeSessionHistory ¶
type ClaudeSessionHistory struct {
// contains filtered or unexported fields
}
ClaudeSessionHistory manages access to Claude session history
func NewClaudeSessionHistory ¶
func NewClaudeSessionHistory(historyPath string) (*ClaudeSessionHistory, error)
NewClaudeSessionHistory creates a new ClaudeSessionHistory instance
func NewClaudeSessionHistoryFromClaudeDir ¶
func NewClaudeSessionHistoryFromClaudeDir() (*ClaudeSessionHistory, error)
NewClaudeSessionHistoryFromClaudeDir creates a ClaudeSessionHistory from ~/.claude directory
func (*ClaudeSessionHistory) Count ¶
func (sh *ClaudeSessionHistory) Count() int
Count returns the total number of history entries
func (*ClaudeSessionHistory) GetAll ¶
func (sh *ClaudeSessionHistory) GetAll() []ClaudeHistoryEntry
GetAll returns all history entries, sorted by UpdatedAt descending
func (*ClaudeSessionHistory) GetByID ¶
func (sh *ClaudeSessionHistory) GetByID(id string) (*ClaudeHistoryEntry, error)
GetByID returns a specific history entry by ID
func (*ClaudeSessionHistory) GetByProject ¶
func (sh *ClaudeSessionHistory) GetByProject(projectPath string) []ClaudeHistoryEntry
GetByProject returns all history entries for a specific project path
func (*ClaudeSessionHistory) GetMessagesFromConversationFile ¶
func (sh *ClaudeSessionHistory) GetMessagesFromConversationFile(sessionID string, limit int) ([]ClaudeConversationMessage, error)
GetMessagesFromConversationFile reads messages from the conversation file for the given sessionID. When limit > 0 only the last limit messages are returned (using an efficient reverse-read that avoids loading the full file). When limit == 0 all messages are returned.
Results are always in chronological order (oldest first).
func (*ClaudeSessionHistory) GetProjects ¶
func (sh *ClaudeSessionHistory) GetProjects() []string
GetProjects returns a list of unique project paths from history
func (*ClaudeSessionHistory) LastLoadTime ¶
func (sh *ClaudeSessionHistory) LastLoadTime() time.Time
LastLoadTime returns when the history was last loaded from disk
func (*ClaudeSessionHistory) Reload ¶
func (sh *ClaudeSessionHistory) Reload() error
Reload loads history from ~/.claude/history.jsonl, which Claude maintains as a compact index of all conversations. Each line is one user message; we aggregate by sessionId to reconstruct per-session metadata (name, timestamps, message count).
func (*ClaudeSessionHistory) Search ¶
func (sh *ClaudeSessionHistory) Search(query string) []ClaudeHistoryEntry
Search searches history entries by name or project path
type ClaudeSessionManager ¶
type ClaudeSessionManager struct {
// contains filtered or unexported fields
}
ClaudeSessionManager handles Claude Code session detection and management
func NewClaudeSessionManager ¶
func NewClaudeSessionManager() *ClaudeSessionManager
NewClaudeSessionManager creates a new Claude session manager
func (*ClaudeSessionManager) AttachToSession ¶
func (csm *ClaudeSessionManager) AttachToSession(sessionID string) error
AttachToSession attempts to attach to a Claude Code session
func (*ClaudeSessionManager) CreateSessionData ¶
func (csm *ClaudeSessionManager) CreateSessionData(session ClaudeSession, settings ClaudeSettings) ClaudeSessionData
CreateSessionData creates ClaudeSessionData from a detected session
func (*ClaudeSessionManager) DetectAvailableSessions ¶
func (csm *ClaudeSessionManager) DetectAvailableSessions() ([]ClaudeSession, error)
DetectAvailableSessions scans for available Claude Code sessions
func (*ClaudeSessionManager) FindSessionByProject ¶
func (csm *ClaudeSessionManager) FindSessionByProject(projectPath string) ([]ClaudeSession, error)
FindSessionByProject finds Claude sessions that match a given project/working directory
func (*ClaudeSessionManager) GetSessionByID ¶
func (csm *ClaudeSessionManager) GetSessionByID(sessionID string) (*ClaudeSession, error)
GetSessionByID retrieves a specific Claude session by ID
type ClaudeSettings ¶
type ClaudeSettings struct {
AutoReattach bool `json:"auto_reattach"` // Automatically reattach to last session on resume
PreferredSessionName string `json:"preferred_session_name"` // Preferred session naming pattern
CreateNewOnMissing bool `json:"create_new_on_missing"` // Create new session if previous one is missing
ShowSessionSelector bool `json:"show_session_selector"` // Show session selection menu on resume
SessionTimeoutMinutes int `json:"session_timeout_minutes"` // Consider sessions stale after this time
}
ClaudeSettings contains user preferences for Claude Code integration
type CloudContext ¶
type CloudContext struct {
// Provider is the cloud provider name (aws/gcp/azure/custom)
Provider string `json:"provider,omitempty"`
// Region is the cloud region/zone
Region string `json:"region,omitempty"`
// InstanceID is the cloud instance identifier
InstanceID string `json:"instance_id,omitempty"`
// APIEndpoint is the API endpoint URL for the cloud service
APIEndpoint string `json:"api_endpoint,omitempty"`
// APIKeyRef is a reference to secure key storage (not the actual key)
APIKeyRef string `json:"api_key_ref,omitempty"`
// CloudSessionID is the cloud provider's session identifier
CloudSessionID string `json:"cloud_session_id,omitempty"`
// ConversationID is the conversation/thread identifier for AI services
ConversationID string `json:"conversation_id,omitempty"`
}
CloudContext represents the cloud-related context for a session. This includes cloud provider details, region, and API configuration.
func (*CloudContext) IsConfigured ¶
func (c *CloudContext) IsConfigured() bool
IsConfigured returns true if the CloudContext has minimum required configuration
func (*CloudContext) IsEmpty ¶
func (c *CloudContext) IsEmpty() bool
IsEmpty returns true if the CloudContext has no meaningful data
type Command ¶
type Command struct {
ID string `json:"id"`
Text string `json:"text"`
Priority int `json:"priority"` // Higher priority = executed first
Timestamp time.Time `json:"timestamp"` // When the command was queued
Status CommandStatus `json:"status"`
Result string `json:"result,omitempty"` // Command result/output
Error string `json:"error,omitempty"` // Error message if failed
StartTime time.Time `json:"start_time,omitempty"` // When execution started
EndTime time.Time `json:"end_time,omitempty"` // When execution finished
}
Command represents a command to be executed in a Claude instance.
type CommandExecutor ¶
type CommandExecutor struct {
// contains filtered or unexported fields
}
CommandExecutor executes commands by writing to PTY and monitoring responses.
func NewCommandExecutor ¶
func NewCommandExecutor( sessionName string, ptyAccess *PTYAccess, responseStream *ResponseStream, statusDetector detection.TerminalDetector, queue *CommandQueue, ) *CommandExecutor
NewCommandExecutor creates a new command executor for the given session.
func NewCommandExecutorWithOptions ¶
func NewCommandExecutorWithOptions( sessionName string, ptyAccess *PTYAccess, responseStream *ResponseStream, statusDetector detection.TerminalDetector, queue *CommandQueue, options ExecutionOptions, ) *CommandExecutor
NewCommandExecutorWithOptions creates a command executor with custom options.
func (*CommandExecutor) ExecuteImmediate ¶
func (ce *CommandExecutor) ExecuteImmediate(cmd *Command) (*ExecutionResult, error)
ExecuteImmediate executes a command immediately without using the queue. This is useful for interactive commands that need immediate execution.
func (*CommandExecutor) GetCurrentCommand ¶
func (ce *CommandExecutor) GetCurrentCommand() *Command
GetCurrentCommand returns the currently executing command, or nil if none.
func (*CommandExecutor) GetOptions ¶
func (ce *CommandExecutor) GetOptions() ExecutionOptions
GetOptions returns the current execution options.
func (*CommandExecutor) GetSessionName ¶
func (ce *CommandExecutor) GetSessionName() string
GetSessionName returns the session name for this executor.
func (*CommandExecutor) IsExecuting ¶
func (ce *CommandExecutor) IsExecuting() bool
IsExecuting returns whether the executor is currently running.
func (*CommandExecutor) SetOptions ¶
func (ce *CommandExecutor) SetOptions(options ExecutionOptions)
SetOptions updates execution options (only applies to future commands).
func (*CommandExecutor) SetResultCallback ¶
func (ce *CommandExecutor) SetResultCallback(callback func(*ExecutionResult))
SetResultCallback sets a callback function to be invoked after each command execution.
func (*CommandExecutor) Start ¶
func (ce *CommandExecutor) Start(ctx context.Context) error
Start begins processing commands from the queue.
func (*CommandExecutor) Stop ¶
func (ce *CommandExecutor) Stop() error
Stop stops the command executor and waits for completion.
type CommandHistory ¶
type CommandHistory struct {
// contains filtered or unexported fields
}
CommandHistory tracks all executed commands with persistence.
func NewCommandHistory ¶
func NewCommandHistory(sessionName string) *CommandHistory
NewCommandHistory creates a new command history tracker.
func NewCommandHistoryWithPersistence ¶
func NewCommandHistoryWithPersistence(sessionName string, persistDir string) (*CommandHistory, error)
NewCommandHistoryWithPersistence creates a command history with persistence enabled.
func (*CommandHistory) Add ¶
func (ch *CommandHistory) Add(entry *HistoryEntry) error
Add adds a command execution to the history.
func (*CommandHistory) AddFromResult ¶
func (ch *CommandHistory) AddFromResult(result *ExecutionResult) error
AddFromResult creates and adds a history entry from an execution result.
func (*CommandHistory) Clear ¶
func (ch *CommandHistory) Clear() error
Clear removes all history entries.
func (*CommandHistory) Count ¶
func (ch *CommandHistory) Count() int
Count returns the total number of entries in history.
func (*CommandHistory) GetAll ¶
func (ch *CommandHistory) GetAll() []*HistoryEntry
GetAll returns all history entries (most recent first).
func (*CommandHistory) GetByCommandID ¶
func (ch *CommandHistory) GetByCommandID(commandID string) []*HistoryEntry
GetByCommandID returns all history entries for a specific command ID.
func (*CommandHistory) GetByStatus ¶
func (ch *CommandHistory) GetByStatus(status CommandStatus) []*HistoryEntry
GetByStatus returns entries with a specific command status.
func (*CommandHistory) GetByTimeRange ¶
func (ch *CommandHistory) GetByTimeRange(start, end time.Time) []*HistoryEntry
GetByTimeRange returns entries within the specified time range.
func (*CommandHistory) GetFailed ¶
func (ch *CommandHistory) GetFailed() []*HistoryEntry
GetFailed returns all failed command executions.
func (*CommandHistory) GetMaxEntries ¶
func (ch *CommandHistory) GetMaxEntries() int
GetMaxEntries returns the current maximum entries limit.
func (*CommandHistory) GetPersistPath ¶
func (ch *CommandHistory) GetPersistPath() string
GetPersistPath returns the path where history is persisted.
func (*CommandHistory) GetRecent ¶
func (ch *CommandHistory) GetRecent(n int) []*HistoryEntry
GetRecent returns the N most recent history entries.
func (*CommandHistory) GetSessionName ¶
func (ch *CommandHistory) GetSessionName() string
GetSessionName returns the session name for this history.
func (*CommandHistory) GetStatistics ¶
func (ch *CommandHistory) GetStatistics() HistoryStatistics
GetStatistics returns statistics about command execution history.
func (*CommandHistory) GetSuccessful ¶
func (ch *CommandHistory) GetSuccessful() []*HistoryEntry
GetSuccessful returns all successful command executions.
func (*CommandHistory) Load ¶
func (ch *CommandHistory) Load() error
Load restores the history from disk.
func (*CommandHistory) Save ¶
func (ch *CommandHistory) Save() error
Save persists the history to disk.
func (*CommandHistory) Search ¶
func (ch *CommandHistory) Search(query string) []*HistoryEntry
Search searches history entries by command text (case-insensitive substring match).
func (*CommandHistory) SetMaxEntries ¶
func (ch *CommandHistory) SetMaxEntries(max int)
SetMaxEntries sets the maximum number of entries to keep in history. Setting to 0 means unlimited. If current entries exceed the new limit, oldest entries are removed.
func (*CommandHistory) SetPersistPath ¶
func (ch *CommandHistory) SetPersistPath(path string)
SetPersistPath sets the path for history persistence.
type CommandQueue ¶
type CommandQueue struct {
// contains filtered or unexported fields
}
CommandQueue manages a priority queue of commands with persistence.
func NewCommandQueue ¶
func NewCommandQueue(sessionName string) *CommandQueue
NewCommandQueue creates a new command queue for the given session.
func NewCommandQueueWithPersistence ¶
func NewCommandQueueWithPersistence(sessionName string, persistDir string) (*CommandQueue, error)
NewCommandQueueWithPersistence creates a command queue with persistence enabled. The queue state will be saved to the specified directory.
func (*CommandQueue) Cancel ¶
func (cq *CommandQueue) Cancel(id string) error
Cancel marks a command as cancelled and removes it from the queue. Returns an error if the command is not found or is already executing.
func (*CommandQueue) Clear ¶
func (cq *CommandQueue) Clear() error
Clear removes all commands from the queue.
func (*CommandQueue) Dequeue ¶
func (cq *CommandQueue) Dequeue() *Command
Dequeue removes and returns the highest priority command from the queue. Returns nil if the queue is empty.
func (*CommandQueue) Enqueue ¶
func (cq *CommandQueue) Enqueue(cmd *Command) error
Enqueue adds a command to the queue with the specified priority. Higher priority commands are executed first.
func (*CommandQueue) Get ¶
func (cq *CommandQueue) Get(id string) (*Command, error)
Get retrieves a command by ID without removing it from the queue.
func (*CommandQueue) GetPersistPath ¶
func (cq *CommandQueue) GetPersistPath() string
GetPersistPath returns the path where the queue state is persisted.
func (*CommandQueue) IsEmpty ¶
func (cq *CommandQueue) IsEmpty() bool
IsEmpty returns true if the queue is empty.
func (*CommandQueue) Len ¶
func (cq *CommandQueue) Len() int
Len returns the number of commands in the queue.
func (*CommandQueue) List ¶
func (cq *CommandQueue) List() []*Command
List returns all commands currently in the queue. The returned slice is a copy to prevent external modification.
func (*CommandQueue) ListByStatus ¶
func (cq *CommandQueue) ListByStatus(status CommandStatus) []*Command
ListByStatus returns all commands with the specified status.
func (*CommandQueue) Load ¶
func (cq *CommandQueue) Load() error
Load restores the queue state from disk.
func (*CommandQueue) NotifyChannel ¶
func (cq *CommandQueue) NotifyChannel() <-chan struct{}
NotifyChannel returns a channel that receives a notification when commands are added. This can be used to wait for new commands without polling.
func (*CommandQueue) Peek ¶
func (cq *CommandQueue) Peek() *Command
Peek returns the highest priority command without removing it. Returns nil if the queue is empty.
func (*CommandQueue) Save ¶
func (cq *CommandQueue) Save() error
Save persists the queue state to disk.
func (*CommandQueue) SetPersistPath ¶
func (cq *CommandQueue) SetPersistPath(path string)
SetPersistPath sets the path for queue persistence.
func (*CommandQueue) Update ¶
func (cq *CommandQueue) Update(cmd *Command) error
Update updates the status and metadata of a command.
type CommandStatus ¶
type CommandStatus int
CommandStatus represents the current status of a command in the queue.
const ( CommandPending CommandStatus = iota CommandExecuting CommandCompleted CommandFailed CommandCancelled )
func (CommandStatus) String ¶
func (cs CommandStatus) String() string
String returns a human-readable string for the command status.
type CompletionCallback ¶ added in v1.35.0
type CompletionCallback func(instanceName string, outcome AutonomousDriverOutcome)
CompletionCallback is called when the driver exits with a final outcome.
type ContentProvider ¶ added in v1.35.0
type ContentProvider interface {
GetContent(inst *Instance, statusInfo InstanceStatusInfo, paneActivity map[string]time.Time) string
EvictInstance(title string)
}
ContentProvider fetches terminal content for a session. Defined at the consumption point so tests can inject fakes without tmux.
func NewPollerContentProvider ¶ added in v1.35.0
func NewPollerContentProvider() ContentProvider
NewPollerContentProvider creates a new pollerContentProvider. It is exported so server/dependencies.go can pass it to NewStartupScanner.
type ContextOptions ¶
type ContextOptions struct {
// Context loading flags
LoadGit bool // Git repository context (branch, commit, remotes)
LoadFilesystem bool // Filesystem context (directory state, file counts)
LoadTerminal bool // Terminal context (output, command history)
LoadUI bool // UI context (position, focus state, expanded/collapsed)
LoadActivity bool // Activity context (last active, duration, events)
LoadCloud bool // Cloud context (API sessions, remote state)
// Child data loading flags (from existing LoadOptions)
LoadWorktree bool // Git worktree data
LoadDiffStats bool // Diff statistics (added/removed counts)
LoadDiffContent bool // Full diff content (heavy - only load when needed)
LoadTags bool // Session tags
LoadClaudeSession bool // Claude Code session data
}
ContextOptions specifies which optional contexts to load when querying sessions. This enables optimized queries that only load the data needed for each use case.
func FromLoadOptions ¶
func FromLoadOptions(lo LoadOptions) ContextOptions
FromLoadOptions creates ContextOptions from the legacy LoadOptions type. This provides backward compatibility when migrating existing code.
func (ContextOptions) AnyChildDataLoaded ¶
func (o ContextOptions) AnyChildDataLoaded() bool
AnyChildDataLoaded returns true if any child data is configured to load.
func (ContextOptions) AnyContextLoaded ¶
func (o ContextOptions) AnyContextLoaded() bool
AnyContextLoaded returns true if any context is configured to load.
func (ContextOptions) Merge ¶
func (o ContextOptions) Merge(other ContextOptions) ContextOptions
Merge combines two ContextOptions, returning options that load the union of both. This is useful for combining requirements from multiple components.
func (ContextOptions) String ¶
func (o ContextOptions) String() string
String returns a human-readable description of what will be loaded.
func (ContextOptions) ToLoadOptions ¶
func (o ContextOptions) ToLoadOptions() LoadOptions
ToLoadOptions converts ContextOptions to the legacy LoadOptions type. This provides backward compatibility with existing code.
func (ContextOptions) WithActivity ¶
func (o ContextOptions) WithActivity() ContextOptions
WithActivity returns a copy of options with activity context loading enabled.
func (ContextOptions) WithCloud ¶
func (o ContextOptions) WithCloud() ContextOptions
WithCloud returns a copy of options with cloud context loading enabled.
func (ContextOptions) WithDiffContent ¶
func (o ContextOptions) WithDiffContent() ContextOptions
WithDiffContent returns a copy of options with diff content loading enabled.
func (ContextOptions) WithFilesystem ¶
func (o ContextOptions) WithFilesystem() ContextOptions
WithFilesystem returns a copy of options with filesystem context loading enabled.
func (ContextOptions) WithGit ¶
func (o ContextOptions) WithGit() ContextOptions
WithGit returns a copy of options with git context loading enabled.
func (ContextOptions) WithTags ¶
func (o ContextOptions) WithTags() ContextOptions
WithTags returns a copy of options with tag loading enabled.
func (ContextOptions) WithTerminal ¶
func (o ContextOptions) WithTerminal() ContextOptions
WithTerminal returns a copy of options with terminal context loading enabled.
func (ContextOptions) WithUI ¶
func (o ContextOptions) WithUI() ContextOptions
WithUI returns a copy of options with UI context loading enabled.
func (ContextOptions) WithoutDiffContent ¶
func (o ContextOptions) WithoutDiffContent() ContextOptions
WithoutDiffContent returns a copy of options with diff content loading disabled.
func (ContextOptions) WithoutTags ¶
func (o ContextOptions) WithoutTags() ContextOptions
WithoutTags returns a copy of options with tag loading disabled.
type ControllerManager ¶
type ControllerManager struct {
// contains filtered or unexported fields
}
ControllerManager owns the ClaudeController and InstanceStatusManager references that were previously bare fields on Instance.
Instance keeps thin wrapper methods (with lifecycle guards) that delegate here. ControllerManager itself has no knowledge of Instance lifecycle; it only manages the controller and status-manager references.
Note: claudeSession is intentionally NOT included here because it is a rich data object with complex lifecycle management (persistence, re-attachment, session selection) that is tightly coupled to Instance business logic. It remains a direct field on Instance for now.
Both controller and statusManager use atomic.Pointer for lock-free concurrent access. Write operations (Register/Unregister/Set) are expected to be called sequentially from the Instance lifecycle path and are not themselves concurrency-safe against each other. ControllerManager must not be copied after first use (enforced by noCopy).
func (*ControllerManager) GetController ¶
func (cm *ControllerManager) GetController() *ClaudeController
GetController returns the current ClaudeController (may be nil).
func (*ControllerManager) GetStatusManager ¶
func (cm *ControllerManager) GetStatusManager() *InstanceStatusManager
GetStatusManager returns the current InstanceStatusManager (may be nil).
func (*ControllerManager) HasController ¶
func (cm *ControllerManager) HasController() bool
HasController reports whether a ClaudeController has been registered.
func (*ControllerManager) RegisterController ¶
func (cm *ControllerManager) RegisterController(title string, controller *ClaudeController)
RegisterController wires a new controller into the status manager and stores it. Any existing controller is stopped first.
func (*ControllerManager) SetController ¶
func (cm *ControllerManager) SetController(c *ClaudeController)
SetController replaces the controller. Callers are responsible for stopping the old controller before calling this.
func (*ControllerManager) SetStatusManager ¶
func (cm *ControllerManager) SetStatusManager(m *InstanceStatusManager)
SetStatusManager replaces the status manager.
func (*ControllerManager) StopAndClearController ¶
func (cm *ControllerManager) StopAndClearController()
StopAndClearController stops the controller (if running) and clears the reference.
func (*ControllerManager) UnregisterController ¶
func (cm *ControllerManager) UnregisterController(title string)
UnregisterController stops and clears the controller, and removes it from the status manager.
type ConversationID ¶ added in v1.35.0
type ConversationID string
ConversationID represents a validated Claude/Antigravity conversation UUID.
func ParseConversationID ¶ added in v1.35.0
func ParseConversationID(s string) (ConversationID, error)
ParseConversationID parses and validates a raw string as a ConversationID.
type CriterionVerdict ¶ added in v1.35.0
type CriterionVerdict = domain.CriterionVerdict
CriterionVerdict holds the review outcome for a single acceptance criterion. Type alias — session.CriterionVerdict and domain.CriterionVerdict are identical types.
type DefaultStatusDeterminer ¶ added in v1.35.0
type DefaultStatusDeterminer struct {
// contains filtered or unexported fields
}
DefaultStatusDeterminer implements StatusDeterminer with the standard detection logic.
func NewDefaultStatusDeterminer ¶ added in v1.35.0
func NewDefaultStatusDeterminer(config ReviewQueuePollerConfig) *DefaultStatusDeterminer
NewDefaultStatusDeterminer creates a DefaultStatusDeterminer with the given config.
func (*DefaultStatusDeterminer) Determine ¶ added in v1.35.0
func (d *DefaultStatusDeterminer) Determine( inst *Instance, content string, statusInfo InstanceStatusInfo, detector detection.TerminalDetector, ) DetectionResult
Determine evaluates a session's state and returns a DetectionResult. It is pure: no queue mutations, no storage calls, no side effects.
type DefaultWorkflowEngine ¶ added in v1.35.0
type DefaultWorkflowEngine struct {
// contains filtered or unexported fields
}
DefaultWorkflowEngine implements WorkflowEngine using the hardcoded validTransitions map and TransitionGuard function from backlog.go.
func NewDefaultWorkflowEngine ¶ added in v1.35.0
func NewDefaultWorkflowEngine() *DefaultWorkflowEngine
NewDefaultWorkflowEngine constructs an engine backed by the static validTransitions map. The map is deep-copied to avoid shared mutable state.
func (*DefaultWorkflowEngine) AllowedTransitions ¶ added in v1.35.0
func (e *DefaultWorkflowEngine) AllowedTransitions(from BacklogStatus) []BacklogStatus
AllowedTransitions implements WorkflowEngine.
func (*DefaultWorkflowEngine) CanTransition ¶ added in v1.35.0
func (e *DefaultWorkflowEngine) CanTransition(from, to BacklogStatus) bool
CanTransition implements WorkflowEngine.
func (*DefaultWorkflowEngine) ValidateGates ¶ added in v1.35.0
func (e *DefaultWorkflowEngine) ValidateGates(item BacklogItemTransitionInput, to BacklogStatus) error
ValidateGates implements WorkflowEngine by delegating to TransitionGuard.
type DetectionAction ¶ added in v1.35.0
type DetectionAction int
DetectionAction represents what the poller should do after status determination.
const ( DetectionActionSkip DetectionAction = iota // No change to queue DetectionActionAdd // Add/update item in queue DetectionActionRemove // Remove item from queue )
type DetectionResult ¶ added in v1.35.0
type DetectionResult struct {
Action DetectionAction
Reason AttentionReason
Priority Priority
Context string
ClaudeStatus detection.DetectedStatus
// CleanWorktree is true when the worktree was inspected and found clean.
// checkSession uses this to remove a queued UncommittedChanges entry immediately.
CleanWorktree bool
}
DetectionResult is the output of status determination — pure data, no side effects.
func (DetectionResult) IsHighPriority ¶ added in v1.35.0
func (r DetectionResult) IsHighPriority() bool
IsHighPriority returns true when the result warrants bypassing grace-period suppression.
type DiffStatsData ¶
type DiffStatsData struct {
Added int `json:"added"`
Removed int `json:"removed"`
Content string `json:"-"` // Excluded from serialization - generated on-demand
}
DiffStatsData represents the serializable data of a DiffStats Note: Content is excluded from JSON serialization to reduce state file size. Diffs are generated on-demand via GetSessionDiff RPC when needed.
type DiscoveryMode ¶
type DiscoveryMode int
DiscoveryMode controls what instances are discovered and how they can be interacted with
const ( // DiscoveryModeManaged discovers only squad-managed sessions (default, safest) DiscoveryModeManaged DiscoveryMode = iota // DiscoveryModeExtended discovers managed + external instances in read-only mode DiscoveryModeExtended // DiscoveryModeFull discovers all instances with attach capability (power user mode) DiscoveryModeFull )
func ParseDiscoveryMode ¶
func ParseDiscoveryMode(s string) DiscoveryMode
ParseDiscoveryMode parses a string into a DiscoveryMode
func (DiscoveryMode) String ¶
func (dm DiscoveryMode) String() string
type DriverOption ¶ added in v1.35.0
type DriverOption func(*AutonomousDriver)
DriverOption is a functional option for configuring an AutonomousDriver.
func WithStartupTimeout ¶ added in v1.35.0
func WithStartupTimeout(d time.Duration) DriverOption
WithStartupTimeout overrides the default 60s startup idle-wait timeout. Use a longer timeout for sessions that spawn parallel subagents (e.g. triage).
type EntPipelineModeRepository ¶ added in v1.38.0
type EntPipelineModeRepository struct {
// contains filtered or unexported fields
}
EntPipelineModeRepository implements PipelineModeRepository using the ent ORM.
func NewEntPipelineModeRepository ¶ added in v1.38.0
func NewEntPipelineModeRepository(client *ent.Client) *EntPipelineModeRepository
NewEntPipelineModeRepository creates a new ent-backed pipeline mode repository.
func (*EntPipelineModeRepository) Create ¶ added in v1.38.0
func (r *EntPipelineModeRepository) Create(ctx context.Context, m PipelineModeCreateInput) (*ent.PipelineMode, error)
Create inserts a new pipeline mode definition. Returns ent.ConstraintError when a duplicate slug exists.
func (*EntPipelineModeRepository) GetByID ¶ added in v1.38.0
func (r *EntPipelineModeRepository) GetByID(ctx context.Context, id uuid.UUID) (*ent.PipelineMode, error)
GetByID retrieves a pipeline mode by UUID.
func (*EntPipelineModeRepository) GetBySlug ¶ added in v1.38.0
func (r *EntPipelineModeRepository) GetBySlug(ctx context.Context, slug string) (*ent.PipelineMode, error)
GetBySlug retrieves a pipeline mode by slug.
func (*EntPipelineModeRepository) ListAll ¶ added in v1.38.0
func (r *EntPipelineModeRepository) ListAll(ctx context.Context) ([]*ent.PipelineMode, error)
ListAll returns all pipeline modes sorted ascending by created_at. A safety cap of 1000 is applied to prevent runaway queries.
func (*EntPipelineModeRepository) ListEnabled ¶ added in v1.38.0
func (r *EntPipelineModeRepository) ListEnabled(ctx context.Context) ([]*ent.PipelineMode, error)
ListEnabled returns only pipeline modes where enabled is true.
func (*EntPipelineModeRepository) Update ¶ added in v1.38.0
func (r *EntPipelineModeRepository) Update(ctx context.Context, id uuid.UUID, m PipelineModeUpdateInput) (*ent.PipelineMode, error)
Update applies a partial update to an existing pipeline mode by UUID.
type EntRepository ¶
type EntRepository struct {
// contains filtered or unexported fields
}
EntRepository implements the Repository interface using Ent ORM as the storage backend. It provides type-safe database operations with automatic schema migrations.
func NewEntRepository ¶
func NewEntRepository(opts ...RepositoryOption) (*EntRepository, error)
NewEntRepository creates a new Ent repository with the given options. The database will be initialized with the schema if it doesn't exist.
func NewEntRepositoryFromClient ¶ added in v1.35.0
func NewEntRepositoryFromClient(client *ent.Client) *EntRepository
NewEntRepositoryFromClient wraps a pre-existing *ent.Client in an EntRepository. The caller is responsible for running schema migration on the client beforehand. Use this when you need to share an already-opened client across subsystems (e.g. injecting a test client or reusing an existing connection).
func (*EntRepository) AllRules ¶ added in v1.12.0
func (r *EntRepository) AllRules(ctx context.Context) ([]ApprovalRuleData, error)
func (*EntRepository) AppendProgressNote ¶ added in v1.38.0
func (r *EntRepository) AppendProgressNote(ctx context.Context, itemID string, criterionIndex int, note, status string) error
AppendProgressNote records a single report_progress call as an immutable history entry, in addition to (not instead of) the current-note-per-criterion stored on BacklogItem.AcceptanceCriteria. Callers should treat failures here as best-effort: the history is an enrichment for reviewers, not part of report_progress's primary contract of updating the criterion's current status/note.
func (*EntRepository) ArchiveBacklogItem ¶ added in v1.35.0
func (r *EntRepository) ArchiveBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
ArchiveBacklogItem sets the archived_at timestamp on a backlog item.
func (*EntRepository) AssignSessionsToProject ¶ added in v1.23.0
func (r *EntRepository) AssignSessionsToProject(ctx context.Context, projectName string, sessionTitles []string) error
AssignSessionsToProject links sessions (by title) to a project (by name).
func (*EntRepository) BackfillMissingPRNumbers ¶ added in v1.37.0
func (r *EntRepository) BackfillMissingPRNumbers(ctx context.Context) (int, error)
BackfillMissingPRNumbers finds pr_pending items with a pr_url but no pr_number (pr_number == 0) and parses the number out of the URL. Such items are otherwise permanently invisible to FindPRPendingItems' PrNumberGT(0) filter, so ReconcilePRPending never polls them — a real stuck-forever case found via manual QA against live data, not something the loop itself would ever have surfaced. Best-effort: a URL that doesn't match is left as-is and logged, not treated as fatal.
func (*EntRepository) Close ¶
func (r *EntRepository) Close() error
Close performs cleanup and releases resources
func (*EntRepository) CountReviewCyclesSince ¶ added in v1.38.0
func (r *EntRepository) CountReviewCyclesSince(ctx context.Context, itemID string, since time.Time) (int, error)
CountReviewCyclesSince counts in_progress->review BacklogStatusEvent transitions for itemID created at or after since — the "round trip" signal the bouncing detector (isBouncing) keys off.
func (*EntRepository) Create ¶
func (r *EntRepository) Create(ctx context.Context, data InstanceData) error
Create inserts a new session into the database
func (*EntRepository) CreateBacklogItem ¶ added in v1.35.0
func (r *EntRepository) CreateBacklogItem(ctx context.Context, data BacklogItemData) (*BacklogItemData, error)
CreateBacklogItem inserts a new backlog item.
func (*EntRepository) CreateItemSession ¶ added in v1.35.0
func (r *EntRepository) CreateItemSession(ctx context.Context, data ItemSessionData) (ItemSessionSummary, error)
CreateItemSession creates a new ItemSession linked to a BacklogItem.
func (*EntRepository) CreateItemSessionWithVerdict ¶ added in v1.35.0
func (r *EntRepository) CreateItemSessionWithVerdict(ctx context.Context, isData ItemSessionData, verdict ReviewVerdictData) (ItemSessionSummary, error)
CreateItemSessionWithVerdict atomically creates an ItemSession and its initial ReviewVerdict in a single transaction. If the verdict write fails the ItemSession is rolled back, preventing dangling sessions with no verdict.
func (*EntRepository) CreateItemSource ¶ added in v1.35.0
func (r *EntRepository) CreateItemSource(ctx context.Context, data ItemSourceData) (*ItemSourceData, error)
CreateItemSource registers a new external item source.
func (*EntRepository) CreateProject ¶ added in v1.23.0
func (r *EntRepository) CreateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
CreateProject inserts a new project.
func (*EntRepository) CreateSession ¶
func (r *EntRepository) CreateSession(ctx context.Context, session *Session) error
CreateSession creates a new session from the Session domain model. Stub: not yet implemented; use InstanceData-based methods instead.
func (*EntRepository) CreateShell ¶ added in v1.35.0
func (r *EntRepository) CreateShell(ctx context.Context, sessionTitle string, data ShellData) (*ent.Shell, error)
CreateShell persists a new Shell entity for the given session title.
func (*EntRepository) CreateSourceSyncEvent ¶ added in v1.35.0
func (r *EntRepository) CreateSourceSyncEvent(ctx context.Context, sourceID string, cursorAfter string, created, updated, skipped, errored int, errMsg string, startedAt, finishedAt time.Time) error
CreateSourceSyncEvent records a completed (or failed) sync run for an ItemSource. errMsg should be non-empty only when the sync run failed outright (e.g. the plugin's Fetch call errored); errored counts per-item failures within an otherwise-successful fetch.
func (*EntRepository) Delete ¶
func (r *EntRepository) Delete(ctx context.Context, title string) error
Delete removes a session from the database by title
func (*EntRepository) DeleteBacklogItem ¶ added in v1.35.0
func (r *EntRepository) DeleteBacklogItem(ctx context.Context, id string) error
DeleteBacklogItem permanently removes an item and all its child records.
func (*EntRepository) DeleteItemSource ¶ added in v1.35.0
func (r *EntRepository) DeleteItemSource(ctx context.Context, id string) error
DeleteItemSource removes an item source by UUID string.
func (*EntRepository) DeleteProject ¶ added in v1.23.0
func (r *EntRepository) DeleteProject(ctx context.Context, name string) error
DeleteProject removes a project; sessions are unassigned (FK cleared) atomically.
func (*EntRepository) DeleteRule ¶ added in v1.12.0
func (r *EntRepository) DeleteRule(ctx context.Context, id string) error
func (*EntRepository) DeleteShell ¶ added in v1.35.0
func (r *EntRepository) DeleteShell(ctx context.Context, shellID string) error
DeleteShell removes a Shell entity by ID.
func (*EntRepository) FindOpenStuckStates ¶ added in v1.38.0
func (r *EntRepository) FindOpenStuckStates(ctx context.Context) ([]OpenStuckStateData, error)
FindOpenStuckStates returns every BacklogStuckState row that is currently open (resolved_at IS NULL) and not currently snoozed (snoozed_until IS NULL OR snoozed_until is in the past), eager-loading the parent item so the projection carries title/status/pr_number/pr_url for rendering without a second round trip.
func (*EntRepository) FindPRPendingItems ¶ added in v1.37.0
func (r *EntRepository) FindPRPendingItems(ctx context.Context) ([]*ent.BacklogItem, error)
FindPRPendingItems returns backlog items in "pr_pending" status that have a PR number set. Used by ReconcilePRPending to poll for merged PRs.
func (*EntRepository) FindReviewItemsWithoutGate ¶ added in v1.37.0
func (r *EntRepository) FindReviewItemsWithoutGate(ctx context.Context) ([]*ent.BacklogItem, error)
FindReviewItemsWithoutGate returns backlog items in "review" status that have no review ItemSession. These are items where the review gate was never spawned (e.g. the headless pool was unavailable at the time of the work session exit). Each returned item has its ItemSessions edge loaded (work sessions only).
func (*EntRepository) FindStuckReviewItems ¶ added in v1.38.0
func (r *EntRepository) FindStuckReviewItems(ctx context.Context) ([]*ent.BacklogItem, error)
FindStuckReviewItems returns backlog items in "review" status that already have at least one review ItemSession (so FindReviewItemsWithoutGate's "no gate at all" filter won't catch them) but currently have no active (EndedAt still nil) review or work session — i.e. nothing is in flight for the item, yet it never resolved to done/in_progress/pr_pending.
This is the class of item left behind when AutoReopenAfterFailedReview's spawn attempt failed and rolled the status back to "review" (e.g. blocked by hasActiveWorkSession because the prior work session's underlying tmux/CLI session never got marked ended), or when a legacy/interactive review session exited without ever calling submit_review_verdict. Both cases leave the item permanently invisible to every other reconciler: FindReviewItemsWithoutGate excludes it (a review session does exist), and reconcileStaleWorkSessions only scans "in_progress" items. Found via manual QA against a live-data item stuck in review for 24+ hours with three UNVERIFIABLE re-review verdicts and only ever one work session on record.
func (*EntRepository) FindZombieReviewItems ¶ added in v1.38.0
func (r *EntRepository) FindZombieReviewItems(ctx context.Context) ([]*ent.BacklogItem, error)
FindZombieReviewItems returns backlog items in "review" status that have an active (EndedAt IS NULL) review-or-work ItemSession recorded in the DB — exactly the class FindStuckReviewItems excludes (its "nothing in flight" filter requires no un-ended session at all). Each returned item eager-loads only that active session so the caller can verify, via an injected liveness checker, whether the underlying tmux/CLI process the row claims is active has actually gone away (a zombie: the DB row looks live, the process is gone). Not every returned item is a zombie — the caller must still check liveness per active session.
func (*EntRepository) FinishSourceSync ¶ added in v1.35.0
func (r *EntRepository) FinishSourceSync(ctx context.Context, sourceID string, cursorAfter string, created, updated, skipped, errored int, startedAt, finishedAt time.Time) error
FinishSourceSync atomically advances an ItemSource's sync cursor/last_synced_at and records the SourceSyncEvent for a successful sync run. Wrapping both writes in one transaction prevents a crash between them from leaving the cursor advanced with no corresponding history row — which would silently hide the fact that a batch of items was processed (or dropped) in that run.
func (*EntRepository) Get ¶
func (r *EntRepository) Get(ctx context.Context, title string) (*InstanceData, error)
Get retrieves a single session by title
func (*EntRepository) GetAllItemSessionsWithBacklogInfo ¶ added in v1.37.0
func (r *EntRepository) GetAllItemSessionsWithBacklogInfo(ctx context.Context) ([]ItemSessionBacklogEntry, error)
GetAllItemSessionsWithBacklogInfo returns all item sessions joined with their parent backlog item's ID, title, and status. Used by the Insights dashboard index.
func (*EntRepository) GetAllSessionArtifacts ¶ added in v1.35.0
GetAllSessionArtifacts returns a map of title → raw artifacts JSON for all sessions that have a non-empty session_artifacts column. Single query replaces N per-session queries in LoadInstances (M-4 fix).
func (*EntRepository) GetBacklogItem ¶ added in v1.35.0
func (r *EntRepository) GetBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
GetBacklogItem retrieves a backlog item by UUID string.
func (*EntRepository) GetBacklogItemByExternalID ¶ added in v1.35.0
func (r *EntRepository) GetBacklogItemByExternalID(ctx context.Context, sourceID, externalID string) (*ent.BacklogItem, error)
GetBacklogItemByExternalID retrieves a BacklogItem by its external_id, scoped to sourceID. External IDs (e.g. GitHub issue/PR numbers) are only unique within their source, not globally — two different repos can both have an issue #1, so this must never match across sources.
func (*EntRepository) GetBaseCommitSHAsForSessions ¶ added in v1.37.0
func (r *EntRepository) GetBaseCommitSHAsForSessions(ctx context.Context, sessionUUIDs []string) (map[string]string, error)
GetBaseCommitSHAsForSessions returns a map of sessionUUID → last_commit_sha for the given session UUIDs, including only rows where last_commit_sha is non-empty. Used at startup to restore dirBaseSHA for directory-mode backlog sessions.
func (*EntRepository) GetClaudeConversationUUIDBySessionUUID ¶ added in v1.37.0
func (r *EntRepository) GetClaudeConversationUUIDBySessionUUID(ctx context.Context, sessionUUID string) (string, error)
GetClaudeConversationUUIDBySessionUUID returns the Claude conversation UUID for the session whose title (tmux session name) matches sessionUUID. Returns "" if the session has no associated ClaudeSession.
func (*EntRepository) GetEntClient ¶ added in v1.35.0
func (r *EntRepository) GetEntClient() *ent.Client
GetEntClient returns the underlying *ent.Client so callers (e.g. ErrorRegistry) can operate on entities not managed by the Repository interface.
func (*EntRepository) GetItemSession ¶ added in v1.35.0
func (r *EntRepository) GetItemSession(ctx context.Context, id string) (ItemSessionSummary, error)
GetItemSession retrieves an ItemSession by entity UUID string. Loads the BacklogItem edge.
func (*EntRepository) GetItemSessionBySessionAndItem ¶ added in v1.35.0
func (r *EntRepository) GetItemSessionBySessionAndItem(ctx context.Context, sessionUUID string, itemID string) (ItemSessionSummary, error)
GetItemSessionBySessionAndItem looks up an ItemSession by both sessionUUID and backlog item ID.
func (*EntRepository) GetItemSessionBySessionUUID ¶ added in v1.35.0
func (r *EntRepository) GetItemSessionBySessionUUID(ctx context.Context, sessionUUID string) (ItemSessionSummary, error)
GetItemSessionBySessionUUID looks up the most recent active ItemSession by session UUID alone. session_uuid is not unique across records (a session may be reused), so we order by created_at descending and take the first match. Returns ErrNotFound if no record exists. Loads the BacklogItem edge so BacklogItemID is populated in the returned summary.
func (*EntRepository) GetItemSourceByID ¶ added in v1.35.0
func (r *EntRepository) GetItemSourceByID(ctx context.Context, id string) (*ent.ItemSource, error)
GetItemSourceByID retrieves a raw *ent.ItemSource by UUID string.
func (*EntRepository) GetMostRecentReviewVerdictForItem ¶ added in v1.35.0
func (r *EntRepository) GetMostRecentReviewVerdictForItem(ctx context.Context, itemID string) (ReviewOutcome, error)
GetMostRecentReviewVerdictForItem returns the OverallOutcome from the most recently created ReviewVerdict associated with any ItemSession for the given BacklogItem UUID. Returns "" (not an error) when no verdict exists yet.
func (*EntRepository) GetMostRecentStatusEventAt ¶ added in v1.38.0
func (r *EntRepository) GetMostRecentStatusEventAt(ctx context.Context, itemID string, toStatus BacklogStatus) (time.Time, bool, error)
GetMostRecentStatusEventAt returns the created_at timestamp of the most recent BacklogStatusEvent for itemID whose to_status equals toStatus. Returns (zero time, false, nil) when no such event exists (e.g. an item seeded directly into a status without a recorded transition). Used by the abandoned_review 15-minute grace check (abandonedReview pure fn) so a item that JUST entered review isn't flagged before the reconciler has had a chance to re-spawn a review gate.
func (*EntRepository) GetSession ¶
func (r *EntRepository) GetSession(ctx context.Context, title string, opts ContextOptions) (*Session, error)
GetSession retrieves a session using the new Session domain model. Stub: not yet implemented; use InstanceData-based methods instead.
func (*EntRepository) GetSessionArtifacts ¶ added in v1.35.0
GetSessionArtifacts loads the raw JSON artifact blob for a session. Returns ("", nil) if the session exists but has no artifacts stored yet.
func (*EntRepository) GetSubcommandBreakdown ¶ added in v1.35.0
func (r *EntRepository) GetSubcommandBreakdown(ctx context.Context, program string, since time.Time) ([]SubcommandDecisionCount, error)
func (*EntRepository) GetSubcommandTrend ¶ added in v1.35.0
func (r *EntRepository) GetSubcommandTrend(ctx context.Context, program, subcommand string, since time.Time) ([]AnalyticsData, error)
func (*EntRepository) GetWithOptions ¶
func (r *EntRepository) GetWithOptions(ctx context.Context, title string, options LoadOptions) (*InstanceData, error)
GetWithOptions retrieves a single session with selective child data loading. EntRepository: Delegates to Get with full loading.
func (*EntRepository) GetWorktreeDataBySessionUUID ¶ added in v1.37.0
func (r *EntRepository) GetWorktreeDataBySessionUUID(ctx context.Context, sessionUUID string) (GitWorktreeData, error)
GetWorktreeDataBySessionUUID returns the git worktree data for the Session with the given UUID. Returns an empty GitWorktreeData (no error) if the session does not exist or is a directory-mode session without a dedicated worktree.
func (*EntRepository) List ¶
func (r *EntRepository) List(ctx context.Context) ([]InstanceData, error)
List retrieves all sessions from the database
func (*EntRepository) ListAnalytics ¶ added in v1.12.0
func (r *EntRepository) ListAnalytics(ctx context.Context, limit int) ([]AnalyticsData, error)
func (*EntRepository) ListAnalyticsByProgramSince ¶ added in v1.35.0
func (r *EntRepository) ListAnalyticsByProgramSince(ctx context.Context, program string, since time.Time, limit int) ([]AnalyticsData, error)
func (*EntRepository) ListAnalyticsSince ¶ added in v1.35.0
func (r *EntRepository) ListAnalyticsSince(ctx context.Context, since time.Time, limit int) ([]AnalyticsData, error)
func (*EntRepository) ListBacklogItemSummaries ¶ added in v1.37.0
func (r *EntRepository) ListBacklogItemSummaries(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemSummary, error)
ListBacklogItemSummaries returns lightweight BacklogItemSummary values for list views. Three-phase: (1) scalar fields via .All(), (2) item sessions + review verdicts via edge loading.
func (*EntRepository) ListBacklogItems ¶ added in v1.35.0
func (r *EntRepository) ListBacklogItems(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemData, error)
ListBacklogItems returns backlog items with optional filtering.
func (*EntRepository) ListByStatus ¶
func (r *EntRepository) ListByStatus(ctx context.Context, status Status) ([]InstanceData, error)
ListByStatus retrieves sessions filtered by status
func (*EntRepository) ListByStatusWithOptions ¶
func (r *EntRepository) ListByStatusWithOptions(ctx context.Context, status Status, options LoadOptions) ([]InstanceData, error)
ListByStatusWithOptions retrieves sessions filtered by status with selective loading. EntRepository: Delegates to ListByStatus with full loading.
func (*EntRepository) ListByTag ¶
func (r *EntRepository) ListByTag(ctx context.Context, tagName string) ([]InstanceData, error)
ListByTag retrieves sessions that have a specific tag
func (*EntRepository) ListByTagWithOptions ¶
func (r *EntRepository) ListByTagWithOptions(ctx context.Context, tag string, options LoadOptions) ([]InstanceData, error)
ListByTagWithOptions retrieves sessions with a specific tag with selective loading. EntRepository: Delegates to ListByTag with full loading.
func (*EntRepository) ListItemSessions ¶ added in v1.35.0
func (r *EntRepository) ListItemSessions(ctx context.Context, itemID string) ([]ItemSessionSummary, error)
ListItemSessions returns all ItemSessions for a given BacklogItem UUID string.
func (*EntRepository) ListItemSources ¶ added in v1.35.0
func (r *EntRepository) ListItemSources(ctx context.Context) ([]ItemSourceData, error)
ListItemSources returns all registered item sources.
func (*EntRepository) ListProgressNotesForItem ¶ added in v1.38.0
func (r *EntRepository) ListProgressNotesForItem(ctx context.Context, itemID string) ([]ProgressNoteData, error)
ListProgressNotesForItem returns the full append-only history of report_progress calls for a backlog item, ordered by created_at ascending (oldest first).
func (*EntRepository) ListProjects ¶ added in v1.23.0
func (r *EntRepository) ListProjects(ctx context.Context) ([]ProjectData, error)
ListProjects returns all projects.
func (*EntRepository) ListRecentCommandsByProgram ¶ added in v1.35.0
func (*EntRepository) ListSessions ¶
func (r *EntRepository) ListSessions(ctx context.Context, opts ContextOptions) ([]*Session, error)
ListSessions retrieves all sessions using the new Session domain model. Stub: not yet implemented; use InstanceData-based methods instead.
func (*EntRepository) ListShells ¶ added in v1.35.0
ListShells returns all shells for the given session title, ordered by order_index.
func (*EntRepository) ListSourceSyncEvents ¶ added in v1.35.0
func (r *EntRepository) ListSourceSyncEvents(ctx context.Context, sourceID string) ([]SourceSyncEventData, bool, error)
ListSourceSyncEvents returns sync history events for an item source, most recent first, capped at maxSourceSyncEventsHistory rows. truncated is true when older events exist beyond the cap — callers should surface this to avoid silently hiding history for sources with long or frequent sync runs.
func (*EntRepository) ListWithOptions ¶
func (r *EntRepository) ListWithOptions(ctx context.Context, options LoadOptions) ([]InstanceData, error)
ListWithOptions retrieves all sessions with selective child data loading. EntRepository: Delegates to List with full loading.
func (*EntRepository) MarkStuck ¶ added in v1.38.0
func (r *EntRepository) MarkStuck(ctx context.Context, itemID string, reason domain.StuckReason, expectedStatus BacklogStatus, stuckContext string) (applied bool, err error)
MarkStuck opens, refreshes, or reopens a durable BacklogStuckState row for the given item + reason via a resolve-in-place upsert on the (item_id, reason) unique index — there is exactly one row per pair at all times.
A best-effort item-status precondition is applied before writing: if the item's current status does not equal expectedStatus, MarkStuck returns (false, nil) without writing. This precondition is NOT atomic with the write itself (a concurrent transition can still race in between); the self-heal sweep (reconcile pipeline, Phase 2) is the correctness backstop for any stale write that still lands.
Row semantics on conflict with an existing (item_id, reason) row:
- OPEN row (resolved_at IS NULL): only last_checked_at and context are refreshed. first_detected_at and notified_at are left untouched, so notify-once dedup and the "stuck for N" duration both survive repeated ticks.
- RESOLVED row (resolved_at IS NOT NULL): the SAME row is reopened in place — resolved_at and notified_at are cleared and first_detected_at is reset to now — never a second row for the same pair.
Implementation note: this is two atomic statements (an INSERT ... ON CONFLICT upsert, then a conditional UPDATE ... WHERE resolved_at IS NOT NULL) inside one DB transaction, rather than a single raw SQL statement. Ent's generated upsert Update() callback has no portable way to express a per-row CASE WHEN keyed off the pre-existing resolved_at value without hand-written dialect-specific SQL, so the reopen adjustment is split into its own atomic, idempotent conditional UPDATE. Row-dedup itself — the concurrency-sensitive part — is still guaranteed by the single upsert statement; there is no read-then-write for detecting whether the row exists.
func (*EntRepository) MarkStuckNotified ¶ added in v1.38.0
func (r *EntRepository) MarkStuckNotified(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
MarkStuckNotified sets notified_at=now on an open, not-yet-notified stuck row — the durable notify-once dedup write, called once after a stuck notification has actually been sent. A no-op (not an error) if the row is already notified or doesn't exist.
func (*EntRepository) ReconcileStuckItems ¶ added in v1.35.0
func (r *EntRepository) ReconcileStuckItems(ctx context.Context) (int, error)
ReconcileStuckItems finds in_progress items whose all linked ItemSessions have ended, and transitions them to review status. Returns the count of transitioned items. All updates are wrapped in a single transaction so they succeed or fail atomically.
func (*EntRepository) RecordAnalytics ¶ added in v1.12.0
func (r *EntRepository) RecordAnalytics(ctx context.Context, data AnalyticsData) error
func (*EntRepository) ResolveStuck ¶ added in v1.38.0
func (r *EntRepository) ResolveStuck(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
ResolveStuck atomically, idempotently closes an open BacklogStuckState row via a single conditional UPDATE ... WHERE resolved_at IS NULL. Returns whether a row was actually resolved by this call; resolving an already-resolved or nonexistent (item_id, reason) row is a no-op, not an error, and never overwrites an existing resolved_at.
func (*EntRepository) SaveReviewVerdict ¶ added in v1.35.0
func (r *EntRepository) SaveReviewVerdict(ctx context.Context, itemSessionID string, verdict ReviewVerdictData) error
SaveReviewVerdict upserts a ReviewVerdict for a given ItemSession. The query-then-create/update is wrapped in a transaction to prevent a check-then-act race condition when concurrent callers save verdicts for the same item session.
func (*EntRepository) SnoozeStuckState ¶ added in v1.38.0
func (r *EntRepository) SnoozeStuckState(ctx context.Context, itemID string, reason domain.StuckReason, until time.Time) (bool, error)
SnoozeStuckState sets snoozed_until on an open BacklogStuckState row via a single atomic conditional UPDATE ... WHERE resolved_at IS NULL, matching the ResolveStuck pattern. Returns whether a row was actually updated by this call; snoozing a nonexistent or already-resolved (item_id, reason) row is a no-op, not an error. A snoozed-until-past-now value simply un-snoozes the row on the next FindOpenStuckStates read (its predicate is snoozed_until IS NULL OR snoozed_until < now).
func (*EntRepository) TransitionBacklogItemStatus ¶ added in v1.35.0
func (r *EntRepository) TransitionBacklogItemStatus(ctx context.Context, id string, toStatus BacklogStatus, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
TransitionBacklogItemStatus changes the status of a backlog item with optional precondition.
func (*EntRepository) Update ¶
func (r *EntRepository) Update(ctx context.Context, data InstanceData) error
Update modifies an existing session in the database
func (*EntRepository) UpdateAcCriterionStatus ¶ added in v1.35.0
func (r *EntRepository) UpdateAcCriterionStatus(ctx context.Context, itemID string, criterionIndex int, status string, note string) error
UpdateAcCriterionStatus updates a single acceptance criterion's status by index.
func (*EntRepository) UpdateBacklogItem ¶ added in v1.35.0
func (r *EntRepository) UpdateBacklogItem(ctx context.Context, id string, update BacklogItemUpdate, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
UpdateBacklogItem modifies an existing backlog item with optional precondition check.
func (*EntRepository) UpdateGitHubPRNumber ¶ added in v1.35.0
UpdateGitHubPRNumber persists a discovered PR number for a session. Called by PRStatusPoller when it auto-discovers a PR for a branch-based session.
func (*EntRepository) UpdateItemSessionEnded ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionEnded(ctx context.Context, id string, endedAt time.Time) error
UpdateItemSessionEnded records the end time for an ItemSession.
func (*EntRepository) UpdateItemSessionFileTouch ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionFileTouch(ctx context.Context, id string, touchAt time.Time) error
UpdateItemSessionFileTouch updates the last file touch timestamp on an ItemSession.
func (*EntRepository) UpdateItemSessionGitActivity ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionGitActivity(ctx context.Context, id string, sha, msg string, commitAt time.Time, commitCount int) error
UpdateItemSessionGitActivity updates git-related fields on an ItemSession.
func (*EntRepository) UpdateItemSessionSessionUUID ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionSessionUUID(ctx context.Context, id string, sessionUUID string) error
UpdateItemSessionSessionUUID updates the session_uuid field on an existing ItemSession.
func (*EntRepository) UpdateItemSessionStarted ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionStarted(ctx context.Context, id string, startedAt time.Time) error
UpdateItemSessionStarted records the start time for an ItemSession.
func (*EntRepository) UpdateItemSessionTriageResult ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSessionTriageResult(ctx context.Context, id string, triageResult string) error
UpdateItemSessionTriageResult stores the triage result JSON payload on an ItemSession.
func (*EntRepository) UpdateItemSessionVerificationNotes ¶ added in v1.37.0
func (r *EntRepository) UpdateItemSessionVerificationNotes(ctx context.Context, id string, verificationNotes string) error
UpdateItemSessionVerificationNotes stores the verification evidence reported via request_review (commands run, manual checks performed) on an ItemSession.
func (*EntRepository) UpdateItemSource ¶ added in v1.35.0
func (r *EntRepository) UpdateItemSource(ctx context.Context, id string, update ItemSourceUpdate) (*ItemSourceData, error)
UpdateItemSource modifies an existing item source.
func (*EntRepository) UpdateLastAcknowledged ¶ added in v1.35.0
func (r *EntRepository) UpdateLastAcknowledged(ctx context.Context, title string, t time.Time) error
UpdateLastAcknowledged sets only the last_acknowledged field for a session, issuing a single UPDATE WHERE title=? without a prior SELECT.
func (*EntRepository) UpdateLastAddedToQueue ¶ added in v1.35.0
func (r *EntRepository) UpdateLastAddedToQueue(ctx context.Context, title string, t time.Time) error
UpdateLastAddedToQueue sets only the last_added_to_queue field for a session, issuing a single UPDATE WHERE title=? without a prior SELECT.
func (*EntRepository) UpdateLastViewed ¶ added in v1.35.0
UpdateLastViewed sets only the last_viewed field for a session, issuing a single UPDATE WHERE title=? without a prior SELECT.
func (*EntRepository) UpdateProject ¶ added in v1.23.0
func (r *EntRepository) UpdateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
UpdateProject modifies an existing project.
func (*EntRepository) UpdateReviewQueueState ¶ added in v1.35.0
func (r *EntRepository) UpdateReviewQueueState(ctx context.Context, title string, lastUserResponse, processingGraceUntil, lastPromptDetected time.Time, lastPromptSignature string) error
UpdateReviewQueueState efficiently updates only the review-queue interaction fields for a session, avoiding the full read-modify-write cycle of updateFieldInRepo.
func (*EntRepository) UpdateSession ¶
func (r *EntRepository) UpdateSession(ctx context.Context, session *Session) error
UpdateSession updates an existing session using the Session domain model. Stub: not yet implemented; use InstanceData-based methods instead.
func (*EntRepository) UpdateSessionArtifacts ¶ added in v1.35.0
func (r *EntRepository) UpdateSessionArtifacts(ctx context.Context, title string, blob string) error
UpdateSessionArtifacts persists the JSON-encoded artifact blob for a session. Wrapped in a transaction for correctness under concurrent writes (M-6 fix). The per-title mutex in ArtifactExtractor (C-1) serializes calls at the application layer; the transaction is belt-and-suspenders for correctness.
func (*EntRepository) UpdateShellStatus ¶ added in v1.35.0
func (r *EntRepository) UpdateShellStatus(ctx context.Context, shellID, status string, exitCode *int) error
UpdateShellStatus updates the status (and optionally exit code + stopped_at) for a shell.
func (*EntRepository) UpdateTimestamps ¶
func (r *EntRepository) UpdateTimestamps(ctx context.Context, title string, lastTerminalUpdate, lastMeaningfulOutput time.Time, lastOutputSignature string) error
UpdateTimestamps efficiently updates only timestamp fields for a session
func (*EntRepository) UpsertRule ¶ added in v1.12.0
func (r *EntRepository) UpsertRule(ctx context.Context, data ApprovalRuleData) error
type EntWorkflowRepository ¶ added in v1.35.0
type EntWorkflowRepository struct {
// contains filtered or unexported fields
}
EntWorkflowRepository implements WorkflowRepository using the ent ORM.
func NewEntWorkflowRepository ¶ added in v1.35.0
func NewEntWorkflowRepository(client *ent.Client) *EntWorkflowRepository
NewEntWorkflowRepository creates a new ent-backed workflow repository.
func (*EntWorkflowRepository) Create ¶ added in v1.35.0
func (r *EntWorkflowRepository) Create(ctx context.Context, w WorkflowCreateInput) (*ent.Workflow, error)
Create inserts a new workflow definition. Returns ent.ConstraintError when a duplicate slug exists.
func (*EntWorkflowRepository) ListAll ¶ added in v1.35.0
ListAll returns all workflows sorted ascending by created_at. A safety cap of 1000 is applied to prevent runaway queries.
func (*EntWorkflowRepository) ListEnabled ¶ added in v1.35.0
ListEnabled returns only workflows where cron_enabled is true.
type ErrDuplicateTag ¶
type ErrDuplicateTag struct {
Tag string
}
ErrDuplicateTag is returned when adding a tag that already exists.
func (ErrDuplicateTag) Error ¶
func (e ErrDuplicateTag) Error() string
type ErrInvalidTransition ¶
ErrInvalidTransition is returned when a status transition is not allowed by the state machine defined in state_machine.go.
func (ErrInvalidTransition) Error ¶
func (e ErrInvalidTransition) Error() string
type ErrTagTooLong ¶
ErrTagTooLong is returned when a tag exceeds the maximum length.
func (ErrTagTooLong) Error ¶
func (e ErrTagTooLong) Error() string
type ErrTooManyTags ¶ added in v1.9.0
ErrTooManyTags is returned when setting more tags than MaxTagCount allows.
func (ErrTooManyTags) Error ¶ added in v1.9.0
func (e ErrTooManyTags) Error() string
type ExecutionOptions ¶
type ExecutionOptions struct {
// Timeout for command execution (0 = no timeout)
Timeout time.Duration
// MaxOutputSize limits captured output (0 = unlimited)
MaxOutputSize int
// StatusCheckInterval for polling status detector
StatusCheckInterval time.Duration
// TerminalStatuses are statuses that indicate command completion
TerminalStatuses []detection.DetectedStatus
}
ExecutionOptions configures command execution behavior.
func DefaultExecutionOptions ¶
func DefaultExecutionOptions() ExecutionOptions
DefaultExecutionOptions returns sensible defaults for command execution.
type ExecutionResult ¶
type ExecutionResult struct {
Command *Command
Success bool
Output string
Error error
StartTime time.Time
EndTime time.Time
FinalStatus detection.DetectedStatus
StatusChanges []StatusChange
}
ExecutionResult represents the result of a command execution.
type ExternalApprovalCallback ¶
type ExternalApprovalCallback func(*ExternalApprovalEvent)
ExternalApprovalCallback is called when an approval is detected.
type ExternalApprovalEvent ¶
type ExternalApprovalEvent struct {
Request *detection.ApprovalRequest
SessionID string // Socket path or unique identifier
SessionTitle string
Source ExternalApprovalSource
Cwd string
Command string
}
ExternalApprovalEvent represents an approval detected in an external session.
type ExternalApprovalMonitor ¶
type ExternalApprovalMonitor struct {
// contains filtered or unexported fields
}
ExternalApprovalMonitor monitors external sessions for approval requests.
func NewExternalApprovalMonitor ¶
func NewExternalApprovalMonitor() *ExternalApprovalMonitor
NewExternalApprovalMonitor creates a new external approval monitor.
func (*ExternalApprovalMonitor) GetAllPendingApprovals ¶
func (m *ExternalApprovalMonitor) GetAllPendingApprovals() map[string][]*detection.ApprovalRequest
GetAllPendingApprovals returns pending approvals across all monitored sessions.
func (*ExternalApprovalMonitor) GetDetector ¶
func (m *ExternalApprovalMonitor) GetDetector() *detection.ApprovalDetector
GetDetector returns the underlying approval detector for configuration.
func (*ExternalApprovalMonitor) GetMonitoredSessions ¶
func (m *ExternalApprovalMonitor) GetMonitoredSessions() []string
GetMonitoredSessions returns the socket paths of all monitored sessions.
func (*ExternalApprovalMonitor) GetPendingApprovals ¶
func (m *ExternalApprovalMonitor) GetPendingApprovals(socketPath string) []*detection.ApprovalRequest
GetPendingApprovals returns all pending approval requests for a session.
func (*ExternalApprovalMonitor) IntegrateWithDiscovery ¶
func (m *ExternalApprovalMonitor) IntegrateWithDiscovery( discovery *ExternalSessionDiscovery, streamerManager *ExternalStreamerManager, )
IntegrateWithDiscovery connects the approval monitor to external session discovery. This auto-monitors new external sessions as they're discovered.
func (*ExternalApprovalMonitor) IntegrateWithDiscoveryTmux ¶
func (m *ExternalApprovalMonitor) IntegrateWithDiscoveryTmux( discovery *ExternalSessionDiscovery, tmuxStreamerManager *ExternalTmuxStreamerManager, )
IntegrateWithDiscoveryTmux connects the approval monitor to external session discovery using tmux-based streaming instead of socket-based streaming.
func (*ExternalApprovalMonitor) MarkApprovalHandled ¶
func (m *ExternalApprovalMonitor) MarkApprovalHandled(socketPath, requestID string, approved bool) error
MarkApprovalHandled marks an approval request as handled.
func (*ExternalApprovalMonitor) MonitorSession ¶
func (m *ExternalApprovalMonitor) MonitorSession( streamer *ExternalStreamer, title string, source ExternalApprovalSource, ) error
MonitorSession starts monitoring an external session for approval requests.
func (*ExternalApprovalMonitor) MonitorSessionTmux ¶
func (m *ExternalApprovalMonitor) MonitorSessionTmux( streamer *ExternalTmuxStreamer, tmuxSessionName string, title string, source ExternalApprovalSource, ) error
MonitorSessionTmux starts monitoring an external session using tmux-based streaming.
func (*ExternalApprovalMonitor) OnApproval ¶
func (m *ExternalApprovalMonitor) OnApproval(callback ExternalApprovalCallback)
OnApproval registers a callback for approval events.
func (*ExternalApprovalMonitor) Start ¶
func (m *ExternalApprovalMonitor) Start()
Start begins monitoring for approvals.
func (*ExternalApprovalMonitor) Stop ¶
func (m *ExternalApprovalMonitor) Stop()
Stop stops all monitoring.
func (*ExternalApprovalMonitor) StopMonitoringSession ¶
func (m *ExternalApprovalMonitor) StopMonitoringSession(socketPath string)
StopMonitoringSession stops monitoring a specific session.
type ExternalApprovalSource ¶
type ExternalApprovalSource string
ExternalApprovalSource identifies the source of an external approval.
const ( SourceIntelliJ ExternalApprovalSource = "IntelliJ" SourceTerminal ExternalApprovalSource = "Terminal" SourceVSCode ExternalApprovalSource = "VS Code" SourceMux ExternalApprovalSource = "mux" SourceUnknown ExternalApprovalSource = "Unknown" )
type ExternalInstanceMetadata ¶
type ExternalInstanceMetadata struct {
// TmuxSocket is the tmux server socket this instance belongs to
// Empty string means the default tmux server
TmuxSocket string
// TmuxSessionName is the full tmux session name
TmuxSessionName string
// DiscoveredAt is when this external instance was first discovered
DiscoveredAt time.Time
// LastSeen is when this instance was last seen during discovery
LastSeen time.Time
// OriginalPID is the process ID when first discovered
OriginalPID int
// MuxSocketPath is the path to an ssq-mux Unix domain socket
// If set, this instance was discovered via ssq-mux and supports
// full bidirectional terminal access
MuxSocketPath string
// MuxEnabled indicates whether this instance supports mux protocol
MuxEnabled bool
// SourceTerminal identifies the source (e.g., "IntelliJ", "Terminal", "tmux")
SourceTerminal string
}
ExternalInstanceMetadata contains metadata for externally discovered Claude instances
type ExternalItem ¶ added in v1.35.0
type ExternalItem struct {
ExternalID string
Title string
Description string
Labels []string
Priority int // 1-5, derived from labels
URL string
}
ExternalItem is a platform-agnostic representation of an external issue/ticket.
type ExternalSessionDiscovery ¶
type ExternalSessionDiscovery struct {
// contains filtered or unexported fields
}
ExternalSessionDiscovery discovers and manages external Claude sessions from ssq-mux multiplexed terminals.
func NewExternalSessionDiscovery ¶
func NewExternalSessionDiscovery() *ExternalSessionDiscovery
NewExternalSessionDiscovery creates a new external session discovery service.
func (*ExternalSessionDiscovery) GetSession ¶
func (e *ExternalSessionDiscovery) GetSession(socketPath string) *Instance
GetSession returns a specific external session by socket path (deprecated - use GetSessionByTmux).
func (*ExternalSessionDiscovery) GetSessionByTmux ¶
func (e *ExternalSessionDiscovery) GetSessionByTmux(tmuxSessionName string) *Instance
GetSessionByTmux returns a specific external session by tmux session name.
func (*ExternalSessionDiscovery) GetSessions ¶
func (e *ExternalSessionDiscovery) GetSessions() []*Instance
GetSessions returns all currently discovered external sessions.
func (*ExternalSessionDiscovery) OnSessionAdded ¶
func (e *ExternalSessionDiscovery) OnSessionAdded(callback func(*Instance))
OnSessionAdded registers a callback for when a new external session is discovered. Multiple callbacks can be registered and will all be invoked.
func (*ExternalSessionDiscovery) OnSessionRemoved ¶
func (e *ExternalSessionDiscovery) OnSessionRemoved(callback func(*Instance))
OnSessionRemoved registers a callback for when an external session is removed. Multiple callbacks can be registered and will all be invoked.
func (*ExternalSessionDiscovery) Start ¶
func (e *ExternalSessionDiscovery) Start(interval time.Duration)
Start begins periodic discovery of external sessions.
func (*ExternalSessionDiscovery) Stop ¶
func (e *ExternalSessionDiscovery) Stop()
Stop stops the discovery service.
type ExternalStreamer ¶
type ExternalStreamer struct {
// contains filtered or unexported fields
}
ExternalStreamer connects to a mux socket and streams terminal output. It handles reconnection and broadcasts output to registered consumers.
func NewExternalStreamer ¶
func NewExternalStreamer(socketPath string, bufferSize int) *ExternalStreamer
NewExternalStreamer creates a new streamer for the given mux socket.
func (*ExternalStreamer) AddConsumer ¶
func (s *ExternalStreamer) AddConsumer(consumer OutputConsumer, catchUp bool) string
AddConsumer registers a callback to receive output data. If catchUp is true, the consumer receives buffered recent output first. Returns a token that must be passed to RemoveConsumer to deregister.
func (*ExternalStreamer) ConsumerCount ¶
func (s *ExternalStreamer) ConsumerCount() int
ConsumerCount returns the number of registered consumers.
func (*ExternalStreamer) GetMetadata ¶
func (s *ExternalStreamer) GetMetadata() *mux.SessionMetadata
GetMetadata returns the session metadata from the mux.
func (*ExternalStreamer) GetRecentOutput ¶
func (s *ExternalStreamer) GetRecentOutput() []byte
GetRecentOutput returns the buffered recent output.
func (*ExternalStreamer) GetSnapshot ¶
func (s *ExternalStreamer) GetSnapshot() ([]byte, error)
GetSnapshot requests a clean screen snapshot from the mux session. This uses tmux capture-pane on the server side to get clean terminal content without ANSI escape sequences, suitable for pattern matching and initial state. The snapshot request is coordinated with the readLoop to avoid race conditions.
func (*ExternalStreamer) IsConnected ¶
func (s *ExternalStreamer) IsConnected() bool
IsConnected returns whether the streamer is currently connected.
func (*ExternalStreamer) RemoveConsumer ¶
func (s *ExternalStreamer) RemoveConsumer(key string)
RemoveConsumer deregisters a consumer by the token returned from AddConsumer.
func (*ExternalStreamer) SendInput ¶
func (s *ExternalStreamer) SendInput(data []byte) error
SendInput sends input data to the mux session.
func (*ExternalStreamer) SendResize ¶
func (s *ExternalStreamer) SendResize(cols, rows uint16) error
SendResize sends a terminal resize command to the mux session.
func (*ExternalStreamer) SocketPath ¶
func (s *ExternalStreamer) SocketPath() string
SocketPath returns the path to the mux socket.
func (*ExternalStreamer) Start ¶
func (s *ExternalStreamer) Start() error
Start connects to the mux socket and begins streaming.
func (*ExternalStreamer) Stop ¶
func (s *ExternalStreamer) Stop()
Stop disconnects and stops the streamer.
type ExternalStreamerManager ¶
type ExternalStreamerManager struct {
// contains filtered or unexported fields
}
ExternalStreamerManager manages multiple external streamers.
func NewExternalStreamerManager ¶
func NewExternalStreamerManager(bufferSize int) *ExternalStreamerManager
NewExternalStreamerManager creates a new streamer manager.
func (*ExternalStreamerManager) Count ¶
func (m *ExternalStreamerManager) Count() int
Count returns the number of active streamers.
func (*ExternalStreamerManager) Get ¶
func (m *ExternalStreamerManager) Get(socketPath string) *ExternalStreamer
Get returns a streamer if it exists.
func (*ExternalStreamerManager) GetOrCreate ¶
func (m *ExternalStreamerManager) GetOrCreate(socketPath string) (*ExternalStreamer, error)
GetOrCreate returns an existing streamer or creates a new one.
func (*ExternalStreamerManager) Remove ¶
func (m *ExternalStreamerManager) Remove(socketPath string)
Remove stops and removes a streamer.
func (*ExternalStreamerManager) StopAll ¶
func (m *ExternalStreamerManager) StopAll()
StopAll stops all streamers.
type ExternalTmuxStreamer ¶
type ExternalTmuxStreamer struct {
// contains filtered or unexported fields
}
ExternalTmuxStreamer provides terminal content streaming for external sessions.
It uses two strategies in priority order:
Control mode (preferred): Starts "tmux -C attach-session -t <name> -r" which provides real-time %output notifications via the tmux control protocol. When an %output event arrives it signals that the pane content has changed, triggering a single capture-pane call to obtain the full terminal snapshot. This eliminates blind polling while preserving the full-snapshot semantic that consumers expect.
Capture-pane polling (fallback): If control mode fails to start (e.g. older tmux, session not found) the streamer falls back to polling capture-pane every 500ms. This is less responsive but universally compatible.
func NewExternalTmuxStreamer ¶
func NewExternalTmuxStreamer(tmuxSessionName string) *ExternalTmuxStreamer
NewExternalTmuxStreamer creates a new tmux-based streamer for an external session.
func (*ExternalTmuxStreamer) AddConsumer ¶
func (s *ExternalTmuxStreamer) AddConsumer(consumer func(content string)) string
AddConsumer registers a callback to receive content updates. The consumer will be called with the full terminal content whenever it changes. Returns a token that must be passed to RemoveConsumer to deregister.
func (*ExternalTmuxStreamer) ConsumerCount ¶
func (s *ExternalTmuxStreamer) ConsumerCount() int
ConsumerCount returns the number of registered consumers.
func (*ExternalTmuxStreamer) GetContent ¶
func (s *ExternalTmuxStreamer) GetContent() string
GetContent returns the current terminal content.
func (*ExternalTmuxStreamer) IsRunning ¶
func (s *ExternalTmuxStreamer) IsRunning() bool
IsRunning returns whether the streamer is currently running.
func (*ExternalTmuxStreamer) RemoveConsumer ¶
func (s *ExternalTmuxStreamer) RemoveConsumer(key string)
RemoveConsumer deregisters a consumer by the token returned from AddConsumer.
func (*ExternalTmuxStreamer) Start ¶
func (s *ExternalTmuxStreamer) Start() error
Start begins streaming the tmux session for content changes. It first attempts to use tmux control mode for event-driven updates. If control mode is unavailable, it falls back to capture-pane polling.
type ExternalTmuxStreamerManager ¶
type ExternalTmuxStreamerManager struct {
// contains filtered or unexported fields
}
ExternalTmuxStreamerManager manages multiple external tmux streamers.
func NewExternalTmuxStreamerManager ¶
func NewExternalTmuxStreamerManager() *ExternalTmuxStreamerManager
NewExternalTmuxStreamerManager creates a new streamer manager.
func (*ExternalTmuxStreamerManager) Count ¶
func (m *ExternalTmuxStreamerManager) Count() int
Count returns the number of active streamers.
func (*ExternalTmuxStreamerManager) Get ¶
func (m *ExternalTmuxStreamerManager) Get(tmuxSessionName string) *ExternalTmuxStreamer
Get returns a streamer if it exists.
func (*ExternalTmuxStreamerManager) GetOrCreate ¶
func (m *ExternalTmuxStreamerManager) GetOrCreate(tmuxSessionName string) (*ExternalTmuxStreamer, error)
GetOrCreate returns an existing streamer or creates a new one.
func (*ExternalTmuxStreamerManager) Remove ¶
func (m *ExternalTmuxStreamerManager) Remove(tmuxSessionName string)
Remove stops and removes a streamer.
func (*ExternalTmuxStreamerManager) StopAll ¶
func (m *ExternalTmuxStreamerManager) StopAll()
StopAll stops all streamers.
type FilesystemContext ¶
type FilesystemContext struct {
// ProjectPath is the root project/repository directory
ProjectPath string `json:"project_path,omitempty"`
// WorkingDir is the current working directory within the project
WorkingDir string `json:"working_dir,omitempty"`
// IsWorktree indicates if this session is using a git worktree
IsWorktree bool `json:"is_worktree,omitempty"`
// MainRepoPath is the parent repository path if this is a worktree
MainRepoPath string `json:"main_repo_path,omitempty"`
// ClonedRepoPath is the path to the cloned repository for external PRs
ClonedRepoPath string `json:"cloned_repo_path,omitempty"`
// ExistingWorktree is the path to an existing worktree being used
ExistingWorktree string `json:"existing_worktree,omitempty"`
// SessionType indicates the type of session workflow
SessionType SessionType `json:"session_type,omitempty"`
}
FilesystemContext represents the filesystem-related context for a session. This includes project paths, working directories, and worktree information.
func (*FilesystemContext) IsEmpty ¶
func (f *FilesystemContext) IsEmpty() bool
IsEmpty returns true if the FilesystemContext has no meaningful data
type ForceReleaseFunc ¶ added in v1.35.0
type ForceReleaseFunc func()
ForceReleaseFunc marks an unconditional-teardown closure: evicts regardless of refcount. No wrapper of ForceRelease exists in this plan — ForceRelease is always called directly with a sessionID. This type exists so that if a future caller wraps ForceRelease into a closure, the return type says so explicitly instead of degrading to a bare func().
type GitContext ¶
type GitContext struct {
// Branch is the current git branch name
Branch string `json:"branch,omitempty"`
// BaseCommitSHA is the commit SHA where this branch diverged from main/master
BaseCommitSHA string `json:"base_commit_sha,omitempty"`
// WorktreeID is a foreign key to the worktrees table (nil if no worktree)
WorktreeID *int64 `json:"worktree_id,omitempty"`
// PRNumber is the pull request number
PRNumber int `json:"pr_number,omitempty"`
// PRURL is the full URL to the pull request
PRURL string `json:"pr_url,omitempty"`
// Owner is the GitHub repository owner/organization
Owner string `json:"owner,omitempty"`
// Repo is the GitHub repository name
Repo string `json:"repo,omitempty"`
// SourceRef is the source branch reference for the PR
SourceRef string `json:"source_ref,omitempty"`
}
GitContext represents the Git-related context for a session. This includes repository information, branch details, and GitHub PR integration.
func (*GitContext) IsEmpty ¶
func (g *GitContext) IsEmpty() bool
IsEmpty returns true if the GitContext has no meaningful data
type GitHubIntegration ¶ added in v1.35.0
type GitHubIntegration struct {
// Repository identity and PR linkage
GitHubPRNumber int
GitHubPRURL string
GitHubOwner string
GitHubRepo string
GitHubSourceRef string
ClonedRepoPath string
MainRepoPath string
IsWorktree bool
GitHubIsFork bool
// PR status fields (populated by PRStatusPoller)
GitHubPRState string
GitHubPRIsDraft bool
GitHubPRPriority string
GitHubApprovedCount int
GitHubChangesReqCount int
GitHubCheckConclusion string
GitHubPRStatusTerminal bool
LastPRStatusCheck time.Time
}
GitHubIntegration groups all GitHub PR / URL integration fields within InstanceSnapshot (CDD Epic 3, Task 3.1a). Access via snap.GitHub.GitHubPRURL etc.
type GitHubIssuesPlugin ¶ added in v1.35.0
type GitHubIssuesPlugin struct{}
GitHubIssuesPlugin fetches backlog items from a GitHub repository's issue tracker.
func NewGitHubIssuesPlugin ¶ added in v1.35.0
func NewGitHubIssuesPlugin() *GitHubIssuesPlugin
NewGitHubIssuesPlugin returns a new GitHubIssuesPlugin.
func (*GitHubIssuesPlugin) Fetch ¶ added in v1.35.0
func (g *GitHubIssuesPlugin) Fetch(ctx context.Context, config PluginConfig, cursor string) ([]ExternalItem, string, error)
Fetch retrieves new and updated GitHub issues since the cursor. The cursor is an ISO 8601 timestamp passed as the `since` query parameter. Returns the updated cursor (the most recent updated_at seen) and the fetched items. If the token field is empty, Fetch returns an empty list and the original cursor.
func (*GitHubIssuesPlugin) MapToBacklogItem ¶ added in v1.35.0
func (g *GitHubIssuesPlugin) MapToBacklogItem(item ExternalItem, sourceID string) BacklogItemData
MapToBacklogItem converts a GitHub ExternalItem to a BacklogItemData.
func (*GitHubIssuesPlugin) PluginID ¶ added in v1.35.0
func (g *GitHubIssuesPlugin) PluginID() string
PluginID returns the unique identifier for this plugin.
type GitHubMetadataView ¶
type GitHubMetadataView struct {
PRNumber int
PRURL string
Owner string
Repo string
SourceRef string
ClonedRepoPath string
}
GitHubMetadataView is a read-only value object for GitHub session metadata. Constructed by Instance.GitHub() from the underlying fields. This is intentionally a value type (not a pointer) for safe concurrent reads.
func (GitHubMetadataView) IsEmpty ¶
func (gh GitHubMetadataView) IsEmpty() bool
IsEmpty returns true if no GitHub metadata is set.
func (GitHubMetadataView) IsGitHubSession ¶
func (gh GitHubMetadataView) IsGitHubSession() bool
IsGitHubSession returns true if owner and repo are both set.
func (GitHubMetadataView) IsPRSession ¶
func (gh GitHubMetadataView) IsPRSession() bool
IsPRSession returns true if this metadata represents a PR-based session.
func (GitHubMetadataView) PRDisplayInfo ¶
func (gh GitHubMetadataView) PRDisplayInfo() string
PRDisplayInfo returns human-readable PR description for UI display. Returns empty string if not a PR session.
func (GitHubMetadataView) RepoFullName ¶
func (gh GitHubMetadataView) RepoFullName() string
RepoFullName returns "owner/repo" format, or empty string if either is missing.
type GitHubPRsPlugin ¶ added in v1.35.0
type GitHubPRsPlugin struct{}
GitHubPRsPlugin fetches open pull requests from a GitHub repository.
func NewGitHubPRsPlugin ¶ added in v1.35.0
func NewGitHubPRsPlugin() *GitHubPRsPlugin
NewGitHubPRsPlugin returns a new GitHubPRsPlugin.
func (*GitHubPRsPlugin) Fetch ¶ added in v1.35.0
func (g *GitHubPRsPlugin) Fetch(ctx context.Context, config PluginConfig, cursor string) ([]ExternalItem, string, error)
Fetch retrieves open pull requests. Cursor is unused (full refresh each time). Returns empty list when token is absent.
func (*GitHubPRsPlugin) MapToBacklogItem ¶ added in v1.35.0
func (g *GitHubPRsPlugin) MapToBacklogItem(item ExternalItem, sourceID string) BacklogItemData
MapToBacklogItem converts a GitHub PR ExternalItem to a BacklogItemData.
func (*GitHubPRsPlugin) PluginID ¶ added in v1.35.0
func (g *GitHubPRsPlugin) PluginID() string
PluginID returns the unique identifier for this plugin.
type GitHubRef ¶
type GitHubRef struct {
Owner string
Repo string
Branch string
PRNumber int
Type GitHubRefType
}
GitHubRef represents a parsed GitHub reference.
func ParseGitHubURL ¶
ParseGitHubURL parses a GitHub URL and returns the components. Supported formats:
- https://github.com/owner/repo
- https://github.com/owner/repo.git
- https://github.com/owner/repo/tree/branch
- https://github.com/owner/repo/pull/123
- owner/repo (shorthand)
- owner/repo:branch (shorthand with branch)
type GitHubRefType ¶
type GitHubRefType int
GitHubRefType indicates what kind of GitHub reference this is.
const ( GitHubRefTypeRepo GitHubRefType = iota GitHubRefTypeBranch GitHubRefTypePR )
type GitManager ¶ added in v1.15.0
type GitManager interface {
HasWorktree() bool
GetWorktree() *git.GitWorktree
SetWorktree(*git.GitWorktree)
GetWorktreePath() string
GetRepoPath() string
GetRepoName() string
GetBranchName() string
GetBaseCommitSHA() string
Setup() error
Cleanup() error
Remove() error
Prune() error
IsDirty() (bool, error)
InvalidateDirtyCache()
CommitChanges(commitMsg string) error
PushChanges(commitMsg string, open bool) error
IsBranchCheckedOut() (bool, error)
OpenBranchURL() error
ComputeDiffIfReady() (stats *git.DiffStats, needsPause bool)
ComputeDiff() *git.DiffStats
UpdateDiffStats()
GetDiffStats() *git.DiffStats
SetDiffStats(*git.DiffStats)
ClearDiffStats()
GetCurrentCommitSHA() (string, error)
PrimeDirtyCacheJitter()
}
GitManager is the interface satisfied by *GitWorktreeManager. It covers all git worktree operations used by Instance and can be implemented by test doubles to avoid requiring a real git repository.
type GitWorktreeData ¶
type GitWorktreeData struct {
RepoPath string `json:"repo_path"`
WorktreePath string `json:"worktree_path"`
SessionName string `json:"session_name"`
BranchName string `json:"branch_name"`
BaseCommitSHA string `json:"base_commit_sha"`
}
GitWorktreeData represents the serializable data of a GitWorktree
type GitWorktreeManager ¶
type GitWorktreeManager struct {
// contains filtered or unexported fields
}
GitWorktreeManager owns the git worktree and diff-stats state that were previously bare fields on Instance.
Instance keeps thin wrapper methods that delegate here. GitWorktreeManager itself has no knowledge of Instance lifecycle; it only manages the worktree and diff operations.
worktree/diffStats are guarded by mu, not by Instance.stateMutex: setup (setupFirstTimeWorktree, called under Instance.startMu) and read-side callers (e.g. GetEffectiveRootDir) don't consistently hold stateMutex, so GitWorktreeManager protects its own fields directly.
func (*GitWorktreeManager) Cleanup ¶
func (gm *GitWorktreeManager) Cleanup() error
Cleanup removes the worktree from the filesystem and git metadata. Returns nil if no worktree is set.
func (*GitWorktreeManager) ClearDiffStats ¶
func (gm *GitWorktreeManager) ClearDiffStats()
ClearDiffStats sets diffStats to nil.
func (*GitWorktreeManager) CommitChanges ¶
func (gm *GitWorktreeManager) CommitChanges(commitMsg string) error
CommitChanges stages all changes and creates a commit.
func (*GitWorktreeManager) ComputeDiff ¶
func (gm *GitWorktreeManager) ComputeDiff() *git.DiffStats
ComputeDiff runs git diff and returns the result without storing it. Returns nil if no worktree is set.
func (*GitWorktreeManager) ComputeDiffIfReady ¶
func (gm *GitWorktreeManager) ComputeDiffIfReady() (stats *git.DiffStats, needsPause bool)
ComputeDiffIfReady checks if the worktree path exists and computes a new diff. Returns (stats, needsPause) where needsPause is true if the worktree directory is missing. This method performs I/O and should be called WITHOUT holding Instance.mu. Returns (nil, false) if no worktree is set.
func (*GitWorktreeManager) GetBaseCommitSHA ¶
func (gm *GitWorktreeManager) GetBaseCommitSHA() string
GetBaseCommitSHA returns the base commit SHA or "" if no worktree.
func (*GitWorktreeManager) GetBranchName ¶
func (gm *GitWorktreeManager) GetBranchName() string
GetBranchName returns the branch name or "" if no worktree.
func (*GitWorktreeManager) GetCurrentCommitSHA ¶
func (gm *GitWorktreeManager) GetCurrentCommitSHA() (string, error)
GetCurrentCommitSHA returns the current HEAD commit SHA for the worktree. Returns an empty string (not an error) if no worktree is set or the repo has no commits yet — this is safe to use in checkpoint creation.
func (*GitWorktreeManager) GetDiffStats ¶
func (gm *GitWorktreeManager) GetDiffStats() *git.DiffStats
GetDiffStats returns the most recently computed diff stats (may be nil).
func (*GitWorktreeManager) GetDirBaseSHA ¶ added in v1.37.0
func (gm *GitWorktreeManager) GetDirBaseSHA() string
GetDirBaseSHA returns the base commit SHA for directory-mode diff computation.
func (*GitWorktreeManager) GetRepoName ¶
func (gm *GitWorktreeManager) GetRepoName() string
GetRepoName returns the repository name or "" if no worktree.
func (*GitWorktreeManager) GetRepoPath ¶
func (gm *GitWorktreeManager) GetRepoPath() string
GetRepoPath returns the repo root path or "" if no worktree.
func (*GitWorktreeManager) GetWorktree ¶
func (gm *GitWorktreeManager) GetWorktree() *git.GitWorktree
GetWorktree returns the underlying GitWorktree (may be nil before Setup).
func (*GitWorktreeManager) GetWorktreePath ¶
func (gm *GitWorktreeManager) GetWorktreePath() string
GetWorktreePath returns the worktree path or "" if no worktree.
func (*GitWorktreeManager) HasWorktree ¶
func (gm *GitWorktreeManager) HasWorktree() bool
HasWorktree reports whether a git worktree has been initialized.
func (*GitWorktreeManager) InvalidateDirtyCache ¶ added in v1.35.0
func (gm *GitWorktreeManager) InvalidateDirtyCache()
InvalidateDirtyCache clears the IsDirty TTL cache so the next call re-runs git status. Call after transitions that may change worktree dirty state (Resume, Stop). No-op if no worktree is set.
func (*GitWorktreeManager) IsBranchCheckedOut ¶
func (gm *GitWorktreeManager) IsBranchCheckedOut() (bool, error)
IsBranchCheckedOut reports whether the branch is currently checked out.
func (*GitWorktreeManager) IsDirty ¶
func (gm *GitWorktreeManager) IsDirty() (bool, error)
IsDirty reports whether the worktree has uncommitted changes.
func (*GitWorktreeManager) OpenBranchURL ¶
func (gm *GitWorktreeManager) OpenBranchURL() error
OpenBranchURL opens the branch URL in the browser.
func (*GitWorktreeManager) PrimeDirtyCacheJitter ¶ added in v1.35.0
func (gm *GitWorktreeManager) PrimeDirtyCacheJitter()
PrimeDirtyCacheJitter staggers the dirty-cache TTL by setting the cache timestamp to a random point in [now-IsDirtyCacheTTL, now). Call this when adding a session to the poller so sessions added in a burst don't all run git-status subprocesses simultaneously when their caches expire.
func (*GitWorktreeManager) Prune ¶
func (gm *GitWorktreeManager) Prune() error
Prune cleans up stale worktree references.
func (*GitWorktreeManager) PushChanges ¶
func (gm *GitWorktreeManager) PushChanges(commitMsg string, open bool) error
PushChanges commits and pushes the worktree branch.
func (*GitWorktreeManager) Remove ¶
func (gm *GitWorktreeManager) Remove() error
Remove removes the worktree from git without pruning.
func (*GitWorktreeManager) SetDiffStats ¶
func (gm *GitWorktreeManager) SetDiffStats(stats *git.DiffStats)
SetDiffStats directly replaces the diff stats (used during deserialization).
func (*GitWorktreeManager) SetDirBaseSHA ¶ added in v1.37.0
func (gm *GitWorktreeManager) SetDirBaseSHA(sha string)
SetDirBaseSHA sets the base commit SHA for directory-mode diff computation.
func (*GitWorktreeManager) SetWorktree ¶
func (gm *GitWorktreeManager) SetWorktree(wt *git.GitWorktree)
SetWorktree replaces the underlying GitWorktree. Used during session start and by tests.
func (*GitWorktreeManager) Setup ¶
func (gm *GitWorktreeManager) Setup() error
Setup prepares the worktree (creates directories, checks out branch, etc.).
func (*GitWorktreeManager) UpdateDiffStats ¶
func (gm *GitWorktreeManager) UpdateDiffStats()
UpdateDiffStats computes a new diff and stores it. Returns nil and clears stats if worktree is not ready.
type HeadlessPoolClient ¶ added in v1.35.0
type HeadlessPoolClient interface {
CallBlocking(ctx context.Context, key headless.FeatureKey, systemPrompt string, userPrompt string, opts headless.CallOptions) (string, float64, error)
}
HeadlessPoolClient is the narrow interface AutonomousDriver needs from the headless pool. *headless.Pool satisfies this interface directly.
type HeadlessTriageResult ¶ added in v1.35.0
type HeadlessTriageResult struct {
Title string `json:"title"`
Summary string `json:"summary"`
Suggestions []TriageSuggestion `json:"suggestions"`
Tasks []TriageTask `json:"tasks,omitempty"`
AcceptanceCriteria []AcCriterion `json:"acceptance_criteria,omitempty"`
// Iteration and Feedback are not part of the LLM's JSON output — the caller
// sets them after parsing, from server-tracked state, before persisting.
Iteration int `json:"iteration,omitempty"`
Feedback string `json:"feedback,omitempty"`
}
HeadlessTriageResult is the parsed output from a headless triage LLM call.
func ParseHeadlessTriageResult ¶ added in v1.35.0
func ParseHeadlessTriageResult(raw string) (HeadlessTriageResult, error)
ParseHeadlessTriageResult unmarshals an LLM JSON response into HeadlessTriageResult. Tolerates preamble text before the JSON block (e.g. "Here is the result:\n\n{...}") and stray unrelated braces earlier in the response (e.g. an illustrative snippet).
The triage prompt instructs the model to emit the JSON object last, so candidates are tried from the end of the response backwards — the first candidate (i.e. the last brace-delimited span in raw) that unmarshals cleanly wins. This correctly skips over any earlier decoy object that happens to also be syntactically valid JSON but isn't the real result.
Caps tasks at maxHeadlessTriageTasks.
type HealthCheckResult ¶
type HealthCheckResult struct {
InstanceTitle string
IsHealthy bool
Issues []string
Actions []string
RecoveryAttempted bool
RecoverySuccess bool
}
HealthCheckResult represents the result of a session health check
type HibernationSweeper ¶ added in v1.35.0
type HibernationSweeper struct {
// contains filtered or unexported fields
}
HibernationSweeper periodically checks all sessions and hibernates those that have been idle longer than the configured timeout or that are consuming memory while the system is under pressure.
func NewHibernationSweeper ¶ added in v1.35.0
func NewHibernationSweeper(storage *Storage, cfg *appconfig.Config, reader memory.Reader) *HibernationSweeper
NewHibernationSweeper creates a HibernationSweeper using the given storage, config, and memory reader.
func (*HibernationSweeper) GetCachedRSSMB ¶ added in v1.35.0
func (s *HibernationSweeper) GetCachedRSSMB(sessionUUID string) int64
GetCachedRSSMB returns the last-measured RSS in MB for the given session UUID. Returns 0 if not yet measured or entry expired. Implements MemoryCacheReader.
func (*HibernationSweeper) SetLiveProvider ¶ added in v1.35.0
func (s *HibernationSweeper) SetLiveProvider(p LiveInstancesProvider)
SetLiveProvider wires the fast-path instance source. Call this after constructing the ReviewQueuePoller so that sweep() uses live in-memory instances instead of calling LoadInstances() (which spawns PTY/tmux subprocesses).
func (*HibernationSweeper) Start ¶ added in v1.35.0
func (s *HibernationSweeper) Start(ctx context.Context)
Start runs the periodic sweep loop. Blocks until ctx is cancelled.
func (*HibernationSweeper) SystemMemoryPct ¶ added in v1.35.0
func (s *HibernationSweeper) SystemMemoryPct() (float64, error)
SystemMemoryPct returns the current system memory usage percentage. The result is cached for sysMemCacheTTL to avoid a syscall on every ListSessions request. The mutex is released before calling the reader to avoid holding the lock during /proc I/O. Implements MemoryCacheReader.
type HistoryAdapter ¶ added in v1.35.0
type HistoryAdapter interface {
Name() string
CanHandle(program string) bool
// Import reads this CLI's native format and returns canonical turns.
Import(ctx context.Context, inst *Instance) ([]CanonicalTurn, error)
// Export writes canonical turns into this CLI's native format so it can resume.
Export(ctx context.Context, turns []CanonicalTurn, inst *Instance) error
}
type HistoryEntry ¶
type HistoryEntry struct {
Command Command `json:"command"`
Result *ExecutionResult `json:"result,omitempty"`
Timestamp time.Time `json:"timestamp"`
SessionName string `json:"session_name"`
ExecutionTime time.Duration `json:"execution_time"`
}
HistoryEntry represents a single command execution in history.
type HistoryFileDetector ¶
type HistoryFileDetector struct {
// contains filtered or unexported fields
}
HistoryFileDetector detects Claude JSONL history files for a given process.
func NewHistoryFileDetector ¶
func NewHistoryFileDetector(inspector ProcessFileInspector) *HistoryFileDetector
NewHistoryFileDetector creates a new HistoryFileDetector.
func NewHistoryFileDetectorWithHomeDir ¶ added in v1.12.0
func NewHistoryFileDetectorWithHomeDir(inspector ProcessFileInspector, homeDir string) *HistoryFileDetector
NewHistoryFileDetectorWithHomeDir creates a HistoryFileDetector with a fixed home directory. Use this in tests to avoid writing to the real home dir.
func NewHistoryFileDetectorWithRealInspector ¶
func NewHistoryFileDetectorWithRealInspector() *HistoryFileDetector
NewHistoryFileDetectorWithRealInspector creates a HistoryFileDetector using the real gopsutil-based ProcessInspector on darwin.
func (*HistoryFileDetector) Detect ¶
func (d *HistoryFileDetector) Detect(pid int32) (*HistoryFileInfo, error)
Detect scans the open files of the given PID for Claude JSONL history files. Returns nil, nil if no matching file is found or the process is dead.
func (*HistoryFileDetector) DetectByPath ¶ added in v1.12.0
func (d *HistoryFileDetector) DetectByPath(projectPath string) (*HistoryFileInfo, error)
DetectByPath scans ~/.claude/projects/<encoded-path>/ for the most recently modified conversation JSONL file. It does NOT require a live process, making it suitable for sessions whose tmux session is dead (e.g. after a reboot).
Returns nil, nil if the project directory does not exist or contains no valid conversation files.
type HistoryFileInfo ¶
HistoryFileInfo contains information about a detected Claude history file.
type HistoryFileWatcher ¶
type HistoryFileWatcher struct {
// contains filtered or unexported fields
}
HistoryFileWatcher watches ~/.claude/projects/ for new JSONL files.
func NewHistoryFileWatcher ¶
func NewHistoryFileWatcher(watchDir string, callback func(filePath string)) *HistoryFileWatcher
NewHistoryFileWatcher creates a watcher for the given directory. If watchDir is empty, defaults to ~/.claude/projects/.
func (*HistoryFileWatcher) Start ¶
func (w *HistoryFileWatcher) Start(ctx context.Context) error
Start begins watching the directory. It returns without error even if the directory does not exist (degraded mode — polling fallback still works).
func (*HistoryFileWatcher) Stopped ¶ added in v1.35.0
func (w *HistoryFileWatcher) Stopped() <-chan struct{}
Stopped returns a channel that is closed when the watcher goroutine has exited.
type HistoryLinker ¶
type HistoryLinker struct {
// contains filtered or unexported fields
}
HistoryLinker is a background service that correlates running sessions with their Claude JSONL history files. It populates Instance.claudeSession.ConversationUUID and Instance.HistoryFilePath when a conversation file is detected.
Detection uses two complementary paths:
- Polling (every 5 s): scans all running sessions via proc_pidinfo open-files
- fsnotify (fast path): watcher callback fires as soon as a new JSONL is created
Both paths call the same correlateSession helper, which is idempotent. Sessions that repeatedly yield no JSONL file are throttled via exponential backoff to reduce subprocess spawn rate on idle worktrees.
func NewHistoryLinker ¶
func NewHistoryLinker(detector *HistoryFileDetector, watcher *HistoryFileWatcher) *HistoryLinker
NewHistoryLinker creates a HistoryLinker backed by the given detector and watcher. Call SetInstances (or AddInstance) to register sessions before starting.
func NewHistoryLinkerFromRealInspector ¶ added in v1.8.0
func NewHistoryLinkerFromRealInspector() *HistoryLinker
NewHistoryLinkerFromRealInspector creates a HistoryLinker backed by the real gopsutil-based process inspector and an fsnotify watcher on ~/.claude/projects/. This is the production constructor; use NewHistoryLinker in tests.
func (*HistoryLinker) AddInstance ¶
func (hl *HistoryLinker) AddInstance(instance *Instance)
AddInstance adds a single instance for monitoring.
func (*HistoryLinker) Instances ¶ added in v1.8.0
func (hl *HistoryLinker) Instances() []*Instance
Instances returns a snapshot of the currently monitored instances. Used by shutdown hooks that need the live set (including externally added sessions).
func (*HistoryLinker) RegisterFileCallback ¶ added in v1.35.0
func (hl *HistoryLinker) RegisterFileCallback(cb func(filePath string))
RegisterFileCallback registers a callback that receives the file path whenever a JSONL history file is created or modified. Used to wire the TokenStore into the existing fsnotify infrastructure without creating a second watcher.
func (*HistoryLinker) RemoveInstance ¶
func (hl *HistoryLinker) RemoveInstance(title string)
RemoveInstance stops monitoring the named instance.
func (*HistoryLinker) ScanAll ¶
func (hl *HistoryLinker) ScanAll()
ScanAll triggers an immediate correlation pass over all monitored instances, including those already linked to a UUID. Exported for use by HistoryFileWatcher callbacks and called on startup. Resets backoffs and force-rechecks all sessions so that UUID changes (e.g., /clear creating a new conversation) are detected promptly rather than waiting for the next cold restore.
func (*HistoryLinker) SetInstances ¶
func (hl *HistoryLinker) SetInstances(instances []*Instance)
SetInstances replaces the full instance list.
func (*HistoryLinker) Start ¶
func (hl *HistoryLinker) Start(ctx context.Context)
Start performs an initial synchronous scan and then runs a background poll loop until ctx is cancelled. The fsnotify watcher is also started here so that new JSONL files trigger instant correlation.
type HistoryStatistics ¶
type HistoryStatistics struct {
TotalCommands int
SuccessfulCommands int
FailedCommands int
CancelledCommands int
AverageExecutionTime time.Duration
FirstCommandTime time.Time
LastCommandTime time.Time
}
HistoryStatistics provides summary statistics about command history.
type Instance ¶
type Instance struct {
// ID is the stable, immutable identifier for this instance.
// Set once at creation; never changes even if Title is renamed.
// Falls back to Title when empty for backward compatibility.
ID string
// Title is the title of the instance.
Title string
// UUID is a stable unique identifier for this instance, generated at creation time.
// Unlike Title, UUID does not change when the session is renamed.
UUID string
// Path is the path to the workspace repository root.
Path string
// WorkingDir is the directory within the repository to start in.
WorkingDir string
// Branch is the branch of the instance.
Branch string
// Status is the status of the instance.
Status Status
// Program is the program to run in the instance.
Program string
// Height is the height of the instance.
Height int
// Width is the width of the instance.
Width int
// CreatedAt is the time the instance was created.
CreatedAt time.Time
// UpdatedAt is the time the instance was last updated.
UpdatedAt time.Time
// AutoYes is true if the instance should automatically press enter when prompted.
AutoYes bool
// Prompt is passed as a CLI argument to the program at process-spawn time (buildClaudeCommand),
// so it only takes effect on a truly fresh spawn (claudeSessionID == "", no --resume) or OneShot.
// Use for content that must exist before the process's first turn, e.g. backlog task context.
// See InitialPrompt for the tmux-typed alternative — the two are independent and can both be
// set on the same instance (e.g. Omnibar sends attachments via Prompt, typed text via InitialPrompt).
Prompt string
// InitialPrompt, unlike Prompt, is typed into the tmux pane as simulated keystrokes once the
// session reaches Ready state (session_driver.go) — the only delivery path that works for
// resuming/attaching to an already-running pane, where a CLI arg can't be injected after the
// fact. Replaces the static driverInitialPrompt when non-empty.
InitialPrompt string
// ExistingWorktree is an optional path to an existing worktree to reuse
ExistingWorktree string
// Category is used for organizing sessions into groups
Category string
// IsExpanded indicates whether this session's category is expanded in the UI
IsExpanded bool
// SessionType determines the session workflow (directory, new_worktree, existing_worktree)
SessionType SessionType
// CreateIfMissing: when SessionTypeDirectory, create the directory and run git init
// if the path does not exist. Set from the request's create_if_missing field.
// Not persisted — only relevant during initial session start.
CreateIfMissing bool `json:"-"`
// TmuxPrefix is the prefix to use for tmux session names
TmuxPrefix string
// TmuxServerSocket is the server socket name for tmux isolation (used with -L flag)
// If empty, uses the default tmux server. For complete isolation (e.g., testing),
// set to a unique value like "test" or "teatest_123" to create separate tmux servers.
TmuxServerSocket string
// Tags are multi-valued labels for flexible session organization
// Sessions can have multiple tags and appear in multiple groups simultaneously
// Examples: ["frontend", "urgent", "client-work"]
Tags []string
// AutonomousMode enables autonomous Earpiece mode (crew autonomy).
// When true, the Fixer will inject correction prompts without user confirmation.
// When false (default), the session runs in supervised mode.
AutonomousMode bool `json:"autonomous_mode,omitempty"`
// AutonomousTurn is the current turn during an active autonomous run.
AutonomousTurn int32 `json:"autonomous_turn,omitempty"`
// AutonomousMaxTurns is the configured max turns for the current run.
AutonomousMaxTurns int32 `json:"autonomous_max_turns,omitempty"`
// AutonomousOutcome is the result of the last autonomous run: "", "done", or "stuck".
AutonomousOutcome string `json:"autonomous_outcome,omitempty"`
// GitHub integration fields for PR/URL-based session creation
// GitHubPRNumber is the PR number if this session was created from a PR URL
GitHubPRNumber int `json:"github_pr_number,omitempty"`
// GitHubPRURL is the full URL to the PR on GitHub
GitHubPRURL string `json:"github_pr_url,omitempty"`
// GitHubOwner is the repository owner (user or organization)
GitHubOwner string `json:"github_owner,omitempty"`
// GitHubRepo is the repository name
GitHubRepo string `json:"github_repo,omitempty"`
// GitHubSourceRef is the original URL or reference used to create this session
GitHubSourceRef string `json:"github_source_ref,omitempty"`
// ClonedRepoPath is the path where we cloned the repo (if cloned)
ClonedRepoPath string `json:"cloned_repo_path,omitempty"`
// MainRepoPath is the path to the main repository when Path is a worktree
// Detected automatically via `git rev-parse --git-common-dir`
MainRepoPath string `json:"main_repo_path,omitempty"`
// IsWorktree indicates whether Path is a git worktree (not the main repo)
IsWorktree bool `json:"is_worktree,omitempty"`
// GitHubIsFork is true when the remote repo is a fork (PR lookup uses upstream)
GitHubIsFork bool `json:"github_is_fork,omitempty"`
// PR status fields — populated by PRStatusPoller; not set on session creation
// GitHubPRState is the PR lifecycle state: "open", "closed", "merged"
GitHubPRState string `json:"github_pr_state,omitempty"`
// GitHubPRIsDraft is true when the PR is in draft mode
GitHubPRIsDraft bool `json:"github_pr_is_draft,omitempty"`
// GitHubPRPriority is the derived priority: blocking/ready/pending/draft/complete/no_pr
GitHubPRPriority string `json:"github_pr_priority,omitempty"`
// GitHubApprovedCount is the count of current non-dismissed APPROVED reviews
GitHubApprovedCount int `json:"github_approved_count,omitempty"`
// GitHubChangesReqCount is the count of current non-dismissed CHANGES_REQUESTED reviews
GitHubChangesReqCount int `json:"github_changes_req_count,omitempty"`
// GitHubCheckConclusion is the CI rollup: success/failure/pending/action_required/neutral/""
GitHubCheckConclusion string `json:"github_check_conclusion,omitempty"`
// GitHubPRStatusTerminal is true when the PR is merged/closed and polling should stop
GitHubPRStatusTerminal bool `json:"github_pr_status_terminal,omitempty"`
// LastPRStatusCheck is when the PR status was last successfully fetched
LastPRStatusCheck time.Time `json:"last_pr_status_check,omitempty"`
Checkpoints CheckpointList
ActiveCheckpoint string
ForkedFromID string
// OneShot runs claude in -p mode; the session exits after the task completes.
OneShot bool
// Hidden excludes this session from the default session list and review queue.
// Set true for system/background sessions (triage, validation) that should not
// appear in the user-facing session viewer.
Hidden bool
// ProjectID is the optional project this session belongs to.
ProjectID string
// HistoryFilePath is the path to the Claude conversation JSONL history file.
// Set by HistoryLinker when it correlates this session to an open JSONL file.
HistoryFilePath string
// MCPServerURL is the URL of the stapler-squad HTTP MCP endpoint.
// When set, passed as --mcp-config to claude on session start so no
// settings-file injection is needed.
MCPServerURL string `json:"mcp_server_url,omitempty"`
// AppendSystemPrompt, when non-empty and the program is claude, passes
// --append-system-prompt to inject extra instructions into the system prompt
// without modifying any file on disk. Survives context compaction.
AppendSystemPrompt string `json:"append_system_prompt,omitempty"`
// AllowedTools, when non-empty, passes --allowedTools to claude to pre-approve
// specific tool calls without requiring interactive permission prompts.
// Format: "Bash,Read,Edit" or "Bash(git commit *),Read".
AllowedTools string `json:"allowed_tools,omitempty"`
// PermissionMode, when non-empty, passes --permission-mode to claude.
// Values: "default", "acceptEdits", "bypassPermissions", "auto".
PermissionMode string `json:"permission_mode,omitempty"`
// CreationProgress holds a human-readable progress message during Creating state.
// Set by the async creation goroutine; cleared once the session becomes Active.
// Not persisted to the database — only meaningful in-memory during startup.
CreationProgress string `json:"-"`
// LaunchCommand is the full command passed to tmux on session start, including
// any injected flags (--resume, --mcp-config, -y, initial prompt). Set once on
// first start and updated on restart. Empty for external (mux-discovered) sessions.
LaunchCommand string `json:"launch_command,omitempty"`
// RateLimitAutoResume controls whether the rate-limit manager will automatically
// send recovery input when a rate limit expires. Persisted so the setting survives
// server restarts. Defaults to true (enabled) when zero value.
RateLimitAutoResume *bool `json:"rate_limit_auto_resume,omitempty"`
// PauseReason records why this session was paused. Use PauseReason* constants.
// Empty when session has never been paused.
PauseReason string `json:"pause_reason,omitempty"`
// WorkflowID is the UUID of the Workflow that spawned this session.
// Empty for manually-created sessions.
WorkflowID string `json:"workflow_id,omitempty"`
// EnvVars are session-level environment variables injected at tmux session creation.
EnvVars map[string]string `json:"env_vars,omitempty"`
// CLIFlags are additional CLI flags appended to the program launch command.
CLIFlags string `json:"cli_flags,omitempty"`
// ArchivedAt is set when the session is archived. Nil means not archived.
ArchivedAt *time.Time `json:"archived_at,omitempty"`
// ReviewState holds all review queue and terminal activity timestamps.
// Fields are embedded (promoted) so external code can still access inst.LastViewed etc.
// Protected by mu (via sendSyncErr / Snapshot).
ReviewState
// Instance type and management metadata
// InstanceType indicates whether this is a squad-managed or external instance
InstanceType InstanceType
// IsManaged is true if this is a squad-managed session (backward compatible helper)
IsManaged bool
// ExternalMetadata contains additional information for externally discovered instances
ExternalMetadata *ExternalInstanceMetadata
// Permissions defines what operations are allowed on this instance
Permissions InstancePermissions
// Artifacts holds structured artifacts extracted from the session's JSONL history.
// Populated asynchronously by ArtifactExtractor. Protected by mu.
Artifacts *artifacts.SessionArtifactsBlob
// contains filtered or unexported fields
}
Instance is a running instance of claude code.
func FromInstanceData ¶
func FromInstanceData(data InstanceData) (*Instance, error)
FromInstanceData creates a new Instance from serialized data FromInstanceData reconstructs an *Instance from persisted data, starting it synchronously (hot-attaching to an already-live tmux session or cold-restoring one) before returning. Use for on-demand single-instance loads (e.g. Registry.Acquire) where the caller needs a ready instance immediately.
Bulk startup loads should use fromInstanceData(data, true) via LoadInstances instead — starting every instance synchronously here is what made server startup block on restoring all sessions (including cold-relaunching every dead one) before the HTTP server could bind. See server/dependencies.go's "Step 6" background goroutine, which already exists to start un-started instances asynchronously once the deferred path skips Start() here.
func NewInstance ¶
func NewInstance(opts InstanceOptions) (*Instance, error)
func NewInstanceWithCleanup ¶
func NewInstanceWithCleanup(opts InstanceOptions) (*Instance, tmux.CleanupFunc, error)
NewInstanceWithCleanup creates a new Instance and returns it along with a cleanup function. Usage: instance, cleanup, err := NewInstanceWithCleanup(opts); if err == nil { defer cleanup() }
func SessionToInstance ¶
SessionToInstance converts a Session back to the legacy Instance type. This adapter enables interoperability during the migration period. Note: Some Session features (like CloudContext) don't have Instance equivalents.
func (*Instance) AddShellInMemory ¶ added in v1.35.0
AddShellInMemory registers a pre-built Shell directly into the in-memory registry without spawning a tmux process. Used by ReconcileShells and by tests that need to inject shells into an Instance without going through the full SpawnShell / tmux path.
func (*Instance) AddTag ¶
AddTag adds a tag to the instance. Delegates to TagManager.Add. Returns ErrTagTooLong if the tag exceeds MaxTagLength, or ErrDuplicateTag if it already exists.
func (*Instance) Approve ¶
Approve transitions the instance to Active (approval granted). Returns an error if the current state does not allow this transition.
func (*Instance) CDPDisplayEnv ¶ added in v1.35.0
CDPDisplayEnv returns the extra environment variable strings to inject into the tmux session for CDP:
- "CDP_PORT=<N>" — the allocated CDP debugging port
- "PATH=<wrapperDir>:<original PATH>" — prepends the wrapper script dir so Chrome launcher scripts resolve to our wrappers, not the real binary
Returns nil if CDP is unavailable or if Allocate has not been called yet.
func (*Instance) CDPManager ¶ added in v1.35.0
func (i *Instance) CDPManager() CDPStreamManager
CDPManager returns the CDPStreamManager for this instance. Always non-nil after NewInstance() — returns a no-op manager when Chrome is unavailable.
func (*Instance) CaptureCurrentState ¶
CaptureCurrentState records the pane's current working directory into WorkingDir. Called during graceful shutdown so cold restore can restart in the right directory. No-op if the session is not started, paused, or the tmux session is dead.
func (*Instance) CapturePaneContent ¶
CapturePaneContent captures the current visible tmux pane content. This is a simple wrapper around TmuxSession.CapturePaneContent() for compatibility with the terminal WebSocket handlers.
func (*Instance) CapturePaneContentRaw ¶
CapturePaneContentRaw captures pane content with ANSI codes preserved (no line joining). Essential for hybrid streaming where cursor positioning codes must be preserved.
func (*Instance) CleanupWorktree ¶
CleanupWorktree removes the git worktree, keeping session intact.
func (*Instance) ClearConversationState ¶ added in v1.35.0
func (i *Instance) ClearConversationState()
ClearConversationState removes the stored Claude conversation UUID and history file path so that the next Resume starts a fresh conversation rather than attempting --resume with a potentially stale or path-mismatched UUID.
func (*Instance) ClosePR ¶
ClosePR closes the PR without merging Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) CreateCheckpoint ¶
func (i *Instance) CreateCheckpoint(label string, scrollbackSeq uint64) (*Checkpoint, error)
CreateCheckpoint captures a named state bookmark for this session. scrollbackSeq should be the current scrollback high-water mark (from ScrollbackManager); pass 0 if the caller does not have access to scrollback state. Thread-safe: routed through the actor mailbox. Returns an error if the instance is not started.
func (*Instance) CurrentBranch ¶ added in v1.35.0
CurrentBranch returns the branch the session is currently on. For worktree sessions, it returns the stored Branch field (set at creation and on worktree changes). For directory sessions, Branch is never stored, so it reads the branch live from the working directory via git. Returns "" if the branch cannot be determined.
func (*Instance) DeleteShell ¶ added in v1.35.0
DeleteShell stops a shell (if running), waits for active handlers to drain, then removes it from memory and the database.
func (*Instance) Deny ¶
Deny transitions the instance to Paused (approval denied). Returns an error if the current state does not allow this transition.
func (*Instance) Destroy ¶
Destroy completely destroys the instance - both tmux session and worktree
func (*Instance) DetectAndPopulateWorktreeInfo ¶
DetectAndPopulateWorktreeInfo detects if the instance path is a worktree and populates the IsWorktree, MainRepoPath, GitHubOwner, and GitHubRepo fields. NOTE: This method writes to GitHub fields (i.GitHubOwner, i.GitHubRepo) directly. A future pass could route writes through a setter method for encapsulation. This is useful for sessions created from existing worktrees where we want to display the actual repository information in the UI.
IMPORTANT: For sessions with git worktrees, we check BOTH paths: 1. The worktree path (gitWorktree.GetWorktreePath()) - to detect IsWorktree and MainRepoPath 2. The original path (i.Path) - as fallback for GitHub owner/repo if worktree detection fails
This is necessary because: - i.Path is the main repository path (e.g., ~/Documents/personal-wiki) - gitWorktree.GetWorktreePath() is the actual worktree (e.g., ~/.stapler-squad/worktrees/...) - The main repo has .git as a directory; the worktree has .git as a file pointing to the main repo
func (*Instance) FireLifecycleEventForTest ¶ added in v1.35.0
func (i *Instance) FireLifecycleEventForTest(event LifecycleEvent, reason string)
FireLifecycleEventForTest is the exported version of fireLifecycleEvent, used exclusively in cross-package tests that need to simulate an unexpected exit.
func (*Instance) ForceStatus ¶ added in v1.35.0
ForceStatus sets the instance status directly without state machine validation. Only call from error recovery paths where the normal transition would itself fail (e.g. the async-creation goroutine cannot cleanly call Stop() because the session was never fully started). Callers must hold no locks.
Routes through the actor mailbox (sendCtx) rather than taking i.mu directly: ForceStatus is invoked from ad hoc goroutines outside the actor (e.g. the async CreateSession goroutine in SessionService), not from inside an actor command. Funneling through sendCtx serializes this write with the actor's command loop when the instance is actor-owned (LiveInstance), and falls back to running synchronously in-place when it isn't (e.g. tests constructing a bare *Instance).
The write (loadStatus) and the buildSnapshot read are done under the SAME i.mu.Lock()/Unlock() critical section (not lock-write-then-unlock-then-read, which is what this used to do). buildSnapshot reads every mutable field, including ones mutated directly under i.mu by legacy setters (MarkViewed, SetLastMeaningfulOutput, MarkUserResponded, MarkAcknowledged, RecoverFromStopped) that bypass the actor entirely and run on arbitrary caller goroutines. Calling buildSnapshot() after releasing the lock left a window where one of those setters could mutate fields concurrently with this unguarded read — caught by -race via a concurrent MarkViewed()/ ForceStatus() pairing during CreateSession. See runActor's doc comment in actor.go for the matching fix on the read side.
func (*Instance) ForkFromCheckpoint ¶
func (i *Instance) ForkFromCheckpoint(checkpointID, newTitle string, configDir string) (*Instance, error)
ForkFromCheckpoint creates a new, unstarted Instance that is an independent branch of i, seeded from the state captured at the checkpoint identified by checkpointID.
func (*Instance) GeneratePRContextPrompt ¶
GeneratePRContextPrompt generates a context prompt for Claude based on PR information This can be used to initialize a Claude Code session with comprehensive PR context Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) GetCategoryPath ¶
GetCategoryPath returns the category path as a slice of strings for nested category support Supports "Work/Frontend" syntax by splitting on "/" delimiter
func (*Instance) GetCheckpoints ¶
func (i *Instance) GetCheckpoints() CheckpointList
GetCheckpoints returns a snapshot copy of the checkpoint list, safe for concurrent reads from outside the instance's lock domain.
func (*Instance) GetClaudeConversationUUID ¶ added in v1.35.0
GetClaudeConversationUUID returns the stored Claude conversation UUID, empty if none. Thread-safe: acquires stateMutex read lock.
func (*Instance) GetClaudeSession ¶
func (i *Instance) GetClaudeSession() *ClaudeSessionData
GetClaudeSession returns the Claude session data for this instance. Thread-safe: acquires stateMutex read lock.
func (*Instance) GetController ¶
func (i *Instance) GetController() *ClaudeController
GetController returns the ClaudeController if one exists.
func (*Instance) GetConversationUUID ¶
GetConversationUUID returns the Claude conversation UUID, or "" if not linked. Thread-safe: acquires stateMutex read lock.
func (*Instance) GetCreatedAt ¶ added in v1.1.0
GetCreatedAt returns the time this instance was created. The field is immutable after creation.
func (*Instance) GetCurrentPaneContent ¶
GetCurrentPaneContent captures the current visible tmux pane content. Delegates to processManager.CaptureViewport.
func (*Instance) GetDetectedContext ¶ added in v1.35.0
GetDetectedContext returns the human-readable context string from the terminal detection layer. Returns an empty string when no controller is active or no context is available.
func (*Instance) GetDetectedStatus ¶ added in v1.35.0
func (i *Instance) GetDetectedStatus() detection.DetectedStatus
GetDetectedStatus returns the raw DetectedStatus from the terminal detection layer. Returns detection.StatusUnknown when no controller is active or no status has been detected. Use this for sub-status display; do not use for lifecycle decisions.
func (*Instance) GetDiffStats ¶
GetDiffStats returns the current git diff statistics.
func (*Instance) GetEffectiveRootDir ¶
GetEffectiveRootDir returns the root directory where this session operates. For worktree sessions, this is the worktree path. For directory sessions, this is Path. Used for injecting configuration files (e.g., .claude/settings.local.json).
func (*Instance) GetEffectiveStatus ¶
GetEffectiveStatus returns the most accurate status for this instance, combining the lifecycle status with real-time terminal detection when available. Unlike Status (which only reflects lifecycle transitions), this consults the ClaudeController's detected terminal state to surface NeedsApproval, Idle, etc.
func (*Instance) GetEscapeParser ¶ added in v1.35.0
func (i *Instance) GetEscapeParser() *analytics.EscapeCodeParser
GetEscapeParser returns the escape code parser from the session's response stream. Returns nil if the controller is not running or has no response stream.
func (*Instance) GetExitContent ¶ added in v1.15.0
GetExitContent returns the last terminal bytes captured before the PTY exited. Returns nil if the controller is not running or no exit content was recorded.
func (*Instance) GetGitHubRepoFullName ¶
GetGitHubRepoFullName returns "owner/repo" format, or empty string. Delegates to GitHubMetadataView.RepoFullName.
func (*Instance) GetGitWorktree ¶
func (i *Instance) GetGitWorktree() (*git.GitWorktree, error)
GetGitWorktree returns the git worktree for the instance.
func (*Instance) GetLifecycleStatus ¶ added in v1.35.0
GetLifecycleStatus returns the current lifecycle status as a typed Status value.
func (*Instance) GetPRComments ¶
GetPRComments fetches all comments on the PR Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) GetPRDiff ¶
GetPRDiff fetches the diff for the PR Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) GetPRDisplayInfo ¶
GetPRDisplayInfo returns a human-readable PR description for UI display. Delegates to GitHubMetadataView.PRDisplayInfo.
func (*Instance) GetPTYReader ¶
GetPTYReader returns the PTY file handle for the tmux session.
func (*Instance) GetPaneCursorPosition ¶
GetPaneCursorPosition gets the current cursor position in the tmux pane. Returns cursor X (column) and Y (row) coordinates, both 0-based.
func (*Instance) GetPaneDimensions ¶
GetPaneDimensions gets the current dimensions of the tmux pane. Returns width (columns) and height (rows).
func (*Instance) GetPanePID ¶
GetPanePID returns the PID of the foreground process in the tmux pane. The DoesSessionExist guard is omitted here: TmuxSession.GetPanePID already uses the CM fast path (no subprocess) and falls back to display-message which returns an error if the session is gone. Avoiding a separate list-sessions call per instance keeps this cheap for HistoryLinker.ScanAll, which calls this sequentially (not fanned out) per session anyway -- and the display-message subprocess fallback is itself gated (session/tmux's exec gate), so there's no need for a second guard here even if that ever changes.
func (*Instance) GetPermissions ¶
func (i *Instance) GetPermissions() InstancePermissions
GetPermissions returns the permissions for this instance based on its type.
func (*Instance) GetRateLimitResetTime ¶ added in v1.35.0
GetRateLimitResetTime returns the time when the rate limit is expected to reset. Returns zero time if no controller is active or no reset time is known.
func (*Instance) GetRateLimitState ¶ added in v1.12.0
GetRateLimitState returns the current rate limit detection state.
func (*Instance) GetReviewItem ¶
func (i *Instance) GetReviewItem() (*ReviewItem, bool)
GetReviewItem returns the review item for this instance if it exists.
func (*Instance) GetReviewQueue ¶
func (i *Instance) GetReviewQueue() *ReviewQueue
GetReviewQueue returns the review queue for this instance.
func (*Instance) GetScrollbackHistory ¶
GetScrollbackHistory captures scrollback history from tmux using line ranges. Uses tmux's native scrollback capabilities instead of stored sequences. startLine and endLine follow tmux conventions: negative numbers go back from current position, use "-" for the start/end of history.
func (*Instance) GetSessionGoal ¶ added in v1.35.0
func (i *Instance) GetSessionGoal() *SessionGoalData
GetSessionGoal returns a thread-safe shallow copy of the current SessionGoalData (nil if not set). A copy is returned so callers cannot mutate the shared struct.
func (*Instance) GetShellExitCh ¶ added in v1.35.0
GetShellExitCh returns a channel that is closed when the shell exits. Multiple callers can select on it without coordination (closed-channel fan-out).
func (*Instance) GetShellPTYReader ¶ added in v1.35.0
GetShellPTYReader returns the PTY for streaming shell output. Lazily attaches if not yet attached (ADR-3: lazy PTY attach).
func (*Instance) GetStableID ¶ added in v1.14.0
GetStableID returns a stable identifier for this instance. If UUID is set, returns it. Falls back to Title for backward compatibility with sessions that pre-date UUID assignment.
func (*Instance) GetStatus ¶ added in v1.12.0
GetStatus returns the current lifecycle status of this instance as an int. This is intentionally returns int to implement the SessionAccessor interface.
Reads via Snapshot(), not i.mu.RLock(): actor commands (transitionToLocked and friends) write i.Status directly while running inside the actor's own serialization, not under i.mu, and only publish the change by atomically storing a fresh snapshot. An RLock here doesn't synchronize with that write at all — caught by -race via a concurrent GetStatus() poll during Start(). Do not call this from within a sendSyncErr/send/sendCtx closure (see Snapshot's reentrancy note).
func (*Instance) GetStatusIconForType ¶
GetStatusIconForType returns the appropriate status icon based on instance type.
func (*Instance) GetStatusManager ¶
func (i *Instance) GetStatusManager() *InstanceStatusManager
GetStatusManager returns the status manager.
func (*Instance) GetTags ¶
GetTags returns a copy of the instance's tags. Delegates to TagManager.All.
func (*Instance) GetTimeSinceLastMeaningfulOutput ¶
GetTimeSinceLastMeaningfulOutput returns how long ago meaningful output was recorded. Fast path: reads the atomic shadow (no lock) once initialised via SyncAtomicTimestamps or UpdateTimestamps. Fallback: Snapshot() when the atomic is zero (before first write, or in tests that set LastMeaningfulOutput directly) — not a fresh i.mu-guarded read, since i.mu doesn't synchronize with actor commands' direct field writes (see GetStatus's doc comment).
func (*Instance) GetTimeSinceLastTerminalUpdate ¶
GetTimeSinceLastTerminalUpdate delegates to ReviewState.TimeSinceLastTerminalUpdate. Falls back to time since creation if no terminal output has been recorded. Reads via Snapshot(), not i.mu.RLock() — see GetTimeSinceLastMeaningfulOutput.
func (*Instance) GetTmuxSession ¶
func (i *Instance) GetTmuxSession() *tmux.TmuxSession
GetTmuxSession returns the underlying tmux session for direct access. Returns nil if the session hasn't been started yet or if the backend is not tmux.
func (*Instance) GetTmuxSessionName ¶ added in v1.15.0
GetTmuxSessionName returns the sanitized tmux session name for reconciliation. Returns empty string for external or uninitialized sessions.
func (*Instance) GetTotalBytesWritten ¶ added in v1.35.0
GetTotalBytesWritten returns the monotonic PTY byte offset from the session's circular buffer. This is the same counter used by Stage 1 analytics so Stage 2 session_seq values remain stable across WebSocket reconnections. Returns 0 if no controller is active or the buffer is unavailable.
func (*Instance) GetVCSInfo ¶
GetVCSInfo returns information about the VCS for this session
func (*Instance) GetWorkingDirectory ¶
GetWorkingDirectory returns the working directory for this instance.
func (*Instance) GitHub ¶
func (i *Instance) GitHub() GitHubMetadataView
GitHub returns a read-only view of the GitHub metadata for this instance.
func (*Instance) HasClaudeSession ¶
HasClaudeSession returns true if this instance has Claude session data. Thread-safe: acquires stateMutex read lock.
func (*Instance) HasGitHubPR ¶ added in v1.35.0
HasGitHubPR reports whether a GitHub PR has been associated with this session. Safe for use from any goroutine.
func (*Instance) HasGitWorktree ¶
HasGitWorktree returns true if the instance has a git worktree.
func (*Instance) HasTag ¶
HasTag returns true if the instance has the specified tag. Delegates to TagManager.Has.
func (*Instance) HasUpdated ¶
HasUpdated reports whether terminal content has changed since the last check. Returns (updated, hasPrompt) and side-effects terminal timestamps on change.
func (*Instance) Hibernate ¶ added in v1.35.0
Hibernate transitions an Active session to Hibernated. It transitions state and dispatches the heavy I/O to a goroutine.
func (*Instance) Hibernated ¶ added in v1.35.0
Hibernated returns true if the instance is hibernated.
func (*Instance) IsActive ¶ added in v1.35.0
IsActive returns true if the instance has a live AI process.
func (*Instance) IsCreating ¶ added in v1.35.0
IsCreating returns true if the instance is in the Creating state.
Reads via Snapshot(), not i.mu.RLock() — see GetStatus's doc comment for why an RLock here doesn't actually synchronize with the actor's status writes.
func (*Instance) IsGitHubSession ¶
IsGitHubSession returns true if this session has GitHub owner and repo set. Delegates to GitHubMetadataView.IsGitHubSession.
func (*Instance) IsHibernated ¶ added in v1.35.0
IsHibernated returns true if the instance has been hibernated (checkpoint written, tmux killed).
func (*Instance) IsPRSession ¶
IsPRSession returns true if this session was created from a GitHub PR URL. Delegates to GitHubMetadataView.IsPRSession.
func (*Instance) IsPaused ¶ added in v1.35.0
IsPaused returns true if the instance is paused (worktree removed, branch preserved).
func (*Instance) IsRateLimitEnabled ¶ added in v1.12.0
IsRateLimitEnabled returns whether rate limit auto-resume is enabled. Returns the persisted RateLimitAutoResume field (default: true when nil).
func (*Instance) IsStopped ¶ added in v1.35.0
IsStopped returns true if the instance is in the terminal Stopped state.
func (*Instance) Kill ¶
Kill terminates the instance and cleans up all resources Kill destroys both tmux session and worktree (legacy method)
func (*Instance) KillExternalSession ¶
KillExternalSession terminates an external mux session by killing its tmux session. This only works for external sessions that were started via ssq-mux with tmux integration. Returns an error if this is not an external instance or lacks tmux session name.
func (*Instance) KillSession ¶
KillSession terminates the tmux session only (leaves worktree intact).
func (*Instance) KillSessionKeepWorktree ¶
KillSessionKeepWorktree terminates tmux session but preserves worktree for recovery scenarios.
func (*Instance) LastMeaningfulOutputTime ¶ added in v1.1.0
LastMeaningfulOutputTime returns the time of the last meaningful terminal output.
Fast path: the atomic shadow (no lock), same as GetTimeSinceLastMeaningfulOutput. Fallback: Snapshot(), not a fresh i.mu-guarded read — i.mu doesn't synchronize with actor commands' direct field writes (see GetStatus's doc comment).
func (*Instance) ListAvailableTargets ¶
func (i *Instance) ListAvailableTargets() (*AvailableTargets, error)
ListAvailableTargets returns available switch targets (branches, bookmarks, worktrees)
func (*Instance) ListShellsInMemory ¶ added in v1.35.0
ListShellsInMemory returns in-memory shells sorted by OrderIndex.
func (*Instance) MarkAcknowledged ¶ added in v1.1.0
func (i *Instance) MarkAcknowledged()
MarkAcknowledged records that the user has acknowledged (dismissed) this session from the review queue.
func (*Instance) MarkNeedsApproval ¶ added in v1.1.0
MarkNeedsApproval is a no-op: NeedsApproval is no longer a lifecycle state. Approval state is now tracked as sub-status via the detection layer. Deprecated: do not call from new code.
func (*Instance) MarkUserResponded ¶ added in v1.1.0
MarkUserResponded records that the user has responded to this session. Returns the timestamp that was set so callers can persist it without a second lock acquisition.
func (*Instance) MarkViewed ¶ added in v1.1.0
func (i *Instance) MarkViewed()
MarkViewed records that the user has viewed this session.
func (*Instance) MatchesID ¶ added in v1.18.0
MatchesID reports whether id refers to this instance. Accepts the stable UUID, the legacy Title, or the full tmux session name (e.g. "staplersquad_my-session") so that hook notifications sent from inside managed tmux sessions are correctly attributed to their human-readable session.
func (*Instance) MergePR ¶
MergePR merges the PR using the specified merge method method can be: "merge", "squash", or "rebase" Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) NeedsReview ¶
NeedsReview returns true if this session is in the review queue.
func (*Instance) PaneProcessDead ¶ added in v1.37.0
PaneProcessDead reports whether the tmux session is alive (TmuxAlive()==true) but the wrapped program running in the pane has already exited. remain-on-exit keeps the tmux session/pane around as a "Pane is dead (signal N, ...)" placeholder after the wrapped program is killed (e.g. OOM SIGKILL) or crashes, rather than tearing the session down -- so TmuxAlive() alone reports this session as healthy forever. Health checks must consult this in addition to TmuxAlive() to detect that failure mode. Returns false for non-tmux backends (e.g. native process manager), which have no equivalent placeholder state.
func (*Instance) Pause ¶
Pause stops the tmux session and removes the worktree, preserving the branch.
func (*Instance) PostComment ¶
PostComment posts a comment to the PR Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) Preview ¶
Preview returns the current visible terminal content. Prefers the in-memory PTY buffer from ClaudeController; falls back to capture-pane.
func (*Instance) PreviewFullHistory ¶
PreviewFullHistory captures the entire tmux pane output including full scrollback history.
func (*Instance) ReconcileShells ¶ added in v1.35.0
ReconcileShells is called after an Instance is loaded from ent on startup. It queries ent for shells marked "running" and checks whether their sibling tmux sessions still exist. Live sessions are rebuilt in memory (without PTY attach — lazy). Dead sessions are marked stopped in ent.
The map lock is never held during I/O: all subprocess calls and DB writes happen outside any map operation; each final map insert is an independent Store call that holds only the bucket lock for nanoseconds.
func (*Instance) RecoverFromStopped ¶ added in v1.23.1
func (i *Instance) RecoverFromStopped()
RecoverFromStopped resets a stale Stopped status to Creating so the instance can be hot-restored via Start(false). Only call this during startup reconciliation when the tmux session is confirmed alive; it bypasses the state machine intentionally. Deprecated: prefer transitionTo(ctx, Active) on the Stopped→Active path.
func (*Instance) RefreshPRInfo ¶
RefreshPRInfo fetches the latest PR information from GitHub Returns an error if this is not a PR session or if the GitHub API call fails
func (*Instance) RefreshTmuxClient ¶
RefreshTmuxClient forces the tmux client to refresh, triggering a redraw of the process running inside. This is critical after resizing to ensure cursor positions and line wrapping are recalculated for the new dimensions.
func (*Instance) RegisterLifecycleListener ¶ added in v1.15.0
func (i *Instance) RegisterLifecycleListener(l LifecycleListener)
RegisterLifecycleListener adds a listener that will receive EventStarted and EventExited notifications for this instance. The listener is called synchronously on the goroutine that fires the event; implementations must return quickly (no long blocking operations).
func (*Instance) RegisterStatusChangeCallback ¶ added in v1.35.0
func (i *Instance) RegisterStatusChangeCallback(fn func(detection.DetectedStatus, string))
RegisterStatusChangeCallback appends fn to the controller's fan-out listener set. Unlike SetStatusChangeCallback, it does not replace existing listeners. Safe to call before or after the controller is started.
func (*Instance) RemoveTag ¶
RemoveTag removes a tag from the instance. Delegates to TagManager.Remove.
func (*Instance) Rename ¶
Rename renames this session. Validates title constraints and updates UpdatedAt.
func (*Instance) RepoName ¶
RepoName returns the name of the git repository. Returns an error if the instance has not been started or has no worktree.
func (*Instance) ResizePTY ¶
ResizePTY resizes the terminal dimensions. This is used when clients resize their terminal windows.
func (*Instance) Restart ¶
Restart restarts the session by killing and recreating the tmux session. The git worktree is preserved during restart. If preserveOutput is true, captures terminal output before killing the session. For Claude sessions, uses --resume flag with the stored session ID.
func (*Instance) RestartShell ¶ added in v1.35.0
RestartShell stops a shell (if running) and relaunches it with the same command and workdir.
func (*Instance) ResumeFromHibernation ¶ added in v1.35.0
ResumeFromHibernation transitions a Hibernated session back to Active. The actual process re-launch happens asynchronously via resumeFromHibernationLocked.
func (*Instance) RunWithResume ¶ added in v1.35.0
RunWithResume spawns a new claude subprocess using --resume <uuid> and -p <message>, waits for completion, and returns the result text. Updates ConversationUUID on success.
func (*Instance) SendInputViaControlMode ¶ added in v1.35.0
SendInputViaControlMode sends raw bytes through the existing control mode connection, avoiding the subprocess spawn overhead and timeout risk of exec.CommandContext.
func (*Instance) SendPrompt ¶
SendPrompt sends a prompt to the tmux session. Delegates to processManager.SendPromptWithEnter.
func (*Instance) SetArchivedAt ¶ added in v1.35.0
SetArchivedAt sets or clears the ArchivedAt timestamp atomically. Pass nil to clear (unarchive).
func (*Instance) SetArchivedAtIfNil ¶ added in v1.35.0
SetArchivedAtIfNil sets ArchivedAt to t only if it is currently nil. Returns true if the value was set (CAS semantics). Now actor-routed.
func (*Instance) SetArtifacts ¶ added in v1.35.0
func (i *Instance) SetArtifacts(blob *artifacts.SessionArtifactsBlob)
SetArtifacts atomically updates the in-memory Artifacts cache.
func (*Instance) SetAutoYes ¶ added in v1.35.0
SetAutoYes sets the AutoYes flag. Used by daemon.go to opt in automated sessions to non-interactive behaviour.
func (*Instance) SetAutonomousComplete ¶ added in v1.35.0
SetAutonomousComplete clears the autonomous-mode flag and turn counters, and records the outcome ("done" or "stuck") atomically.
func (*Instance) SetAutonomousMode ¶ added in v1.35.0
SetAutonomousMode sets the autonomous mode flag and outcome string atomically. Pass outcome="" to clear it when enabling; the existing value is preserved unless explicitly overwritten by the caller.
func (*Instance) SetAutonomousTurn ¶ added in v1.35.0
SetAutonomousTurn atomically updates the current turn counter and max-turns cap during an active autonomous run.
func (*Instance) SetCategory ¶ added in v1.35.0
SetCategory sets the session category.
func (*Instance) SetClaudeConversationUUID ¶ added in v1.35.0
SetClaudeConversationUUID stores the Claude conversation UUID so it is used in subsequent --resume flags. Fires the claudeSessionIDSavedCallback if set. No-op (including callback) if uuid is unchanged.
func (*Instance) SetClaudeSession ¶
func (i *Instance) SetClaudeSession(sessionData *ClaudeSessionData)
SetClaudeSession sets the Claude session data for this instance. Thread-safe: acquires stateMutex write lock.
func (*Instance) SetClaudeSessionIDSavedCallback ¶ added in v1.35.0
func (i *Instance) SetClaudeSessionIDSavedCallback(fn func())
SetClaudeSessionIDSavedCallback registers a callback that fires when SetClaudeConversationUUID is called. Used by the service layer to trigger a storage save when the session_id is discovered.
func (*Instance) SetCreationProgress ¶ added in v1.35.0
SetCreationProgress sets the human-readable creation progress message.
func (*Instance) SetDirBaseSHA ¶ added in v1.37.0
SetDirBaseSHA sets the base commit SHA used to compute diff stats for directory-mode sessions (sessions without an isolated git worktree).
func (*Instance) SetGitHubPR ¶ added in v1.35.0
SetGitHubPR atomically sets the GitHub PR URL and PR number discovered after a RunOneShot or PR-discovery poll. Pass prNumber=0 if not yet known.
func (*Instance) SetGitHubPRNumber ¶ added in v1.35.0
SetGitHubPRNumber atomically updates the in-memory GitHubPRNumber field. Replaces the stateMutex-based implementation; now actor-routed so it is serialised with buildSnapshot.
func (*Instance) SetGitWorktree ¶
func (i *Instance) SetGitWorktree(worktree *git.GitWorktree)
SetGitWorktree sets the git worktree for testing purposes.
func (*Instance) SetHibernateReason ¶ added in v1.35.0
SetHibernateReason sets the reason string that will be recorded in the checkpoint. Must be called before Hibernate(). Values: "manual", "idle", "resource_pressure".
func (*Instance) SetHistoryInfo ¶
SetHistoryInfo updates the conversation UUID and history file path. Thread-safe: acquires stateMutex write lock. No-op if the UUID is already set to the same value.
func (*Instance) SetLastAddedToQueue ¶ added in v1.35.0
SetLastAddedToQueue records when this session was last added to the review queue.
func (*Instance) SetLastMeaningfulOutput ¶ added in v1.1.0
SetLastMeaningfulOutput sets the time of the last meaningful terminal output.
func (*Instance) SetLastPRStatusCheck ¶ added in v1.35.0
SetLastPRStatusCheck records the time of the most recent PR-status fetch.
func (*Instance) SetMCPServerURL ¶ added in v1.35.0
SetMCPServerURL sets the MCP server URL on this instance.
func (*Instance) SetPauseReason ¶ added in v1.35.0
SetPauseReason sets the reason this session was paused.
func (*Instance) SetPreviewSize ¶
SetPreviewSize sets the detached terminal dimensions for preview rendering.
func (*Instance) SetProgram ¶ added in v1.35.0
SetProgram atomically updates the Program field during program-switch.
func (*Instance) SetRateLimitCallbacks ¶ added in v1.35.0
func (i *Instance) SetRateLimitCallbacks( onDetected func(sessionID string, resetTime time.Time), onRecovery func(sessionID string, success bool, errMsg string), )
SetRateLimitCallbacks registers server-layer callbacks for rate limit events. onDetected is called when a rate limit is detected; onRecovery is called when recovery completes. Both are invoked from goroutines in the ratelimit package. Safe to call before or after the controller is started; callbacks are wired at controller start time via wireRateLimitCallbacks.
func (*Instance) SetRateLimitEnabled ¶ added in v1.12.0
SetRateLimitEnabled enables or disables rate limit auto-resume. The setting is persisted in RateLimitAutoResume so it survives restarts, and is applied immediately to the running controller if one exists.
func (*Instance) SetReviewQueue ¶
func (i *Instance) SetReviewQueue(queue *ReviewQueue)
SetReviewQueue sets the review queue for this instance.
func (*Instance) SetSessionGoalCached ¶ added in v1.35.0
func (i *Instance) SetSessionGoalCached(g *SessionGoalData)
SetSessionGoalCached atomically updates the in-memory sessionGoal cache.
func (*Instance) SetShellRepository ¶ added in v1.35.0
func (i *Instance) SetShellRepository(repo ShellRepository)
SetShellRepository injects the shell persistence backend. Called by Storage after loading or creating an instance. Pass nil to disable persistence (e.g., in tests).
func (*Instance) SetStatusChangeCallback ¶ added in v1.35.0
func (i *Instance) SetStatusChangeCallback(fn func(detection.DetectedStatus, string))
SetStatusChangeCallback registers fn to be called on every terminal status change detected by the ClaudeController. Safe to call before or after the controller is started; the callback is wired at controller start time via wireStatusChangeCallback.
func (*Instance) SetStatusManager ¶
func (i *Instance) SetStatusManager(manager *InstanceStatusManager)
SetStatusManager sets the status manager for idle detection.
func (*Instance) SetTags ¶
SetTags replaces all tags with a new deduplicated set. Delegates to TagManager.Set. Returns ErrTagTooLong on the first tag that exceeds MaxTagLength.
func (*Instance) SetTitle ¶
SetTitle sets the title of the instance. Returns an error if the instance has started. We can't change the title once it's been used for a tmux session etc.
func (*Instance) SetTitleDirect ¶ added in v1.35.0
SetTitleDirect sets the Title field directly without tmux-session constraints. Use only from RPC handlers that have already validated uniqueness and title constraints (e.g. UpdateSession, RenameSession rollback).
func (*Instance) SetTmuxSession ¶
func (i *Instance) SetTmuxSession(session *tmux.TmuxSession)
SetTmuxSession sets the tmux session for testing purposes.
func (*Instance) SetWindowSize ¶
SetWindowSize propagates window size changes to the tmux session. This enables proper terminal resizing in environments like IntelliJ where SIGWINCH doesn't work.
func (*Instance) SetWorkingDir ¶ added in v1.35.0
SetWorkingDir sets the working directory for this session.
func (*Instance) Snapshot ¶ added in v1.35.0
func (i *Instance) Snapshot() *InstanceSnapshot
Snapshot returns the most recently published atomic snapshot of this Instance's mutable fields. The returned pointer is never nil. Callers must not mutate the returned struct.
On the first call for an Instance that bypassed finishInstanceConstruction (e.g. struct literals in tests), the snapshot is built lazily under stateMutex and stored via CAS so concurrent first-callers converge on one value.
func (*Instance) SpawnShell ¶ added in v1.35.0
SpawnShell creates and starts a new shell as an independent sibling tmux session. It persists the shell to the ent repository, registers it in memory, and launches the watchShellExit goroutine.
func (*Instance) Start ¶
Start starts the instance by routing through the actor mailbox. firstTimeSetup is true if this is a new instance. Otherwise, it's one loaded from storage.
func (*Instance) StartControlMode ¶ added in v1.15.0
StartControlMode starts the control mode stream on the underlying tmux session.
func (*Instance) StartController ¶
StartController creates and starts a ClaudeController for this instance. The controller enables automated idle detection and queue management.
func (*Instance) StartWithCleanup ¶
func (i *Instance) StartWithCleanup(firstTimeSetup bool) (tmux.CleanupFunc, error)
StartWithCleanup starts the instance and returns a cleanup function. Usage: cleanup, err := instance.StartWithCleanup(firstTimeSetup); if err == nil { defer cleanup() }
func (*Instance) StopControlMode ¶ added in v1.15.0
StopControlMode stops the control mode stream.
func (*Instance) StopController ¶
func (i *Instance) StopController()
StopController stops and cleans up the ClaudeController for this instance.
func (*Instance) StopShell ¶ added in v1.35.0
StopShell stops a running shell by setting status first (stop-while-streaming guard), then closing the handle.
func (*Instance) SubscribeControlModeUpdates ¶ added in v1.15.0
SubscribeControlModeUpdates returns a subscriber ID and a read-only output channel. Returns a pre-closed channel if the tmux session is not available.
func (*Instance) SwitchProgram ¶ added in v1.37.0
func (i *Instance) SwitchProgram(ctx context.Context, rawProgram string, persist func() error) (changed bool, resolvedProgram string, err error)
SwitchProgram atomically switches this instance's Program to rawProgram (resolving an empty string to the configured default), porting Claude<->Antigravity conversation history when crossing between those two and clearing stale conversation linkage (ClearConversationState) when the switch leaves that family entirely. If persist is non-nil it runs after the field mutation but before an Active-session restart, so callers can make the new program durable even if the subsequent restart fails.
The whole operation runs under a per-instance lock (programSwitchMu) so a manual program-switch request and an automatic capacity-monitor fallback firing near- simultaneously serialize instead of double-restarting or double-porting history. This is the single implementation shared by the UpdateSession RPC handler and the capacity-monitor auto-fallback path (SessionService.UpdateSessionProgram) so the two entry points can't drift.
changed reports whether the resolved program actually differed from the current one; a no-op skips persist/restart entirely. err is only ever a Restart failure — persist failures are logged, not returned, matching the pre-existing best-effort save semantics.
func (*Instance) SwitchWorkspace ¶
func (i *Instance) SwitchWorkspace(req WorkspaceSwitchRequest) (*WorkspaceSwitchResult, error)
SwitchWorkspace switches the session's workspace according to the request. For directory changes, this is a simple cd operation. For revision/worktree switches, this restarts Claude with --resume to preserve conversation.
func (*Instance) TapEnter ¶
func (i *Instance) TapEnter()
TapEnter sends an enter key press to the tmux session if AutoYes is enabled.
func (*Instance) TmuxAlive ¶
TmuxAlive returns true if the tmux session is alive. This is a sanity check before attaching.
func (*Instance) TmuxSessionExists ¶ added in v1.23.1
TmuxSessionExists reports whether the underlying tmux session is currently alive. Used at startup to reconcile stale Stopped status against live tmux sessions.
func (*Instance) ToInstanceData ¶
func (i *Instance) ToInstanceData() InstanceData
ToInstanceData converts an Instance to its serializable form
Builds a fresh snapshot via sendSyncErr rather than reading the cached Snapshot(): callers like Storage.UpdateInstance/SaveInstancesSync routinely mutate exported fields (Tags, Category, ...) directly and expect the very next ToInstanceData() call to reflect that — Snapshot()'s cache only refreshes when an actor command republishes it, so those direct-mutation callers would see stale data (caught by TestStorage_UpdateInstance / TestStorage_SaveInstancesSync). Routing the build through sendSyncErr gets a fresh buildSnapshot(s.inst) (current field values, actor-mutation or not) while still serializing against concurrent actor commands: with a live actor this blocks until the mailbox delivers it, matching every other actor command's ordering; with no live actor (tests, pre-NewLiveInstance) it runs synchronously on the calling goroutine, same as before. Do not call from within a sendSyncErr/send/sendCtx closure — see actor.go. LaunchCommand is not in the snapshot (set once during Start) and is read directly. gitManager and claudeSession sub-objects have their own synchronisation.
func (*Instance) ToSession ¶
ToSession converts this Instance to the new Session type. This is a convenience method that wraps InstanceToSession.
func (*Instance) UnsubscribeControlModeUpdates ¶ added in v1.15.0
UnsubscribeControlModeUpdates removes a subscriber by ID.
func (*Instance) UpdateDiffStats ¶
UpdateDiffStats updates the git diff statistics for this instance. Performs I/O (git diff) outside the lock, then updates state under the write lock.
func (*Instance) UpdatePRStatus ¶ added in v1.12.0
func (i *Instance) UpdatePRStatus(state, priority, checkConclusion string, approvedCount, changesReqCount int, isDraft, terminal bool) prUpdateResult
UpdatePRStatus atomically updates the PR status fields on this instance. Called by PRStatusPoller on each successful fetch. Returns prUpdateResult indicating whether the priority changed.
func (*Instance) UpdateTerminalTimestamps ¶
UpdateTerminalTimestamps is a coordinator method that bridges ProcessManager (I/O) with ReviewState (timestamp recording). It:
- Calls processManager.FilterBanners/HasMeaningfulContent (I/O-ish, done before touching the actor — same "no I/O inside the command" discipline as the other *Locked helpers)
- Routes the actual field mutation through the actor's send() — this is called from the PTY-read hot path (server/services/session_service.go's StreamTerminal), exactly the "callback that must not block the caller" case send() exists for (see actor.go's doc comment). Routing through the actor instead of i.mu means this mutation is serialized against every other actor command (transitionToLocked et al.), which don't take i.mu either — caught by -race via a concurrent StreamTerminal + StartController flow.
- Delegates to ReviewState.UpdateTimestamps
This method intentionally stays on Instance because it coordinates two sub-managers. The forceUpdate parameter bypasses meaningful content checking for user-initiated interactions.
func (*Instance) VNCDisplayEnv ¶ added in v1.35.0
VNCDisplayEnv returns the DISPLAY environment variable assignment for this session's display, e.g. "DISPLAY=:101" or "DISPLAY=:0". Returns "" if no display is available (VNC unavailable or StartDisplay not yet called).
func (*Instance) VNCManager ¶ added in v1.35.0
func (i *Instance) VNCManager() VNCProcessManager
VNCManager returns the VNCProcessManager for this instance. Always non-nil — returns a no-op manager on unsupported platforms.
type InstanceAcquirer ¶ added in v1.35.0
type InstanceAcquirer interface {
Acquire(sessionID string) (*LiveInstance, ReleaseFunc, error)
}
InstanceAcquirer is the narrowest interface for callers that only ever call Acquire. WorkspaceService, MCP tool handlers, and most RPC handlers should be typed against this rather than *Registry (Interface Segregation — matches WorkspaceService's existing LiveInstanceFinder convention).
type InstanceContext ¶ added in v1.1.0
type InstanceContext interface {
GetTitle() string
GetStableID() string
GetPTYReader() (*os.File, error)
Preview() (string, error)
LastMeaningfulOutputTime() time.Time
GetCreatedAt() time.Time
SetLastMeaningfulOutput(t time.Time)
GetStatus() int
WriteToPTY(data []byte) (int, error)
}
InstanceContext is the narrow interface ClaudeController needs from its owning Instance. Using an interface breaks the bidirectional Instance ↔ ClaudeController dependency.
type InstanceData ¶
type InstanceData struct {
Title string `json:"title"`
UUID string `json:"uuid,omitempty"`
Path string `json:"path"`
WorkingDir string `json:"working_dir"`
Branch string `json:"branch"`
Status Status `json:"status"`
Height int `json:"height"`
Width int `json:"width"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
AutoYes bool `json:"auto_yes"`
Prompt string `json:"prompt"`
InitialPrompt string `json:"initial_prompt,omitempty"`
Program string `json:"program"`
ExistingWorktree string `json:"existing_worktree,omitempty"`
Worktree GitWorktreeData `json:"worktree"`
DiffStats DiffStatsData `json:"diff_stats"`
// New fields for session organization and grouping
Category string `json:"category,omitempty"`
IsExpanded bool `json:"is_expanded,omitempty"`
Tags []string `json:"tags,omitempty"` // Multi-valued tags for flexible organization
// Session type determines the workflow (directory, new_worktree, existing_worktree)
SessionType SessionType `json:"session_type,omitempty"`
// GitHub integration fields for PR/URL-based session creation
GitHubPRNumber int `json:"github_pr_number,omitempty"`
GitHubPRURL string `json:"github_pr_url,omitempty"`
GitHubOwner string `json:"github_owner,omitempty"`
GitHubRepo string `json:"github_repo,omitempty"`
GitHubSourceRef string `json:"github_source_ref,omitempty"`
ClonedRepoPath string `json:"cloned_repo_path,omitempty"`
// Worktree detection fields
MainRepoPath string `json:"main_repo_path,omitempty"` // Path to main repo when this is a worktree
IsWorktree bool `json:"is_worktree,omitempty"` // True if path is a git worktree
GitHubIsFork bool `json:"github_is_fork,omitempty"` // True when remote repo is a fork
// PR status fields — populated by PRStatusPoller
GitHubPRState string `json:"github_pr_state,omitempty"`
GitHubPRIsDraft bool `json:"github_pr_is_draft,omitempty"`
GitHubPRPriority string `json:"github_pr_priority,omitempty"`
GitHubApprovedCount int `json:"github_approved_count,omitempty"`
GitHubChangesReqCount int `json:"github_changes_req_count,omitempty"`
GitHubCheckConclusion string `json:"github_check_conclusion,omitempty"`
GitHubPRStatusTerminal bool `json:"github_pr_status_terminal,omitempty"`
LastPRStatusCheck time.Time `json:"last_pr_status_check,omitempty"`
// Crew autonomy mode — when true, the Fixer injects correction prompts without user confirmation.
AutonomousMode bool `json:"autonomous_mode,omitempty"`
// Claude Code session persistence
ClaudeSession ClaudeSessionData `json:"claude_session,omitempty"`
// Tmux session prefix for isolation
TmuxPrefix string `json:"tmux_prefix,omitempty"`
// Tmux server socket name for isolation (used with tmux -L flag)
TmuxServerSocket string `json:"tmux_server_socket,omitempty"`
// Terminal update timestamps for activity tracking
LastTerminalUpdate time.Time `json:"last_terminal_update,omitempty"`
LastMeaningfulOutput time.Time `json:"last_meaningful_output,omitempty"`
// Content signature for detecting actual terminal changes vs restarts
// This is a SHA256 hash of the terminal content used to prevent false "new activity"
// notifications when app restarts but terminal content hasn't changed
LastOutputSignature string `json:"last_output_signature,omitempty"`
// Review queue spam prevention
LastAddedToQueue time.Time `json:"last_added_to_queue,omitempty"`
// User interaction tracking
// LastViewed tracks when the user last viewed this session (terminal, session details, etc.)
// Used for smarter review queue notifications (don't notify if just viewed)
LastViewed time.Time `json:"last_viewed,omitempty"`
// Review queue snooze tracking
// LastAcknowledged tracks when the user last dismissed this session from review queue
// Sessions acknowledged after their last update won't appear in the queue until they update again
LastAcknowledged time.Time `json:"last_acknowledged,omitempty"`
// Prompt detection and interaction tracking for smart review queue behavior
LastPromptDetected time.Time `json:"last_prompt_detected,omitempty"`
LastPromptSignature string `json:"last_prompt_signature,omitempty"`
LastUserResponse time.Time `json:"last_user_response,omitempty"`
ProcessingGraceUntil time.Time `json:"processing_grace_until,omitempty"`
// Checkpoint metadata for session state bookmarking (session resumption)
Checkpoints CheckpointList `json:"checkpoints,omitempty"`
ActiveCheckpoint string `json:"active_checkpoint,omitempty"`
ForkedFromID string `json:"forked_from_id,omitempty"`
// History file linkage for cold restore
HistoryFilePath string `json:"history_file_path,omitempty"`
// OneShot runs claude in -p mode; session exits after task completes.
OneShot bool `json:"one_shot,omitempty"`
// Hidden excludes this session from the default session list and review queue.
Hidden bool `json:"hidden,omitempty"`
// ProjectID is the optional project this session belongs to.
ProjectID string `json:"project_id,omitempty"`
// LaunchCommand is the full command passed to tmux on session start, including
// any injected flags (--resume, --mcp-config, -y, initial prompt).
LaunchCommand string `json:"launch_command,omitempty"`
// MCPServerURL is the stapler-squad HTTP MCP endpoint passed to claude via
// --mcp-config on session start. Persisted so restarts re-inject the flag.
MCPServerURL string `json:"mcp_server_url,omitempty"`
// PauseReason records why this session was paused.
// Values: "manual", "auto:inactivity", "auto:session_limit", "auto:resource".
// Empty when session has never been paused.
PauseReason string `json:"pause_reason,omitempty"`
// WorkflowID is the UUID of the Workflow that spawned this session.
// Empty for manually-created sessions.
WorkflowID string `json:"workflow_id,omitempty"`
// ArchivedAt is set when the session is archived. Nil means not archived.
ArchivedAt *time.Time `json:"archived_at,omitempty"`
}
InstanceData represents the serializable data of an Instance
func (InstanceData) GetStableID ¶ added in v1.35.0
func (d InstanceData) GetStableID() string
GetStableID mirrors Instance.GetStableID for InstanceData: returns UUID when set, Title otherwise. Used by Registry.AcquireAll and ListInstanceIDs to produce stable per-session keys without constructing live Instance objects.
func (InstanceData) MatchesID ¶ added in v1.35.0
func (d InstanceData) MatchesID(id string) bool
MatchesID reports whether id refers to this InstanceData. Unlike Instance.MatchesID, there is no tmux-name arm because InstanceData has no GetTmuxSessionName (that method requires the live processManager). For tmux-name matching, call Instance.MatchesID.
type InstanceOptions ¶
type InstanceOptions struct {
// Title is the title of the instance.
Title string
// Path is the path to the workspace repository root.
Path string
// WorkingDir is the directory within the repository to start in.
// If empty, defaults to repository root.
WorkingDir string
// Branch is the git branch name to use when creating a new worktree.
// If empty and SessionType is SessionTypeNewWorktree, a branch name is derived from the title.
Branch string
// Program is the program to run in the instance (e.g. "claude", "aider --model ollama_chat/gemma3:1b")
Program string
// If AutoYes is true, automatically accept prompts
AutoYes bool
// Prompt is passed as a CLI argument at process-spawn time — only takes effect on a fresh
// spawn or OneShot. See InitialPrompt for the tmux-typed alternative; the two are independent
// and may both be set (see Instance.Prompt/Instance.InitialPrompt for the full explanation).
Prompt string
// InitialPrompt, when non-empty, is typed into the tmux pane once the session reaches Ready state,
// replacing the static "Please proceed..." fallback. Use for resume/attach flows where a CLI
// arg can no longer be injected.
InitialPrompt string
// ExistingWorktree is an optional path to an existing worktree to reuse
ExistingWorktree string
// Category is used for organizing sessions into groups
Category string
// Tags are multi-valued labels for flexible organization
Tags []string
// SessionType determines the session workflow (directory, new_worktree, existing_worktree)
SessionType SessionType
// TmuxPrefix is the prefix to use for tmux session names (e.g., "staplersquad_")
TmuxPrefix string
// TmuxServerSocket is the server socket name for tmux isolation (used with -L flag)
// If empty, uses the default tmux server. For complete isolation (e.g., testing),
// set to a unique value like "test" or "teatest_123" to create separate tmux servers.
TmuxServerSocket string
// GitHub integration fields for PR/URL-based session creation
GitHubPRNumber int // PR number if created from PR URL
GitHubPRURL string // Full URL to the PR
GitHubOwner string // Repository owner
GitHubRepo string // Repository name
GitHubSourceRef string // Original URL/reference used to create session
ClonedRepoPath string // Path where repo was cloned (if cloned)
// ResumeId is the Claude conversation ID to resume (from history browser).
// When set, the session will start with --resume <id> flag.
ResumeId string
// OneShot runs claude in -p mode; the session exits after the task completes.
OneShot bool
// Hidden excludes the session from the default session list and review queue.
Hidden bool
// ProjectID associates the session with a project.
ProjectID string
// MCPServerURL, when non-empty and the program is claude, passes
// --mcp-config '{"stapler-squad":{"type":"http","url":"<MCPServerURL>"}}' so the
// session can call back into stapler-squad without any file injection.
MCPServerURL string
// AppendSystemPrompt, when non-empty and the program is claude, passes
// --append-system-prompt so extra instructions are injected into the system
// prompt without touching any file on disk.
AppendSystemPrompt string
// AllowedTools pre-approves specific Claude Code tool calls (--allowedTools).
AllowedTools string
// PermissionMode sets Claude Code's permission handling mode (--permission-mode).
PermissionMode string
// CreateIfMissing: when SessionTypeDirectory, create the directory and run git init
// if the path does not exist. Only set when the user has confirmed the action.
CreateIfMissing bool
// AutonomousMode, when true, starts an AutonomousDriver after session creation
// so the session runs to completion without manual steering.
AutonomousMode bool
// WorkflowID is the UUID of the Workflow that spawned this session.
// Set by the scheduler; empty for manually-created sessions.
WorkflowID string
// EnvVars are session-level environment variables injected at tmux session creation time.
EnvVars map[string]string
// CLIFlags are additional CLI flags appended to the program launch command.
CLIFlags string
}
Options for creating a new instance
type InstancePermissions ¶
type InstancePermissions struct {
// View operations
CanView bool
// Attach to the terminal session
CanAttach bool
// Send commands to the terminal
CanSendCommand bool
// Pause the session (stop tmux, keep worktree)
CanPause bool
// Resume a paused session
CanResume bool
// Destroy the session completely
CanDestroy bool
// Perform git operations (commit, push, worktree management)
CanModifyGit bool
// Add to review queue
CanAddToQueue bool
// RequiresConfirmation maps operation names to whether they need confirmation
// Used for high-risk operations on external instances
RequiresConfirmation map[string]bool
}
InstancePermissions defines what operations are allowed on an instance
func GetExternalPermissions ¶
func GetExternalPermissions(allowAttach bool) InstancePermissions
GetExternalPermissions returns limited permissions for external instances allowAttach controls whether attach operations are permitted (power user mode)
func GetManagedPermissions ¶
func GetManagedPermissions() InstancePermissions
GetManagedPermissions returns full permissions for squad-managed instances
func GetMuxExternalPermissions ¶
func GetMuxExternalPermissions() InstancePermissions
GetMuxExternalPermissions returns permissions for mux-enabled external instances. Mux instances support full bidirectional terminal access and can be destroyed since they're explicitly opted-in by launching through ssq-mux with tmux session.
type InstanceReader ¶ added in v1.35.0
type InstanceReader interface {
// Identity
GetTitle() string
GetStableID() string
// Descriptive metadata
GetWorkingDirectory() string
// GetStatus returns the current lifecycle status as int.
// Deprecated: use GetLifecycleStatus() or the typed predicates below.
GetStatus() int
// GetLifecycleStatus returns the current lifecycle status as a typed Status value.
GetLifecycleStatus() Status
// Typed state predicates — prefer these over comparing GetStatus() against constants.
IsActive() bool
IsPaused() bool
IsHibernated() bool
IsStopped() bool
// Git / diff
GetDiffStats() *git.DiffStats
// Activity timestamps
GetTimeSinceLastMeaningfulOutput() time.Duration
}
InstanceReader exposes a minimal read-only view of an Instance for server-layer code that only needs to observe session state. It is not yet used at every call site (some helpers still take *Instance directly for field access); adopt it incrementally as call sites are converted to use getter methods.
*Instance satisfies this interface automatically. Use it to supply lightweight test doubles without starting a real tmux session.
type InstanceSnapshot ¶ added in v1.35.0
type InstanceSnapshot struct {
// Identity / config
ID string
UUID string
Title string
Path string
WorkingDir string
Branch string
CreatedAt time.Time
UpdatedAt time.Time
Status Status
Program string
Height int
Width int
AutoYes bool
IsExpanded bool
Prompt string
InitialPrompt string
Category string
SessionType SessionType
TmuxPrefix string
TmuxServerSocket string
Tags []string // defensive deep copy — see buildSnapshot
// Autonomous mode (grouped — access as snap.Autonomous.AutonomousMode)
Autonomous AutonomousModeState
// GitHub PR / URL integration (grouped — access as snap.GitHub.GitHubPRURL)
GitHub GitHubIntegration
// Checkpoints
Checkpoints CheckpointList // defensive deep copy — see buildSnapshot
ActiveCheckpoint string
ForkedFromID string
// Misc config
OneShot bool
Hidden bool
ProjectID string
HistoryFilePath string
MCPServerURL string
AppendSystemPrompt string
AllowedTools string
PermissionMode string
RateLimitAutoResume *bool // copy of pointee — see buildSnapshot
PauseReason string
WorkflowID string
EnvVars map[string]string // defensive deep copy — see buildSnapshot
CLIFlags string
ArchivedAt *time.Time // copy of pointee — see buildSnapshot
// Review queue / activity state (embedded value — copied by value)
ReviewState
// Instance type and management metadata
InstanceType InstanceType
IsManaged bool
ExternalMetadata *ExternalInstanceMetadata // copy of pointee — see buildSnapshot
Permissions InstancePermissions // RequiresConfirmation map deep-copied
Artifacts *artifacts.SessionArtifactsBlob
}
InstanceSnapshot is a point-in-time, read-safe copy of all mutable Instance fields. Published via Instance.snapshot (atomic.Pointer) inside stateMutex at the end of every mutator so lock-free readers always see consistent state.
Excluded: manager/dependency objects (gitManager, vncManager, cdpManager, processManager, controllerManager, tagManager, shellRepo, historyDetector) and callback registrations (lifecycleListeners, onRateLimitDetected, onStatusChange). Those are behavior, not data; callers needing them go through dedicated accessors or mailbox round-trips (Epic 3).
type InstanceStatusInfo ¶
type InstanceStatusInfo struct {
BasicStatus Status // Creating, Active, Paused, Stopped, Hibernated
ClaudeStatus detection.DetectedStatus // If ClaudeController is active
StatusContext string // Context/details about current status (e.g., error message)
PendingApprovals int // Number of pending approvals
QueuedCommands int // Number of queued commands
LastCommandStatus string // Status of last command
IsControllerActive bool // Whether ClaudeController is running
IdleState detection.IdleStateInfo // NEW: Idle state information
}
InstanceStatusInfo provides extended status information for an instance.
func (InstanceStatusInfo) GetColorCode ¶
func (info InstanceStatusInfo) GetColorCode() string
GetColorCode returns a color code for the status (for lipgloss styling).
func (InstanceStatusInfo) GetStatusDescription ¶
func (info InstanceStatusInfo) GetStatusDescription() string
GetStatusDescription returns a human-readable status description.
func (InstanceStatusInfo) GetStatusIcon ¶
func (info InstanceStatusInfo) GetStatusIcon() string
GetStatusIcon returns an icon representing the instance status.
func (InstanceStatusInfo) HasPendingWork ¶
func (info InstanceStatusInfo) HasPendingWork() bool
HasPendingWork returns true if the instance has pending commands or approvals.
func (InstanceStatusInfo) IsWaitingForUser ¶
func (info InstanceStatusInfo) IsWaitingForUser() bool
IsWaitingForUser returns true if the instance is waiting for user input.
func (InstanceStatusInfo) NeedsAttention ¶
func (info InstanceStatusInfo) NeedsAttention() bool
NeedsAttention returns true if the instance requires user attention.
type InstanceStatusManager ¶
type InstanceStatusManager struct {
// contains filtered or unexported fields
}
InstanceStatusManager manages status information for instances.
func NewInstanceStatusManager ¶
func NewInstanceStatusManager() *InstanceStatusManager
NewInstanceStatusManager creates a new status manager.
func (*InstanceStatusManager) GetAllControllers ¶
func (ism *InstanceStatusManager) GetAllControllers() map[string]*ClaudeController
GetAllControllers returns all registered controllers.
func (*InstanceStatusManager) GetController ¶
func (ism *InstanceStatusManager) GetController(instanceTitle string) (*ClaudeController, bool)
GetController retrieves a controller for an instance.
func (*InstanceStatusManager) GetStatus ¶
func (ism *InstanceStatusManager) GetStatus(instance *Instance) InstanceStatusInfo
GetStatus retrieves comprehensive status for an instance.
func (*InstanceStatusManager) RegisterController ¶
func (ism *InstanceStatusManager) RegisterController(instanceTitle string, controller *ClaudeController)
RegisterController registers a controller for an instance.
func (*InstanceStatusManager) UnregisterController ¶
func (ism *InstanceStatusManager) UnregisterController(instanceTitle string)
UnregisterController removes a controller for an instance.
type InstanceStore ¶ added in v1.1.0
type InstanceStore interface {
LoadInstances() ([]*Instance, error)
// ListInstanceData returns raw persisted InstanceData without constructing Instance
// objects or spawning PTY processes. Use this for read-only existence/title checks
// where calling LoadInstances() would create unnecessary side effects.
ListInstanceData() ([]InstanceData, error)
SaveInstances([]*Instance) error
AddInstance(*Instance) error
DeleteInstance(title string) error
UpdateInstanceLastUserResponse(title string, t time.Time) error
}
InstanceStore is the minimal interface the server layer needs for session persistence. Defining it here (alongside the concrete Storage) allows test fakes to be built without depending on the full Storage implementation.
type InstanceType ¶
type InstanceType int
InstanceType represents the type of session instance
const ( // InstanceTypeManaged represents a session fully managed by stapler-squad // with complete lifecycle control, git worktrees, and all features InstanceTypeManaged InstanceType = iota // InstanceTypeExternal represents a Claude instance discovered externally // (not created by stapler-squad) with limited interaction capabilities InstanceTypeExternal )
func (InstanceType) String ¶
func (it InstanceType) String() string
type ItemSessionBacklogEntry ¶ added in v1.37.0
type ItemSessionBacklogEntry struct {
SessionUUID string
SessionRole string
ItemID string
ItemTitle string
ItemStatus string
}
ItemSessionBacklogEntry is a lightweight join record linking a tmux session UUID to its parent backlog item's metadata. Returned by GetAllItemSessionsWithBacklogInfo.
type ItemSessionData ¶ added in v1.35.0
type ItemSessionData struct {
ItemID string // BacklogItem UUID
SessionUUID string
SessionRole string
AcSnapshot AcCriteriaJSON
// PipelineModeSnapshot/PipelineModeSnapshotHash freeze the resolved
// PipelineMode slug and its content hash at the moment this session
// first starts — see ItemSessionSummary.PipelineModeSnapshot(Hash).
PipelineModeSnapshot string
PipelineModeSnapshotHash string
TriageResult string
VerificationNotes string // Freeform verification evidence reported via request_review
EstimatedCostUsd float64 // Only set for headless sessions where cost is known at creation time
}
ItemSessionData is the input data for creating a new ItemSession.
type ItemSessionSummary ¶ added in v1.37.0
type ItemSessionSummary struct {
ID string
BacklogItemID string
SessionUUID string
Role string
AcSnapshot AcCriteriaJSON
PipelineModeSnapshot string
PipelineModeSnapshotHash string
LastCommitSha string
LastCommitMessage string
CommitCountSinceSpawn int
StartedAt *time.Time
EndedAt *time.Time
LastCommitAt *time.Time
LastFileTouchAt *time.Time
LastProgressAt *time.Time
CreatedAt time.Time
EstimatedCostUsd float64
TriageResult string // raw JSON stored in triage_result column
TriageResultSummary string // summary field parsed from TriageResult
VerificationNotes string // freeform verification evidence reported via request_review
OverallOutcome string // from linked review_verdict (empty if none)
ReviewVerdict *ReviewVerdictSummary
}
ItemSessionSummary is the domain DTO replacing *ent.ItemSession in Storage returns. Note: item_sessions table has NO status, triage_result_summary, or overall_outcome columns.
- EndedAt == nil means the session is still running
- TriageResultSummary: parsed from the triage_result JSON column
- OverallOutcome: from the review_verdicts table (populated via ReviewVerdict edge)
- ReviewVerdict: eagerly loaded when the query uses WithReviewVerdict()
func RecordDegradedReviewVerdict ¶ added in v1.38.0
func RecordDegradedReviewVerdict(storage *Storage, itemID string, acSnapshot AcCriteriaJSON, uuidPrefix, summary string) (ItemSessionSummary, error)
RecordDegradedReviewVerdict persists a synthetic UNVERIFIABLE verdict for a review that could not actually be attempted or completed (capability self-check failure, codebase-read timeout/cancellation). Thin wrapper around recordTerminalReviewVerdict that fixes the outcome to UNVERIFIABLE and the session UUID convention (uuidPrefix + a fresh random UUID) shared by every "degraded, not a real failure" call site — see recordTerminalReviewVerdict's doc comment for the full rationale.
type ItemSourceData ¶ added in v1.35.0
type ItemSourceData struct {
ID string
PluginID string
DisplayName string
Config string // JSON, may contain encrypted token
Enabled bool
TokenConfigured bool
LastSyncedAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
ItemSourceData is the domain model for an external item source.
type ItemSourcePlugin ¶ added in v1.35.0
type ItemSourcePlugin interface {
// PluginID returns the unique identifier for this plugin (e.g., "github_issues").
PluginID() string
// Fetch retrieves new and updated items since the cursor. Returns items and the new cursor.
Fetch(ctx context.Context, config PluginConfig, cursor string) ([]ExternalItem, string, error)
// MapToBacklogItem converts an external item to a BacklogItemData.
MapToBacklogItem(item ExternalItem, sourceID string) BacklogItemData
}
ItemSourcePlugin is the interface all external source integrations must implement.
type ItemSourceUpdate ¶ added in v1.35.0
ItemSourceUpdate carries the mutable fields for UpdateItemSource.
type LifecycleEvent ¶ added in v1.15.0
type LifecycleEvent int
LifecycleEvent is a notification type emitted by an Instance when key state transitions occur (e.g., the session starts, or the program exits unexpectedly).
const ( // EventStarted fires at the end of start() when the instance has successfully // transitioned to Running and the controller is up. EventStarted LifecycleEvent = iota // EventExited fires when the underlying program exits unexpectedly (not via an // operator-initiated Kill/Stop). Callers may use this to drive auto-restart logic. EventExited )
type LifecycleListener ¶ added in v1.15.0
type LifecycleListener interface {
OnLifecycleEvent(event LifecycleEvent, reason string)
}
LifecycleListener is implemented by any component that wants to receive Instance lifecycle notifications. Implementations must be non-blocking; use a goroutine or channel if the handler needs to do significant work.
type LiveInstance ¶ added in v1.35.0
type LiveInstance struct {
*Instance
// contains filtered or unexported fields
}
LiveInstance is the actor-owning handle for a session. It wraps *Instance with lifecycle fields for the actor goroutine (IAC Epic 3). Supported construction paths from outside this package:
- Registry.Acquire(sessionID) — load-or-construct for an existing persisted session
- Registry.Register(inst) — for brand-new sessions in CreateSession (R2.18a)
- NewLiveInstance(inst) — direct wrap when the caller already holds *Instance
The actor goroutine (runActor in actor.go) is started by NewLiveInstance via finishLiveInstanceConstruction and exits when Stop()/stopActor() cancels the ctx.
func NewLiveInstance ¶ added in v1.35.0
func NewLiveInstance(inst *Instance) *LiveInstance
NewLiveInstance wraps an already-constructed *Instance in a LiveInstance and starts its actor goroutine. Use Registry.Acquire or Registry.Register where possible; call this directly only when the caller already holds a freshly- constructed *Instance (e.g. CreateSession, which builds its own via NewInstance and then passes it to Registry.Register).
func (*LiveInstance) Stop ¶ added in v1.35.0
func (l *LiveInstance) Stop()
Stop signals this instance's actor to exit and waits for it to drain. Idempotent: safe to call multiple times; the second and subsequent calls return immediately once the first call's <-done wait completes.
type LiveInstancesProvider ¶ added in v1.35.0
type LiveInstancesProvider interface {
GetInstances() []*Instance
}
LiveInstancesProvider is satisfied by ReviewQueuePoller. It returns the live in-memory instances without constructing new Instance objects or spawning PTY processes. HibernationSweeper uses this as a fast path to avoid LoadInstances().
type LoadOptions ¶
type LoadOptions struct {
// LoadWorktree controls whether git worktree data is loaded
LoadWorktree bool
// LoadDiffStats controls whether diff statistics (added/removed counts) are loaded
LoadDiffStats bool
// LoadDiffContent controls whether full diff content is loaded
// Note: This implies LoadDiffStats=true, as we need counts to interpret content
LoadDiffContent bool
// LoadTags controls whether session tags are loaded
LoadTags bool
// LoadClaudeSession controls whether Claude Code session data is loaded
LoadClaudeSession bool
}
LoadOptions controls what child data is loaded for sessions. This allows selective loading to optimize performance by avoiding unnecessary data retrieval.
func (LoadOptions) WithDiffContent ¶
func (o LoadOptions) WithDiffContent() LoadOptions
WithDiffContent returns a copy of options with diff content loading enabled.
func (LoadOptions) WithTags ¶
func (o LoadOptions) WithTags() LoadOptions
WithTags returns a copy of options with tag loading enabled.
func (LoadOptions) WithoutDiffContent ¶
func (o LoadOptions) WithoutDiffContent() LoadOptions
WithoutDiffContent returns a copy of options with diff content loading disabled.
func (LoadOptions) WithoutTags ¶
func (o LoadOptions) WithoutTags() LoadOptions
WithoutTags returns a copy of options with tag loading disabled.
type Locked ¶ added in v1.35.0
type Locked[T any] struct { // contains filtered or unexported fields }
Locked bundles a value T with a RWMutex, enforcing lock discipline by only exposing the value through Read/Write callbacks.
This is the Go equivalent of Rust's RwLock<T>: the data and its lock are inseparable, making it structurally impossible to access the value without correct lock discipline. Instead of a mutex sitting next to a field (which the compiler cannot enforce is held on access), callers receive or mutate the value only through Read or Write.
var listeners Locked[[]StatusChangeListener]
// Add a listener — write lock taken automatically
listeners.Write(func(ls *[]StatusChangeListener) {
*ls = append(*ls, fn)
})
// Read all listeners — read lock taken automatically
var snapshot []StatusChangeListener
listeners.Read(func(ls []StatusChangeListener) {
snapshot = append(snapshot, ls...)
})
type MemoryCacheReader ¶ added in v1.35.0
type MemoryCacheReader interface {
GetCachedRSSMB(sessionUUID string) int64
SystemMemoryPct() (float64, error)
}
MemoryCacheReader is implemented by HibernationSweeper so SessionService can read cached RSS values without importing the sweeper concretely.
type MigrationOptions ¶
type MigrationOptions struct {
// JSONPath is the path to the existing JSON state file
JSONPath string
// SQLitePath is the path where the SQLite database will be created
SQLitePath string
// BackupPath is the path where the JSON backup will be saved
BackupPath string
// ForceOverwrite allows overwriting existing SQLite database
ForceOverwrite bool
// DryRun performs validation without actually migrating
DryRun bool
}
MigrationOptions configures the migration from JSON to SQLite
type MigrationResult ¶
type MigrationResult struct {
TotalSessions int
MigratedSessions int
SkippedSessions int
Errors []string
Duration time.Duration
BackupCreated bool
BackupPath string
SQLiteDatabasePath string
}
MigrationResult contains the results of the migration process
func MigrateJSONToEnt ¶
func MigrateJSONToEnt(opts MigrationOptions) (*MigrationResult, error)
MigrateJSONToEnt migrates session data from JSON to Ent ORM storage.
type NativeProcessManager ¶ added in v1.35.0
type NativeProcessManager struct {
// contains filtered or unexported fields
}
NativeProcessManager implements ProcessManager using a raw PTY and process supervision. It launches the configured program directly under a PTY master fd (via creack/pty) and restarts it with exponential backoff when it exits unexpectedly.
Phase 2 implementation: Start(), Close(), IsAlive(), GetPTY(), GetPanePID(), GetSessionIdentifier(), SetWindowSize(), GetPaneDimensions(), SendKeys(), TapEnter(), SetOnExitCallback(), SubscribeToControlModeUpdates(), and GetCurrentWorkingDirectory() are fully functional. Content capture (CapturePaneContent variants) and precise CWD via lsof/proc are deferred to Phase 3.
func NewNativeProcessManager ¶ added in v1.35.0
func NewNativeProcessManager(opts ProcessManagerOptions) *NativeProcessManager
NewNativeProcessManager creates a NativeProcessManager with the given options. Call Start() to launch the process.
func (*NativeProcessManager) Attach ¶ added in v1.35.0
func (n *NativeProcessManager) Attach() (chan struct{}, error)
Attach is not supported for the native backend; returns an error. Interactive TUI attach requires a proper terminal multiplexer.
func (*NativeProcessManager) CapturePaneContent ¶ added in v1.35.0
func (n *NativeProcessManager) CapturePaneContent() (string, error)
CapturePaneContent returns an empty string until scrollback capture is implemented.
func (*NativeProcessManager) CapturePaneContentRaw ¶ added in v1.35.0
func (n *NativeProcessManager) CapturePaneContentRaw() (string, error)
CapturePaneContentRaw returns an empty string until scrollback capture is implemented.
func (*NativeProcessManager) CapturePaneContentWithOptions ¶ added in v1.35.0
func (n *NativeProcessManager) CapturePaneContentWithOptions(_, _ string) (string, error)
CapturePaneContentWithOptions returns an empty string until scrollback capture is implemented.
func (*NativeProcessManager) CaptureViewport ¶ added in v1.35.0
func (n *NativeProcessManager) CaptureViewport(_ int) (string, error)
CaptureViewport returns an empty string until scrollback capture is implemented.
func (*NativeProcessManager) Close ¶ added in v1.35.0
func (n *NativeProcessManager) Close() error
Close terminates the supervised process and stops the restart loop. Implements NM-3 (SIGTERM before context cancel) and NM-5 (goroutines exit).
func (*NativeProcessManager) DetachSafely ¶ added in v1.35.0
func (n *NativeProcessManager) DetachSafely() error
DetachSafely is a no-op for the native backend.
func (*NativeProcessManager) FilterBanners ¶ added in v1.35.0
func (n *NativeProcessManager) FilterBanners(content string) (string, int)
FilterBanners returns content unchanged; banner detection is tmux-specific.
func (*NativeProcessManager) GetCurrentWorkingDirectory ¶ added in v1.35.0
func (n *NativeProcessManager) GetCurrentWorkingDirectory() (string, error)
GetCurrentWorkingDirectory returns the directory passed to the most recent Start() call. Phase 3 follow-on: replace with /proc/<pid>/cwd on Linux or lsof on macOS for the true current working directory of the running process.
func (*NativeProcessManager) GetCursorPosition ¶ added in v1.35.0
func (n *NativeProcessManager) GetCursorPosition() (x, y int, err error)
GetCursorPosition returns (0, 0) for the native backend. There are zero callers in the server/ package that require real cursor position from the native backend (confirmed in plan.md).
func (*NativeProcessManager) GetPTY ¶ added in v1.35.0
func (n *NativeProcessManager) GetPTY() (*os.File, error)
GetPTY returns the PTY master file descriptor.
func (*NativeProcessManager) GetPaneDimensions ¶ added in v1.35.0
func (n *NativeProcessManager) GetPaneDimensions() (width, height int, err error)
GetPaneDimensions returns the last window size set via SetWindowSize. Tracks the value in memory to avoid a TIOCGWINSZ syscall on the hot path (GetPaneDimensions is called 5× per resize event in connectrpc_websocket.go).
func (*NativeProcessManager) GetPanePID ¶ added in v1.35.0
func (n *NativeProcessManager) GetPanePID() (int32, error)
GetPanePID returns the PID of the supervised process.
func (*NativeProcessManager) GetSessionIdentifier ¶ added in v1.35.0
func (n *NativeProcessManager) GetSessionIdentifier() string
GetSessionIdentifier returns the stable session name set at construction.
func (*NativeProcessManager) HasMeaningfulContent ¶ added in v1.35.0
func (n *NativeProcessManager) HasMeaningfulContent(_ string) bool
HasMeaningfulContent always returns false until content analysis is implemented.
func (*NativeProcessManager) HasSession ¶ added in v1.35.0
func (n *NativeProcessManager) HasSession() bool
HasSession reports whether a process has been started at least once. Alias for IsAlive() on the native backend.
func (*NativeProcessManager) HasUpdated ¶ added in v1.35.0
func (n *NativeProcessManager) HasUpdated() (updated bool, hasPrompt bool, content string)
HasUpdated always returns (false, false, "") until content diffing is implemented.
func (*NativeProcessManager) IsAlive ¶ added in v1.35.0
func (n *NativeProcessManager) IsAlive() bool
IsAlive reports whether the supervised process is currently running.
func (*NativeProcessManager) RefreshClient ¶ added in v1.35.0
func (n *NativeProcessManager) RefreshClient() error
RefreshClient is a no-op for the native backend (no tmux client to refresh).
func (*NativeProcessManager) ResetExitOnce ¶ added in v1.35.0
func (n *NativeProcessManager) ResetExitOnce()
ResetExitOnce is a no-op for the native backend; the restart loop does not use a sync.Once guard.
func (*NativeProcessManager) RestoreWithWorkDir ¶ added in v1.35.0
func (n *NativeProcessManager) RestoreWithWorkDir(_ string) error
RestoreWithWorkDir is a no-op for the native backend; the process is already running after Start() and does not need re-attachment.
func (*NativeProcessManager) SendInputViaControlMode ¶ added in v1.35.0
func (n *NativeProcessManager) SendInputViaControlMode(_ context.Context, data []byte) error
SendInputViaControlMode writes raw bytes directly to the PTY master. The native backend has no concept of tmux control mode; bytes are written directly.
func (*NativeProcessManager) SendKeys ¶ added in v1.35.0
func (n *NativeProcessManager) SendKeys(keys string) (int, error)
SendKeys writes the given string to the PTY master.
func (*NativeProcessManager) SendPromptWithEnter ¶ added in v1.35.0
func (n *NativeProcessManager) SendPromptWithEnter(prompt string) error
SendPromptWithEnter sends text followed by Enter.
func (*NativeProcessManager) SetDetachedSize ¶ added in v1.35.0
func (n *NativeProcessManager) SetDetachedSize(width, height int, _ string) error
SetDetachedSize updates the stored window size without requiring an active PTY. The instanceTitle parameter is ignored; it exists only for interface compatibility.
func (*NativeProcessManager) SetOnExitCallback ¶ added in v1.35.0
func (n *NativeProcessManager) SetOnExitCallback(fn func(string))
SetOnExitCallback registers a callback invoked when the supervised process exits unexpectedly (before the restart loop relaunches it).
func (*NativeProcessManager) SetWindowSize ¶ added in v1.35.0
func (n *NativeProcessManager) SetWindowSize(cols, rows int) error
SetWindowSize resizes the PTY to the given columns and rows.
func (*NativeProcessManager) Start ¶ added in v1.35.0
func (n *NativeProcessManager) Start(dir string) error
Start launches the configured program under a PTY in the given directory. If the process is already running, Start is a no-op. Start resets the stop signal so it is safe to call after Close().
func (*NativeProcessManager) StartControlMode ¶ added in v1.35.0
func (n *NativeProcessManager) StartControlMode() error
StartControlMode is a no-op for the native backend; raw PTY reads replace control mode.
func (*NativeProcessManager) StopControlMode ¶ added in v1.35.0
func (n *NativeProcessManager) StopControlMode() error
StopControlMode is a no-op for the native backend.
func (*NativeProcessManager) SubscribeToControlModeUpdates ¶ added in v1.35.0
func (n *NativeProcessManager) SubscribeToControlModeUpdates() (string, chan []byte)
SubscribeToControlModeUpdates adds a subscriber that receives raw PTY output bytes. Returns the subscription ID and a channel that receives byte slices.
func (*NativeProcessManager) TapEnter ¶ added in v1.35.0
func (n *NativeProcessManager) TapEnter() error
TapEnter sends a carriage return + newline sequence to the PTY.
func (*NativeProcessManager) UnsubscribeFromControlModeUpdates ¶ added in v1.35.0
func (n *NativeProcessManager) UnsubscribeFromControlModeUpdates(id string)
UnsubscribeFromControlModeUpdates removes a subscriber by ID and closes its channel.
type Notifier ¶ added in v1.37.0
Notifier publishes an operator-facing notification. Implemented outside this package (typically a thin adapter over the event bus) since this package cannot import pkg/events directly — pkg/events imports session, so the reverse import would be a cycle. notificationType and priority are int32 values matching sessionv1.NotificationType / sessionv1.NotificationPriority; this package stays free of the proto dependency and just passes the raw values through.
type OpenStuckStateData ¶ added in v1.38.0
type OpenStuckStateData struct {
ID string
ItemID string
Reason domain.StuckReason
FirstDetectedAt time.Time
LastCheckedAt time.Time
NotifiedAt *time.Time
Context string
ItemTitle string
ItemStatus BacklogStatus
PrNumber int
PrURL string
}
OpenStuckStateData is a projected, already-filtered (open + un-snoozed) BacklogStuckState row joined with its parent item's rendering-relevant fields. Returned only by FindOpenStuckStates, which applies the "open" (resolved_at IS NULL) and "not currently snoozed" filters at the query boundary — callers never need to re-check ResolvedAt/SnoozedUntil nullability themselves (parse-don't-validate at the repository boundary).
type OutputConsumer ¶
type OutputConsumer func(data []byte)
OutputConsumer is a callback that receives terminal output from external sessions.
type PRFixSpawner ¶ added in v1.37.0
type PRFixSpawner interface {
AutoReopenForPRFix(ctx context.Context, itemID string, fixContext string) error
}
PRFixSpawner can reopen a pr_pending item for rework when CI checks fail or reviewers request changes. The fixContext string contains a summary of the failures/comments to pass as context to the new work session.
type PRStatusPoller ¶ added in v1.12.0
type PRStatusPoller struct {
// contains filtered or unexported fields
}
PRStatusPoller polls GitHub PR status for all sessions at a shared interval. Uses a single workspace-level ticker (not per-session goroutines) and an ETag cache so unchanged PRs return HTTP 304 and cost zero rate-limit quota.
func NewPRStatusPoller ¶ added in v1.12.0
func NewPRStatusPoller(storage *Storage) *PRStatusPoller
NewPRStatusPoller creates a new poller with default configuration.
func NewPRStatusPollerWithConfig ¶ added in v1.12.0
func NewPRStatusPollerWithConfig(storage *Storage, config PRStatusPollerConfig) *PRStatusPoller
NewPRStatusPollerWithConfig creates a poller with custom configuration.
func (*PRStatusPoller) AddInstance ¶ added in v1.12.0
func (p *PRStatusPoller) AddInstance(inst *Instance)
AddInstance adds a single instance to monitor.
func (*PRStatusPoller) GetInstances ¶ added in v1.35.0
func (p *PRStatusPoller) GetInstances() []*Instance
GetInstances returns a defensive copy of the currently monitored instances. Callers must not modify the returned slice elements.
func (*PRStatusPoller) RemoveInstance ¶ added in v1.12.0
func (p *PRStatusPoller) RemoveInstance(title string)
RemoveInstance removes an instance from monitoring.
func (*PRStatusPoller) SetInstances ¶ added in v1.12.0
func (p *PRStatusPoller) SetInstances(instances []*Instance)
SetInstances replaces the full list of monitored instances.
func (*PRStatusPoller) SetOnUpdated ¶ added in v1.12.0
func (p *PRStatusPoller) SetOnUpdated(fn func(*Instance))
SetOnUpdated registers a callback called when a session's PR priority changes. The callback is invoked from a goroutine; it must be concurrency-safe.
func (*PRStatusPoller) Start ¶ added in v1.12.0
func (p *PRStatusPoller) Start(ctx context.Context)
Start begins the polling loop. Safe to call multiple times; subsequent calls are no-ops.
func (*PRStatusPoller) Stop ¶ added in v1.12.0
func (p *PRStatusPoller) Stop()
Stop gracefully shuts down the poller and waits for in-flight requests.
type PRStatusPollerConfig ¶ added in v1.12.0
type PRStatusPollerConfig struct {
// PollInterval controls how often all sessions are checked.
PollInterval time.Duration
// ConcurrentFetches limits simultaneous gh CLI calls (respects secondary rate limits).
ConcurrentFetches int
// CallTimeout is the maximum time for a single gh API call.
CallTimeout time.Duration
// AuthCacheDuration controls how long a successful auth check is cached.
AuthCacheDuration time.Duration
// NoPRBackoff is how long to wait before re-checking a session after ErrNoPR.
// Zero disables the backoff (always re-check).
NoPRBackoff time.Duration
}
PRStatusPollerConfig contains configuration for the PR status poller.
func DefaultPRStatusPollerConfig ¶ added in v1.12.0
func DefaultPRStatusPollerConfig() PRStatusPollerConfig
DefaultPRStatusPollerConfig returns sensible defaults.
type PTYAccess ¶
type PTYAccess struct {
// contains filtered or unexported fields
}
PTYAccess provides thread-safe access to a tmux session's PTY for reading and writing. It wraps the PTY file descriptor with synchronization primitives to enable concurrent access from multiple goroutines (e.g., command execution, response streaming, status monitoring).
func NewPTYAccess ¶
func NewPTYAccess(sessionName string, pty *os.File, buffer *CircularBuffer) *PTYAccess
NewPTYAccess creates a new PTYAccess wrapper for a PTY file descriptor. The buffer parameter specifies the circular buffer for storing PTY output history.
func (*PTYAccess) Close ¶
Close marks the PTY access as closed and prevents further operations. It does NOT close the underlying PTY file descriptor - that's handled by the tmux session.
func (*PTYAccess) GetBuffer ¶
GetBuffer returns the most recent output from the circular buffer. This provides access to historical PTY output without blocking. Returns a copy of the buffer contents to prevent concurrent modification issues.
func (*PTYAccess) GetFile ¶ added in v1.35.0
GetFile returns the underlying PTY *os.File and whether the PTY has been closed. Returns (f, false) when open, (nil, false) when not yet initialized, (nil, true) when closed. The returned file must not be used after a subsequent UpdatePTY or Close call.
func (*PTYAccess) GetRecentHash ¶ added in v1.37.0
GetRecentHash returns the murmur3-64 hash of the last n bytes without copying. Returns (0, false) when no data is available.
func (*PTYAccess) GetRecentOutput ¶
GetRecentOutput returns the last n bytes from the circular buffer. This is useful for status detection and response streaming.
func (*PTYAccess) GetRecentOutputInto ¶ added in v1.37.0
GetRecentOutputInto copies the last n bytes into dst and returns the number of bytes written. dst must have length >= n. Prefer over GetRecentOutput when the caller can provide a pooled buffer.
func (*PTYAccess) GetSessionName ¶
GetSessionName returns the name of the session this PTY access is for.
func (*PTYAccess) Read ¶
Read reads data from the PTY in a thread-safe manner. This is a blocking call that will wait for data to be available. Returns the number of bytes read and any error encountered.
type PTYCategory ¶
type PTYCategory int
PTYCategory represents grouping of PTYs
const ( PTYCategorySquad PTYCategory = iota // Squad-managed sessions PTYCategoryOrphaned // Unmanaged Claude instances PTYCategoryOther // Other tools (aider, etc.) )
func (PTYCategory) String ¶
func (c PTYCategory) String() string
type PTYConnection ¶
type PTYConnection struct {
Path string // /dev/pts/12
PID int // Process ID
Command string // "claude" or "aider"
SessionName string // Associated squad session (if any)
Status PTYStatus // Current status
LastActivity time.Time // Last activity timestamp
Controller *ClaudeController // Connected controller (if any)
// Ownership and management metadata
IsManaged bool // True if this is a squad-managed session
TmuxSocket string // Which tmux server socket (empty = default)
TmuxSessionName string // Full tmux session name
CanAttach bool // Whether attach operations are allowed
CanDestroy bool // Whether destroy operations are allowed
Owner string // "squad" for managed, "external" for discovered
}
PTYConnection represents a discovered PTY
func (*PTYConnection) GetDisplayName ¶
func (conn *PTYConnection) GetDisplayName() string
GetDisplayName returns a human-readable name for the PTY
func (*PTYConnection) GetPTYBasename ¶
func (conn *PTYConnection) GetPTYBasename() string
GetPTYBasename returns just the PTY number (e.g., "12" from "/dev/pts/12")
func (*PTYConnection) GetStatusColor ¶
func (conn *PTYConnection) GetStatusColor() string
GetStatusColor returns a color code for PTY status
func (*PTYConnection) GetStatusIcon ¶
func (conn *PTYConnection) GetStatusIcon() string
GetStatusIcon returns a visual indicator for PTY status
type PTYDiscovery ¶
type PTYDiscovery struct {
// contains filtered or unexported fields
}
PTYDiscovery manages PTY discovery and monitoring
func NewPTYDiscovery ¶
func NewPTYDiscovery(opts ...PTYDiscoveryOption) *PTYDiscovery
NewPTYDiscovery creates a new PTY discovery service with default configuration. Optional PTYDiscoveryOption values are applied after initialization.
func NewPTYDiscoveryWithConfig ¶
func NewPTYDiscoveryWithConfig(config PTYDiscoveryConfig, opts ...PTYDiscoveryOption) *PTYDiscovery
NewPTYDiscoveryWithConfig creates a new PTY discovery service with custom configuration. Optional PTYDiscoveryOption values are applied after initialization.
func (*PTYDiscovery) GetConnection ¶
func (pd *PTYDiscovery) GetConnection(path string) *PTYConnection
GetConnection returns a specific PTY connection by path
func (*PTYDiscovery) GetConnections ¶
func (pd *PTYDiscovery) GetConnections() []*PTYConnection
GetConnections returns all discovered PTY connections
func (*PTYDiscovery) GetConnectionsByCategory ¶
func (pd *PTYDiscovery) GetConnectionsByCategory() map[PTYCategory][]*PTYConnection
GetConnectionsByCategory returns PTYs grouped by category
func (*PTYDiscovery) Refresh ¶
func (pd *PTYDiscovery) Refresh() error
Refresh performs a full PTY discovery scan
func (*PTYDiscovery) SetSessions ¶
func (pd *PTYDiscovery) SetSessions(sessions []*Instance)
SetSessions updates the session map for correlation
type PTYDiscoveryConfig ¶
type PTYDiscoveryConfig struct {
// Primary tmux server socket for squad-managed sessions
// Empty string means use the default tmux server
PrimarySocket string
// ExternalSockets are additional tmux servers to scan for external instances
// Only used when Mode is Extended or Full
ExternalSockets []string
// Mode controls discovery scope and permissions
Mode DiscoveryMode
// ManagedPrefix is the tmux session prefix for squad-managed sessions
// Default: "staplersquad_"
ManagedPrefix string
// DiscoverExternal enables discovery of non-prefixed Claude instances
// Automatically enabled for Extended and Full modes
DiscoverExternal bool
// AllowExternalAttach permits attaching to external instances
// Only effective in Full mode
AllowExternalAttach bool
// RequireConfirmation requires user confirmation for external operations
// Recommended to keep true for safety
RequireConfirmation bool
// DiscoveryInterval controls how often to refresh discovery
DiscoveryInterval time.Duration
// ParallelDiscovery enables parallel scanning of multiple tmux servers
ParallelDiscovery bool
}
PTYDiscoveryConfig controls PTY discovery scope and behavior
func DefaultPTYDiscoveryConfig ¶
func DefaultPTYDiscoveryConfig() PTYDiscoveryConfig
DefaultPTYDiscoveryConfig returns the default discovery configuration
func (*PTYDiscoveryConfig) CanAttachExternal ¶
func (c *PTYDiscoveryConfig) CanAttachExternal() bool
CanAttachExternal returns true if attaching to external instances is allowed
func (*PTYDiscoveryConfig) ShouldDiscoverExternal ¶
func (c *PTYDiscoveryConfig) ShouldDiscoverExternal() bool
ShouldDiscoverExternal returns true if external instances should be discovered
type PTYDiscoveryOption ¶ added in v1.18.0
type PTYDiscoveryOption func(*PTYDiscovery)
PTYDiscoveryOption is a functional option for PTYDiscovery construction.
func WithSessionLister ¶ added in v1.18.0
func WithSessionLister(l tmux.SessionLister) PTYDiscoveryOption
WithSessionLister injects a SessionLister; used in tests to avoid exec.Command forks.
type PTYSubscriber ¶ added in v1.35.0
type PTYSubscriber interface {
// Push appends data to the buffer. Must be goroutine-safe and never block.
// Returns ErrSubscriberFull if the buffer is at capacity; the caller should
// then close the subscriber and force the consumer to reconnect.
Push(data []byte) error
// Chan returns the receive-only channel from which the consumer reads buffered
// data. The channel is closed when Close is called and all queued data is drained.
Chan() <-chan []byte
// Close signals that no more data will be pushed and releases resources.
Close()
}
PTYSubscriber is a lossless, ordered buffer for raw PTY bytes from a single session. fanOut calls Push; the consumer reads from Chan. Implementations must be goroutine-safe.
The interface is intentionally minimal so that alternative backends (e.g. a memory-mapped circular file for large or persistent sessions) can be substituted without changing callers.
type PendingApproval ¶
type PendingApproval struct {
Request *detection.ApprovalRequest
Decision *PolicyDecision
ReceivedAt time.Time
ExpiresAt time.Time
Status PendingApprovalStatus
UserResponse *detection.ApprovalResponse
}
PendingApproval represents an approval request awaiting action.
type PendingApprovalStatus ¶
type PendingApprovalStatus string
PendingApprovalStatus tracks the state of a pending approval.
const ( PendingStatusAwaiting PendingApprovalStatus = "awaiting" PendingStatusProcessed PendingApprovalStatus = "processed" PendingStatusExpired PendingApprovalStatus = "expired" PendingStatusCancelled PendingApprovalStatus = "cancelled" )
type PipelineEngine ¶ added in v1.38.0
type PipelineEngine interface {
// SlashCommandSet returns the filename→rendered-content map that
// WriteSlashCommands writes to .claude/commands/backlog/ for item.
SlashCommandSet(item *BacklogItemData) (map[string]string, error)
// TriagePromptFor builds the headless-triage prompt for item.
TriagePromptFor(item *BacklogItemData, artifactAbsPath string) string
// ReviewPromptFor builds the headless-review prompt for item.
ReviewPromptFor(item *BacklogItemData, acSnapshot []AcCriterion, diff string, diffTruncated bool, verificationNotes string, extras ReviewContextExtras) string
// InitialPromptFor builds the interactive/autonomous session's initial
// prompt (inst.Prompt).
InitialPromptFor(item *BacklogItemData, priorSessions []ItemSessionSummary) string
// ContentHashFor returns the content hash of a resolved mode's 9 raw
// content-template fields. ok is false for PipelineModeDefault (code-
// backed content can't drift without a redeploy — nothing to hash) or an
// unresolved slug.
ContentHashFor(mode PipelineMode) (hash string, ok bool)
}
PipelineEngine is the narrow (5-method) seam described in the package doc comment above. CachingPipelineEngine is its single concrete implementation.
The method count (5) intentionally exceeds the usual 1-3-method interface- segregation guidance: each method shares the same resolve-and-render mechanism and has a genuine, independently-verified caller elsewhere in the codebase (see plan.md's Pattern Decisions row on method count) — splitting them into multiple interfaces would be exactly the kind of speculative interface-pollution .claude/rules/interface-pollution-checklist.md warns against, not less of it.
type PipelineMode ¶ added in v1.38.0
type PipelineMode string
PipelineMode identifies which PipelineMode definition (by slug) drives a backlog item's triage/work/review content.
const PipelineModeDefault PipelineMode = ""
PipelineModeDefault is the sentinel PipelineMode value meaning "no mode chosen — use the pre-existing hardcoded pipeline." Resolving this value is guaranteed, by construction, to never touch pipelineModeCache or PipelineModeRepository — this is the concrete mechanism that keeps "no uncached DB read on the hot path for the common case" true without needing runtime feature-flagging.
type PipelineModeContentFields ¶ added in v1.38.0
type PipelineModeContentFields struct {
Slug string
ValidateSlug bool
StatusCommandTemplate string
DoneCommandTemplate string
FailCommandTemplate string
ReviewCommandTemplate string
ShipCommandTemplate string
HelpCommandTemplate string
TriagePromptTemplate string
ReviewPromptTemplate string
InitialPromptTemplate string
}
PipelineModeContentFields groups the slug and the 9 content-template fields ValidatePipelineModeContent checks.
ValidateSlug should be true only for a Create-style call: slug is required and format-checked there. Update never sets it, because UpdatePipelineModeRequest has no slug field at all — slug is immutable after creation (see proto/session/v1/backlog.proto) — so there is nothing for an Update call to validate.
Any content-template field left as "" (e.g. a field a partial Update request didn't set) trivially passes both content checks below (an empty string contains no shell metacharacters and no placeholder tokens), so callers building this struct for an Update only need to populate whichever fields the request actually sets — omitted fields never fail validation they didn't ask for.
type PipelineModeCreateInput ¶ added in v1.38.0
type PipelineModeCreateInput struct {
Slug string
Name string
Description string
Enabled bool
StatusCommandTemplate string
DoneCommandTemplate string
FailCommandTemplate string
ReviewCommandTemplate string
ShipCommandTemplate string
HelpCommandTemplate string
TriagePromptTemplate string
ReviewPromptTemplate string
InitialPromptTemplate string
}
PipelineModeCreateInput holds the fields for creating a new pipeline mode.
type PipelineModeRepository ¶ added in v1.38.0
type PipelineModeRepository interface {
Create(ctx context.Context, m PipelineModeCreateInput) (*ent.PipelineMode, error)
Update(ctx context.Context, id uuid.UUID, m PipelineModeUpdateInput) (*ent.PipelineMode, error)
Delete(ctx context.Context, id uuid.UUID) error
GetByID(ctx context.Context, id uuid.UUID) (*ent.PipelineMode, error)
GetBySlug(ctx context.Context, slug string) (*ent.PipelineMode, error)
ListAll(ctx context.Context) ([]*ent.PipelineMode, error)
ListEnabled(ctx context.Context) ([]*ent.PipelineMode, error)
}
PipelineModeRepository defines persistence operations for pipeline mode definitions.
type PipelineModeUpdateInput ¶ added in v1.38.0
type PipelineModeUpdateInput struct {
Name *string
Description *string
Enabled *bool
StatusCommandTemplate *string
DoneCommandTemplate *string
FailCommandTemplate *string
ReviewCommandTemplate *string
ShipCommandTemplate *string
HelpCommandTemplate *string
TriagePromptTemplate *string
ReviewPromptTemplate *string
InitialPromptTemplate *string
}
PipelineModeUpdateInput holds optional fields for updating an existing pipeline mode. Pointer fields are only applied when non-nil (partial update).
type PluginConfig ¶ added in v1.35.0
type PluginConfig struct {
Raw string // JSON
}
PluginConfig is opaque config passed to a plugin. Plugins decode their own fields.
type PluginRegistry ¶ added in v1.35.0
type PluginRegistry struct {
// contains filtered or unexported fields
}
PluginRegistry holds registered source plugins.
func NewDefaultRegistry ¶ added in v1.35.0
func NewDefaultRegistry() *PluginRegistry
NewDefaultRegistry returns a registry with all built-in plugins registered.
func NewPluginRegistry ¶ added in v1.35.0
func NewPluginRegistry() *PluginRegistry
NewPluginRegistry creates a new empty PluginRegistry.
func (*PluginRegistry) Get ¶ added in v1.35.0
func (r *PluginRegistry) Get(id string) (ItemSourcePlugin, bool)
Get retrieves a plugin by ID.
func (*PluginRegistry) Register ¶ added in v1.35.0
func (r *PluginRegistry) Register(p ItemSourcePlugin)
Register adds a plugin to the registry.
type PolicyAction ¶
type PolicyAction string
PolicyAction specifies what to do when a policy matches.
const ( ActionAutoApprove PolicyAction = "auto_approve" ActionAutoReject PolicyAction = "auto_reject" ActionPrompt PolicyAction = "prompt" ActionLog PolicyAction = "log_only" )
type PolicyAuditEntry ¶
type PolicyAuditEntry struct {
Timestamp time.Time `json:"timestamp"`
RequestID string `json:"request_id"`
PolicyID string `json:"policy_id"`
PolicyName string `json:"policy_name"`
Action PolicyAction `json:"action"`
MatchedRequest *detection.ApprovalRequest `json:"matched_request"`
Reason string `json:"reason"`
}
PolicyAuditEntry records policy evaluation results.
type PolicyCondition ¶
type PolicyCondition struct {
Field string `json:"field"` // Field to check (e.g., "command", "file_path")
Operator string `json:"operator"` // "equals", "contains", "regex", "not_contains"
Value string `json:"value"` // Value to compare against
// contains filtered or unexported fields
}
PolicyCondition represents a single condition that must be met.
type PolicyDecision ¶
type PolicyDecision struct {
Request *detection.ApprovalRequest `json:"request"`
Timestamp time.Time `json:"timestamp"`
Decision PolicyAction `json:"decision"`
Matched bool `json:"matched"`
MatchedPolicy *ApprovalPolicy `json:"matched_policy,omitempty"`
Reason string `json:"reason"`
}
PolicyDecision represents the result of policy evaluation.
type PolicyEngine ¶
type PolicyEngine struct {
// contains filtered or unexported fields
}
PolicyEngine manages approval policies and evaluates approval requests.
func NewPolicyEngine ¶
func NewPolicyEngine() *PolicyEngine
NewPolicyEngine creates a new approval policy engine.
func (*PolicyEngine) AddPolicy ¶
func (pe *PolicyEngine) AddPolicy(policy *ApprovalPolicy) error
AddPolicy adds a new approval policy.
func (*PolicyEngine) ClearAuditLog ¶
func (pe *PolicyEngine) ClearAuditLog()
ClearAuditLog removes all audit log entries.
func (*PolicyEngine) Evaluate ¶
func (pe *PolicyEngine) Evaluate(request *detection.ApprovalRequest) (*PolicyDecision, error)
Evaluate evaluates an approval request against all policies.
func (*PolicyEngine) GetAuditLog ¶
func (pe *PolicyEngine) GetAuditLog(limit int) []PolicyAuditEntry
GetAuditLog returns recent audit log entries.
func (*PolicyEngine) GetPolicy ¶
func (pe *PolicyEngine) GetPolicy(id string) *ApprovalPolicy
GetPolicy retrieves a policy by ID.
func (*PolicyEngine) GetStatistics ¶
func (pe *PolicyEngine) GetStatistics() PolicyStatistics
GetStatistics returns statistics about policy usage.
func (*PolicyEngine) ListPolicies ¶
func (pe *PolicyEngine) ListPolicies() []*ApprovalPolicy
ListPolicies returns all policies, sorted by priority.
func (*PolicyEngine) RemovePolicy ¶
func (pe *PolicyEngine) RemovePolicy(id string) bool
RemovePolicy removes a policy by ID.
func (*PolicyEngine) SetMaxAuditLog ¶
func (pe *PolicyEngine) SetMaxAuditLog(max int)
SetMaxAuditLog sets the maximum number of audit log entries to keep.
func (*PolicyEngine) UpdatePolicy ¶
func (pe *PolicyEngine) UpdatePolicy(updated *ApprovalPolicy) error
UpdatePolicy updates an existing policy.
type PolicyStatistics ¶
type PolicyStatistics struct {
TotalPolicies int
EnabledPolicies int
TotalEvaluations int
AutoApprovals int
AutoRejections int
PromptedApprovals int
LoggedOnly int
}
PolicyStatistics provides summary statistics.
type ProcessFileInspector ¶
type ProcessFileInspector interface {
OpenFiles(pid int32) ([]string, error)
IsAlive(pid int32, expectedCreateTimeMs int64) bool
}
ProcessFileInspector is the interface used by HistoryFileDetector. This allows mocking in tests.
type ProcessManager ¶ added in v1.35.0
type ProcessManager interface {
// Lifecycle
Start(dir string) error
RestoreWithWorkDir(workDir string) error
Close() error
IsAlive() bool
// Identification
GetSessionIdentifier() string
// Existence / state
HasSession() bool
// Working directory (via pane or process introspection)
GetCurrentWorkingDirectory() (string, error)
// Terminal I/O
GetPTY() (*os.File, error)
SendKeys(keys string) (int, error)
TapEnter() error
SendPromptWithEnter(prompt string) error
SendInputViaControlMode(ctx context.Context, data []byte) error
// Terminal state
CapturePaneContent() (string, error)
CapturePaneContentRaw() (string, error)
CapturePaneContentWithOptions(startLine, endLine string) (string, error)
CaptureViewport(lines int) (string, error)
GetCursorPosition() (x, y int, err error)
GetPaneDimensions() (width, height int, err error)
SetWindowSize(cols, rows int) error
SetDetachedSize(width, height int, instanceTitle string) error
RefreshClient() error
// Process metadata
GetPanePID() (int32, error)
// Content helpers
HasUpdated() (updated bool, hasPrompt bool, content string)
FilterBanners(content string) (string, int)
HasMeaningfulContent(content string) bool
// Streaming (control mode)
StartControlMode() error
StopControlMode() error
// SubscribeToControlModeUpdates returns a subscription ID and a bidirectional channel.
// The channel must be bidirectional (chan []byte, not <-chan []byte) because some callers
// write synthetic frames for testing. Implementations must not write to the channel themselves.
SubscribeToControlModeUpdates() (string, chan []byte)
UnsubscribeFromControlModeUpdates(id string)
// Attach (interactive TUI)
Attach() (chan struct{}, error)
DetachSafely() error
// Exit notifications
SetOnExitCallback(fn func(string))
ResetExitOnce()
}
ProcessManager abstracts terminal process lifecycle and I/O. Implementations: TmuxBackend (wraps TmuxProcessManager), NativeProcessManager (Phase 2).
func NewProcessManager ¶ added in v1.35.0
func NewProcessManager(_ context.Context, defaultBackend ProcessManagerBackend, opts ProcessManagerOptions) ProcessManager
NewProcessManager returns the ProcessManager implementation selected by the registered backend. Falls back to TmuxBackend for unknown values.
type ProcessManagerBackend ¶ added in v1.35.0
type ProcessManagerBackend string
ProcessManagerBackend identifies the backend implementation.
const ( BackendTmux ProcessManagerBackend = "tmux" BackendNative ProcessManagerBackend = "native" )
type ProcessManagerOptions ¶ added in v1.35.0
type ProcessManagerOptions struct {
SessionName string
Prefix string
ServerSocket string
Program string
Args []string
}
ProcessManagerOptions holds constructor parameters for NewProcessManager.
type ProgressNoteData ¶ added in v1.38.0
ProgressNoteData is the domain DTO replacing *ent.BacklogProgressNote in Storage returns. Unlike the current-note-per-criterion stored on BacklogItem.AcceptanceCriteria, this represents a single append-only history entry from one report_progress call.
type ProjectData ¶ added in v1.23.0
type ProjectData struct {
// ID is the unique project name (used as string external identifier)
ID string
Name string
Description string
CreatedAt time.Time
UpdatedAt time.Time
}
ProjectData is the domain model for a project that groups sessions.
type Registry ¶ added in v1.35.0
type Registry struct {
// contains filtered or unexported fields
}
Registry owns the sessionID → live-actor mapping plus refcounts. Its mutex guards map membership only — not per-field Instance state. Construct with NewRegistry; the zero value is not usable.
func NewRegistry ¶ added in v1.35.0
func NewRegistry(storage *Storage, onConstruct func(*LiveInstance)) *Registry
NewRegistry constructs a Registry. onConstruct may be nil (e.g. daemon.go's own Registry, which has no SessionService to wire callbacks for); Acquire nil-checks before calling it.
func (*Registry) Acquire ¶ added in v1.35.0
func (r *Registry) Acquire(sessionID string) (*LiveInstance, ReleaseFunc, error)
Acquire returns the live handle for sessionID, constructing its actor on first access. On success, the caller MUST call the returned ReleaseFunc exactly once — prefer WithInstance for synchronous single-call-stack callers to avoid forgetting it.
Three outcomes:
- Not in storage → ErrSessionNotFound
- Not in map, construction succeeds → new entry, refcount=1
- Already in map (or races with concurrent Acquire) → refcount++
func (*Registry) AcquireAll ¶ added in v1.35.0
func (r *Registry) AcquireAll() ([]*LiveInstance, ReleaseFunc, error)
AcquireAll acquires every session known to Storage in one call; returns one release closing over all of them. Sugar for sweep-style callers (health.go, hibernation_sweeper.go). Sessions that fail to Acquire are logged and skipped, not returned.
func (*Registry) ForceRelease ¶ added in v1.35.0
ForceRelease tears down sessionID's actor and map entry immediately, regardless of refcount (R2.18 — DeleteSession's force-invalidate; also used by CreateSession to abort a Register()'d entry when the immediately-following storage.AddInstance fails).
Other holders' *LiveInstance pointers stay valid Go values; their next command must return a typed error (Story 2.5.9c's contract, implemented in Epic 3), never hang.
For CreateSession's abort path: use ForceRelease (not the release() closure Register returned) because a concurrent Acquire racing between Register and the abort would bump refcount to 2, making plain release() decrement 2→1 and leave the phantom entry alive. ForceRelease deletes unconditionally, regardless of current refcount.
func (*Registry) List ¶ added in v1.35.0
func (r *Registry) List() []*LiveInstance
List returns a snapshot of all currently-live instances, holding the lock only for the copy.
func (*Registry) Register ¶ added in v1.35.0
func (r *Registry) Register(instance *LiveInstance) (ReleaseFunc, error)
Register is the construction-time counterpart to Acquire (R2.18a). CreateSession builds a brand-new *LiveInstance via NewInstance (no persisted row exists yet for Acquire to look up) and hands it to Register before calling storage.AddInstance.
Register deliberately does NOT invoke onConstruct: CreateSession already performs its own explicit post-construction wiring, so routing Register through onConstruct would wire the same callbacks twice. onConstruct exists solely to backfill wiring for the Acquire-from-storage path (sessions loaded on server restart), which has no other caller positioned to do it.
No double-checked locking here (unlike Acquire): Register has no storage I/O to release the lock around, so the whole check-then-insert runs under one lock acquisition.
func (*Registry) Shutdown ¶ added in v1.35.0
func (r *Registry) Shutdown()
Shutdown force-stops every actor regardless of refcount. Register this as a shutdownHooks entry (Story 2.5.5d) so it fires on server shutdown.
func (*Registry) Storage ¶ added in v1.35.0
Storage returns the Registry's backing storage. Used by callers (e.g. daemon.go) that need access to storage through a Registry reference.
func (*Registry) WithInstance ¶ added in v1.35.0
func (r *Registry) WithInstance(ctx context.Context, sessionID string, fn func(*LiveInstance) error) error
WithInstance is the preferred entry point for synchronous, single-call-stack callers (RPC handlers, one-shot lookups) where forgetting release() is the common failure mode. Reserve raw Acquire/release() for genuinely long-lived holders (WebSocket streams, poller caches, background goroutines).
type RegistryInspector ¶ added in v1.35.0
type RegistryInspector interface {
List() []*LiveInstance
Count() int
}
RegistryInspector is the narrowest interface for callers that only enumerate live instances without acquiring individual handles.
type ReleaseFunc ¶ added in v1.35.0
type ReleaseFunc func()
ReleaseFunc is the refcount-gated teardown closure returned by Acquire and Register. It is idempotent (safe to call more than once via an internal sync.Once) and must be called exactly once per successful Acquire/Register to avoid refcount leaks. Distinct from ForceReleaseFunc so that future callers storing it generically cannot silently conflate refcount-gated and unconditional teardown (type-driven-audit finding B).
type RepoPathManager ¶
type RepoPathManager struct {
// contains filtered or unexported fields
}
RepoPathManager handles GOPATH-style repository path management. Repositories are stored in a consistent location based on their URL:
- ~/.stapler-squad/repos/github.com/owner/repo (main clone)
- Worktrees are created relative to the main repo as needed
func NewRepoPathManager ¶
func NewRepoPathManager() *RepoPathManager
NewRepoPathManager creates a new RepoPathManager with the default base directory.
func NewRepoPathManagerWithBase ¶
func NewRepoPathManagerWithBase(baseDir string) *RepoPathManager
NewRepoPathManagerWithBase creates a RepoPathManager with a custom base directory.
func (*RepoPathManager) EnsureRepoCloned ¶
func (m *RepoPathManager) EnsureRepoCloned(ref *GitHubRef) (string, error)
EnsureRepoCloned ensures the repository is cloned to the local path. If already cloned, it fetches the latest changes. Returns the path to the cloned repository.
func (*RepoPathManager) GetCloneURL ¶
func (m *RepoPathManager) GetCloneURL(ref *GitHubRef) string
GetCloneURL returns the git clone URL for a GitHub ref.
func (*RepoPathManager) GetRepoPath ¶
func (m *RepoPathManager) GetRepoPath(ref *GitHubRef) string
GetRepoPath returns the local path where a GitHub repo should be stored. Format: ~/.stapler-squad/repos/github.com/owner/repo
func (*RepoPathManager) ResolveGitHubInput ¶
func (m *RepoPathManager) ResolveGitHubInput(input string) (localPath string, ref *GitHubRef, err error)
ResolveGitHubInput takes a GitHub URL/shorthand and returns a resolved path. It clones the repo if necessary and returns the local path. Also returns the parsed GitHubRef for storing metadata.
type Repository ¶
type Repository interface {
// Create inserts a new session into storage
Create(ctx context.Context, data InstanceData) error
// Update modifies an existing session in storage
Update(ctx context.Context, data InstanceData) error
// Delete removes a session from storage by title
Delete(ctx context.Context, title string) error
// Get retrieves a single session by title with full child data
// For selective loading, use GetWithOptions instead
Get(ctx context.Context, title string) (*InstanceData, error)
// GetWithOptions retrieves a single session with selective child data loading
// Use LoadOptions presets (LoadMinimal, LoadSummary, LoadFull) or custom options
GetWithOptions(ctx context.Context, title string, options LoadOptions) (*InstanceData, error)
// List retrieves all sessions with summary child data (no diff content)
// For selective loading, use ListWithOptions instead
List(ctx context.Context) ([]InstanceData, error)
// ListWithOptions retrieves all sessions with selective child data loading
// Use LoadOptions presets (LoadMinimal, LoadSummary, LoadFull) or custom options
ListWithOptions(ctx context.Context, options LoadOptions) ([]InstanceData, error)
// ListByStatus retrieves sessions filtered by status with summary child data
// For selective loading, use ListByStatusWithOptions instead
ListByStatus(ctx context.Context, status Status) ([]InstanceData, error)
// ListByStatusWithOptions retrieves sessions filtered by status with selective loading
ListByStatusWithOptions(ctx context.Context, status Status, options LoadOptions) ([]InstanceData, error)
// ListByTag retrieves sessions with a specific tag with summary child data
// For selective loading, use ListByTagWithOptions instead
ListByTag(ctx context.Context, tag string) ([]InstanceData, error)
// ListByTagWithOptions retrieves sessions with a specific tag with selective loading
ListByTagWithOptions(ctx context.Context, tag string, options LoadOptions) ([]InstanceData, error)
// UpdateTimestamps efficiently updates only timestamp fields for a session
// This is optimized for frequent updates from WebSocket terminal streaming
UpdateTimestamps(ctx context.Context, title string, lastTerminalUpdate, lastMeaningfulOutput time.Time, lastOutputSignature string) error
// UpdateReviewQueueState efficiently updates the review-queue interaction fields
// (LastUserResponse, ProcessingGraceUntil, LastPromptDetected, LastPromptSignature)
// without the read-modify-write overhead of a full Get+Update cycle.
UpdateReviewQueueState(ctx context.Context, title string, lastUserResponse, processingGraceUntil, lastPromptDetected time.Time, lastPromptSignature string) error
// UpdateLastAddedToQueue sets only the last_added_to_queue field for a session.
// Issues a single UPDATE WHERE title=? without a prior SELECT.
UpdateLastAddedToQueue(ctx context.Context, title string, t time.Time) error
// UpdateLastAcknowledged sets only the last_acknowledged field for a session.
// Issues a single UPDATE WHERE title=? without a prior SELECT.
UpdateLastAcknowledged(ctx context.Context, title string, t time.Time) error
// UpdateLastViewed sets only the last_viewed field for a session.
// Issues a single UPDATE WHERE title=? without a prior SELECT.
UpdateLastViewed(ctx context.Context, title string, t time.Time) error
// Close performs cleanup and releases resources
Close() error
// GetSession retrieves a session using the new Session domain model.
// Use ContextOptions to control which optional contexts are loaded.
// Returns nil if session not found.
GetSession(ctx context.Context, title string, opts ContextOptions) (*Session, error)
// ListSessions retrieves all sessions using the new Session domain model.
// Use ContextOptions to control which optional contexts are loaded.
ListSessions(ctx context.Context, opts ContextOptions) ([]*Session, error)
// CreateSession creates a new session from the Session domain model.
CreateSession(ctx context.Context, session *Session) error
// UpdateSession updates an existing session using the Session domain model.
UpdateSession(ctx context.Context, session *Session) error
// AllRules returns all auto-approval rules.
AllRules(ctx context.Context) ([]ApprovalRuleData, error)
// UpsertRule creates or updates an auto-approval rule.
UpsertRule(ctx context.Context, rule ApprovalRuleData) error
// DeleteRule removes an auto-approval rule by ID.
DeleteRule(ctx context.Context, id string) error
// RecordAnalytics logs a classification decision.
RecordAnalytics(ctx context.Context, data AnalyticsData) error
// ListAnalytics retrieves recent classification decisions.
ListAnalytics(ctx context.Context, limit int) ([]AnalyticsData, error)
// ListAnalyticsSince retrieves analytics entries with created_at >= since.
// Replaces the in-Go date filter in LoadWindow. Implements AC-1.
// Pass limit=0 for no limit.
ListAnalyticsSince(ctx context.Context, since time.Time, limit int) ([]AnalyticsData, error)
// ListAnalyticsByProgramSince retrieves entries for a specific program since a time.
// Uses the compound index (command_program, created_at). Implements AC-3.
// Pass limit=0 for no limit.
ListAnalyticsByProgramSince(ctx context.Context, program string, since time.Time, limit int) ([]AnalyticsData, error)
// GetSubcommandBreakdown returns per-(subcommand, decision) counts for a program
// in the given time window. Uses SQL GROUP BY via ent Aggregate. Implements AC-4.
GetSubcommandBreakdown(ctx context.Context, program string, since time.Time) ([]SubcommandDecisionCount, error)
// ListRecentCommandsByProgram returns the most recent n command_preview strings
// for (program, subcommand). Pass subcommand="" to match all subcommands.
// Implements AC-5.
ListRecentCommandsByProgram(ctx context.Context, program, subcommand string, since time.Time, n int) ([]string, error)
// GetSubcommandTrend returns raw analytics rows for (program, subcommand) since
// a given time. The caller buckets these using ComputeDailyBuckets. Implements AC-6.
// Pass subcommand="" to match all subcommands for the program.
GetSubcommandTrend(ctx context.Context, program, subcommand string, since time.Time) ([]AnalyticsData, error)
// CreateProject inserts a new project.
CreateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
// ListProjects returns all projects.
ListProjects(ctx context.Context) ([]ProjectData, error)
// UpdateProject modifies an existing project.
UpdateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
// DeleteProject removes a project by name; sessions are unassigned.
DeleteProject(ctx context.Context, name string) error
// AssignSessionsToProject links sessions (by title) to a project (by name).
AssignSessionsToProject(ctx context.Context, projectName string, sessionTitles []string) error
// CreateBacklogItem inserts a new backlog item.
CreateBacklogItem(ctx context.Context, data BacklogItemData) (*BacklogItemData, error)
// GetBacklogItem retrieves a backlog item by UUID string.
GetBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
// ListBacklogItems returns backlog items with optional filtering.
ListBacklogItems(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemData, error)
// UpdateBacklogItem modifies an existing backlog item with optional precondition check.
UpdateBacklogItem(ctx context.Context, id string, update BacklogItemUpdate, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
// ArchiveBacklogItem sets the archived_at timestamp on a backlog item.
ArchiveBacklogItem(ctx context.Context, id string) (*BacklogItemData, error)
// DeleteBacklogItem permanently removes an item and all its child records.
DeleteBacklogItem(ctx context.Context, id string) error
// TransitionBacklogItemStatus changes the status of a backlog item with optional precondition.
TransitionBacklogItemStatus(ctx context.Context, id string, toStatus BacklogStatus, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
// GetAllItemSessionsWithBacklogInfo returns all item sessions joined with their parent backlog item metadata.
// Used by the Insights dashboard to annotate sessions with backlog context.
GetAllItemSessionsWithBacklogInfo(ctx context.Context) ([]ItemSessionBacklogEntry, error)
// ListBacklogItemSummaries returns lightweight summaries for the list view.
// Unlike ListBacklogItems it omits Description/plan fields and eagerly loads
// ItemSessions (with ReviewVerdict) without over-fetching status events.
ListBacklogItemSummaries(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemSummary, error)
// CreateItemSource registers a new external item source.
CreateItemSource(ctx context.Context, data ItemSourceData) (*ItemSourceData, error)
// ListItemSources returns all registered item sources.
ListItemSources(ctx context.Context) ([]ItemSourceData, error)
// UpdateItemSource modifies an existing item source.
UpdateItemSource(ctx context.Context, id string, update ItemSourceUpdate) (*ItemSourceData, error)
// DeleteItemSource removes an item source by UUID string.
DeleteItemSource(ctx context.Context, id string) error
}
Repository defines the interface for session persistence operations. This abstraction allows multiple storage backends (SQLite, JSON, etc.) while maintaining a consistent API for session management.
type RepositoryOption ¶
type RepositoryOption func(interface{}) error
RepositoryOption is a function that configures a repository
func WithDatabasePath ¶
func WithDatabasePath(path string) RepositoryOption
WithDatabasePath sets the database file path for the repository
type ResponseChunk ¶
ResponseChunk represents a chunk of output from the Claude instance.
type ResponseStream ¶
type ResponseStream struct {
OnEOF func() // Called when the PTY exits unexpectedly (program exit, not Stop())
// contains filtered or unexported fields
}
ResponseStream manages real-time streaming of Claude instance responses to multiple subscribers. It reads from the PTY access layer and broadcasts output to all active subscribers.
func NewResponseStream ¶
func NewResponseStream(sessionName string, ptyAccess *PTYAccess) *ResponseStream
NewResponseStream creates a new response stream for the given session. The bufferSize parameter determines how many chunks can be buffered per subscriber.
func NewResponseStreamWithBuffer ¶
func NewResponseStreamWithBuffer(sessionName string, ptyAccess *PTYAccess, bufferSize int) *ResponseStream
NewResponseStreamWithBuffer creates a response stream with a custom buffer size.
func (*ResponseStream) GetBufferSize ¶
func (rs *ResponseStream) GetBufferSize() int
GetBufferSize returns the current buffer size setting.
func (*ResponseStream) GetEscapeParser ¶ added in v1.35.0
func (rs *ResponseStream) GetEscapeParser() *analytics.EscapeCodeParser
GetEscapeParser returns the escape code parser for this stream. Used by the WebSocket handler for Stage 2 analytics observations. Returns nil if no parser is configured.
func (*ResponseStream) GetExitTail ¶ added in v1.15.0
func (rs *ResponseStream) GetExitTail() []byte
GetExitTail returns the last exitTailSize bytes from the circular buffer. The circular buffer already holds this data; no separate rolling copy is needed.
func (*ResponseStream) GetSubscriberCount ¶
func (rs *ResponseStream) GetSubscriberCount() int
GetSubscriberCount returns the number of active subscribers.
func (*ResponseStream) GetSubscriberIDs ¶
func (rs *ResponseStream) GetSubscriberIDs() []string
GetSubscriberIDs returns the IDs of all active subscribers.
func (*ResponseStream) GetSubscriberInfo ¶
func (rs *ResponseStream) GetSubscriberInfo(subscriberID string) (created time.Time, exists bool)
GetSubscriberInfo returns information about a specific subscriber.
func (*ResponseStream) GetTotalBytesWritten ¶ added in v1.35.0
func (rs *ResponseStream) GetTotalBytesWritten() int64
GetTotalBytesWritten returns the monotonic PTY byte offset from the circular buffer. This is the same counter used by Stage 1 (Parse) so Stage 2 (ParseStage2) session_seq values are stable across WebSocket reconnections. Returns 0 if no buffer is available.
func (*ResponseStream) IsStarted ¶
func (rs *ResponseStream) IsStarted() bool
IsStarted returns whether the stream is currently active.
func (*ResponseStream) SetBufferSize ¶
func (rs *ResponseStream) SetBufferSize(size int)
SetBufferSize sets the buffer size for future subscribers. Does not affect existing subscribers.
func (*ResponseStream) SetOnOutput ¶ added in v1.9.0
func (rs *ResponseStream) SetOnOutput(fn func())
SetOnOutput registers a callback invoked each time PTY bytes arrive. Used by ClaudeController to drive event-based activity tracking in IdleDetector. Must be called before Start().
func (*ResponseStream) SetStableSessionID ¶ added in v1.35.0
func (rs *ResponseStream) SetStableSessionID(id string)
SetStableSessionID switches the escape parser's recorded session identifier from the tmux session name (used at construction time, before the owning Instance's stable UUID is available) to the stable UUID. This only affects how escape_event rows are tagged — it does not change rs.sessionName, which is still used for logging, PTY naming, and history keyed off the tmux name.
func (*ResponseStream) Start ¶
func (rs *ResponseStream) Start(ctx context.Context) error
Start begins streaming responses from the PTY to all subscribers. This is a non-blocking call that starts a background goroutine. Use the provided context to stop the stream.
func (*ResponseStream) Stop ¶
func (rs *ResponseStream) Stop() error
Stop stops the response stream and closes all subscriber channels. This is a blocking call that waits for the streaming goroutine to finish.
func (*ResponseStream) Subscribe ¶
func (rs *ResponseStream) Subscribe(subscriberID string) (<-chan ResponseChunk, error)
Subscribe registers a new subscriber and returns a channel for receiving response chunks. The subscriber ID should be unique. Returns an error if the ID is already in use.
func (*ResponseStream) Unsubscribe ¶
func (rs *ResponseStream) Unsubscribe(subscriberID string) error
Unsubscribe removes a subscriber and closes their channel.
type RestartState ¶
type RestartState struct {
// Working directory to restore
WorkingDir string
// Claude session ID for --resume flag
ClaudeSessionID string
// Environment variables to restore
Environment map[string]string
// Original command/program
Program string
// AutoYes flag
AutoYes bool
// Original prompt
Prompt string
}
RestartState holds the state needed to restart a session
type ReviewContextExtras ¶ added in v1.38.0
type ReviewContextExtras struct {
// PriorSessions is the full ItemSession history for this backlog item (as returned
// by Storage.ListItemSessions). Used to render "## Prior Review Attempts" — only
// review-role sessions with a non-nil ReviewVerdict contribute to that section.
PriorSessions []ItemSessionSummary
// ProgressNotes is the full append-only report_progress history for this item (as
// returned by Storage.ListProgressNotesForItem). Used to render "## Full Notes
// History", which supersedes the single latest-note-per-criterion view already
// shown in "## Acceptance Criteria" with the complete timeline.
ProgressNotes []ProgressNoteData
// ItemDescription is the backlog item's Description, rendered in "## Item Context"
// alongside StatusEvents. Kept separate from the *BacklogItemData already passed to
// BuildHeadlessReviewPrompt because that pointer may not have StatusEvents loaded —
// callers typically populate both fields together from a single freshly-loaded
// GetBacklogItem(..., WithStatusEvents) call.
ItemDescription string
// StatusEvents is the item's status transition history, used to render "## Item
// Context" alongside ItemDescription.
StatusEvents []BacklogStatusEventData
// TranscriptRelPath is the path (relative to codebaseWorkDir) of a searchable
// session transcript file written by WriteReviewTranscriptFile, or "" when no
// transcript is available (e.g. scrollback fetch failed or was empty — best-effort
// enrichment, never required). Rendered as an instruction in "## Session
// Transcript".
TranscriptRelPath string
}
ReviewContextExtras bundles the additional context sources available to the empty-diff codebase-read review path (prior review verdicts, full progress-notes history, item goal/status history, and a searchable session transcript file). Passed as a single struct to BuildHeadlessReviewPrompt rather than as separate positional parameters because Go has no named/optional parameters and this prompt builder already has five — the same rationale headless.CallOptions uses for its own set of optional per-call knobs. Every field is a zero-value-safe optional: an unset field simply omits the corresponding prompt section rather than requiring a distinct code path per caller. Only rendered when diff == "" (see BuildHeadlessReviewPrompt) — this is deliberately more expensive context than the normal diff-review path carries.
type ReviewGateRunner ¶ added in v1.37.0
type ReviewGateRunner struct {
// contains filtered or unexported fields
}
ReviewGateRunner encapsulates the spawnReviewGate logic into a testable value type. BacklogLifecycleListener holds one as a field and delegates to it.
getAutoReopener, getNotifier, and getSessionCreator are getter functions rather than stored values so that the runner always observes the latest reopener/notifier/spawner even when SetAutoReopener / SetNotifier / SetSessionCreator are called after construction.
func NewReviewGateRunner ¶ added in v1.37.0
func NewReviewGateRunner( storage *Storage, getAutoReopener func() AutoReopenSpawner, getNotifier func() Notifier, getSessionCreator func() ReviewGateSpawner, ) *ReviewGateRunner
NewReviewGateRunner constructs a ReviewGateRunner. getAutoReopener, getNotifier, and getSessionCreator are getter functions (typically method values from BacklogLifecycleListener) so the runner sees the latest values when dynamic setters are called after construction.
func (*ReviewGateRunner) Run ¶ added in v1.37.0
func (r *ReviewGateRunner) Run( ctx context.Context, item *BacklogItemData, is ItemSessionSummary, onPass func(ctx context.Context, item *BacklogItemData, is ItemSessionSummary), )
Run executes the review gate for a backlog item session. ctx should be the listener's shutdownCtx so long-running calls are cancelled on shutdown. onPass is retained for signature compatibility with existing callers (BacklogLifecycleListener.pushAndCreatePR) but is no longer invoked directly from Run: since review now always happens in a real, hidden session.Instance, the PASS/FAIL/PARTIAL/UNVERIFIABLE outcome is only known once that session exits and calls submit_review_verdict — handled by BacklogLifecycleListener.handleReviewSessionExited, not here.
type ReviewGateSpawner ¶ added in v1.35.0
type ReviewGateSpawner interface {
// SpawnReviewSession creates a one-shot review session for item using prompt.
// itemSessionID is the UUID of the work ItemSession being reviewed.
SpawnReviewSession(ctx context.Context, item *BacklogItemData, itemSessionID string, prompt string) (*Instance, error)
}
ReviewGateSpawner can create a short-lived review session for a backlog item. Deprecated: use headless.Pool via NewBacklogLifecycleListenerWithSpawner instead. Retained for backward compatibility with existing tests and callers.
type ReviewOutcome ¶ added in v1.37.0
type ReviewOutcome = domain.ReviewOutcome
ReviewOutcome is a typed verdict outcome value (PASS, FAIL, PARTIAL, UNVERIFIABLE). Type alias — session.ReviewOutcome and domain.ReviewOutcome are identical types.
type ReviewQueueObserver ¶
type ReviewQueueObserver = queue.ReviewQueueObserver
ReviewQueueObserver re-export
type ReviewQueuePoller ¶
type ReviewQueuePoller struct {
// contains filtered or unexported fields
}
ReviewQueuePoller automatically monitors sessions and adds them to the review queue when they become idle or need attention.
func NewReviewQueuePoller ¶
func NewReviewQueuePoller(queue *ReviewQueue, statusManager StatusProvider, storage *Storage) *ReviewQueuePoller
NewReviewQueuePoller creates a new poller for automatically managing the review queue. The storage parameter is optional (can be nil) but required for persisting LastAddedToQueue timestamps.
func NewReviewQueuePollerWithConfig ¶
func NewReviewQueuePollerWithConfig(queue *ReviewQueue, statusManager StatusProvider, storage *Storage, config ReviewQueuePollerConfig) *ReviewQueuePoller
NewReviewQueuePollerWithConfig creates a poller with custom configuration. The storage parameter is optional (can be nil) but required for persisting LastAddedToQueue timestamps.
func (*ReviewQueuePoller) AddInstance ¶
func (rqp *ReviewQueuePoller) AddInstance(instance *Instance)
AddInstance adds a single instance to monitor.
func (*ReviewQueuePoller) CheckSession ¶
func (rqp *ReviewQueuePoller) CheckSession(inst *Instance)
CheckSession checks a single session immediately (exported for ReactiveQueueManager). This allows external components to trigger immediate re-evaluation without waiting for the next poll cycle, providing <100ms feedback on user interactions. Fetches a fresh pane activity snapshot for accurate cache invalidation.
func (*ReviewQueuePoller) FindInstance ¶
func (rqp *ReviewQueuePoller) FindInstance(sessionID string) *Instance
FindInstance finds an instance by session ID (exported for ReactiveQueueManager). Returns nil if the instance is not found in the monitored list.
func (*ReviewQueuePoller) ForceReconcile ¶ added in v1.24.0
func (rqp *ReviewQueuePoller) ForceReconcile()
ForceReconcile immediately runs session reconciliation outside the normal 30s cadence. Safe to call concurrently; typically used by the fork pressure monitor to rapidly clean up dead sessions when subprocess failures indicate stale Active states.
func (*ReviewQueuePoller) GetConfig ¶
func (rqp *ReviewQueuePoller) GetConfig() ReviewQueuePollerConfig
GetConfig returns the current configuration.
func (*ReviewQueuePoller) GetInstances ¶
func (rqp *ReviewQueuePoller) GetInstances() []*Instance
GetInstances returns a snapshot of all live in-memory instances held by the poller. Use this instead of LoadInstances() for read-only operations to avoid the side effect of FromInstanceData() calling Start() on every non-paused instance.
func (*ReviewQueuePoller) GetMonitoredCount ¶
func (rqp *ReviewQueuePoller) GetMonitoredCount() int
GetMonitoredCount returns the number of instances being monitored.
func (*ReviewQueuePoller) IsRunning ¶
func (rqp *ReviewQueuePoller) IsRunning() bool
IsRunning returns true if the poller is currently running.
func (*ReviewQueuePoller) RemoveInstance ¶
func (rqp *ReviewQueuePoller) RemoveInstance(instanceTitle string)
RemoveInstance removes an instance from monitoring.
func (*ReviewQueuePoller) SetActivityChannel ¶ added in v1.23.0
func (rqp *ReviewQueuePoller) SetActivityChannel(ch <-chan struct{})
SetActivityChannel wires an external signal channel to the poll loop. When a signal arrives on ch, the loop snaps back to the fast interval (PollInterval). Must be called before Start(); subsequent calls have no effect once the loop is running.
func (*ReviewQueuePoller) SetApprovalProvider ¶
func (rqp *ReviewQueuePoller) SetApprovalProvider(provider ApprovalMetadataProvider)
SetApprovalProvider sets the approval metadata provider for enriching review queue items.
func (*ReviewQueuePoller) SetInstances ¶
func (rqp *ReviewQueuePoller) SetInstances(instances []*Instance)
SetInstances sets the list of instances to monitor.
func (*ReviewQueuePoller) Start ¶
func (rqp *ReviewQueuePoller) Start(ctx context.Context)
Start begins polling for idle sessions.
func (*ReviewQueuePoller) UpdateConfig ¶
func (rqp *ReviewQueuePoller) UpdateConfig(config ReviewQueuePollerConfig)
UpdateConfig updates the poller configuration.
type ReviewQueuePollerConfig ¶
type ReviewQueuePollerConfig struct {
PollInterval time.Duration // How often to check sessions (fast path, default 2s)
SlowPollInterval time.Duration // Interval when review queue is empty (default 8s); 0 = no backoff
IdleThreshold time.Duration // Duration before considering session idle and adding to queue
InputWaitDuration time.Duration // Time waiting for input before flagging
StalenessThreshold time.Duration // Duration since last meaningful output before considering stale
ReconcileInterval time.Duration // How often to reconcile in-memory state against tmux reality (0 = disabled)
}
ReviewQueuePollerConfig contains configuration for the review queue poller.
func DefaultReviewQueuePollerConfig ¶
func DefaultReviewQueuePollerConfig() ReviewQueuePollerConfig
DefaultReviewQueuePollerConfig returns sensible defaults for polling.
type ReviewQueueStatistics ¶
type ReviewQueueStatistics = queue.ReviewQueueStatistics
ReviewQueueStatistics re-export
type ReviewQueueWriter ¶ added in v1.35.0
type ReviewQueueWriter interface {
Add(item *ReviewItem) bool
}
ReviewQueueWriter is the write-side interface for the review queue. It is satisfied by *ReviewQueue and can be used in place of the concrete type wherever only Add is required, making it easy to supply a test double.
type ReviewState ¶
type ReviewState struct {
// LastAcknowledged tracks when the user last acknowledged this session in the review queue.
// Sessions acknowledged after their last update won't appear in the queue until they update again.
LastAcknowledged time.Time
// LastAddedToQueue tracks when this session was last added to the review queue.
// Used to prevent notification spam by enforcing a minimum re-add interval.
LastAddedToQueue time.Time
// LastTerminalUpdate is the timestamp of the last output received from the terminal (any output).
LastTerminalUpdate time.Time
// LastMeaningfulOutput is the timestamp of the last meaningful output (excludes tmux status banners).
// Used by the review queue to determine session staleness.
LastMeaningfulOutput time.Time
// LastOutputSignature is a hash of the terminal content, used to detect actual changes
// vs app restarts with unchanged content (prevents false "new activity" notifications).
LastOutputSignature string
// LastViewed tracks when the user last interacted with this session
// (viewing the terminal, attaching via tmux, or viewing session details).
// Used for smarter review queue notifications (don't notify if just viewed).
LastViewed time.Time
// LastPromptDetected is the timestamp when we last detected a prompt requiring user input.
// Used to distinguish new prompts from the same prompt re-appearing.
LastPromptDetected time.Time
// LastPromptSignature is a hash of the prompt content (last 10 lines before cursor).
// Used to determine if this is the same prompt or a new one.
LastPromptSignature string
// LastUserResponse is the timestamp when the user last provided input/interaction.
// Used to determine if user responded AFTER a prompt was detected.
LastUserResponse time.Time
// ProcessingGraceUntil is the deadline for waiting for the session to respond after
// user interaction. If the session shows no activity by this time, it may be re-added
// to the review queue.
ProcessingGraceUntil time.Time
// contains filtered or unexported fields
}
ReviewState holds all timestamps and state related to the review queue and terminal activity tracking for a session. It is embedded in Instance so all field accesses remain unchanged.
Fields are NOT protected by Instance.mu. Mutation is serialized through the actor's send()/sendSyncErr() closures instead (see UpdateTerminalTimestamps in instance_approval.go, which routes through i.send() rather than i.mu.Lock()) - the same "no locking, serialize via the actor's own command queue" discipline used by transitionToLocked et al. Methods on ReviewState are intentionally non-locking - callers must be running inside an actor command closure (or otherwise be the sole writer) if concurrent access is possible.
Direct field access via Go embedding promotion (inst.LastMeaningfulOutput etc.) is used by:
- session/review_queue_poller.go: reads LastMeaningfulOutput, LastAcknowledged, LastAddedToQueue, ProcessingGraceUntil, LastPromptDetected, LastPromptSignature, LastUserResponse, LastViewed, LastTerminalUpdate, LastOutputSignature
- server/dependencies.go: reads LastMeaningfulOutput, LastTerminalUpdate, LastAddedToQueue, LastAcknowledged
- server/adapters/instance_adapter.go: reads LastTerminalUpdate, LastMeaningfulOutput
- server/review_queue_manager.go: writes LastUserResponse directly
All access is either within the session package (via the actor's serialized closures) or through Instance methods that route through i.send()/sendSyncErr().
TODO: Migrate cross-package field accesses (server/) to accessor methods to enable future encapsulation of ReviewState as a composed (non-embedded) field.
func (*ReviewState) ComputePromptSignature ¶
func (rs *ReviewState) ComputePromptSignature(content string) string
ComputePromptSignature computes a hash of the prompt content using the last 10 lines. Returns "" if content is empty. Caller may call this without holding any lock.
func (*ReviewState) DetectAndTrackPrompt ¶
func (rs *ReviewState) DetectAndTrackPrompt(content string, statusInfo InstanceStatusInfo, sessionTitle string) bool
DetectAndTrackPrompt detects whether the current status represents a new user-facing prompt and records it. Returns true only when a NEW prompt is detected (signature changed or first). Caller must hold Instance.mu when writing prompt fields.
func (*ReviewState) IsAcknowledgedAfterOutput ¶
func (rs *ReviewState) IsAcknowledgedAfterOutput() bool
IsAcknowledgedAfterOutput returns true if the user acknowledged this session more recently than the last meaningful terminal output — meaning no new output has occurred since the user last dismissed the session from the review queue. Returns false when LastMeaningfulOutput is zero: if no output has ever been recorded, the acknowledgment cannot logically be "after" output, so the session is not snoozed. Caller must hold the relevant mutex if concurrent access is possible.
func (*ReviewState) IsInProcessingGracePeriod ¶
func (rs *ReviewState) IsInProcessingGracePeriod() bool
IsInProcessingGracePeriod returns true if the session is within its processing grace window. Caller must hold the relevant mutex if concurrent access is possible.
func (*ReviewState) SyncAtomicTimestamps ¶ added in v1.35.0
func (rs *ReviewState) SyncAtomicTimestamps()
SyncAtomicTimestamps initialises atomic shadow fields from their time.Time counterparts. Must be called once after constructing ReviewState from persisted or restored data so that lock-free readers see the correct initial value immediately.
func (*ReviewState) TimeSinceLastMeaningfulOutput ¶
func (rs *ReviewState) TimeSinceLastMeaningfulOutput(createdAt time.Time) time.Duration
TimeSinceLastMeaningfulOutput returns how long ago meaningful terminal output was received. If LastMeaningfulOutput is zero, returns the duration since the given createdAt time. Caller must hold the relevant mutex if concurrent access is possible.
func (*ReviewState) TimeSinceLastTerminalUpdate ¶
func (rs *ReviewState) TimeSinceLastTerminalUpdate(createdAt time.Time) time.Duration
TimeSinceLastTerminalUpdate returns how long ago any terminal output was received. If LastTerminalUpdate is zero, returns the duration since the given createdAt time. Caller must hold the relevant mutex if concurrent access is possible.
func (*ReviewState) UpdateTimestamps ¶
func (rs *ReviewState) UpdateTimestamps(rawContent, filteredContent string, shouldUpdateMeaningful bool, sessionTitle string) bool
UpdateTimestamps updates terminal activity timestamps based on processed content.
- rawContent: original captured output, used for the LastTerminalUpdate non-blank check.
- filteredContent: rawContent with tmux banners stripped, used for signature computation.
- shouldUpdateMeaningful: true when the content carries meaningful signal (not just banners).
- sessionTitle: used only for structured debug logging.
Caller must be running inside the actor's serialized command closure (via i.send()/ sendSyncErr()), not holding Instance.mu - see UpdateTerminalTimestamps in instance_approval.go, the sole caller. Returns true when any field was updated (caller should rebuild the snapshot).
func (*ReviewState) UserRespondedAfterPrompt ¶
func (rs *ReviewState) UserRespondedAfterPrompt() bool
UserRespondedAfterPrompt returns true if the user responded (LastUserResponse) after a prompt was detected (LastPromptDetected), indicating the session is no longer waiting. Caller must hold the relevant mutex if concurrent access is possible.
type ReviewVerdictData ¶ added in v1.35.0
type ReviewVerdictData struct {
ItemSessionID string
OverallOutcome ReviewOutcome
PerCriterion string // JSON
Summary string
DiffHash string
PromptHash string
DiffTokenCount int
DiffTruncated bool
OverrideBy string
OverrideReason string
OverrideAt *time.Time
}
ReviewVerdictData is the input data for saving a ReviewVerdict.
type ReviewVerdictSummary ¶ added in v1.37.0
type ReviewVerdictSummary struct {
ID string
OverallOutcome string
PerCriterion string // JSON []CriterionVerdict
Summary string
DiffTokenCount int
DiffTruncated bool
OverrideBy string
OverrideReason string
OverrideAt *time.Time
CreatedAt time.Time
}
ReviewVerdictSummary is a domain DTO for a review verdict embedded in ItemSessionSummary.
type RevisionTarget ¶
type RevisionTarget struct {
ID string
ShortID string
Description string
Author string
Timestamp time.Time
IsCurrent bool
}
RevisionTarget represents a revision as a switch target
type Session ¶
type Session struct {
// Identity
ID string `json:"id"`
Title string `json:"title"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Process
Status Status `json:"status"`
Program string `json:"program"`
// Configuration
AutoYes bool `json:"auto_yes,omitempty"`
Prompt string `json:"prompt,omitempty"`
// Optional contexts (nil = not loaded or not applicable)
Git *GitContext `json:"git,omitempty"`
Filesystem *FilesystemContext `json:"filesystem,omitempty"`
Terminal *TerminalContext `json:"terminal,omitempty"`
UI *UIPreferences `json:"ui,omitempty"`
Activity *ActivityTracking `json:"activity,omitempty"`
Cloud *CloudContext `json:"cloud,omitempty"`
}
Session represents the core domain entity for an AI agent session. It contains only universally required fields, with optional contexts for deployment-specific functionality.
Context types are defined in contexts.go: - GitContext: Git repository, branch, PR integration - FilesystemContext: Paths, working directories, worktree detection - TerminalContext: Terminal dimensions, tmux configuration - UIPreferences: Categories, tags, display preferences - ActivityTracking: Timestamps, output signatures, queue tracking - CloudContext: Cloud provider, API configuration
func InstanceToSession ¶
InstanceToSession converts a legacy Instance to the new Session type. This adapter enables gradual migration while maintaining backward compatibility. It populates all relevant contexts from the Instance fields.
func NewSession ¶
NewSession creates a new Session with the required fields. Optional contexts can be added using the With* methods.
func (*Session) GetBranch ¶
GetBranch returns the Git branch name, or empty string if no Git context.
func (*Session) GetCategory ¶
GetCategory returns the UI category, or empty string if no UI preferences.
func (*Session) GetLastMeaningfulOutput ¶
GetLastMeaningfulOutput returns when the session had meaningful output, or zero time if no activity tracking.
func (*Session) GetLastViewed ¶
GetLastViewed returns when the session was last viewed, or zero time if no activity tracking.
func (*Session) GetPath ¶
GetPath returns the filesystem project path, or empty string if no filesystem context.
func (*Session) GetTerminalDimensions ¶
GetTerminalDimensions returns the terminal width and height, or 0,0 if no terminal context.
func (*Session) GetTmuxSessionName ¶
GetTmuxSessionName returns the tmux session name, or empty string if no terminal context.
func (*Session) GetWorkingDir ¶
GetWorkingDir returns the working directory, or empty string if no filesystem context.
func (*Session) HasActivityTracking ¶
HasActivityTracking returns true if activity tracking is available.
func (*Session) HasCloudContext ¶
HasCloudContext returns true if cloud context is available.
func (*Session) HasFilesystemContext ¶
HasFilesystemContext returns true if filesystem context is available.
func (*Session) HasGitContext ¶
HasGitContext returns true if Git context is available.
func (*Session) HasTerminalContext ¶
HasTerminalContext returns true if terminal context is available.
func (*Session) HasUIPreferences ¶
HasUIPreferences returns true if UI preferences are available.
func (*Session) IsCloudConfigured ¶
IsCloudConfigured returns true if the cloud context is properly configured.
func (*Session) NeedsReviewQueueAttention ¶
NeedsReviewQueueAttention returns true if session has unacknowledged output.
func (*Session) WithActivityTracking ¶
func (s *Session) WithActivityTracking(activity *ActivityTracking) *Session
WithActivityTracking adds activity tracking to the session.
func (*Session) WithCloudContext ¶
func (s *Session) WithCloudContext(cloud *CloudContext) *Session
WithCloudContext adds cloud context to the session.
func (*Session) WithFilesystemContext ¶
func (s *Session) WithFilesystemContext(fs *FilesystemContext) *Session
WithFilesystemContext adds filesystem context to the session.
func (*Session) WithGitContext ¶
func (s *Session) WithGitContext(git *GitContext) *Session
WithGitContext adds Git context to the session.
func (*Session) WithTerminalContext ¶
func (s *Session) WithTerminalContext(terminal *TerminalContext) *Session
WithTerminalContext adds terminal context to the session.
func (*Session) WithUIPreferences ¶
func (s *Session) WithUIPreferences(ui *UIPreferences) *Session
WithUIPreferences adds UI preferences to the session.
type SessionGoalData ¶ added in v1.35.0
type SessionGoalData struct {
UUID string `json:"uuid"`
SessionUUID string `json:"session_uuid"`
Goal string `json:"goal"`
Status string `json:"status"`
Tasks []TaskNode `json:"tasks,omitempty"`
SetBy string `json:"set_by,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
SessionGoalData holds the goal state for a session, including the task tree.
func (*SessionGoalData) TasksDone ¶ added in v1.35.0
func (g *SessionGoalData) TasksDone() int
TasksDone returns the count of all tasks with status "done" (including nested children).
func (*SessionGoalData) TasksTotal ¶ added in v1.35.0
func (g *SessionGoalData) TasksTotal() int
TasksTotal returns the total count of all tasks (including nested children) in the goal.
type SessionHealthChecker ¶
type SessionHealthChecker struct {
// contains filtered or unexported fields
}
SessionHealthChecker manages session health validation and recovery
func NewSessionHealthChecker ¶
func NewSessionHealthChecker(storage *Storage) *SessionHealthChecker
NewSessionHealthChecker creates a new session health checker
func (*SessionHealthChecker) CheckAllSessions ¶
func (h *SessionHealthChecker) CheckAllSessions() ([]HealthCheckResult, error)
CheckAllSessions performs a health check on all active sessions
func (*SessionHealthChecker) RecoverUnhealthySessions ¶
func (h *SessionHealthChecker) RecoverUnhealthySessions() error
RecoverUnhealthySessions attempts to recover all unhealthy sessions
func (*SessionHealthChecker) ScheduledHealthCheck ¶
func (h *SessionHealthChecker) ScheduledHealthCheck(interval time.Duration, stopChan <-chan struct{})
ScheduledHealthCheck runs health checks at regular intervals
type SessionType ¶
type SessionType = config.SessionType
SessionType is an alias for config.SessionType so callers can use either package.
type Shell ¶ added in v1.35.0
type Shell struct {
// ID is the stable UUID for this shell. Also the fragment used in the tmux session name.
ID string
// Name is the user-visible label for the shell tab.
Name string
// Command is the command running in the shell (e.g. "bash", "python").
Command string
// WorkingDir is the working directory for the shell process.
WorkingDir string
// TmuxSessionName is the full computed tmux session name:
// "{parentPrefix}_shell_{shellID}"
TmuxSessionName string
// Status is the current lifecycle status.
Status ShellStatus
// ExitCode is the process exit code (meaningful when Status != ShellStatusRunning).
ExitCode int
// OrderIndex controls tab display order.
OrderIndex int
// StartedAt is when the shell was spawned.
StartedAt time.Time
// contains filtered or unexported fields
}
Shell represents a custom shell attached to a session. It is the in-memory projection of the ent Shell entity; changes are written back through the repository.
type ShellData ¶ added in v1.35.0
type ShellData struct {
// ID is the UUID for the shell. If empty, the caller must populate it.
ID string
// Name is the user-visible label.
Name string
// Command is the command to run in the shell.
Command string
// WorkingDir is the starting directory for the shell process.
WorkingDir string
// TmuxSessionName is the full sibling tmux session name.
TmuxSessionName string
// OrderIndex is the display order for the tab.
OrderIndex int
}
ShellData carries the input fields for creating a new shell.
type ShellHandle ¶ added in v1.35.0
type ShellHandle interface {
// GetPTY returns the PTY file for reading terminal output.
// Returns ErrShellStopped if the shell has been closed.
GetPTY() (*os.File, error)
// Resize updates the PTY dimensions.
Resize(cols, rows int) error
// Close stops the shell process and releases resources.
Close() error
}
ShellHandle is the interface for managing a single shell PTY. It is implemented by session/tmux.ShellTmuxHandle for real sessions and can be mocked in tests.
type ShellRegistry ¶ added in v1.35.0
type ShellRegistry struct {
// contains filtered or unexported fields
}
ShellRegistry is a concurrent shell+handle store. Zero value is not usable; create with newShellRegistry(). The exported API intentionally has no Lock/Unlock methods — mutations go through named operations that hold the bucket lock only for fast in-memory work.
func (*ShellRegistry) Add ¶ added in v1.35.0
func (r *ShellRegistry) Add(sh *Shell, handle *tmux.ShellTmuxHandle)
Add stores a new shell+handle pair. Overwrites any existing entry for the same ID.
func (*ShellRegistry) AddStopped ¶ added in v1.35.0
func (r *ShellRegistry) AddStopped(sh *Shell)
AddStopped stores a shell that has no live handle (already stopped or error).
func (*ShellRegistry) Get ¶ added in v1.35.0
func (r *ShellRegistry) Get(shellID string) (*Shell, bool)
Get returns the Shell for shellID, or (nil, false) if absent.
func (*ShellRegistry) GetBoth ¶ added in v1.35.0
func (r *ShellRegistry) GetBoth(shellID string) (*Shell, *tmux.ShellTmuxHandle, bool)
GetBoth returns both shell and handle in one atomic load.
func (*ShellRegistry) GetHandle ¶ added in v1.35.0
func (r *ShellRegistry) GetHandle(shellID string) (*tmux.ShellTmuxHandle, bool)
GetHandle returns the ShellTmuxHandle for shellID, or (nil, false) if absent.
func (*ShellRegistry) Len ¶ added in v1.35.0
func (r *ShellRegistry) Len() int
Len returns the number of shells in the registry.
func (*ShellRegistry) List ¶ added in v1.35.0
func (r *ShellRegistry) List() []*Shell
List returns all shells sorted by OrderIndex.
func (*ShellRegistry) Remove ¶ added in v1.35.0
func (r *ShellRegistry) Remove(shellID string)
Remove deletes the entry for shellID. No-op if not present.
func (*ShellRegistry) SetHandle ¶ added in v1.35.0
func (r *ShellRegistry) SetHandle(shellID string, handle *tmux.ShellTmuxHandle)
SetHandle atomically replaces the handle for shellID without changing the shell.
func (*ShellRegistry) UpdateForRestart ¶ added in v1.35.0
func (r *ShellRegistry) UpdateForRestart(shellID string, newHandle *tmux.ShellTmuxHandle, newSessionName string, exitCh, watcherDone chan struct{})
UpdateForRestart atomically replaces a shell's mutable restart fields with new values (Status=Running, ExitCode=0, new TmuxSessionName, new exitCh/watcherDone). If the shellID is not found it stores a brand-new entry built from newShell.
func (*ShellRegistry) UpdateStatus ¶ added in v1.35.0
func (r *ShellRegistry) UpdateStatus(shellID string, status ShellStatus, exitCode *int) bool
UpdateStatus atomically updates Shell.Status and Shell.ExitCode for shellID. Returns true if the entry was found and updated.
type ShellRepository ¶ added in v1.35.0
type ShellRepository interface {
// CreateShell persists a new shell record under the given session title.
CreateShell(ctx context.Context, sessionTitle string, data ShellData) (*ent.Shell, error)
// ListShells returns all shell records for the given session title, ordered by order_index.
ListShells(ctx context.Context, sessionTitle string) ([]*ent.Shell, error)
// UpdateShellStatus sets the status (and optionally exit code) for the shell with the given ID.
UpdateShellStatus(ctx context.Context, shellID, status string, exitCode *int) error
// DeleteShell removes the shell record with the given ID.
DeleteShell(ctx context.Context, shellID string) error
}
ShellRepository is the minimal persistence interface for per-session shell management. It is implemented by EntRepository; pass nil to disable persistence (e.g., tests).
type ShellStatus ¶ added in v1.35.0
type ShellStatus string
ShellStatus represents the lifecycle status of a custom shell.
const ( // ShellStatusRunning means the shell process is alive and the PTY is open. ShellStatusRunning ShellStatus = "running" // ShellStatusStopped means the shell exited cleanly (via exit command or StopShell). ShellStatusStopped ShellStatus = "stopped" // ShellStatusError means the shell exited with a non-zero status unexpectedly. ShellStatusError ShellStatus = "error" )
type SourceSyncEventData ¶ added in v1.37.0
type SourceSyncEventData struct {
ID string
ItemsCreated int
ItemsUpdated int
ItemsSkipped int
ItemsErrored int
ErrorMessage string
CursorAfter string
StartedAt time.Time
FinishedAt *time.Time
}
SourceSyncEventData is the domain DTO replacing *ent.SourceSyncEvent in Storage returns.
type SpawnShellRequest ¶ added in v1.35.0
type SpawnShellRequest struct {
// Name is the optional user-visible label. Defaults to the command base name.
Name string
// Command is the command to run. Defaults to $SHELL or /bin/sh.
Command string
// WorkingDir is the starting directory. Defaults to the session's WorkingDir.
WorkingDir string
}
SpawnShellRequest carries the parameters for Instance.SpawnShell.
type StartupScanner ¶ added in v1.35.0
type StartupScanner struct {
// contains filtered or unexported fields
}
StartupScanner scans running sessions for pre-existing approval prompts and adds matches to the review queue immediately, before the first regular poll cycle.
func NewStartupScanner ¶ added in v1.35.0
func NewStartupScanner(statusManager StatusProvider, contentProvider ContentProvider) *StartupScanner
NewStartupScanner creates a StartupScanner using the provided status and content providers.
func (*StartupScanner) Scan ¶ added in v1.35.0
func (ss *StartupScanner) Scan(instances []*Instance, queue ReviewQueueWriter) int
Scan iterates over instances and adds any that need attention to the queue. Returns the number of sessions added to the queue.
type Status ¶
type Status int
const ( // Creating is the status when the instance is being initialized. Creating Status = 0 // Active is the status when the instance has a live AI process (running or ready). Active Status = 1 // Paused is if the instance is paused (worktree removed but branch preserved). Paused Status = 2 // Stopped is a terminal state: the instance has been shut down and cannot transition further. Stopped Status = 3 // Hibernated is the status when the instance has been checkpointed and the tmux session killed. Hibernated Status = 4 // Restoring is the transient startup state when a hibernated session is being restored. // Never persisted to the database — transitions to Active or Creating on completion. Restoring Status = 5 // Deprecated: use Active. Running = Active // Deprecated: use Active. Ready = Active // Deprecated: use Creating. Loading = Creating )
func StatusFromDetected ¶
func StatusFromDetected(detected detection.DetectedStatus) Status
StatusFromDetected maps a DetectedStatus to the corresponding lifecycle Status. All detected states map to Active because the instance process is still executing. NeedsApproval, InputRequired, Error, and TestsFailing are sub-status signals surfaced via GetEffectiveStatus() — they do not change the lifecycle state.
type StatusChange ¶
type StatusChange struct {
Timestamp time.Time
Status detection.DetectedStatus
Context string
}
StatusChange represents a change in detected status during execution.
type StatusChangeListener ¶ added in v1.35.0
type StatusChangeListener func(newStatus detection.DetectedStatus, sessionName string)
StatusChangeListener is called when the controller detects a terminal status transition. Always invoked from the controller's own background goroutine, outside any lock.
type StatusDeterminer ¶ added in v1.35.0
type StatusDeterminer interface {
Determine(
inst *Instance,
content string,
statusInfo InstanceStatusInfo,
detector detection.TerminalDetector,
) DetectionResult
}
StatusDeterminer evaluates whether a session should be added to, removed from, or left unchanged in the review queue. It is a pure function — no queue operations.
type StatusProvider ¶ added in v1.35.0
type StatusProvider interface {
GetStatus(inst *Instance) InstanceStatusInfo
GetController(instanceTitle string) (*ClaudeController, bool)
}
StatusProvider is the interface ReviewQueuePoller uses to fetch session status. Defined at the consumption point (the poller), not the production point.
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage handles saving and loading instances via the repository backend.
func NewStorageWithRepository ¶
func NewStorageWithRepository(repo Repository) (*Storage, error)
NewStorageWithRepository creates a Storage backed by a Repository.
func (*Storage) AddInstance ¶
AddInstance adds a new instance to storage. Unlike SaveInstances, this does not require instance.Started() to be true.
func (*Storage) AllRules ¶ added in v1.12.0
func (s *Storage) AllRules(ctx context.Context) ([]ApprovalRuleData, error)
AllRules returns all auto-approval rules from the repository.
func (*Storage) AppendProgressNote ¶ added in v1.38.0
func (s *Storage) AppendProgressNote(ctx context.Context, itemID string, criterionIndex int, note, status string) error
AppendProgressNote records a single report_progress call as an immutable history entry, in addition to the current-note-per-criterion updated by UpdateAcCriterionStatus.
func (*Storage) ArchiveBacklogItem ¶ added in v1.35.0
ArchiveBacklogItem sets the archived_at timestamp.
func (*Storage) AssignSessionsToProject ¶ added in v1.23.0
func (s *Storage) AssignSessionsToProject(ctx context.Context, projectName string, sessionTitles []string) error
AssignSessionsToProject links sessions to a project in storage.
func (*Storage) CreateBacklogItem ¶ added in v1.35.0
func (s *Storage) CreateBacklogItem(ctx context.Context, data BacklogItemData) (*BacklogItemData, error)
CreateBacklogItem inserts a new backlog item.
func (*Storage) CreateItemSession ¶ added in v1.35.0
func (s *Storage) CreateItemSession(ctx context.Context, data ItemSessionData) (ItemSessionSummary, error)
CreateItemSession creates a new ItemSession linked to a BacklogItem.
func (*Storage) CreateItemSessionWithVerdict ¶ added in v1.35.0
func (s *Storage) CreateItemSessionWithVerdict(ctx context.Context, isData ItemSessionData, verdict ReviewVerdictData) (ItemSessionSummary, error)
CreateItemSessionWithVerdict atomically creates an ItemSession and its initial ReviewVerdict in a single transaction. Falls back gracefully if the backend is not ent-based.
func (*Storage) CreateItemSource ¶ added in v1.35.0
func (s *Storage) CreateItemSource(ctx context.Context, data ItemSourceData) (*ItemSourceData, error)
CreateItemSource registers a new external item source.
func (*Storage) CreateProject ¶ added in v1.23.0
func (s *Storage) CreateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
CreateProject inserts a new project into storage.
func (*Storage) CreateSourceSyncEvent ¶ added in v1.35.0
func (s *Storage) CreateSourceSyncEvent(ctx context.Context, sourceID, cursorAfter string, created, updated, skipped, errored int, errMsg string, startedAt, finishedAt time.Time) error
CreateSourceSyncEvent records a sync run for an item source. Direct EntRepository delegation, like ListSourceSyncEvents above.
func (*Storage) DeleteAllInstances ¶
DeleteAllInstances removes all stored instances.
func (*Storage) DeleteBacklogItem ¶ added in v1.35.0
DeleteBacklogItem permanently removes an item and all its child records.
func (*Storage) DeleteInstance ¶
DeleteInstance removes an instance from storage.
func (*Storage) DeleteItemSource ¶ added in v1.35.0
DeleteItemSource removes an item source by UUID string.
func (*Storage) DeleteProject ¶ added in v1.23.0
DeleteProject removes a project from storage (sessions are unassigned).
func (*Storage) DeleteRule ¶ added in v1.12.0
DeleteRule removes an auto-approval rule from the repository.
func (*Storage) FindInstanceDataByID ¶ added in v1.35.0
func (s *Storage) FindInstanceDataByID(id string) (*InstanceData, error)
FindInstanceDataByID finds the first InstanceData whose stable ID or title matches id. Returns ErrInstanceDataNotFound when no match exists.
func (*Storage) FindOpenStuckStates ¶ added in v1.38.0
func (s *Storage) FindOpenStuckStates(ctx context.Context) ([]OpenStuckStateData, error)
FindOpenStuckStates returns every open (unresolved, un-snoozed) BacklogStuckState row, joined with rendering-relevant item fields. Returns an empty slice (no error) when the backend does not support stuck-state queries (e.g. an in-memory test double).
func (*Storage) GetAllInstanceArtifacts ¶ added in v1.35.0
GetAllInstanceArtifacts returns a map of title → raw artifacts JSON for all sessions that have stored artifacts. Single bulk query (M-4 fix).
func (*Storage) GetAllItemSessionsWithBacklogInfo ¶ added in v1.37.0
func (s *Storage) GetAllItemSessionsWithBacklogInfo(ctx context.Context) ([]ItemSessionBacklogEntry, error)
GetAllItemSessionsWithBacklogInfo returns all item sessions joined with backlog item metadata. Delegates to EntRepository; returns an error for non-ent backends.
func (*Storage) GetBacklogItem ¶ added in v1.35.0
GetBacklogItem retrieves a backlog item by UUID string.
func (*Storage) GetBaseCommitSHAsForSessions ¶ added in v1.37.0
func (s *Storage) GetBaseCommitSHAsForSessions(ctx context.Context, uuids []string) (map[string]string, error)
GetBaseCommitSHAsForSessions returns a sessionUUID→base_commit_sha map for the given UUIDs.
func (*Storage) GetClaudeConversationUUIDBySessionUUID ¶ added in v1.37.0
func (s *Storage) GetClaudeConversationUUIDBySessionUUID(ctx context.Context, sessionUUID string) (string, error)
GetClaudeConversationUUIDBySessionUUID returns the Claude conversation UUID for the session whose title matches the given UUID. Returns "" when the session has no ClaudeSession, and ErrNotFound when no session matches.
func (*Storage) GetEntClient ¶ added in v1.35.0
GetEntClient returns the *ent.Client from the underlying EntRepository, or nil when the repository is not ent-backed (e.g. in-memory test doubles).
func (*Storage) GetInstanceArtifacts ¶ added in v1.35.0
GetInstanceArtifacts loads the raw JSON-encoded artifact blob for a session. Returns ("", nil) if the session exists but has no artifacts yet.
func (*Storage) GetItemSession ¶ added in v1.35.0
GetItemSession looks up an ItemSession by entity UUID (loads BacklogItem edge).
func (*Storage) GetItemSessionBySessionAndItem ¶ added in v1.35.0
func (s *Storage) GetItemSessionBySessionAndItem(ctx context.Context, sessionUUID string, itemID string) (ItemSessionSummary, error)
GetItemSessionBySessionAndItem looks up an ItemSession by both sessionUUID and backlog item ID. Returns ErrNotFound if no matching record exists.
func (*Storage) GetItemSessionBySessionUUID ¶ added in v1.35.0
func (s *Storage) GetItemSessionBySessionUUID(ctx context.Context, sessionUUID string) (ItemSessionSummary, error)
GetItemSessionBySessionUUID looks up the ItemSession for a given session UUID (loads BacklogItem edge).
func (*Storage) GetMostRecentReviewVerdictForItem ¶ added in v1.35.0
func (s *Storage) GetMostRecentReviewVerdictForItem(ctx context.Context, itemID string) (ReviewOutcome, error)
GetMostRecentReviewVerdictForItem returns the OverallOutcome of the most recent ReviewVerdict linked to any ItemSession for itemID. Returns "" when none exists.
func (*Storage) GetSession ¶
func (s *Storage) GetSession(ctx context.Context, title string, opts ContextOptions) (*Session, error)
GetSession retrieves a session by title using the Session domain model. Use ContextOptions presets (ContextMinimal, ContextUIView, etc.) to control what is loaded.
func (*Storage) GetSessionGoal ¶ added in v1.35.0
GetSessionGoal retrieves the goal for a session by session UUID. Returns ErrNotFound if no goal has been set for the session.
func (*Storage) GetSubcommandBreakdown ¶ added in v1.35.0
func (s *Storage) GetSubcommandBreakdown(ctx context.Context, program string, since time.Time) ([]SubcommandDecisionCount, error)
GetSubcommandBreakdown returns per-(subcommand, decision) counts for a program.
func (*Storage) GetSubcommandTrend ¶ added in v1.35.0
func (s *Storage) GetSubcommandTrend(ctx context.Context, program, subcommand string, since time.Time) ([]AnalyticsData, error)
GetSubcommandTrend returns raw analytics rows for (program, subcommand) since a time.
func (*Storage) GetWorktreeDataBySessionUUID ¶ added in v1.37.0
func (s *Storage) GetWorktreeDataBySessionUUID(ctx context.Context, sessionUUID string) (GitWorktreeData, error)
GetWorktreeDataBySessionUUID returns the git worktree data for the Session with the given UUID. Returns empty GitWorktreeData for directory-mode sessions or if the session is not found.
func (*Storage) ListAnalytics ¶ added in v1.12.0
ListAnalytics retrieves recent classification decisions from the repository.
func (*Storage) ListAnalyticsByProgramSince ¶ added in v1.35.0
func (s *Storage) ListAnalyticsByProgramSince(ctx context.Context, program string, since time.Time, limit int) ([]AnalyticsData, error)
ListAnalyticsByProgramSince retrieves entries for a specific program since a time.
func (*Storage) ListAnalyticsSince ¶ added in v1.35.0
func (s *Storage) ListAnalyticsSince(ctx context.Context, since time.Time, limit int) ([]AnalyticsData, error)
ListAnalyticsSince retrieves analytics entries with created_at >= since.
func (*Storage) ListBacklogItemSummaries ¶ added in v1.37.0
func (s *Storage) ListBacklogItemSummaries(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemSummary, error)
ListBacklogItemSummaries returns lightweight summaries for list views.
func (*Storage) ListBacklogItems ¶ added in v1.35.0
func (s *Storage) ListBacklogItems(ctx context.Context, filter BacklogItemFilter) ([]BacklogItemData, error)
ListBacklogItems returns backlog items with optional filtering.
func (*Storage) ListInstanceData ¶ added in v1.18.0
func (s *Storage) ListInstanceData() ([]InstanceData, error)
ListInstanceData returns raw InstanceData from the repository without constructing Instance objects. This avoids the side effect of FromInstanceData() calling Start() (which spawns PTY processes). Use for read-only existence and title checks.
func (*Storage) ListInstanceIDs ¶ added in v1.35.0
ListInstanceIDs returns the stable ID (UUID if set, else Title) for every stored InstanceData. Used by Registry.AcquireAll to seed the initial live-handle set.
func (*Storage) ListItemSessions ¶ added in v1.35.0
func (s *Storage) ListItemSessions(ctx context.Context, itemID string) ([]ItemSessionSummary, error)
ListItemSessions returns all ItemSessions for a given BacklogItem UUID string.
func (*Storage) ListItemSources ¶ added in v1.35.0
func (s *Storage) ListItemSources(ctx context.Context) ([]ItemSourceData, error)
ListItemSources returns all registered item sources.
func (*Storage) ListProgressNotesForItem ¶ added in v1.38.0
func (s *Storage) ListProgressNotesForItem(ctx context.Context, itemID string) ([]ProgressNoteData, error)
ListProgressNotesForItem returns the full append-only history of report_progress calls for a backlog item, ordered by created_at ascending.
func (*Storage) ListProjects ¶ added in v1.23.0
func (s *Storage) ListProjects(ctx context.Context) ([]ProjectData, error)
ListProjects returns all projects from storage.
func (*Storage) ListRecentCommandsByProgram ¶ added in v1.35.0
func (s *Storage) ListRecentCommandsByProgram(ctx context.Context, program, subcommand string, since time.Time, n int) ([]string, error)
ListRecentCommandsByProgram returns the most recent n command_preview strings.
func (*Storage) ListSessionRecords ¶ added in v1.35.0
func (s *Storage) ListSessionRecords() []tokens.SessionRecord
ListSessionRecords returns a snapshot of all sessions as SessionRecords, for use by the tokens.Associator to match JSONL files to stapler-squad sessions.
func (*Storage) ListSessions ¶
ListSessions retrieves all sessions using the Session domain model. Use ContextOptions presets (ContextMinimal, ContextUIView, etc.) to control what is loaded.
func (*Storage) ListSourceSyncEvents ¶ added in v1.35.0
func (s *Storage) ListSourceSyncEvents(ctx context.Context, sourceID string) ([]SourceSyncEventData, bool, error)
ListSourceSyncEvents returns sync history events for an item source, most recent first. Direct EntRepository delegation, like GetItemSession below.
func (*Storage) LoadInstances ¶
LoadInstances loads the list of instances from the repository.
func (*Storage) MarkStuck ¶ added in v1.38.0
func (s *Storage) MarkStuck(ctx context.Context, itemID string, reason domain.StuckReason, expectedStatus BacklogStatus, stuckContext string) (bool, error)
MarkStuck opens/refreshes/reopens a durable BacklogStuckState row for (itemID, reason). Thin passthrough so callers outside package session (e.g. server/services, which cannot reach the unexported repo field) can write stuck state. Returns false, nil when the backend does not support stuck-state writes — never an error for an unsupported backend.
func (*Storage) MarkStuckNotified ¶ added in v1.38.0
func (s *Storage) MarkStuckNotified(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
MarkStuckNotified sets notified_at=now on an open, not-yet-notified stuck row for (itemID, reason). Thin passthrough, same rationale as MarkStuck above.
func (*Storage) RecordAnalytics ¶ added in v1.12.0
func (s *Storage) RecordAnalytics(ctx context.Context, data AnalyticsData) error
RecordAnalytics logs a classification decision to the repository.
func (*Storage) ResolveStuck ¶ added in v1.38.0
func (s *Storage) ResolveStuck(ctx context.Context, itemID string, reason domain.StuckReason) (bool, error)
ResolveStuck atomically, idempotently closes an open BacklogStuckState row for (itemID, reason). Thin passthrough, same rationale as MarkStuck above.
func (*Storage) SaveInstances ¶
SaveInstances upserts each started instance into the repository.
func (*Storage) SaveInstancesSync ¶
SaveInstancesSync saves instances synchronously (same as SaveInstances for the repo backend).
func (*Storage) SaveReviewVerdict ¶ added in v1.35.0
func (s *Storage) SaveReviewVerdict(ctx context.Context, itemSessionID string, verdict ReviewVerdictData) error
SaveReviewVerdict upserts a ReviewVerdict for a given ItemSession UUID.
func (*Storage) SaveSession ¶
SaveSession upserts a session using the Session domain model. If the session exists it is updated; otherwise it is created. Deprecated InstanceData-based methods (SaveInstances, LoadInstances) remain for backward compatibility.
func (*Storage) SetSessionGoal ¶ added in v1.35.0
func (s *Storage) SetSessionGoal(ctx context.Context, sessionUUID string, goal string, status string, tasks []TaskNode, setBy string) (*SessionGoalData, error)
SetSessionGoal upserts the goal for a session (1:1 per session_uuid). If a goal already exists for the session, it is replaced.
func (*Storage) SnoozeStuckState ¶ added in v1.38.0
func (s *Storage) SnoozeStuckState(ctx context.Context, itemID string, reason domain.StuckReason, until time.Time) (bool, error)
SnoozeStuckState sets snoozed_until on an open BacklogStuckState row for (itemID, reason). Returns false, nil when the backend does not support stuck-state writes or no matching open row exists — never an error for a missing row.
func (*Storage) TransitionBacklogItemStatus ¶ added in v1.35.0
func (s *Storage) TransitionBacklogItemStatus(ctx context.Context, id string, toStatus BacklogStatus, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
TransitionBacklogItemStatus changes the status of a backlog item.
func (*Storage) UpdateAcCriterionStatus ¶ added in v1.35.0
func (s *Storage) UpdateAcCriterionStatus(ctx context.Context, itemID string, criterionIndex int, status string, note string) error
UpdateAcCriterionStatus updates a single acceptance criterion's status by index.
func (*Storage) UpdateBacklogItem ¶ added in v1.35.0
func (s *Storage) UpdateBacklogItem(ctx context.Context, id string, update BacklogItemUpdate, precondition *BacklogItemPrecondition) (*BacklogItemData, error)
UpdateBacklogItem modifies an existing backlog item.
func (*Storage) UpdateInstance ¶
UpdateInstance updates an existing instance in storage.
func (*Storage) UpdateInstanceAcknowledged ¶ added in v1.18.0
UpdateInstanceAcknowledged sets the LastAcknowledged timestamp to now for a specific instance. Used by AcknowledgeSession when the instance is not available in the live poller.
func (*Storage) UpdateInstanceArtifacts ¶ added in v1.35.0
UpdateInstanceArtifacts persists the JSON-encoded artifact blob for a session. Only the session_artifacts column is touched; all other fields are unchanged.
func (*Storage) UpdateInstanceForkFlag ¶ added in v1.12.0
UpdateInstanceForkFlag is intentionally a no-op: fork status is not persisted in the ent schema. Callers (e.g. PRStatusPoller) call this as a persistence hook, but no DB write occurs.
func (*Storage) UpdateInstanceLastAddedToQueue ¶
UpdateInstanceLastAddedToQueue updates ONLY the LastAddedToQueue field for a specific instance.
func (*Storage) UpdateInstanceLastUserResponse ¶
UpdateInstanceLastUserResponse persists the LastUserResponse timestamp for a session. Uses a direct UPDATE (no read round-trip) via UpdateReviewQueueState.
func (*Storage) UpdateInstancePRNumber ¶ added in v1.12.0
UpdateInstancePRNumber persists the discovered PR number for a session so it survives restarts and avoids repeated branch-name lookups in PRStatusPoller.
func (*Storage) UpdateInstancePRStatus ¶ added in v1.12.0
UpdateInstancePRStatus updates the PR status fields for a specific instance. PR fields are not stored in the ent schema — they live in memory and are re-populated by PRStatusPoller on each poll cycle. No DB write is needed.
func (*Storage) UpdateInstanceProcessingGrace ¶
UpdateInstanceProcessingGrace persists the ProcessingGraceUntil timestamp. Uses a direct UPDATE (no read round-trip) via UpdateReviewQueueState.
func (*Storage) UpdateInstanceTimestampsOnly ¶
func (s *Storage) UpdateInstanceTimestampsOnly(title string, lastTerminalUpdate, lastMeaningfulOutput time.Time, lastOutputSignature string, lastViewed time.Time) error
UpdateInstanceTimestampsOnly updates ONLY the timestamp fields in storage without creating Instance objects. This preserves in-memory state like controllers. This is critical for WebSocket terminal streaming which updates timestamps frequently.
func (*Storage) UpdateItemSessionEnded ¶ added in v1.35.0
UpdateItemSessionEnded records the end time for an ItemSession.
func (*Storage) UpdateItemSessionGitActivity ¶ added in v1.37.0
func (s *Storage) UpdateItemSessionGitActivity(ctx context.Context, id string, sha, msg string, commitAt time.Time, commitCount int) error
UpdateItemSessionGitActivity records the latest commit SHA and related fields on an ItemSession.
func (*Storage) UpdateItemSessionSessionUUID ¶ added in v1.35.0
func (s *Storage) UpdateItemSessionSessionUUID(ctx context.Context, id string, sessionUUID string) error
UpdateItemSessionSessionUUID updates the session_uuid on an existing ItemSession record.
func (*Storage) UpdateItemSessionStarted ¶ added in v1.35.0
func (s *Storage) UpdateItemSessionStarted(ctx context.Context, id string, startedAt time.Time) error
UpdateItemSessionStarted records the start time for an ItemSession.
func (*Storage) UpdateItemSessionTriageResult ¶ added in v1.35.0
func (s *Storage) UpdateItemSessionTriageResult(ctx context.Context, id string, triageResult string) error
UpdateItemSessionTriageResult stores the triage result JSON payload on an ItemSession.
func (*Storage) UpdateItemSessionVerificationNotes ¶ added in v1.37.0
func (s *Storage) UpdateItemSessionVerificationNotes(ctx context.Context, id string, verificationNotes string) error
UpdateItemSessionVerificationNotes stores verification evidence (commands run, manual checks performed) reported via request_review on an ItemSession.
func (*Storage) UpdateItemSource ¶ added in v1.35.0
func (s *Storage) UpdateItemSource(ctx context.Context, id string, update ItemSourceUpdate) (*ItemSourceData, error)
UpdateItemSource modifies an existing item source.
func (*Storage) UpdateProject ¶ added in v1.23.0
func (s *Storage) UpdateProject(ctx context.Context, data ProjectData) (*ProjectData, error)
UpdateProject modifies an existing project in storage.
func (*Storage) UpdateSessionTaskStatus ¶ added in v1.35.0
func (s *Storage) UpdateSessionTaskStatus(ctx context.Context, sessionUUID string, taskID string, newStatus string) (*SessionGoalData, error)
UpdateSessionTaskStatus loads the goal for a session, finds the task by ID, updates its status, and saves the goal back. Returns ErrNotFound if no goal exists, or an error if task_id is not found in the tree. The read-modify-write is wrapped in a transaction to prevent concurrent update races.
func (*Storage) UpsertRule ¶ added in v1.12.0
func (s *Storage) UpsertRule(ctx context.Context, rule ApprovalRuleData) error
UpsertRule creates or updates an auto-approval rule in the repository.
type SubcommandDecisionCount ¶ added in v1.35.0
SubcommandDecisionCount holds a (subcommand, decision) aggregate count. Returned by GetSubcommandBreakdown.
type Subscriber ¶
type Subscriber struct {
ID string
Ch chan ResponseChunk
// contains filtered or unexported fields
}
Subscriber represents a client that is receiving response chunks.
type SyncLoop ¶ added in v1.35.0
type SyncLoop struct {
// contains filtered or unexported fields
}
SyncLoop drives periodic sync of all enabled ItemSources.
func NewSyncLoop ¶ added in v1.35.0
func NewSyncLoop(storage *Storage, registry *PluginRegistry) *SyncLoop
NewSyncLoop creates a SyncLoop with the default interval and no key provider.
func NewSyncLoopWithKeyProvider ¶ added in v1.35.0
func NewSyncLoopWithKeyProvider(storage *Storage, registry *PluginRegistry, keyFunc func() ([]byte, error)) *SyncLoop
NewSyncLoopWithKeyProvider creates a SyncLoop with a key provider for decryption.
func (*SyncLoop) Start ¶ added in v1.35.0
Start runs the sync loop until ctx is cancelled or Stop is called.
func (*SyncLoop) Stop ¶ added in v1.35.0
func (sl *SyncLoop) Stop()
Stop gracefully shuts down the sync loop. Safe to call multiple times.
func (*SyncLoop) SyncByID ¶ added in v1.35.0
SyncByID looks up an ItemSource by ID and syncs it, regardless of its Enabled flag — unlike the periodic loop (runAllSources), which only syncs enabled sources, this is for an explicit manual/on-demand trigger where the caller already decided to sync this specific source.
func (*SyncLoop) SyncOne ¶ added in v1.35.0
SyncOne fetches and upserts items for a single ItemSource. Concurrent calls for the same source (e.g. a manual TriggerSync racing the periodic tick) are serialized via a per-source lock — see syncSourceLocks.
func (*SyncLoop) TestDecryptConfigToken ¶ added in v1.35.0
decryptConfigToken decrypts an encrypted token in config JSON if needed. If the config has "encrypted":true, it decrypts the token field using the provided key function. If decryption is not available or not needed, returns the raw config unchanged. Exported for testing.
type TagManager ¶
type TagManager struct {
// contains filtered or unexported fields
}
TagManager provides CRUD operations for session tags. It is a pure data structure with no I/O or external dependencies. Thread safety is provided by Instance.mu -- callers must hold the lock when calling TagManager methods.
TagManager stores a pointer to the Instance.Tags slice so that mutations are automatically visible via inst.Tags (used by instance_adapter.go, review_queue_poller.go, and ToInstanceData for serialization).
func NewTagManager ¶
func NewTagManager(tags *[]string) TagManager
NewTagManager creates a TagManager backed by the given slice pointer.
func (*TagManager) Add ¶
func (tm *TagManager) Add(tag string) error
Add adds a tag if it does not already exist and does not exceed MaxTagLength. Returns ErrTagTooLong if the tag exceeds MaxTagLength. Returns ErrDuplicateTag if the tag already exists.
func (*TagManager) Has ¶
func (tm *TagManager) Has(tag string) bool
Has returns true if the tag exists.
func (*TagManager) Remove ¶
func (tm *TagManager) Remove(tag string)
Remove removes a tag by value. No-op if the tag does not exist.
func (*TagManager) Set ¶
func (tm *TagManager) Set(tags []string) error
Set replaces all tags with a new deduplicated set. Returns ErrTagTooLong on the first tag that exceeds MaxTagLength. Returns ErrTooManyTags if the deduplicated count exceeds MaxTagCount.
type TaskNode ¶ added in v1.35.0
type TaskNode struct {
ID string `json:"id"`
Title string `json:"title"`
Status string `json:"status"`
Children []TaskNode `json:"children,omitempty"`
}
TaskNode represents a single task in the goal's task tree.
func DecodeTasks ¶ added in v1.35.0
DecodeTasks deserializes a JSON string to a task tree.
type TerminalContext ¶
type TerminalContext struct {
// Height is the terminal height in rows
Height int `json:"height,omitempty"`
// Width is the terminal width in columns
Width int `json:"width,omitempty"`
// TmuxSessionName is the name of the tmux session
TmuxSessionName string `json:"tmux_session_name,omitempty"`
// TmuxPrefix is the prefix used for tmux session naming
TmuxPrefix string `json:"tmux_prefix,omitempty"`
// TmuxServerSocket is the path to the tmux server socket
TmuxServerSocket string `json:"tmux_server_socket,omitempty"`
// TerminalType indicates the terminal backend type
// Possible values: "tmux", "mux", "pty", "web"
TerminalType string `json:"terminal_type,omitempty"`
}
TerminalContext represents the terminal-related context for a session. This includes terminal dimensions, tmux configuration, and terminal type.
func (*TerminalContext) IsEmpty ¶
func (t *TerminalContext) IsEmpty() bool
IsEmpty returns true if the TerminalContext has no meaningful data
type TimeRestriction ¶
type TimeRestriction struct {
DaysOfWeek []time.Weekday `json:"days_of_week"` // Empty = all days
StartHour int `json:"start_hour"` // 0-23
EndHour int `json:"end_hour"` // 0-23
}
TimeRestriction limits when a policy is active.
type TmuxBackend ¶ added in v1.35.0
type TmuxBackend struct {
// contains filtered or unexported fields
}
TmuxBackend implements ProcessManager by delegating to TmuxManager. It is the default backend used when process_manager_backend = "tmux" (or empty).
func NewTmuxBackend ¶ added in v1.35.0
func NewTmuxBackend(mgr TmuxManager) *TmuxBackend
NewTmuxBackend creates a TmuxBackend wrapping the given TmuxManager.
func (*TmuxBackend) Attach ¶ added in v1.35.0
func (b *TmuxBackend) Attach() (chan struct{}, error)
func (*TmuxBackend) CapturePaneContent ¶ added in v1.35.0
func (b *TmuxBackend) CapturePaneContent() (string, error)
func (*TmuxBackend) CapturePaneContentRaw ¶ added in v1.35.0
func (b *TmuxBackend) CapturePaneContentRaw() (string, error)
func (*TmuxBackend) CapturePaneContentWithOptions ¶ added in v1.35.0
func (b *TmuxBackend) CapturePaneContentWithOptions(start, end string) (string, error)
func (*TmuxBackend) CaptureViewport ¶ added in v1.35.0
func (b *TmuxBackend) CaptureViewport(lines int) (string, error)
func (*TmuxBackend) Close ¶ added in v1.35.0
func (b *TmuxBackend) Close() error
func (*TmuxBackend) DetachSafely ¶ added in v1.35.0
func (b *TmuxBackend) DetachSafely() error
func (*TmuxBackend) FilterBanners ¶ added in v1.35.0
func (b *TmuxBackend) FilterBanners(content string) (string, int)
func (*TmuxBackend) GetCurrentWorkingDirectory ¶ added in v1.35.0
func (b *TmuxBackend) GetCurrentWorkingDirectory() (string, error)
GetCurrentWorkingDirectory returns the current working directory of the pane. Delegates to the underlying Session().GetPaneCurrentPath() via type assertion.
func (*TmuxBackend) GetCursorPosition ¶ added in v1.35.0
func (b *TmuxBackend) GetCursorPosition() (x, y int, err error)
func (*TmuxBackend) GetPaneDimensions ¶ added in v1.35.0
func (b *TmuxBackend) GetPaneDimensions() (width, height int, err error)
func (*TmuxBackend) GetPanePID ¶ added in v1.35.0
func (b *TmuxBackend) GetPanePID() (int32, error)
func (*TmuxBackend) GetSessionIdentifier ¶ added in v1.35.0
func (b *TmuxBackend) GetSessionIdentifier() string
GetSessionIdentifier implements ProcessManager by delegating to GetTmuxSessionName. This is the name-mapping method: backend-agnostic callers use GetSessionIdentifier, but the value is identical to what GetTmuxSessionName returns for the tmux backend.
func (*TmuxBackend) HasMeaningfulContent ¶ added in v1.35.0
func (b *TmuxBackend) HasMeaningfulContent(content string) bool
func (*TmuxBackend) HasSession ¶ added in v1.35.0
func (b *TmuxBackend) HasSession() bool
func (*TmuxBackend) HasUpdated ¶ added in v1.35.0
func (b *TmuxBackend) HasUpdated() (updated bool, hasPrompt bool, content string)
func (*TmuxBackend) IsAlive ¶ added in v1.35.0
func (b *TmuxBackend) IsAlive() bool
func (*TmuxBackend) RefreshClient ¶ added in v1.35.0
func (b *TmuxBackend) RefreshClient() error
func (*TmuxBackend) ResetExitOnce ¶ added in v1.35.0
func (b *TmuxBackend) ResetExitOnce()
func (*TmuxBackend) RestoreWithWorkDir ¶ added in v1.35.0
func (b *TmuxBackend) RestoreWithWorkDir(w string) error
func (*TmuxBackend) SendInputViaControlMode ¶ added in v1.35.0
func (b *TmuxBackend) SendInputViaControlMode(ctx context.Context, data []byte) error
func (*TmuxBackend) SendKeys ¶ added in v1.35.0
func (b *TmuxBackend) SendKeys(keys string) (int, error)
func (*TmuxBackend) SendPromptWithEnter ¶ added in v1.35.0
func (b *TmuxBackend) SendPromptWithEnter(p string) error
func (*TmuxBackend) SetDetachedSize ¶ added in v1.35.0
func (b *TmuxBackend) SetDetachedSize(w, h int, title string) error
func (*TmuxBackend) SetOnExitCallback ¶ added in v1.35.0
func (b *TmuxBackend) SetOnExitCallback(fn func(string))
func (*TmuxBackend) SetWindowSize ¶ added in v1.35.0
func (b *TmuxBackend) SetWindowSize(cols, rows int) error
func (*TmuxBackend) Start ¶ added in v1.35.0
func (b *TmuxBackend) Start(dir string) error
func (*TmuxBackend) StartControlMode ¶ added in v1.35.0
func (b *TmuxBackend) StartControlMode() error
func (*TmuxBackend) StopControlMode ¶ added in v1.35.0
func (b *TmuxBackend) StopControlMode() error
func (*TmuxBackend) SubscribeToControlModeUpdates ¶ added in v1.35.0
func (b *TmuxBackend) SubscribeToControlModeUpdates() (string, chan []byte)
func (*TmuxBackend) TapEnter ¶ added in v1.35.0
func (b *TmuxBackend) TapEnter() error
func (*TmuxBackend) TmuxManager ¶ added in v1.35.0
func (b *TmuxBackend) TmuxManager() TmuxManager
TmuxManager returns the underlying TmuxManager for type assertions in reconciliation paths that need tmux-specific operations (e.g. Session(), SetSession()).
func (*TmuxBackend) UnsubscribeFromControlModeUpdates ¶ added in v1.35.0
func (b *TmuxBackend) UnsubscribeFromControlModeUpdates(id string)
type TmuxManager ¶ added in v1.15.0
type TmuxManager interface {
HasSession() bool
Session() *tmux.TmuxSession
SetSession(*tmux.TmuxSession)
GetTmuxSessionName() string
IsAlive() bool
Close() error
DetachSafely() error
DoesSessionExist() bool
SetDetachedSize(width, height int, instanceTitle string) error
Attach() (chan struct{}, error)
CapturePaneContent() (string, error)
CapturePaneContentRaw() (string, error)
CapturePaneContentWithOptions(startLine, endLine string) (string, error)
GetPaneDimensions() (width, height int, err error)
GetCursorPosition() (x, y int, err error)
GetPTY() (*os.File, error)
SendKeys(keys string) (int, error)
SetWindowSize(cols, rows int) error
RefreshClient() error
TapEnter() error
HasUpdated() (updated bool, hasPrompt bool, content string)
RestoreWithWorkDir(workDir string) error
Start(dir string) error
FilterBanners(content string) (string, int)
HasMeaningfulContent(content string) bool
CaptureViewport(lines int) (string, error)
SendPromptWithEnter(prompt string) error
GetPanePID() (int32, error)
SetOnExitCallback(fn func(string))
ResetExitOnce()
StartControlMode() error
StopControlMode() error
SubscribeToControlModeUpdates() (string, chan []byte)
UnsubscribeFromControlModeUpdates(id string)
SendInputViaControlMode(ctx context.Context, data []byte) error
// PaneExitStatus reports whether the pane's wrapped program has already
// exited even though the tmux session object itself is still alive.
// remain-on-exit keeps a "Pane is dead" placeholder pane around after the
// wrapped program is killed (e.g. OOM SIGKILL) instead of tearing the
// session down, so IsAlive()/HasSession() alone cannot detect this state.
PaneExitStatus() (code int, signal string, dead bool)
}
TmuxManager is the interface satisfied by *TmuxProcessManager. It covers all tmux session operations used by Instance and can be implemented by test doubles to avoid requiring a real tmux server.
type TmuxProcessManager ¶
type TmuxProcessManager struct {
// contains filtered or unexported fields
}
TmuxProcessManager owns the tmux session and preview-size tracking state that were previously scattered as bare fields on Instance.
Instance keeps thin wrapper methods (with started/paused guards) that delegate here. TmuxProcessManager itself has no knowledge of Instance lifecycle; it only manages the tmux session and the preview-resize bookkeeping.
func (*TmuxProcessManager) Attach ¶
func (tm *TmuxProcessManager) Attach() (chan struct{}, error)
Attach returns a channel that closes when the user detaches from the session.
func (*TmuxProcessManager) CapturePaneContent ¶
func (tm *TmuxProcessManager) CapturePaneContent() (string, error)
CapturePaneContent returns the current visible pane content. Results are cached for capturePaneCacheTTL to reduce subprocess/forkLock contention when called per-session on every poll tick.
func (*TmuxProcessManager) CapturePaneContentRaw ¶
func (tm *TmuxProcessManager) CapturePaneContentRaw() (string, error)
CapturePaneContentRaw returns pane content with ANSI escape codes preserved.
func (*TmuxProcessManager) CapturePaneContentWithOptions ¶
func (tm *TmuxProcessManager) CapturePaneContentWithOptions(startLine, endLine string) (string, error)
CapturePaneContentWithOptions captures pane content between startLine and endLine.
func (*TmuxProcessManager) CaptureViewport ¶
func (tm *TmuxProcessManager) CaptureViewport(lines int) (string, error)
CaptureViewport captures the last N lines of the pane. If lines <= 0, captures the current viewport height.
func (*TmuxProcessManager) Close ¶
func (tm *TmuxProcessManager) Close() error
Close terminates the tmux session.
func (*TmuxProcessManager) DetachSafely ¶
func (tm *TmuxProcessManager) DetachSafely() error
DetachSafely detaches the current tmux client from the session without closing it.
func (*TmuxProcessManager) DoesSessionExist ¶
func (tm *TmuxProcessManager) DoesSessionExist() bool
DoesSessionExist returns true if the tmux session name is registered with the server.
func (*TmuxProcessManager) FilterBanners ¶
func (tm *TmuxProcessManager) FilterBanners(content string) (string, int)
FilterBanners strips banner/header content from terminal output.
func (*TmuxProcessManager) GetCursorPosition ¶
func (tm *TmuxProcessManager) GetCursorPosition() (x, y int, err error)
GetCursorPosition returns the current cursor column and row (0-based).
func (*TmuxProcessManager) GetPTY ¶
func (tm *TmuxProcessManager) GetPTY() (*os.File, error)
GetPTY returns the PTY master file for reading terminal output.
func (*TmuxProcessManager) GetPaneDimensions ¶
func (tm *TmuxProcessManager) GetPaneDimensions() (width, height int, err error)
GetPaneDimensions returns the current pane width and height.
func (*TmuxProcessManager) GetPanePID ¶
func (tm *TmuxProcessManager) GetPanePID() (int32, error)
GetPanePID returns the PID of the foreground process in the pane. The pane PID is stable for the lifetime of a tmux pane, so the result is cached after the first successful lookup to avoid repeated subprocess calls.
func (*TmuxProcessManager) GetTmuxSessionName ¶ added in v1.15.0
func (tm *TmuxProcessManager) GetTmuxSessionName() string
GetTmuxSessionName returns the sanitized tmux session name for reconciliation. Returns empty string when no session has been initialized.
func (*TmuxProcessManager) HasMeaningfulContent ¶
func (tm *TmuxProcessManager) HasMeaningfulContent(content string) bool
HasMeaningfulContent reports whether the terminal output contains substantive content.
func (*TmuxProcessManager) HasSession ¶
func (tm *TmuxProcessManager) HasSession() bool
HasSession reports whether a tmux session has been initialized.
func (*TmuxProcessManager) HasUpdated ¶
func (tm *TmuxProcessManager) HasUpdated() (updated bool, hasPrompt bool, content string)
HasUpdated reports whether the pane content has changed since the last check.
func (*TmuxProcessManager) IsAlive ¶
func (tm *TmuxProcessManager) IsAlive() bool
IsAlive reports whether the tmux session process is still running.
func (*TmuxProcessManager) PaneExitStatus ¶ added in v1.37.0
func (tm *TmuxProcessManager) PaneExitStatus() (code int, signal string, dead bool)
PaneExitStatus reports the wrapped program's exit code/signal for a dead pane whose tmux session is otherwise still alive (remain-on-exit keeps the placeholder pane around after the wrapped program exits/is killed). Returns dead=false if there is no session, or the pane is still running.
func (*TmuxProcessManager) RefreshClient ¶
func (tm *TmuxProcessManager) RefreshClient() error
RefreshClient forces the tmux client to redraw.
func (*TmuxProcessManager) ResetExitOnce ¶ added in v1.15.0
func (tm *TmuxProcessManager) ResetExitOnce()
ResetExitOnce resets the sync.Once guard so that the exit callback can fire again on the next start cycle (e.g., after a restart). No-op if no session.
func (*TmuxProcessManager) RestoreWithWorkDir ¶
func (tm *TmuxProcessManager) RestoreWithWorkDir(workDir string) error
RestoreWithWorkDir re-attaches to an existing session in the given directory.
func (*TmuxProcessManager) SendInputViaControlMode ¶ added in v1.35.0
func (tm *TmuxProcessManager) SendInputViaControlMode(ctx context.Context, data []byte) error
SendInputViaControlMode sends raw bytes through the existing control mode connection.
func (*TmuxProcessManager) SendKeys ¶
func (tm *TmuxProcessManager) SendKeys(keys string) (int, error)
SendKeys sends a string of keys to the tmux session and returns the number of bytes written.
func (*TmuxProcessManager) SendPromptWithEnter ¶
func (tm *TmuxProcessManager) SendPromptWithEnter(prompt string) error
SendPromptWithEnter sends text to the session followed by Enter key. Includes a brief pause between text and Enter to prevent interpretation issues.
func (*TmuxProcessManager) Session ¶
func (tm *TmuxProcessManager) Session() *tmux.TmuxSession
Session returns the underlying tmux session (may be nil before Start).
func (*TmuxProcessManager) SetDetachedSize ¶
func (tm *TmuxProcessManager) SetDetachedSize(width, height int, instanceTitle string) error
SetDetachedSize updates the tmux window dimensions without attaching. Rate-limits PTY-not-initialized warnings to avoid log spam.
func (*TmuxProcessManager) SetOnExitCallback ¶ added in v1.15.0
func (tm *TmuxProcessManager) SetOnExitCallback(fn func(string))
SetOnExitCallback registers a callback that fires when the tmux session exits unexpectedly. No-op if no session is initialized.
func (*TmuxProcessManager) SetSession ¶
func (tm *TmuxProcessManager) SetSession(s *tmux.TmuxSession)
SetSession replaces the underlying tmux session. Used by tests and by Instance.start() when reusing a pre-created session.
func (*TmuxProcessManager) SetWindowSize ¶
func (tm *TmuxProcessManager) SetWindowSize(cols, rows int) error
SetWindowSize resizes the tmux window to the given columns and rows.
func (*TmuxProcessManager) Start ¶
func (tm *TmuxProcessManager) Start(dir string) error
Start creates and starts the tmux session in the given directory.
func (*TmuxProcessManager) StartControlMode ¶ added in v1.15.0
func (tm *TmuxProcessManager) StartControlMode() error
StartControlMode starts the tmux control mode stream. Returns nil if no session is initialized.
func (*TmuxProcessManager) StopControlMode ¶ added in v1.15.0
func (tm *TmuxProcessManager) StopControlMode() error
StopControlMode stops the tmux control mode stream. Returns nil if no session is initialized.
func (*TmuxProcessManager) SubscribeToControlModeUpdates ¶ added in v1.15.0
func (tm *TmuxProcessManager) SubscribeToControlModeUpdates() (string, chan []byte)
SubscribeToControlModeUpdates registers a new subscriber for real-time terminal output. Returns a pre-closed channel if no session is initialized.
func (*TmuxProcessManager) TapEnter ¶
func (tm *TmuxProcessManager) TapEnter() error
TapEnter sends an Enter key to the session.
func (*TmuxProcessManager) UnsubscribeFromControlModeUpdates ¶ added in v1.15.0
func (tm *TmuxProcessManager) UnsubscribeFromControlModeUpdates(id string)
UnsubscribeFromControlModeUpdates removes a subscriber by ID. No-op if no session is initialized.
type TmuxSocketQuerier ¶ added in v1.37.0
type TmuxSocketQuerier interface {
// ListSessions returns the set of live tmux session names on serverSocket.
ListSessions(serverSocket string) (map[string]bool, error)
// IsServerDown reports whether the tmux server on serverSocket is unreachable.
IsServerDown(serverSocket string) bool
}
TmuxSocketQuerier abstracts read-only tmux server-socket queries so that callers needing to know "which sessions are alive on this socket" or "is this socket's server down" can be exercised in tests without a real tmux server. Production code backs this with the real tmux package (via realTmuxSocketQuerier); tests substitute a fake.
Both ReviewQueuePoller.reconcileSessions and SessionHealthChecker.CheckAllSessions need this: instances can be spread across multiple tmux server sockets (the default socket for ordinary sessions, isolated sockets for some worktree/test scenarios), so every query must be scoped to a specific socket rather than assumed to be shared across all instances.
type TransitionDef ¶ added in v1.35.0
type TransitionDef struct {
From Status
To Status
// Guard is called before the status is updated. Return non-nil to abort.
// nil means unconditionally allowed.
Guard func(ctx context.Context, i *Instance) error
// After is called once the status has been updated (side-effects: process
// management, worktree ops, scrollback restore, etc.).
// nil means no post-transition side-effect.
After func(ctx context.Context, i *Instance)
}
TransitionDef describes a single valid state machine transition with optional guard (pre-condition) and after (post-transition side-effect) hooks.
type TriageSuggestion ¶ added in v1.35.0
TriageSuggestion is a canonical suggestion entry shared by the headless triage path and the submit_triage_result MCP tool.
type TriageTask ¶ added in v1.35.0
type TriageTask struct {
Text string `json:"text"`
Estimate string `json:"estimate"`
Category string `json:"category"`
}
TriageTask is a canonical implementation task shared by the headless triage path and the submit_triage_result MCP tool.
type TurnCallback ¶ added in v1.35.0
TurnCallback is called after each successful turn injection.
type UIPreferences ¶
type UIPreferences struct {
// Category is the organizational category for the session
Category string `json:"category,omitempty"`
// IsExpanded indicates if the session is expanded in grouped views
IsExpanded bool `json:"is_expanded,omitempty"`
// Tags are the user-defined tags for multi-dimensional organization
Tags []string `json:"tags,omitempty"`
// GroupingStrategy is the current grouping mode (e.g., "category", "tag", "branch")
GroupingStrategy string `json:"grouping_strategy,omitempty"`
// SortOrder is the preferred sort order (e.g., "name", "date", "status")
SortOrder string `json:"sort_order,omitempty"`
}
UIPreferences represents the UI-related preferences for a session. This includes categorization, tags, and display preferences.
func (*UIPreferences) HasTag ¶
func (u *UIPreferences) HasTag(tag string) bool
HasTag returns true if the UIPreferences contains the specified tag
func (*UIPreferences) IsEmpty ¶
func (u *UIPreferences) IsEmpty() bool
IsEmpty returns true if the UIPreferences has no meaningful data
type UsageLimit ¶
type UsageLimit struct {
MaxUses int `json:"max_uses"` // 0 = unlimited
TimeWindow time.Duration `json:"time_window"` // 0 = no time window
PerApproval bool `json:"per_approval"` // Track per approval type vs globally
}
UsageLimit restricts how many times a policy can be used.
type VCSInfo ¶
type VCSInfo struct {
// VCSType is "jj" or "git"
VCSType string
// HasJJ indicates if JJ is available
HasJJ bool
// HasGit indicates if Git is available
HasGit bool
// IsColocated indicates if this is a JJ+Git colocated repo
IsColocated bool
// RepoPath is the repository root path
RepoPath string
// CurrentBookmark is the current branch/bookmark name
CurrentBookmark string
// CurrentRevision is the current revision (short ID)
CurrentRevision string
// HasUncommittedChanges indicates if there are uncommitted changes
HasUncommittedChanges bool
// ModifiedFileCount is the count of modified/added/deleted files
ModifiedFileCount int
}
VCSInfo contains version control information for a session
type VNCProcessManager ¶ added in v1.35.0
type VNCProcessManager = vnc.VNCProcessManager
VNCProcessManager is a local alias for the vnc package interface so that files within the session package can reference it without importing vnc directly.
type WorkflowCreateInput ¶ added in v1.35.0
type WorkflowCreateInput struct {
Slug string
Name string
Description string
Command string
TargetDirectory string
InputTemplate string
SessionType string
Model string
AgentType string
CronExpression string
CronEnabled bool
KeepSessions *int // nil = use default (0, disabled); 0 = keep all
ArchiveAfterHours *int // nil = use default (0, disabled); 0 = disabled
}
WorkflowCreateInput holds the fields for creating a new workflow.
type WorkflowEngine ¶ added in v1.35.0
type WorkflowEngine interface {
// CanTransition returns true if transitioning from → to is structurally allowed.
CanTransition(from, to BacklogStatus) bool
// ValidateGates runs guard rules for the transition. Returns nil if gates pass.
ValidateGates(item BacklogItemTransitionInput, to BacklogStatus) error
// AllowedTransitions returns the set of statuses reachable from from.
AllowedTransitions(from BacklogStatus) []BacklogStatus
}
WorkflowEngine is the policy object that governs which backlog status transitions are permitted and what guards must pass.
type WorkflowRepository ¶ added in v1.35.0
type WorkflowRepository interface {
Create(ctx context.Context, w WorkflowCreateInput) (*ent.Workflow, error)
Update(ctx context.Context, id uuid.UUID, w WorkflowUpdateInput) (*ent.Workflow, error)
Delete(ctx context.Context, id uuid.UUID) error
GetByID(ctx context.Context, id uuid.UUID) (*ent.Workflow, error)
GetBySlug(ctx context.Context, slug string) (*ent.Workflow, error)
ListAll(ctx context.Context) ([]*ent.Workflow, error)
ListEnabled(ctx context.Context) ([]*ent.Workflow, error) // cron_enabled=true
}
WorkflowRepository defines persistence operations for workflow definitions.
type WorkflowUpdateInput ¶ added in v1.35.0
type WorkflowUpdateInput struct {
Name *string
Description *string
Command *string
TargetDirectory *string
InputTemplate *string
SessionType *string
Model *string
AgentType *string
CronExpression *string
CronEnabled *bool
KeepSessions *int // nil = do not update; 0 = keep all (disabled)
ArchiveAfterHours *int // nil = do not update; 0 = disabled
}
WorkflowUpdateInput holds optional fields for updating an existing workflow. Pointer fields are only applied when non-nil (partial update).
type Workspace ¶ added in v1.12.0
type Workspace struct {
// EffectivePath is the directory where the session process runs.
// For worktree sessions: the worktree directory.
// For directory sessions: the session's Path field.
EffectivePath string
// RepoRoot is the git repository root (the main checkout, not the worktree).
// For directory sessions, this is the same as EffectivePath.
RepoRoot string
}
Workspace describes where a session is operating. Use Instance.Workspace() to obtain this value; do not construct directly.
type WorkspacePath ¶ added in v1.35.0
type WorkspacePath string
WorkspacePath represents a cleaned, resolved workspace root path.
func NewWorkspacePath ¶ added in v1.35.0
func NewWorkspacePath(s string) (WorkspacePath, error)
NewWorkspacePath resolves symlinks and cleans a path to guarantee a single canonical representation.
type WorkspaceSwitchRequest ¶
type WorkspaceSwitchRequest struct {
// Type is the type of switch operation
Type WorkspaceSwitchType
// Target is the destination (directory path, revision/branch, or worktree path)
Target string
// ChangeStrategy determines how to handle uncommitted changes
ChangeStrategy vcs.ChangeStrategy
// CreateIfMissing creates the bookmark/branch/worktree if it doesn't exist
CreateIfMissing bool
// BaseRevision is the base for new bookmark creation (empty = current)
BaseRevision string
// VCSPreference overrides the default VCS preference for this operation
VCSPreference vcs.VCSPreference
}
WorkspaceSwitchRequest represents a request to switch the workspace
type WorkspaceSwitchResult ¶
type WorkspaceSwitchResult struct {
// Success indicates if the switch was successful
Success bool
// Error contains any error that occurred
Error error
// PreviousRevision is the revision before the switch
PreviousRevision string
// CurrentRevision is the revision after the switch
CurrentRevision string
// VCSType is the VCS that was used
VCSType vcs.VCSType
// ChangesHandled describes how uncommitted changes were handled
ChangesHandled string
}
WorkspaceSwitchResult contains the result of a workspace switch operation
type WorkspaceSwitchType ¶
type WorkspaceSwitchType int
WorkspaceSwitchType defines the type of workspace switch operation
const ( // SwitchTypeDirectory is a simple directory change (no VCS, no restart) SwitchTypeDirectory WorkspaceSwitchType = iota // SwitchTypeRevision switches to a different revision/branch SwitchTypeRevision // SwitchTypeWorktree switches to or creates a different worktree SwitchTypeWorktree )
func (WorkspaceSwitchType) String ¶
func (t WorkspaceSwitchType) String() string
type WorktreeInfo ¶
type WorktreeInfo struct {
// IsWorktree is true if the path is a git worktree (not the main repo)
IsWorktree bool
// MainRepoPath is the path to the main repository's .git directory
// For a worktree at ~/.stapler-squad/worktrees/foo, this might be /path/to/main/repo/.git
MainRepoPath string
// MainRepoRoot is the working directory root of the main repository
MainRepoRoot string
// RemoteURL is the git remote origin URL (e.g., https://github.com/owner/repo.git)
RemoteURL string
// GitHubOwner is the owner extracted from a GitHub remote URL
GitHubOwner string
// GitHubRepo is the repo name extracted from a GitHub remote URL
GitHubRepo string
}
WorktreeInfo contains information about a git worktree
func DetectWorktree ¶
func DetectWorktree(path string) (*WorktreeInfo, error)
DetectWorktree checks if the given path is a git worktree and extracts relevant info. Results are cached per-path for 5 minutes to avoid repeated git subprocess calls on every LoadInstances invocation for sessions whose GitHubOwner was never resolved. Returns WorktreeInfo with IsWorktree=false if it's not a worktree or not a git repo.
type WorktreePRPoller ¶ added in v1.35.0
type WorktreePRPoller struct {
// contains filtered or unexported fields
}
WorktreePRPoller polls GitHub PR status for worktrees that have no active session. It is the counterpart to PRStatusPoller (which covers session-backed worktrees). The two pollers divide the worktree space: PRStatusPoller owns worktrees with a running session; WorktreePRPoller owns the rest.
Concurrency design:
- data cache is a sync.Map — lock-free reads in the steady state
- auth state is an atomic.Value (pollerAuthResult) — same pattern as PRStatusPoller
- onUpdated callback is an atomic.Value — writers Store, readers Load, no lock
- rateLimitedUntil and noPRPollAfter are guarded by mu
func NewWorktreePRPoller ¶ added in v1.35.0
func NewWorktreePRPoller(etagCache *github.ETagCache, prPoller *PRStatusPoller) *WorktreePRPoller
NewWorktreePRPoller creates a WorktreePRPoller with default configuration. source may be nil at construction time; call SetSource before Start.
func NewWorktreePRPollerWithConfig ¶ added in v1.35.0
func NewWorktreePRPollerWithConfig(etagCache *github.ETagCache, prPoller *PRStatusPoller, cfg WorktreePRPollerConfig) *WorktreePRPoller
NewWorktreePRPollerWithConfig creates a WorktreePRPoller with custom configuration.
func (*WorktreePRPoller) GetPRData ¶ added in v1.35.0
func (p *WorktreePRPoller) GetPRData(repoPath, branch string) *github.PRInfo
GetPRData returns cached PR info for a worktree, or nil if not yet known.
func (*WorktreePRPoller) SetOnUpdated ¶ added in v1.35.0
func (p *WorktreePRPoller) SetOnUpdated(fn func(repoPath, branch string, info *github.PRInfo))
SetOnUpdated registers a callback invoked whenever cached PR data changes. Safe to call before or after Start; the callback is replaced atomically.
func (*WorktreePRPoller) SetSource ¶ added in v1.35.0
func (p *WorktreePRPoller) SetSource(src WorktreeSource)
SetSource sets the worktree data source. Safe to call before Start.
func (*WorktreePRPoller) Start ¶ added in v1.35.0
func (p *WorktreePRPoller) Start(ctx context.Context)
Start begins the polling loop. It is a no-op if already started.
func (*WorktreePRPoller) Stop ¶ added in v1.35.0
func (p *WorktreePRPoller) Stop()
Stop gracefully shuts down the poller and waits for in-flight requests.
type WorktreePRPollerConfig ¶ added in v1.35.0
type WorktreePRPollerConfig struct {
PollInterval time.Duration
CallTimeout time.Duration
AuthCacheDuration time.Duration
// NoPRBackoff is how long to skip a branch after its PR list returns empty.
// Zero disables the backoff.
NoPRBackoff time.Duration
}
WorktreePRPollerConfig controls polling cadence and auth caching.
func DefaultWorktreePRPollerConfig ¶ added in v1.35.0
func DefaultWorktreePRPollerConfig() WorktreePRPollerConfig
DefaultWorktreePRPollerConfig returns sensible defaults matching PRStatusPoller.
type WorktreeScanItem ¶ added in v1.35.0
WorktreeScanItem is the minimal worktree info the poller needs from the unfinished-work scanner. Using a local struct avoids an import cycle:
session → session/unfinished → pkg/events → session
The server layer bridges the two packages via WorktreeSource (adapter pattern).
type WorktreeSource ¶ added in v1.35.0
type WorktreeSource interface {
// ScanDone returns a channel that receives the scan time after every scan pass.
ScanDone() <-chan time.Time
// GetWorktrees returns a snapshot of all currently-known worktrees.
GetWorktrees() []WorktreeScanItem
}
WorktreeSource provides the set of currently-known worktrees. Implement this interface by wrapping an *unfinished.Scanner in the server layer.
Source Files
¶
- actor.go
- agy_adapter.go
- approval_automation.go
- approval_policy.go
- artifact_lookup.go
- autonomous_driver.go
- backend_factory.go
- backlog.go
- backlog_commands.go
- backlog_context.go
- backlog_crypto.go
- backlog_lifecycle.go
- backlog_plugin.go
- backlog_plugin_github.go
- backlog_plugin_github_prs.go
- backlog_review.go
- backlog_sync.go
- backlog_triage.go
- canonical.go
- checkpoint.go
- circular_buffer.go
- claude_adapter.go
- claude_command_builder.go
- claude_controller.go
- claude_session_manager.go
- command_executor.go
- command_history.go
- command_queue.go
- context_options.go
- contexts.go
- controller_manager.go
- ent_pipeline_mode_repository.go
- ent_repository.go
- ent_repository_backlog.go
- ent_workflow_repository.go
- external_approval.go
- external_discovery.go
- external_streamer.go
- external_tmux_streamer.go
- feature_controller.go
- git_worktree_manager.go
- github_metadata.go
- health.go
- hibernation_sweeper.go
- history.go
- history_adapter.go
- history_detector.go
- history_fork.go
- history_linker.go
- history_transfer.go
- history_watcher.go
- instance.go
- instance_actor_setters.go
- instance_approval.go
- instance_cdp.go
- instance_checkpoint.go
- instance_claude.go
- instance_controller.go
- instance_hibernate.go
- instance_program.go
- instance_serialization.go
- instance_shells.go
- instance_snapshot.go
- instance_state.go
- instance_status.go
- instance_tags.go
- instance_terminal.go
- instance_tmux.go
- instance_vnc.go
- instance_workspace.go
- instance_worktree.go
- interfaces.go
- live_instance.go
- load_options.go
- locked.go
- migrate.go
- native_process_manager.go
- orphan_sweep.go
- pipeline_engine.go
- pipeline_mode_repository.go
- pipeline_mode_validation.go
- pr_status_poller.go
- pr_tracking.go
- process_manager.go
- pty_access.go
- pty_discovery.go
- pty_subscriber.go
- registry.go
- repo_path.go
- repository.go
- response_stream.go
- review_gate.go
- review_queue.go
- review_queue_determiner.go
- review_queue_poller.go
- review_state.go
- review_transcript.go
- session.go
- session_driver.go
- session_goal.go
- shell.go
- shell_registry.go
- startup_scanner.go
- state_machine.go
- status_mapping.go
- status_remap.go
- storage.go
- storage_backlog.go
- stuck_decisions.go
- tag_manager.go
- tmux_backend.go
- tmux_process_manager.go
- tmux_socket_querier.go
- types.go
- workflow_engine.go
- workflow_repository.go
- workflow_slug.go
- worktree_pr_poller.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cdp provides per-session Chrome DevTools Protocol (CDP) browser streaming.
|
Package cdp provides per-session Chrome DevTools Protocol (CDP) browser streaming. |
|
binaries
Package binaries provides per-binary BinaryDetector implementations.
|
Package binaries provides per-binary BinaryDetector implementations. |
|
dtypes
Package dtypes contains shared types for the detection package and its sub-packages.
|
Package dtypes contains shared types for the detection package and its sub-packages. |
|
Package domain contains pure domain types for the backlog subsystem.
|
Package domain contains pure domain types for the backlog subsystem. |
|
Package headless provides a subprocess-based interface for running claude -p headlessly.
|
Package headless provides a subprocess-based interface for running claude -p headlessly. |
|
Package hibernation provides checkpoint writing and cleanup for hibernated sessions.
|
Package hibernation provides checkpoint writing and cleanup for hibernated sessions. |
|
Package memory provides session memory measurement for the hibernation sweeper.
|
Package memory provides session memory measurement for the hibernation sweeper. |
|
memorytest
Package memorytest provides test doubles for the memory package.
|
Package memorytest provides test doubles for the memory package. |
|
Package mux provides PTY multiplexing functionality for external Claude sessions.
|
Package mux provides PTY multiplexing functionality for external Claude sessions. |
|
Package tokens provides JSONL-based token usage parsing and aggregation for Claude Code sessions.
|
Package tokens provides JSONL-based token usage parsing and aggregation for Claude Code sessions. |
|
Package unfinished provides background scanning for git worktrees that have uncommitted changes, commits ahead of the default branch, or commits behind.
|
Package unfinished provides background scanning for git worktrees that have uncommitted changes, commits ahead of the default branch, or commits behind. |
|
gogitstore
mmapindex.go implements the mmap-backed .idx loader described in session/unfinished/design/pluggable-gitstore.md §5 ("mmap for the index — designed, not built").
|
mmapindex.go implements the mmap-backed .idx loader described in session/unfinished/design/pluggable-gitstore.md §5 ("mmap for the index — designed, not built"). |
|
Package vcs provides an abstraction layer over version control systems.
|
Package vcs provides an abstraction layer over version control systems. |
|
Package vnc provides per-session virtual display and VNC server lifecycle management.
|
Package vnc provides per-session virtual display and VNC server lifecycle management. |
|
Package workspace provides workspace tracking and status management for stapler-squad sessions.
|
Package workspace provides workspace tracking and status management for stapler-squad sessions. |