Documentation
¶
Overview ¶
Package executor runs Claude Code tasks in the background.
Package executor provides task execution with pluggable executor backends.
Index ¶
- Constants
- Variables
- func CapturePaneContent(taskID int64, lines int) string
- func ClaudeConfigFilePath(dir string) string
- func ClaudeSessionExists(sessionID, workDir, configDir string) bool
- func CleanupClaudeSessions(worktreePath, configDir string) error
- func DefaultClaudeConfigDir() string
- func DefaultExecutorName() string
- func FindClaudeSessionID(workDir string) string
- func GetClaudePIDFromPane(paneID string) int
- func GetTasksWithRunningShellProcess() map[int64]bool
- func GetWorktreeInitScript(projectDir string) string
- func GetWorktreeTeardownScript(projectDir string) string
- func HasRunningProcessInTaskUI() bool
- func PurgeStaleClaudeProjectConfigs(configPath string) (int, error)
- func RemoveClaudeProjectConfig(configPath, projectPath string) error
- func RenameClaudeSession(workDir, newName, configDir string) error
- func ResolveClaudeConfigDir(custom string) string
- func SendKeyToPane(taskID int64, keys ...string) error
- func TmuxSessionName(taskID int64) string
- func TmuxWindowName(taskID int64) string
- type ClaudeExecutor
- func (c *ClaudeExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (c *ClaudeExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (c *ClaudeExecutor) FindSessionID(workDir string) string
- func (c *ClaudeExecutor) GetProcessID(taskID int64) int
- func (c *ClaudeExecutor) IsAvailable() bool
- func (c *ClaudeExecutor) IsSuspended(taskID int64) bool
- func (c *ClaudeExecutor) Kill(taskID int64) bool
- func (c *ClaudeExecutor) Name() string
- func (c *ClaudeExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (c *ClaudeExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (c *ClaudeExecutor) ResumeProcess(taskID int64) bool
- func (c *ClaudeExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (c *ClaudeExecutor) SupportsDangerousMode() bool
- func (c *ClaudeExecutor) SupportsSessionResume() bool
- func (c *ClaudeExecutor) Suspend(taskID int64) bool
- type CodexExecutor
- func (c *CodexExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (c *CodexExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (c *CodexExecutor) FindSessionID(workDir string) string
- func (c *CodexExecutor) GetProcessID(taskID int64) int
- func (c *CodexExecutor) IsAvailable() bool
- func (c *CodexExecutor) IsSuspended(taskID int64) bool
- func (c *CodexExecutor) Kill(taskID int64) bool
- func (c *CodexExecutor) Name() string
- func (c *CodexExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (c *CodexExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (c *CodexExecutor) ResumeProcess(taskID int64) bool
- func (c *CodexExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (c *CodexExecutor) SupportsDangerousMode() bool
- func (c *CodexExecutor) SupportsSessionResume() bool
- func (c *CodexExecutor) Suspend(taskID int64) bool
- type ExecResult
- type Executor
- func (e *Executor) AllExecutors() []string
- func (e *Executor) ArchiveWorktree(task *db.Task) error
- func (e *Executor) AvailableExecutors() []string
- func (e *Executor) CleanupDuplicateWindows(taskID int64)
- func (e *Executor) CleanupStaleWorktreesManual(maxAge time.Duration, dryRun bool) ([]*db.Task, error)
- func (e *Executor) CleanupWorktree(task *db.Task) error
- func (e *Executor) DisplayName() string
- func (e *Executor) ExecuteNow(ctx context.Context, taskID int64) error
- func (e *Executor) ExecutorSlug() string
- func (e *Executor) GetExecutor(name string) TaskExecutor
- func (e *Executor) GetProjectDir(project string) string
- func (e *Executor) GetTaskExecutor(task *db.Task) TaskExecutor
- func (e *Executor) Interrupt(taskID int64) bool
- func (e *Executor) IsClaudeRunning(taskID int64) bool
- func (e *Executor) IsRunning(taskID int64) bool
- func (e *Executor) IsSuspended(taskID int64) bool
- func (e *Executor) KillClaudeProcess(taskID int64) bool
- func (e *Executor) KillPiProcess(taskID int64) bool
- func (e *Executor) NotifyTaskChange(eventType string, task *db.Task)
- func (e *Executor) RenameClaudeSessionForTask(task *db.Task, newName string)
- func (e *Executor) ResumeDangerous(taskID int64) bool
- func (e *Executor) ResumeSafe(taskID int64) bool
- func (e *Executor) ResumeTask(taskID int64) bool
- func (e *Executor) RunningTasks() []int64
- func (e *Executor) Start(ctx context.Context)
- func (e *Executor) Stop()
- func (e *Executor) Subscribe(taskID int64) chan *db.TaskLog
- func (e *Executor) SubscribeTaskEvents() chan TaskEvent
- func (e *Executor) SuspendTask(taskID int64) bool
- func (e *Executor) TriggerProcessing()
- func (e *Executor) UnarchiveWorktree(task *db.Task) error
- func (e *Executor) Unsubscribe(taskID int64, ch chan *db.TaskLog)
- func (e *Executor) UnsubscribeTaskEvents(ch chan TaskEvent)
- type ExecutorFactory
- type GeminiExecutor
- func (g *GeminiExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (g *GeminiExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (g *GeminiExecutor) FindSessionID(workDir string) string
- func (g *GeminiExecutor) GetProcessID(taskID int64) int
- func (g *GeminiExecutor) IsAvailable() bool
- func (g *GeminiExecutor) IsSuspended(taskID int64) bool
- func (g *GeminiExecutor) Kill(taskID int64) bool
- func (g *GeminiExecutor) Name() string
- func (g *GeminiExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (g *GeminiExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (g *GeminiExecutor) ResumeProcess(taskID int64) bool
- func (g *GeminiExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (g *GeminiExecutor) SupportsDangerousMode() bool
- func (g *GeminiExecutor) SupportsSessionResume() bool
- func (g *GeminiExecutor) Suspend(taskID int64) bool
- type OpenClawExecutor
- func (o *OpenClawExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (o *OpenClawExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (o *OpenClawExecutor) FindSessionID(workDir string) string
- func (o *OpenClawExecutor) GetProcessID(taskID int64) int
- func (o *OpenClawExecutor) IsAvailable() bool
- func (o *OpenClawExecutor) IsSuspended(taskID int64) bool
- func (o *OpenClawExecutor) Kill(taskID int64) bool
- func (o *OpenClawExecutor) Name() string
- func (o *OpenClawExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (o *OpenClawExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (o *OpenClawExecutor) ResumeProcess(taskID int64) bool
- func (o *OpenClawExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (o *OpenClawExecutor) SupportsDangerousMode() bool
- func (o *OpenClawExecutor) SupportsSessionResume() bool
- func (o *OpenClawExecutor) Suspend(taskID int64) bool
- type OpenCodeExecutor
- func (o *OpenCodeExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (o *OpenCodeExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (o *OpenCodeExecutor) FindSessionID(workDir string) string
- func (o *OpenCodeExecutor) GetProcessID(taskID int64) int
- func (o *OpenCodeExecutor) IsAvailable() bool
- func (o *OpenCodeExecutor) IsSuspended(taskID int64) bool
- func (o *OpenCodeExecutor) Kill(taskID int64) bool
- func (o *OpenCodeExecutor) Name() string
- func (o *OpenCodeExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (o *OpenCodeExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (o *OpenCodeExecutor) ResumeProcess(taskID int64) bool
- func (o *OpenCodeExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (o *OpenCodeExecutor) SupportsDangerousMode() bool
- func (o *OpenCodeExecutor) SupportsSessionResume() bool
- func (o *OpenCodeExecutor) Suspend(taskID int64) bool
- type PiExecutor
- func (p *PiExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
- func (p *PiExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
- func (p *PiExecutor) FindSessionID(workDir string) string
- func (p *PiExecutor) GetProcessID(taskID int64) int
- func (p *PiExecutor) IsAvailable() bool
- func (p *PiExecutor) IsSuspended(taskID int64) bool
- func (p *PiExecutor) Kill(taskID int64) bool
- func (p *PiExecutor) Name() string
- func (p *PiExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
- func (p *PiExecutor) ResumeDangerous(task *db.Task, workDir string) bool
- func (p *PiExecutor) ResumeSafe(task *db.Task, workDir string) bool
- func (p *PiExecutor) SupportsDangerousMode() bool
- func (p *PiExecutor) SupportsSessionResume() bool
- func (p *PiExecutor) Suspend(taskID int64) bool
- type ProjectConfig
- type TaskEvent
- type TaskExecutor
- type WorktreeConfig
Constants ¶
const ConventionalInitScript = "bin/worktree-setup"
ConventionalInitScript is the conventional location for a worktree init script. If no config file exists but this script is present and executable, it will be used.
const ConventionalTeardownScript = "bin/worktree-teardown"
ConventionalTeardownScript is the conventional location for a worktree teardown script. If no config file exists but this script is present and executable, it will be used.
const DefaultSuspendIdleTimeout = 6 * time.Hour
DefaultSuspendIdleTimeout is the default time a blocked task must be idle before being suspended.
const DefaultWorktreeCleanupMaxAge = 7 * 24 * time.Hour // 7 days
DefaultWorktreeCleanupMaxAge is the default time after completion before a done/archived task's worktree is automatically archived and removed to reclaim disk space.
const DoneTaskCleanupTimeout = 30 * time.Minute
DoneTaskCleanupTimeout is how long after a task is marked done before its Claude process is killed. This gives users time to review output or retry the task before the process is cleaned up.
const TmuxDaemonSession = "task-daemon"
TmuxDaemonSession is the default session name that holds all Claude task windows. This is now deprecated - use getDaemonSessionName() for instance-specific names.
Variables ¶
var ConfigFileNames = []string{".taskyou.yml", ".taskyou.yaml", "taskyou.yml", "taskyou.yaml"}
ConfigFileNames are the supported configuration file names, in order of precedence.
Functions ¶
func CapturePaneContent ¶
CapturePaneContent captures the last N lines from a task's tmux pane. Returns the trimmed content, or empty string if the pane doesn't exist or capture fails.
func ClaudeConfigFilePath ¶
ClaudeConfigFilePath returns the path to the claude.json configuration alongside the directory.
func ClaudeSessionExists ¶
ClaudeSessionExists checks if a Claude session file exists for the given session ID and workDir.
func CleanupClaudeSessions ¶
CleanupClaudeSessions removes Claude session files for a given worktree path. Claude stores sessions under CLAUDE_CONFIG_DIR/projects/<escaped-path>/. This should be called when deleting a task to clean up session data.
func DefaultClaudeConfigDir ¶
func DefaultClaudeConfigDir() string
DefaultClaudeConfigDir returns the resolved CLAUDE_CONFIG_DIR taking the environment into account.
func DefaultExecutorName ¶
func DefaultExecutorName() string
DefaultExecutorName returns the fallback executor display name.
func FindClaudeSessionID ¶
FindClaudeSessionID finds the most recent claude session ID for a workDir using the default config dir. Exported for use by the UI to check for resumable sessions.
func GetClaudePIDFromPane ¶
GetClaudePIDFromPane returns the Claude PID for a specific tmux pane. This is used by the UI when it knows the exact pane ID.
func GetTasksWithRunningShellProcess ¶
GetTasksWithRunningShellProcess returns a map of task IDs that have a running process in their shell pane. A process is considered "running" if the shell pane exists and has a foreground command that differs from the user's default shell.
func GetWorktreeInitScript ¶
GetWorktreeInitScript returns the path to the worktree init script for a project. It checks: 1. The init_script configured in .taskyou.yml 2. The conventional bin/worktree-setup script if it exists and is executable Returns empty string if no init script is configured or found.
func GetWorktreeTeardownScript ¶
GetWorktreeTeardownScript returns the path to the worktree teardown script for a project. It checks: 1. The teardown_script configured in .taskyou.yml 2. The conventional bin/worktree-teardown script if it exists and is executable Returns empty string if no teardown script is configured or found.
func HasRunningProcessInTaskUI ¶
func HasRunningProcessInTaskUI() bool
HasRunningProcessInTaskUI checks if the task-ui session has a running process in the shell pane (pane index 2). This is used to detect running processes for the currently viewed task, whose panes are joined to task-ui rather than being in the daemon.
func PurgeStaleClaudeProjectConfigs ¶
PurgeStaleClaudeProjectConfigs removes entries from claude.json for paths that no longer exist. Returns the number of entries removed and any error encountered.
func RemoveClaudeProjectConfig ¶
RemoveClaudeProjectConfig removes a project entry from claude.json. This should be called when deleting a worktree to clean up stale config entries.
func RenameClaudeSession ¶
RenameClaudeSession renames the Claude session for a given workDir to the new name. It uses Claude's /rename slash command via print mode. This is useful when a task title changes and we want the Claude session to reflect it.
func ResolveClaudeConfigDir ¶
ResolveClaudeConfigDir resolves a custom CLAUDE_CONFIG_DIR override. If custom is empty, the default directory (respecting CLAUDE_CONFIG_DIR env) is returned.
func SendKeyToPane ¶
SendKeyToPane sends a key sequence to a task's executor tmux pane. Used for quick approve/deny from the kanban view.
func TmuxSessionName ¶
TmuxSessionName returns the full tmux target for a task (session:window).
func TmuxWindowName ¶
TmuxWindowName returns the window name for a task.
Types ¶
type ClaudeExecutor ¶
type ClaudeExecutor struct {
// contains filtered or unexported fields
}
ClaudeExecutor implements TaskExecutor for Claude Code CLI. This wraps the existing Claude execution logic in executor.go.
func NewClaudeExecutor ¶
func NewClaudeExecutor(e *Executor) *ClaudeExecutor
NewClaudeExecutor creates a new Claude executor.
func (*ClaudeExecutor) BuildCommand ¶
func (c *ClaudeExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive Claude session.
func (*ClaudeExecutor) Execute ¶
func (c *ClaudeExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using Claude Code CLI.
func (*ClaudeExecutor) FindSessionID ¶
func (c *ClaudeExecutor) FindSessionID(workDir string) string
FindSessionID discovers the most recent Claude session ID for the given workDir.
func (*ClaudeExecutor) GetProcessID ¶
func (c *ClaudeExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the Claude process for a task.
func (*ClaudeExecutor) IsAvailable ¶
func (c *ClaudeExecutor) IsAvailable() bool
IsAvailable checks if the claude CLI is installed.
func (*ClaudeExecutor) IsSuspended ¶
func (c *ClaudeExecutor) IsSuspended(taskID int64) bool
IsSuspended checks if a task's Claude process is suspended.
func (*ClaudeExecutor) Kill ¶
func (c *ClaudeExecutor) Kill(taskID int64) bool
Kill terminates the Claude process for a task.
func (*ClaudeExecutor) Name ¶
func (c *ClaudeExecutor) Name() string
Name returns the executor name.
func (*ClaudeExecutor) Resume ¶
func (c *ClaudeExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume resumes a previous Claude session with feedback.
func (*ClaudeExecutor) ResumeDangerous ¶
func (c *ClaudeExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous kills the current Claude process and restarts with --dangerously-skip-permissions.
func (*ClaudeExecutor) ResumeProcess ¶
func (c *ClaudeExecutor) ResumeProcess(taskID int64) bool
ResumeProcess resumes a suspended Claude process.
func (*ClaudeExecutor) ResumeSafe ¶
func (c *ClaudeExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe kills the current Claude process and restarts without --dangerously-skip-permissions.
func (*ClaudeExecutor) SupportsDangerousMode ¶
func (c *ClaudeExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns true - Claude supports --dangerously-skip-permissions.
func (*ClaudeExecutor) SupportsSessionResume ¶
func (c *ClaudeExecutor) SupportsSessionResume() bool
SupportsSessionResume returns true - Claude supports session resume via --resume.
func (*ClaudeExecutor) Suspend ¶
func (c *ClaudeExecutor) Suspend(taskID int64) bool
Suspend pauses the Claude process for a task.
type CodexExecutor ¶
type CodexExecutor struct {
// contains filtered or unexported fields
}
CodexExecutor implements TaskExecutor for OpenAI's Codex CLI.
func NewCodexExecutor ¶
func NewCodexExecutor(e *Executor) *CodexExecutor
NewCodexExecutor creates a new Codex executor.
func (*CodexExecutor) BuildCommand ¶
func (c *CodexExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive Codex session.
func (*CodexExecutor) Execute ¶
func (c *CodexExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using Codex CLI.
func (*CodexExecutor) FindSessionID ¶
func (c *CodexExecutor) FindSessionID(workDir string) string
FindSessionID discovers the most recent Codex session ID for the given workDir. Codex stores sessions in ~/.codex/sessions/ with project-specific subdirectories.
func (*CodexExecutor) GetProcessID ¶
func (c *CodexExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the Codex process for a task.
func (*CodexExecutor) IsAvailable ¶
func (c *CodexExecutor) IsAvailable() bool
IsAvailable checks if the codex CLI is installed.
func (*CodexExecutor) IsSuspended ¶
func (c *CodexExecutor) IsSuspended(taskID int64) bool
IsSuspended checks if a task's Codex process is suspended.
func (*CodexExecutor) Kill ¶
func (c *CodexExecutor) Kill(taskID int64) bool
Kill terminates the Codex process for a task.
func (*CodexExecutor) Resume ¶
func (c *CodexExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume resumes a previous Codex session with feedback.
func (*CodexExecutor) ResumeDangerous ¶
func (c *CodexExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous kills the current Codex process and restarts with --dangerously-bypass-approvals-and-sandbox.
func (*CodexExecutor) ResumeProcess ¶
func (c *CodexExecutor) ResumeProcess(taskID int64) bool
ResumeProcess resumes a suspended Codex process.
func (*CodexExecutor) ResumeSafe ¶
func (c *CodexExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe kills the current Codex process and restarts without the dangerous flag.
func (*CodexExecutor) SupportsDangerousMode ¶
func (c *CodexExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns true - Codex supports --dangerously-bypass-approvals-and-sandbox.
func (*CodexExecutor) SupportsSessionResume ¶
func (c *CodexExecutor) SupportsSessionResume() bool
SupportsSessionResume returns true - Codex supports session resume via --resume.
func (*CodexExecutor) Suspend ¶
func (c *CodexExecutor) Suspend(taskID int64) bool
Suspend pauses the Codex process for a task.
type ExecResult ¶
type ExecResult struct {
Success bool // Task completed successfully
NeedsInput bool // Task is waiting for user input
Interrupted bool // Task was interrupted by user
Message string // Status message or error
}
ExecResult represents the result of executing a task.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor manages background task execution.
func NewWithLogging ¶
NewWithLogging creates an executor that logs to stderr (for daemon mode).
func (*Executor) AllExecutors ¶
AllExecutors returns the names of all registered executors.
func (*Executor) ArchiveWorktree ¶
ArchiveWorktree saves the complete worktree state (including uncommitted changes) to a git ref and then removes the worktree. This allows the task to be unarchived later with all changes restored.
The archive process: 1. Saves all changes (committed, uncommitted, tracked, untracked) to a git ref 2. Stores the archive state in the database 3. Runs teardown script 4. Removes the worktree with --force
func (*Executor) AvailableExecutors ¶
AvailableExecutors returns the names of all available executors.
func (*Executor) CleanupDuplicateWindows ¶
CleanupDuplicateWindows removes duplicate tmux windows for a task, keeping only the canonical one. This prevents window proliferation that can occur from repeated break-pane operations.
func (*Executor) CleanupStaleWorktreesManual ¶
func (e *Executor) CleanupStaleWorktreesManual(maxAge time.Duration, dryRun bool) ([]*db.Task, error)
CleanupStaleWorktreesManual runs stale worktree cleanup on demand and returns the list of tasks that were cleaned up. If dryRun is true, no changes are made.
func (*Executor) CleanupWorktree ¶
CleanupWorktree removes a task's worktree.
func (*Executor) DisplayName ¶
DisplayName returns the configured executor display name.
func (*Executor) ExecuteNow ¶
ExecuteNow runs a task immediately (blocking).
func (*Executor) ExecutorSlug ¶
ExecutorSlug returns the normalized identifier for the executor (e.g., "codex").
func (*Executor) GetExecutor ¶
func (e *Executor) GetExecutor(name string) TaskExecutor
GetExecutor returns the executor for a task by name.
func (*Executor) GetProjectDir ¶
GetProjectDir returns the directory for a project (exported for UI).
func (*Executor) GetTaskExecutor ¶
func (e *Executor) GetTaskExecutor(task *db.Task) TaskExecutor
GetTaskExecutor returns the executor for a specific task.
func (*Executor) Interrupt ¶
Interrupt cancels a running task. If running in this process, cancels directly. Also marks in DB for cross-process interrupt.
func (*Executor) IsClaudeRunning ¶
IsClaudeRunning checks if a Claude process is running for a task.
func (*Executor) IsSuspended ¶
IsSuspended checks if a task is currently suspended.
func (*Executor) KillClaudeProcess ¶
KillClaudeProcess terminates the Claude process for a task to free up memory. This is called when a task is completed, closed, or deleted. Exported for use by the UI when deleting tasks.
func (*Executor) KillPiProcess ¶
KillPiProcess terminates the Pi process for a task to free up memory.
func (*Executor) NotifyTaskChange ¶
NotifyTaskChange notifies subscribers of a task change (for use by UI/other components). If the task is newly queued, it also triggers immediate processing so the executor starts without waiting for the next poll cycle.
func (*Executor) RenameClaudeSessionForTask ¶
RenameClaudeSessionForTask renames the Claude session for a task if it has a worktree. This is a convenience method that handles the common case of renaming based on task.
func (*Executor) ResumeDangerous ¶
ResumeDangerous kills the current executor process and restarts it with dangerous mode enabled. This allows switching a running task to dangerous mode without restarting the daemon. Returns true if successfully restarted, false otherwise. This is executor-aware and will delegate to the appropriate executor's implementation.
func (*Executor) ResumeSafe ¶
ResumeSafe kills the current executor process and restarts it with dangerous mode disabled. This allows switching a running task back from dangerous mode to safe mode. Returns true if successfully restarted, false otherwise. This is executor-aware and will delegate to the appropriate executor's implementation.
func (*Executor) ResumeTask ¶
ResumeTask resumes a suspended task's Claude process using SIGCONT. Returns true if successfully resumed.
func (*Executor) RunningTasks ¶
RunningTasks returns the IDs of currently processing tasks.
func (*Executor) SubscribeTaskEvents ¶
SubscribeTaskEvents subscribes to task change events (status changes, etc.).
func (*Executor) SuspendTask ¶
SuspendTask suspends a task's Claude process using SIGTSTP (same as Ctrl+Z) to save memory. Returns true if successfully suspended.
func (*Executor) TriggerProcessing ¶
func (e *Executor) TriggerProcessing()
TriggerProcessing wakes up the worker loop to process queued tasks immediately. This is a non-blocking operation; if a wakeup is already pending, the call is a no-op.
func (*Executor) UnarchiveWorktree ¶
UnarchiveWorktree recreates a worktree from saved archive state and restores all changes (including uncommitted changes that were saved during archiving).
The unarchive process: 1. Recreates the worktree (handling edge cases like branch deleted, dir taken, etc.) 2. Restores changes from the archive ref 3. Runs init script 4. Clears the archive state from the database
func (*Executor) Unsubscribe ¶
Unsubscribe from log updates.
func (*Executor) UnsubscribeTaskEvents ¶
UnsubscribeTaskEvents unsubscribes from task events.
type ExecutorFactory ¶
type ExecutorFactory struct {
// contains filtered or unexported fields
}
ExecutorFactory manages creation of task executors.
func NewExecutorFactory ¶
func NewExecutorFactory() *ExecutorFactory
NewExecutorFactory creates a new executor factory.
func (*ExecutorFactory) All ¶
func (f *ExecutorFactory) All() []string
All returns all registered executor names.
func (*ExecutorFactory) Available ¶
func (f *ExecutorFactory) Available() []string
Available returns the names of all registered executors that are available.
func (*ExecutorFactory) Get ¶
func (f *ExecutorFactory) Get(name string) TaskExecutor
Get returns the executor for the given name, or nil if not found.
func (*ExecutorFactory) Register ¶
func (f *ExecutorFactory) Register(executor TaskExecutor)
Register adds an executor to the factory.
type GeminiExecutor ¶
type GeminiExecutor struct {
// contains filtered or unexported fields
}
GeminiExecutor implements TaskExecutor for Google's Gemini CLI.
func NewGeminiExecutor ¶
func NewGeminiExecutor(e *Executor) *GeminiExecutor
NewGeminiExecutor creates a new Gemini executor.
func (*GeminiExecutor) BuildCommand ¶
func (g *GeminiExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive Gemini session.
func (*GeminiExecutor) Execute ¶
func (g *GeminiExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using the Gemini CLI.
func (*GeminiExecutor) FindSessionID ¶
func (g *GeminiExecutor) FindSessionID(workDir string) string
FindSessionID discovers the most recent Gemini session ID for the given workDir. Gemini stores sessions in ~/.gemini/tmp/<project_hash>/chats/ directory.
func (*GeminiExecutor) GetProcessID ¶
func (g *GeminiExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the Gemini process for a task.
func (*GeminiExecutor) IsAvailable ¶
func (g *GeminiExecutor) IsAvailable() bool
IsAvailable checks if the gemini CLI is installed.
func (*GeminiExecutor) IsSuspended ¶
func (g *GeminiExecutor) IsSuspended(taskID int64) bool
IsSuspended reports whether the Gemini process is suspended for a task.
func (*GeminiExecutor) Kill ¶
func (g *GeminiExecutor) Kill(taskID int64) bool
Kill terminates the Gemini process for a task.
func (*GeminiExecutor) Name ¶
func (g *GeminiExecutor) Name() string
Name returns the executor name.
func (*GeminiExecutor) Resume ¶
func (g *GeminiExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume runs Gemini again with the full prompt plus feedback since sessions are stateless.
func (*GeminiExecutor) ResumeDangerous ¶
func (g *GeminiExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous kills the current Gemini process and restarts with --dangerously-allow-run.
func (*GeminiExecutor) ResumeProcess ¶
func (g *GeminiExecutor) ResumeProcess(taskID int64) bool
ResumeProcess resumes a previously suspended Gemini process.
func (*GeminiExecutor) ResumeSafe ¶
func (g *GeminiExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe kills the current Gemini process and restarts without the dangerous flag.
func (*GeminiExecutor) SupportsDangerousMode ¶
func (g *GeminiExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns true - Gemini supports --dangerously-allow-run.
func (*GeminiExecutor) SupportsSessionResume ¶
func (g *GeminiExecutor) SupportsSessionResume() bool
SupportsSessionResume returns true - Gemini supports session resume via --resume.
func (*GeminiExecutor) Suspend ¶
func (g *GeminiExecutor) Suspend(taskID int64) bool
Suspend pauses the Gemini process for a task.
type OpenClawExecutor ¶
type OpenClawExecutor struct {
// contains filtered or unexported fields
}
OpenClawExecutor implements TaskExecutor for OpenClaw AI assistant. OpenClaw is an open-source personal AI assistant that runs locally, capable of automating tasks across your digital life. See: https://openclaw.ai
CLI Reference (using openclaw tui for interactive terminal UI):
- openclaw tui --session <key> - Connect to a session
- openclaw tui --message "prompt" - Send initial message after connecting
- openclaw tui --thinking <level> - Set reasoning depth (off/minimal/low/medium/high)
func NewOpenClawExecutor ¶
func NewOpenClawExecutor(e *Executor) *OpenClawExecutor
NewOpenClawExecutor creates a new OpenClaw executor.
func (*OpenClawExecutor) BuildCommand ¶
func (o *OpenClawExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive OpenClaw session.
func (*OpenClawExecutor) Execute ¶
func (o *OpenClawExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using the OpenClaw CLI.
func (*OpenClawExecutor) FindSessionID ¶
func (o *OpenClawExecutor) FindSessionID(workDir string) string
FindSessionID returns the session key for the given task. OpenClaw uses explicit session keys rather than auto-discovering from files.
func (*OpenClawExecutor) GetProcessID ¶
func (o *OpenClawExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the OpenClaw process for a task.
func (*OpenClawExecutor) IsAvailable ¶
func (o *OpenClawExecutor) IsAvailable() bool
IsAvailable checks if the openclaw CLI is installed.
func (*OpenClawExecutor) IsSuspended ¶
func (o *OpenClawExecutor) IsSuspended(taskID int64) bool
IsSuspended reports whether the OpenClaw process is suspended for a task.
func (*OpenClawExecutor) Kill ¶
func (o *OpenClawExecutor) Kill(taskID int64) bool
Kill terminates the OpenClaw process for a task.
func (*OpenClawExecutor) Name ¶
func (o *OpenClawExecutor) Name() string
Name returns the executor name.
func (*OpenClawExecutor) Resume ¶
func (o *OpenClawExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume resumes a previous session using OpenClaw's --session-id flag. If no session ID exists, starts fresh with the full prompt + feedback.
func (*OpenClawExecutor) ResumeDangerous ¶
func (o *OpenClawExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous is not supported for OpenClaw as it doesn't have a dangerous mode flag.
func (*OpenClawExecutor) ResumeProcess ¶
func (o *OpenClawExecutor) ResumeProcess(taskID int64) bool
ResumeProcess resumes a previously suspended OpenClaw process.
func (*OpenClawExecutor) ResumeSafe ¶
func (o *OpenClawExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe is not supported for OpenClaw as it doesn't have a dangerous mode flag.
func (*OpenClawExecutor) SupportsDangerousMode ¶
func (o *OpenClawExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns false - OpenClaw does not currently have a dangerous mode flag. Users can configure OpenClaw's permissions through its own settings.
func (*OpenClawExecutor) SupportsSessionResume ¶
func (o *OpenClawExecutor) SupportsSessionResume() bool
SupportsSessionResume returns true - OpenClaw supports session resume via --session.
func (*OpenClawExecutor) Suspend ¶
func (o *OpenClawExecutor) Suspend(taskID int64) bool
Suspend pauses the OpenClaw process for a task.
type OpenCodeExecutor ¶
type OpenCodeExecutor struct {
// contains filtered or unexported fields
}
OpenCodeExecutor implements TaskExecutor for OpenCode AI assistant. OpenCode is an open-source AI coding assistant that runs in terminal, IDE, or desktop. It supports multiple LLM providers including Claude, GPT, and Gemini. See: https://opencode.ai
CLI Reference:
- opencode - Start interactive TUI session
- Supports @-symbol fuzzy search for file references
- Plan mode (Tab) for review before implementation
- /init - Analyze project and generate AGENTS.md
- /undo, /redo - Revert or restore changes
- /share - Generate shareable conversation links
func NewOpenCodeExecutor ¶
func NewOpenCodeExecutor(e *Executor) *OpenCodeExecutor
NewOpenCodeExecutor creates a new OpenCode executor.
func (*OpenCodeExecutor) BuildCommand ¶
func (o *OpenCodeExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive OpenCode session.
func (*OpenCodeExecutor) Execute ¶
func (o *OpenCodeExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using the OpenCode CLI.
func (*OpenCodeExecutor) FindSessionID ¶
func (o *OpenCodeExecutor) FindSessionID(workDir string) string
FindSessionID returns empty - OpenCode doesn't support session discovery.
func (*OpenCodeExecutor) GetProcessID ¶
func (o *OpenCodeExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the OpenCode process for a task.
func (*OpenCodeExecutor) IsAvailable ¶
func (o *OpenCodeExecutor) IsAvailable() bool
IsAvailable checks if the opencode CLI is installed.
func (*OpenCodeExecutor) IsSuspended ¶
func (o *OpenCodeExecutor) IsSuspended(taskID int64) bool
IsSuspended reports whether the OpenCode process is suspended for a task.
func (*OpenCodeExecutor) Kill ¶
func (o *OpenCodeExecutor) Kill(taskID int64) bool
Kill terminates the OpenCode process for a task.
func (*OpenCodeExecutor) Name ¶
func (o *OpenCodeExecutor) Name() string
Name returns the executor name.
func (*OpenCodeExecutor) Resume ¶
func (o *OpenCodeExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume resumes a previous session with feedback. OpenCode doesn't have explicit session resumption, so we replay full prompt + feedback.
func (*OpenCodeExecutor) ResumeDangerous ¶
func (o *OpenCodeExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous is not supported for OpenCode as it doesn't have a dangerous mode flag.
func (*OpenCodeExecutor) ResumeProcess ¶
func (o *OpenCodeExecutor) ResumeProcess(taskID int64) bool
ResumeProcess resumes a previously suspended OpenCode process.
func (*OpenCodeExecutor) ResumeSafe ¶
func (o *OpenCodeExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe is not supported for OpenCode as it doesn't have a dangerous mode flag.
func (*OpenCodeExecutor) SupportsDangerousMode ¶
func (o *OpenCodeExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns false - OpenCode does not currently have a dangerous mode flag. It runs in an interactive TUI and requires user interaction for actions.
func (*OpenCodeExecutor) SupportsSessionResume ¶
func (o *OpenCodeExecutor) SupportsSessionResume() bool
SupportsSessionResume returns false - OpenCode doesn't have explicit session resume. Conversations can be shared via /share but not resumed from command line.
func (*OpenCodeExecutor) Suspend ¶
func (o *OpenCodeExecutor) Suspend(taskID int64) bool
Suspend pauses the OpenCode process for a task.
type PiExecutor ¶
type PiExecutor struct {
// contains filtered or unexported fields
}
PiExecutor implements TaskExecutor for Pi coding agent.
func NewPiExecutor ¶
func NewPiExecutor(e *Executor) *PiExecutor
NewPiExecutor creates a new Pi executor.
func (*PiExecutor) BuildCommand ¶
func (p *PiExecutor) BuildCommand(task *db.Task, sessionID, prompt string) string
BuildCommand returns the shell command to start an interactive Pi session.
func (*PiExecutor) Execute ¶
func (p *PiExecutor) Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
Execute runs a task using Pi.
func (*PiExecutor) FindSessionID ¶
func (p *PiExecutor) FindSessionID(workDir string) string
FindSessionID discovers the most recent Pi session ID for the given workDir.
func (*PiExecutor) GetProcessID ¶
func (p *PiExecutor) GetProcessID(taskID int64) int
GetProcessID returns the PID of the Pi process for a task.
func (*PiExecutor) IsAvailable ¶
func (p *PiExecutor) IsAvailable() bool
IsAvailable checks if the pi CLI is installed.
func (*PiExecutor) IsSuspended ¶
func (p *PiExecutor) IsSuspended(taskID int64) bool
IsSuspended checks if a task's Pi process is suspended.
func (*PiExecutor) Kill ¶
func (p *PiExecutor) Kill(taskID int64) bool
Kill terminates the Pi process for a task.
func (*PiExecutor) Resume ¶
func (p *PiExecutor) Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
Resume resumes a previous Pi session with feedback.
func (*PiExecutor) ResumeDangerous ¶
func (p *PiExecutor) ResumeDangerous(task *db.Task, workDir string) bool
ResumeDangerous is not supported for Pi.
func (*PiExecutor) ResumeSafe ¶
func (p *PiExecutor) ResumeSafe(task *db.Task, workDir string) bool
ResumeSafe is not supported for Pi.
func (*PiExecutor) SupportsDangerousMode ¶
func (p *PiExecutor) SupportsDangerousMode() bool
SupportsDangerousMode returns false - Pi doesn't have a dangerous mode flag.
func (*PiExecutor) SupportsSessionResume ¶
func (p *PiExecutor) SupportsSessionResume() bool
SupportsSessionResume returns true - Pi supports session resume via --continue.
func (*PiExecutor) Suspend ¶
func (p *PiExecutor) Suspend(taskID int64) bool
Suspend pauses the Pi process for a task.
type ProjectConfig ¶
type ProjectConfig struct {
Worktree WorktreeConfig `yaml:"worktree"`
}
ProjectConfig represents the .taskyou.yml configuration file in a project root.
func LoadProjectConfig ¶
func LoadProjectConfig(projectDir string) (*ProjectConfig, error)
LoadProjectConfig loads the project configuration from the given directory. It returns nil if no configuration file exists.
type TaskEvent ¶
type TaskEvent struct {
Type string // "created", "updated", "deleted", "status_changed"
Task *db.Task // The task (may be nil for deleted)
TaskID int64 // Always set
}
TaskEvent represents a change to a task.
type TaskExecutor ¶
type TaskExecutor interface {
// Name returns the executor name (e.g., "claude", "codex")
Name() string
// Execute runs a task with the given prompt and returns the result.
// The workDir is the directory where the executor should run.
Execute(ctx context.Context, task *db.Task, workDir, prompt string) ExecResult
// Resume resumes a previous session with additional feedback.
// If no previous session exists, it should start fresh with the full prompt + feedback.
Resume(ctx context.Context, task *db.Task, workDir, prompt, feedback string) ExecResult
// BuildCommand returns the shell command to start an interactive session.
// This is used by the UI to start the executor in a tmux window.
// The sessionID is optional - if provided, the executor should resume that session if supported.
// The prompt is the task prompt to pass to the executor.
BuildCommand(task *db.Task, sessionID, prompt string) string
// IsAvailable checks if the executor CLI is installed and available.
IsAvailable() bool
// GetProcessID returns the PID of the executor process for a task, or 0 if not running.
GetProcessID(taskID int64) int
// Kill terminates the executor process for a task.
Kill(taskID int64) bool
// Suspend pauses the executor process for a task (to save memory).
Suspend(taskID int64) bool
// IsSuspended checks if a task's executor process is suspended.
IsSuspended(taskID int64) bool
// SupportsSessionResume returns true if the executor supports resuming previous sessions.
// If true, FindSessionID and session-based Resume will work.
SupportsSessionResume() bool
// SupportsDangerousMode returns true if the executor has a "dangerous mode" flag
// that skips permission prompts for autonomous operation.
SupportsDangerousMode() bool
// FindSessionID discovers and returns the most recent session ID for the given workDir.
// Returns empty string if no session is found or sessions aren't supported.
FindSessionID(workDir string) string
// ResumeDangerous kills the current process and restarts with dangerous mode enabled.
// Returns true if successfully restarted. Requires session resume support.
ResumeDangerous(task *db.Task, workDir string) bool
// ResumeSafe kills the current process and restarts with dangerous mode disabled.
// Returns true if successfully restarted. Requires session resume support.
ResumeSafe(task *db.Task, workDir string) bool
}
TaskExecutor defines the interface for task execution backends. Implementations handle the actual running of tasks using different CLI tools.
type WorktreeConfig ¶
type WorktreeConfig struct {
// InitScript is the path to a script that runs after worktree creation.
// Can be relative to the project root (e.g., "bin/worktree-setup").
InitScript string `yaml:"init_script"`
// TeardownScript is the path to a script that runs before worktree deletion.
// Can be relative to the project root (e.g., "bin/worktree-teardown").
TeardownScript string `yaml:"teardown_script"`
}
WorktreeConfig contains worktree-specific configuration.