db

package
v0.2.26 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package db provides SQLite database operations.

Index

Constants

View Source
const (
	StatusBacklog    = "backlog"    // Created but not yet started
	StatusQueued     = "queued"     // Waiting to be processed
	StatusProcessing = "processing" // Currently being executed
	StatusBlocked    = "blocked"    // Needs input/clarification
	StatusDone       = "done"       // Completed
	StatusArchived   = "archived"   // Archived (hidden from view)
)

Task statuses

View Source
const (
	TypeCode     = "code"
	TypeWriting  = "writing"
	TypeThinking = "thinking"
)

Task types (default values, actual types are stored in task_types table)

View Source
const (
	ExecutorClaude   = "claude"   // Claude Code CLI (default)
	ExecutorCodex    = "codex"    // OpenAI Codex CLI
	ExecutorGemini   = "gemini"   // Google Gemini CLI
	ExecutorOpenClaw = "openclaw" // OpenClaw AI assistant (https://openclaw.ai)
	ExecutorOpenCode = "opencode" // OpenCode AI assistant (https://opencode.ai)
	ExecutorPi       = "pi"       // Pi coding agent (https://github.com/mariozechner/pi-coding-agent)
)

Task executors

View Source
const (
	PortRangeStart = 3100 // First port in the allocation range
	PortRangeEnd   = 4099 // Last port in the allocation range (1000 ports total)
)

Port allocation constants

Variables

View Source
var DefaultProjectColors = []string{
	"#C678DD",
	"#61AFEF",
	"#56B6C2",
	"#98C379",
	"#E5C07B",
	"#E06C75",
	"#D19A66",
	"#ABB2BF",
}

DefaultProjectColors is a palette of distinct colors for projects. These are assigned to projects that don't have a color set.

View Source
var ErrProjectNotFound = fmt.Errorf("project not found")

ErrProjectNotFound is returned when a task is created with a non-existent project.

Functions

func DefaultExecutor

func DefaultExecutor() string

DefaultExecutor returns the default executor if none is specified.

func DefaultPath

func DefaultPath() string

DefaultPath returns the default database path.

func IsInProgress

func IsInProgress(status string) bool

IsInProgress returns true if the task is actively being worked on.

Types

type Attachment

type Attachment struct {
	ID        int64
	TaskID    int64
	Filename  string
	MimeType  string
	Size      int64
	Data      []byte
	CreatedAt LocalTime
}

Attachment represents a file attached to a task.

type DB

type DB struct {
	*sql.DB
	// contains filtered or unexported fields
}

DB wraps the SQLite database connection.

func Open

func Open(path string) (*DB, error)

Open opens or creates a SQLite database at the given path.

func (*DB) AddAttachment

func (db *DB) AddAttachment(taskID int64, filename, mimeType string, data []byte) (*Attachment, error)

AddAttachment adds a file attachment to a task.

func (*DB) AddDependency

func (db *DB) AddDependency(blockerID, blockedID int64, autoQueue bool) error

AddDependency creates a dependency where blockerID blocks blockedID. Returns an error if the dependency already exists or would create a cycle.

func (*DB) AllocatePort

func (db *DB) AllocatePort(taskID int64) (int, error)

AllocatePort assigns an available port to a task. Returns the allocated port, or an error if no ports are available.

func (*DB) AppendTaskLog

func (db *DB) AppendTaskLog(taskID int64, lineType, content string) error

AppendTaskLog appends a log entry to a task.

func (*DB) ClearArchiveState

func (db *DB) ClearArchiveState(taskID int64) error

ClearArchiveState clears the archive state for a task after unarchiving.

func (*DB) ClearTaskLogs

func (db *DB) ClearTaskLogs(taskID int64) error

ClearTaskLogs clears all logs for a task.

func (*DB) ClearTaskTmuxIDs

func (db *DB) ClearTaskTmuxIDs(taskID int64) error

ClearTaskTmuxIDs clears all tmux-related IDs for a task. This should be called before retrying/restarting a task to prevent stale references. Clears: tmux_window_id, claude_pane_id, shell_pane_id

func (*DB) ClearTaskWorktreePath

func (db *DB) ClearTaskWorktreePath(taskID int64) error

ClearTaskWorktreePath clears just the worktree_path for a task. Used during async archive cleanup to avoid overwriting other fields.

func (*DB) CompleteOnboarding

func (db *DB) CompleteOnboarding() error

CompleteOnboarding marks the onboarding as complete.

func (*DB) CountAttachments

func (db *DB) CountAttachments(taskID int64) (int, error)

CountAttachments returns the number of attachments for a task.

func (*DB) CountTasksByProject

func (db *DB) CountTasksByProject(projectName string) (int, error)

CountTasksByProject returns the number of tasks associated with a project name.

func (*DB) CountTasksByStatus

func (db *DB) CountTasksByStatus(status string) (int, error)

CountTasksByStatus returns the count of tasks with a given status.

func (*DB) CreateProject

func (db *DB) CreateProject(p *Project) error

CreateProject creates a new project.

func (*DB) CreateTask

func (db *DB) CreateTask(t *Task) error

CreateTask creates a new task.

func (*DB) CreateTaskType

func (db *DB) CreateTaskType(t *TaskType) error

CreateTaskType creates a new task type.

func (*DB) DeleteAttachment

func (db *DB) DeleteAttachment(id int64) error

DeleteAttachment removes an attachment.

func (*DB) DeleteProject

func (db *DB) DeleteProject(id int64) error

DeleteProject deletes a project.

func (*DB) DeleteTask

func (db *DB) DeleteTask(id int64) error

DeleteTask deletes a task.

func (*DB) DeleteTaskType

func (db *DB) DeleteTaskType(id int64) error

DeleteTaskType deletes a task type (only non-builtin types can be deleted).

func (*DB) GetActiveTaskPorts

func (db *DB) GetActiveTaskPorts() (map[int]bool, error)

GetActiveTaskPorts returns all ports currently in use by active (non-done, non-archived) tasks.

func (*DB) GetAllDependencies

func (db *DB) GetAllDependencies(taskID int64) (blockers []*Task, blockedBy []*Task, err error)

GetAllDependencies returns all dependencies for a given task (both blockers and blocked).

func (*DB) GetAllSettings

func (db *DB) GetAllSettings() (map[string]string, error)

GetAllSettings returns all settings as a map.

func (*DB) GetAttachment

func (db *DB) GetAttachment(id int64) (*Attachment, error)

GetAttachment retrieves an attachment by ID.

func (*DB) GetBlockedBy

func (db *DB) GetBlockedBy(taskID int64) ([]*Task, error)

GetBlockedBy returns all tasks that are blocked by the given task.

func (*DB) GetBlockers

func (db *DB) GetBlockers(taskID int64) ([]*Task, error)

GetBlockers returns all tasks that block the given task.

func (*DB) GetConversationHistoryLogs

func (db *DB) GetConversationHistoryLogs(taskID int64) ([]*TaskLog, error)

GetConversationHistoryLogs retrieves only logs relevant for building conversation history. This is much more efficient than GetTaskLogs for the executor's prompt building, as it skips large output/tool log content that isn't needed for conversation context. Only fetches: continuation markers, questions, and user feedback.

func (*DB) GetDependency

func (db *DB) GetDependency(blockerID, blockedID int64) (*Dependency, error)

GetDependency returns the dependency between two tasks, or nil if none exists.

func (*DB) GetExecutorUsageByProject

func (db *DB) GetExecutorUsageByProject(project string) (map[string]int, error)

GetExecutorUsageByProject returns a map of executor names to their usage counts for a project. This counts how many tasks have been created with each executor for the given project.

func (*DB) GetLastExecutorForProject

func (db *DB) GetLastExecutorForProject(project string) (string, error)

GetLastExecutorForProject returns the last used executor for a project.

func (*DB) GetLastQuestion

func (db *DB) GetLastQuestion(taskID int64) (string, error)

GetLastQuestion retrieves the most recent question log for a task.

func (*DB) GetLastTaskTypeForProject

func (db *DB) GetLastTaskTypeForProject(project string) (string, error)

GetLastTaskTypeForProject returns the last used task type for a project.

func (*DB) GetLastUsedProject

func (db *DB) GetLastUsedProject() (string, error)

GetLastUsedProject returns the last used project name.

func (*DB) GetMostRecentlyCreatedTask

func (db *DB) GetMostRecentlyCreatedTask() (*Task, error)

GetMostRecentlyCreatedTask returns the task with the most recent created_at timestamp. This is used to get the last task's project for defaulting in new task forms.

func (*DB) GetNextQueuedTask

func (db *DB) GetNextQueuedTask() (*Task, error)

GetNextQueuedTask returns the next task to process.

func (*DB) GetOpenBlockerCount

func (db *DB) GetOpenBlockerCount(taskID int64) (int, error)

GetOpenBlockerCount returns the number of incomplete blockers for a task.

func (*DB) GetProjectByName

func (db *DB) GetProjectByName(name string) (*Project, error)

GetProjectByName returns a project by name or alias.

func (*DB) GetProjectByPath

func (db *DB) GetProjectByPath(cwd string) (*Project, error)

GetProjectByPath returns a project whose path matches the given directory. It checks if cwd equals or is a subdirectory of any project's path.

func (*DB) GetProjectContext

func (db *DB) GetProjectContext(projectName string) (string, error)

GetProjectContext returns the auto-generated context for a project. This context is cached exploration results that can be reused across tasks.

func (*DB) GetQueuedTasks

func (db *DB) GetQueuedTasks() ([]*Task, error)

GetQueuedTasks returns all queued tasks (waiting to be processed).

func (*DB) GetRetryFeedback

func (db *DB) GetRetryFeedback(taskID int64) (string, error)

GetRetryFeedback returns the feedback from the most recent retry, or empty string if not a retry. Looks for "Feedback: ..." log entry after "--- Continuation ---" marker.

func (*DB) GetSetting

func (db *DB) GetSetting(key string) (string, error)

GetSetting returns a setting value.

func (*DB) GetStaleWorktreeTasks

func (db *DB) GetStaleWorktreeTasks(maxAge time.Duration) ([]*Task, error)

GetStaleWorktreeTasks returns done/archived tasks that have worktree paths set and were completed more than maxAge ago. These are candidates for cleanup.

func (*DB) GetTagsList

func (db *DB) GetTagsList() ([]string, error)

GetTagsList returns all unique tags used across all tasks.

func (*DB) GetTask

func (db *DB) GetTask(id int64) (*Task, error)

GetTask retrieves a task by ID.

func (*DB) GetTaskLogCount

func (db *DB) GetTaskLogCount(taskID int64) (int, error)

GetTaskLogCount returns the number of logs for a task. This is a fast operation useful for checking if logs have changed.

func (*DB) GetTaskLogs

func (db *DB) GetTaskLogs(taskID int64, limit int) ([]*TaskLog, error)

GetTaskLogs retrieves logs for a task.

func (*DB) GetTaskLogsSince

func (db *DB) GetTaskLogsSince(taskID int64, sinceID int64) ([]*TaskLog, error)

GetTaskLogsSince retrieves logs after a given ID.

func (*DB) GetTaskType

func (db *DB) GetTaskType(id int64) (*TaskType, error)

GetTaskType retrieves a task type by ID.

func (*DB) GetTaskTypeByName

func (db *DB) GetTaskTypeByName(name string) (*TaskType, error)

GetTaskTypeByName retrieves a task type by name.

func (*DB) HasContinuationMarker

func (db *DB) HasContinuationMarker(taskID int64) (bool, error)

HasContinuationMarker checks if a task has any continuation markers. This is a fast EXISTS-style query to avoid loading logs just to check.

func (*DB) IsBlocked

func (db *DB) IsBlocked(taskID int64) (bool, error)

IsBlocked returns true if the task has any incomplete blockers.

func (*DB) IsFirstRun

func (db *DB) IsFirstRun() bool

IsFirstRun returns true if this is the first time the app is being used. This is determined by checking if onboarding has been completed.

func (*DB) ListAttachments

func (db *DB) ListAttachments(taskID int64) ([]*Attachment, error)

ListAttachments retrieves all attachments for a task (without data for efficiency).

func (*DB) ListAttachmentsWithData

func (db *DB) ListAttachmentsWithData(taskID int64) ([]*Attachment, error)

ListAttachmentsWithData retrieves all attachments for a task including data.

func (*DB) ListProjects

func (db *DB) ListProjects() ([]*Project, error)

ListProjects returns all projects, with "personal" always first.

func (*DB) ListTaskTypes

func (db *DB) ListTaskTypes() ([]*TaskType, error)

ListTaskTypes returns all task types ordered by sort_order.

func (*DB) ListTasks

func (db *DB) ListTasks(opts ListTasksOptions) ([]*Task, error)

ListTasks retrieves tasks with optional filters.

func (*DB) MarkTaskStarted

func (db *DB) MarkTaskStarted(id int64) error

MarkTaskStarted sets the started_at timestamp if not already set.

func (*DB) Path

func (db *DB) Path() string

Path returns the path to the database file.

func (*DB) ProcessCompletedBlocker

func (db *DB) ProcessCompletedBlocker(blockerID int64) ([]*Task, error)

ProcessCompletedBlocker checks tasks blocked by the completed task and updates their status if they become unblocked. Returns the list of tasks that were unblocked.

func (*DB) RecoverStaleTmuxRefs

func (db *DB) RecoverStaleTmuxRefs(activeSessions map[string]bool, validWindowIDs map[string]bool) (int, int, error)

RecoverStaleTmuxRefs clears stale daemon_session and tmux_window_id references from tasks. Called automatically on daemon startup to recover from crashes. Returns (staleDaemonCount, staleWindowCount) of cleaned references.

func (*DB) RemoveDependency

func (db *DB) RemoveDependency(blockerID, blockedID int64) error

RemoveDependency removes a dependency between two tasks.

func (*DB) RetryTask

func (db *DB) RetryTask(id int64, feedback string) error

RetryTask clears logs, appends feedback to body, and re-queues a task. Also clears stale tmux window/pane IDs to prevent duplicate window issues.

func (*DB) SaveArchiveState

func (db *DB) SaveArchiveState(taskID int64, archiveRef, archiveCommit, worktreePath, branchName string) error

SaveArchiveState saves the archive state for a task. This stores the git ref, commit hash, worktree path, and branch name that were active at the time of archiving.

func (*DB) SearchTasks

func (db *DB) SearchTasks(query string, limit int) ([]*Task, error)

SearchTasks searches for tasks by query string across title, project, ID, and PR number. This is used by the command palette to search all tasks, not just the preloaded ones.

func (*DB) SetAutoQueue

func (db *DB) SetAutoQueue(blockerID, blockedID int64, autoQueue bool) error

SetAutoQueue updates the auto_queue flag for a dependency.

func (*DB) SetEventEmitter

func (db *DB) SetEventEmitter(emitter EventEmitter)

SetEventEmitter sets the event emitter for this database. This is called by the executor to enable event emission.

func (*DB) SetLastExecutorForProject

func (db *DB) SetLastExecutorForProject(project, executor string) error

SetLastExecutorForProject saves the last used executor for a project.

func (*DB) SetLastTaskTypeForProject

func (db *DB) SetLastTaskTypeForProject(project, taskType string) error

SetLastTaskTypeForProject saves the last used task type for a project.

func (*DB) SetLastUsedProject

func (db *DB) SetLastUsedProject(project string) error

SetLastUsedProject saves the last used project name.

func (*DB) SetProjectContext

func (db *DB) SetProjectContext(projectName string, context string) error

SetProjectContext saves auto-generated context for a project. This overwrites any existing context.

func (*DB) SetSetting

func (db *DB) SetSetting(key, value string) error

SetSetting sets a setting value.

func (*DB) UpdateProject

func (db *DB) UpdateProject(p *Project) error

UpdateProject updates a project.

func (*DB) UpdateTask

func (db *DB) UpdateTask(t *Task) error

UpdateTask updates a task's fields.

func (*DB) UpdateTaskClaudeSessionID

func (db *DB) UpdateTaskClaudeSessionID(taskID int64, sessionID string) error

UpdateTaskClaudeSessionID updates only the Claude session ID for a task.

func (*DB) UpdateTaskDaemonSession

func (db *DB) UpdateTaskDaemonSession(taskID int64, daemonSession string) error

UpdateTaskDaemonSession updates the tmux daemon session name for a task. This is used to track which daemon session owns the task's tmux window, so we can properly kill the Claude process when the task completes.

func (*DB) UpdateTaskDangerousMode

func (db *DB) UpdateTaskDangerousMode(taskID int64, dangerousMode bool) error

UpdateTaskDangerousMode updates only the dangerous_mode flag for a task.

func (*DB) UpdateTaskLastAccessedAt

func (db *DB) UpdateTaskLastAccessedAt(taskID int64) error

UpdateTaskLastAccessedAt updates the last_accessed_at timestamp for a task. This is used to track when a task was last accessed/opened in the UI, enabling the command palette to show recently visited tasks first.

func (*DB) UpdateTaskPRInfo

func (db *DB) UpdateTaskPRInfo(taskID int64, prURL string, prNumber int, prInfoJSON string) error

UpdateTaskPRInfo updates only the PR-related fields for a task. This is used to persist PR state from GitHub API responses without touching other fields.

func (*DB) UpdateTaskPaneIDs

func (db *DB) UpdateTaskPaneIDs(taskID int64, claudePaneID, shellPaneID string) error

UpdateTaskPaneIDs updates the tmux pane IDs for a task. This is used to track the unique pane IDs (e.g., "%1234") for reliable pane identification when joining/breaking panes between the daemon and the TUI.

func (*DB) UpdateTaskPinned

func (db *DB) UpdateTaskPinned(taskID int64, pinned bool) error

UpdateTaskPinned updates only the pinned flag for a task.

func (*DB) UpdateTaskStartedAt

func (db *DB) UpdateTaskStartedAt(taskID int64, t time.Time) error

UpdateTaskStartedAt updates the started_at timestamp for a task. This is primarily used for testing.

func (*DB) UpdateTaskStatus

func (db *DB) UpdateTaskStatus(id int64, status string) error

UpdateTaskStatus updates a task's status.

func (*DB) UpdateTaskSummary

func (db *DB) UpdateTaskSummary(taskID int64, summary string) error

UpdateTaskSummary updates the task summary and distillation timestamp.

func (*DB) UpdateTaskType

func (db *DB) UpdateTaskType(t *TaskType) error

UpdateTaskType updates a task type.

func (*DB) UpdateTaskWindowID

func (db *DB) UpdateTaskWindowID(taskID int64, windowID string) error

UpdateTaskWindowID updates the tmux window ID for a task. This is used to track the unique window ID (e.g., "@1234") for reliable window targeting.

type Dependency

type Dependency struct {
	ID        int64     `json:"id"`
	BlockerID int64     `json:"blocker_id"`
	BlockedID int64     `json:"blocked_id"`
	AutoQueue bool      `json:"auto_queue"` // If true, auto-queue blocked task when unblocked
	CreatedAt time.Time `json:"created_at"`
}

Dependency represents a blocking relationship between two tasks. The blocker task must be completed before the blocked task can proceed.

type EventEmitter

type EventEmitter interface {
	EmitTaskCreated(task *Task)
	EmitTaskUpdated(task *Task, changes map[string]interface{})
	EmitTaskDeleted(taskID int64, title string)
	EmitTaskPinned(task *Task)
	EmitTaskUnpinned(task *Task)
}

EventEmitter is an interface for emitting task events. This allows the DB to emit events without depending on the events package.

type ListTasksOptions

type ListTasksOptions struct {
	Status        string
	Type          string
	Project       string
	Limit         int
	Offset        int
	IncludeClosed bool // Include closed tasks even when Status is empty
}

ListTasksOptions defines options for listing tasks.

type LocalTime

type LocalTime struct {
	time.Time
}

LocalTime wraps time.Time and converts from UTC to local timezone when scanning.

func (*LocalTime) Scan

func (lt *LocalTime) Scan(value interface{}) error

Scan implements sql.Scanner, converting scanned time to local timezone.

func (LocalTime) Value

func (lt LocalTime) Value() (driver.Value, error)

Value implements driver.Valuer for inserting LocalTime into database.

type Project

type Project struct {
	ID              int64
	Name            string
	Path            string
	Aliases         string          // comma-separated
	Instructions    string          // project-specific instructions for AI
	Actions         []ProjectAction // actions triggered on task events (stored as JSON)
	Color           string          // hex color for display (e.g., "#61AFEF")
	ClaudeConfigDir string          // override CLAUDE_CONFIG_DIR for this project
	UseWorktrees    bool            // whether to use git worktrees for task isolation (default true)
	CreatedAt       LocalTime
}

Project represents a configured project.

func (*Project) GetAction

func (p *Project) GetAction(trigger string) *ProjectAction

GetAction returns the action for a given trigger, or nil if not found.

func (*Project) UsesWorktrees

func (p *Project) UsesWorktrees() bool

UsesWorktrees returns whether this project uses git worktrees for task isolation. Defaults to true for backward compatibility.

type ProjectAction

type ProjectAction struct {
	Trigger      string `json:"trigger"`      // "on_create", "on_status:queued", etc.
	Instructions string `json:"instructions"` // prompt/instructions for this action
}

ProjectAction defines an action that runs on tasks for a project.

type Task

type Task struct {
	ID              int64
	Title           string
	Body            string
	Status          string
	Type            string
	Project         string
	Executor        string // Task executor: "claude" (default), "codex", "gemini"
	WorktreePath    string
	BranchName      string
	Port            int    // Unique port for running the application in this task's worktree
	ClaudeSessionID string // Claude session ID for resuming conversations
	DaemonSession   string // tmux daemon session name (e.g., "task-daemon-12345")
	TmuxWindowID    string // tmux window ID (e.g., "@1234") for unique window identification
	ClaudePaneID    string // tmux pane ID (e.g., "%1234") for the Claude/executor pane
	ShellPaneID     string // tmux pane ID (e.g., "%1235") for the shell pane
	PRURL           string // Pull request URL (if associated with a PR)
	PRNumber        int    // Pull request number (if associated with a PR)
	PRInfoJSON      string // Cached PR state as JSON (state, checks, mergeable, etc.)
	DangerousMode   bool   // Whether task is running in dangerous mode (--dangerously-skip-permissions)
	Pinned          bool   // Whether the task is pinned to the top of its column
	Tags            string // Comma-separated tags for categorization (e.g., "customer-support,email,influence-kit")
	SourceBranch    string // Existing branch to checkout for worktree (e.g., "fix/ui-overflow") instead of creating new branch
	Summary         string // Distilled summary of what was accomplished (for search and context)
	CreatedAt       LocalTime
	UpdatedAt       LocalTime
	StartedAt       *LocalTime
	CompletedAt     *LocalTime
	// Distillation tracking
	LastDistilledAt *LocalTime // When task was last distilled for learnings
	// UI tracking
	LastAccessedAt *LocalTime // When task was last accessed/opened in the UI
	// Archive state for preserving worktree state when archiving
	ArchiveRef          string // Git ref storing stashed changes (e.g., "refs/task-archive/123")
	ArchiveCommit       string // Commit hash at time of archiving
	ArchiveWorktreePath string // Original worktree path before archiving
	ArchiveBranchName   string // Original branch name before archiving
}

Task represents a task in the database.

func (*Task) HasArchiveState

func (t *Task) HasArchiveState() bool

HasArchiveState returns true if the task has saved archive state.

type TaskLog

type TaskLog struct {
	ID        int64
	TaskID    int64
	LineType  string // "output", "tool", "error", "system"
	Content   string
	CreatedAt LocalTime
}

TaskLog represents a log entry for a task.

type TaskType

type TaskType struct {
	ID           int64
	Name         string // e.g., "code", "writing", "thinking"
	Label        string // Display label
	Instructions string // Prompt template for this type
	SortOrder    int    // For UI ordering
	IsBuiltin    bool   // Protect default types from deletion
	CreatedAt    LocalTime
}

TaskType represents a configurable task type with its prompt instructions.

Jump to

Keyboard shortcuts

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