Documentation
¶
Index ¶
- Constants
- Variables
- func ClearAgentErrors(baseDir string) error
- func ClearSecurityEvents(baseDir string) error
- func CountAgentErrors(baseDir string) (int, error)
- func LogAgentError(baseDir string, args []string, errMsg string, sessionID string) error
- func LogSecurityEvent(baseDir string, event SecurityEvent) error
- func NormalizeIssueID(id string) string
- type AgentError
- type DB
- func (db *DB) AddComment(comment *models.Comment) error
- func (db *DB) AddDependency(issueID, dependsOnID, relationType string) error
- func (db *DB) AddGitSnapshot(snapshot *models.GitSnapshot) error
- func (db *DB) AddHandoff(handoff *models.Handoff) error
- func (db *DB) AddLog(log *models.Log) error
- func (db *DB) BaseDir() string
- func (db *DB) CascadeUpParentStatus(issueID string, targetStatus models.Status, sessionID string) (int, []string)
- func (db *DB) Close() error
- func (db *DB) CreateIssue(issue *models.Issue) error
- func (db *DB) CreateWorkSession(ws *models.WorkSession) error
- func (db *DB) DeleteHandoff(handoffID int64) error
- func (db *DB) DeleteIssue(id string) error
- func (db *DB) GetActiveSessions(since time.Time) ([]string, error)
- func (db *DB) GetBlockedBy(issueID string) ([]string, error)
- func (db *DB) GetComments(issueID string) ([]models.Comment, error)
- func (db *DB) GetDependencies(issueID string) ([]string, error)
- func (db *DB) GetDescendantIssues(issueID string, statuses []models.Status) ([]*models.Issue, error)
- func (db *DB) GetDirectChildren(issueID string) ([]*models.Issue, error)
- func (db *DB) GetExtendedStats() (*models.ExtendedStats, error)
- func (db *DB) GetIssue(id string) (*models.Issue, error)
- func (db *DB) GetIssueSessionLog(sessionID string) ([]string, error)
- func (db *DB) GetLastAction(sessionID string) (*models.ActionLog, error)
- func (db *DB) GetLatestHandoff(issueID string) (*models.Handoff, error)
- func (db *DB) GetLinkedFiles(issueID string) ([]models.IssueFile, error)
- func (db *DB) GetLogs(issueID string, limit int) ([]models.Log, error)
- func (db *DB) GetLogsByWorkSession(wsID string) ([]models.Log, error)
- func (db *DB) GetRecentActions(sessionID string, limit int) ([]models.ActionLog, error)
- func (db *DB) GetRecentActionsAll(limit int) ([]models.ActionLog, error)
- func (db *DB) GetRecentCommentsAll(limit int) ([]models.Comment, error)
- func (db *DB) GetRecentHandoffs(limit int, since time.Time) ([]models.Handoff, error)
- func (db *DB) GetRecentLogsAll(limit int) ([]models.Log, error)
- func (db *DB) GetSchemaVersion() (int, error)
- func (db *DB) GetSessionHistory(issueID string) ([]models.IssueSessionHistory, error)
- func (db *DB) GetStartSnapshot(issueID string) (*models.GitSnapshot, error)
- func (db *DB) GetStats() (map[string]int, error)
- func (db *DB) GetWorkSession(id string) (*models.WorkSession, error)
- func (db *DB) GetWorkSessionIssues(wsID string) ([]string, error)
- func (db *DB) HasChildren(issueID string) (bool, error)
- func (db *DB) LinkFile(issueID, filePath string, role models.FileRole, sha string) error
- func (db *DB) ListIssues(opts ListIssuesOptions) ([]models.Issue, error)
- func (db *DB) ListWorkSessions(limit int) ([]models.WorkSession, error)
- func (db *DB) LogAction(action *models.ActionLog) error
- func (db *DB) MarkActionUndone(actionID int64) error
- func (db *DB) RecordSessionAction(issueID, sessionID string, action models.IssueSessionAction) error
- func (db *DB) RemoveDependency(issueID, dependsOnID string) error
- func (db *DB) RestoreIssue(id string) error
- func (db *DB) RunMigrations() (int, error)
- func (db *DB) SearchIssues(query string, opts ListIssuesOptions) ([]models.Issue, error)
- func (db *DB) SearchIssuesRanked(query string, opts ListIssuesOptions) ([]SearchResult, error)
- func (db *DB) SetSchemaVersion(version int) error
- func (db *DB) TagIssueToWorkSession(wsID, issueID string) error
- func (db *DB) UnlinkFile(issueID, filePath string) error
- func (db *DB) UntagIssueFromWorkSession(wsID, issueID string) error
- func (db *DB) UpdateIssue(issue *models.Issue) error
- func (db *DB) UpdateWorkSession(ws *models.WorkSession) error
- func (db *DB) WasSessionInvolved(issueID, sessionID string) (bool, error)
- type ListIssuesOptions
- type Migration
- type SearchResult
- type SecurityEvent
Constants ¶
const SchemaVersion = 7
SchemaVersion is the current database schema version
Variables ¶
var Migrations = []Migration{
{
Version: 2,
Description: "Add action_log table for undo support",
SQL: `
CREATE TABLE IF NOT EXISTS action_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
action_type TEXT NOT NULL,
entity_type TEXT NOT NULL,
entity_id TEXT NOT NULL,
previous_data TEXT DEFAULT '',
new_data TEXT DEFAULT '',
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
undone INTEGER DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_action_log_session ON action_log(session_id);
CREATE INDEX IF NOT EXISTS idx_action_log_timestamp ON action_log(timestamp);
`,
},
{
Version: 3,
Description: "Allow work session logs without issue_id",
SQL: `
-- SQLite doesn't support ALTER COLUMN, so we need to recreate the table
CREATE TABLE logs_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
issue_id TEXT DEFAULT '',
session_id TEXT NOT NULL,
work_session_id TEXT DEFAULT '',
message TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'progress',
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO logs_new SELECT * FROM logs;
DROP TABLE logs;
ALTER TABLE logs_new RENAME TO logs;
CREATE INDEX IF NOT EXISTS idx_logs_issue ON logs(issue_id);
CREATE INDEX IF NOT EXISTS idx_logs_work_session ON logs(work_session_id);
`,
},
{
Version: 4,
Description: "Add minor flag to issues for self-reviewable tasks",
SQL: `ALTER TABLE issues ADD COLUMN minor INTEGER DEFAULT 0;`,
},
{
Version: 5,
Description: "Add created_branch to issues",
SQL: `ALTER TABLE issues ADD COLUMN created_branch TEXT DEFAULT '';`,
},
{
Version: 6,
Description: "Add creator_session for review enforcement",
SQL: `ALTER TABLE issues ADD COLUMN creator_session TEXT DEFAULT '';`,
},
{
Version: 7,
Description: "Add session history for review enforcement",
SQL: `CREATE TABLE IF NOT EXISTS issue_session_history (
id TEXT PRIMARY KEY,
issue_id TEXT NOT NULL,
session_id TEXT NOT NULL,
action TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (issue_id) REFERENCES issues(id)
);
CREATE INDEX IF NOT EXISTS idx_ish_issue ON issue_session_history(issue_id);
CREATE INDEX IF NOT EXISTS idx_ish_session ON issue_session_history(session_id);`,
},
}
Migrations is the list of all database migrations in order
Functions ¶
func ClearAgentErrors ¶ added in v0.4.16
ClearAgentErrors removes the agent errors file.
func ClearSecurityEvents ¶ added in v0.5.0
ClearSecurityEvents removes the security events file
func CountAgentErrors ¶ added in v0.4.16
CountAgentErrors returns the number of logged errors.
func LogAgentError ¶ added in v0.4.16
LogAgentError appends a failed command to the agent errors file. baseDir is the project root. If the .todos directory doesn't exist, the error is silently dropped (project not initialized).
func LogSecurityEvent ¶ added in v0.5.0
func LogSecurityEvent(baseDir string, event SecurityEvent) error
LogSecurityEvent appends a security event to the jsonl file
func NormalizeIssueID ¶ added in v0.4.17
NormalizeIssueID ensures an issue ID has the td- prefix Accepts bare hex IDs like "abc123" and returns "td-abc123"
Types ¶
type AgentError ¶ added in v0.4.16
type AgentError struct {
Timestamp time.Time `json:"ts"`
Args []string `json:"args"`
Error string `json:"error"`
SessionID string `json:"session,omitempty"`
}
AgentError represents a failed command invocation
func ReadAgentErrors ¶ added in v0.4.16
func ReadAgentErrors(baseDir string) ([]AgentError, error)
ReadAgentErrors reads all agent errors from the file. Returns empty slice if file doesn't exist.
func ReadAgentErrorsFiltered ¶ added in v0.4.16
func ReadAgentErrorsFiltered(baseDir string, sessionID string, since time.Time, limit int) ([]AgentError, error)
ReadAgentErrorsFiltered reads agent errors matching the filter criteria.
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB wraps the database connection
func Initialize ¶
Initialize creates the database and runs migrations
func (*DB) AddComment ¶
AddComment adds a comment to an issue
func (*DB) AddDependency ¶
AddDependency adds a dependency between issues
func (*DB) AddGitSnapshot ¶
func (db *DB) AddGitSnapshot(snapshot *models.GitSnapshot) error
AddGitSnapshot records a git state snapshot
func (*DB) AddHandoff ¶
AddHandoff adds a handoff entry
func (*DB) CascadeUpParentStatus ¶ added in v0.4.16
func (db *DB) CascadeUpParentStatus(issueID string, targetStatus models.Status, sessionID string) (int, []string)
CascadeUpParentStatus checks if all children of a parent epic have reached the target status, and if so, updates the parent to that status. Works recursively up the parent chain. Returns the number of parents that were cascaded and the list of cascaded parent IDs.
func (*DB) CreateIssue ¶
CreateIssue creates a new issue
func (*DB) CreateWorkSession ¶
func (db *DB) CreateWorkSession(ws *models.WorkSession) error
CreateWorkSession creates a new work session
func (*DB) DeleteHandoff ¶ added in v0.4.16
DeleteHandoff removes a handoff by ID (for undo support)
func (*DB) DeleteIssue ¶
DeleteIssue soft-deletes an issue
func (*DB) GetActiveSessions ¶
GetActiveSessions returns distinct session IDs with activity since the given time
func (*DB) GetBlockedBy ¶
GetBlockedBy returns what issues are blocked by this issue
func (*DB) GetComments ¶
GetComments retrieves comments for an issue
func (*DB) GetDependencies ¶
GetDependencies returns what an issue depends on
func (*DB) GetDescendantIssues ¶ added in v0.4.16
func (db *DB) GetDescendantIssues(issueID string, statuses []models.Status) ([]*models.Issue, error)
GetDescendantIssues returns all descendant issues (children, grandchildren, etc.) filtered by the given statuses (empty = all statuses)
func (*DB) GetDirectChildren ¶ added in v0.4.16
GetDirectChildren returns the direct children of an issue (not recursive)
func (*DB) GetExtendedStats ¶ added in v0.4.1
func (db *DB) GetExtendedStats() (*models.ExtendedStats, error)
GetExtendedStats returns detailed statistics for dashboard/stats displays
func (*DB) GetIssue ¶
GetIssue retrieves an issue by ID Accepts bare IDs without the td- prefix (e.g., "abc123" becomes "td-abc123")
func (*DB) GetIssueSessionLog ¶
GetIssueSessionLog returns issues touched by a session
func (*DB) GetLastAction ¶
GetLastAction returns the most recent undoable action for a session
func (*DB) GetLatestHandoff ¶
GetLatestHandoff retrieves the latest handoff for an issue
func (*DB) GetLinkedFiles ¶
GetLinkedFiles returns files linked to an issue
func (*DB) GetLogsByWorkSession ¶
GetLogsByWorkSession retrieves logs for a specific work session
func (*DB) GetRecentActions ¶
GetRecentActions returns recent actions for a session
func (*DB) GetRecentActionsAll ¶
GetRecentActionsAll returns recent action_log entries across all sessions
func (*DB) GetRecentCommentsAll ¶
GetRecentCommentsAll returns recent comments across all issues
func (*DB) GetRecentHandoffs ¶
GetRecentHandoffs retrieves recent handoffs across all issues
func (*DB) GetRecentLogsAll ¶
GetRecentLogsAll returns recent logs across all issues
func (*DB) GetSchemaVersion ¶
GetSchemaVersion returns the current schema version from the database
func (*DB) GetSessionHistory ¶ added in v0.4.26
func (db *DB) GetSessionHistory(issueID string) ([]models.IssueSessionHistory, error)
GetSessionHistory returns all session interactions for an issue
func (*DB) GetStartSnapshot ¶
func (db *DB) GetStartSnapshot(issueID string) (*models.GitSnapshot, error)
GetStartSnapshot returns the start snapshot for an issue
func (*DB) GetWorkSession ¶
func (db *DB) GetWorkSession(id string) (*models.WorkSession, error)
GetWorkSession retrieves a work session
func (*DB) GetWorkSessionIssues ¶
GetWorkSessionIssues returns issues tagged to a work session
func (*DB) HasChildren ¶ added in v0.4.16
HasChildren returns true if the issue has any child issues
func (*DB) ListIssues ¶
func (db *DB) ListIssues(opts ListIssuesOptions) ([]models.Issue, error)
ListIssues returns issues matching the filter
func (*DB) ListWorkSessions ¶
func (db *DB) ListWorkSessions(limit int) ([]models.WorkSession, error)
ListWorkSessions returns recent work sessions
func (*DB) MarkActionUndone ¶
MarkActionUndone marks an action as undone
func (*DB) RecordSessionAction ¶ added in v0.4.26
func (db *DB) RecordSessionAction(issueID, sessionID string, action models.IssueSessionAction) error
RecordSessionAction logs a session's interaction with an issue
func (*DB) RemoveDependency ¶
RemoveDependency removes a dependency
func (*DB) RestoreIssue ¶
RestoreIssue restores a soft-deleted issue
func (*DB) RunMigrations ¶
RunMigrations runs any pending database migrations
func (*DB) SearchIssues ¶
SearchIssues performs full-text search across issues
func (*DB) SearchIssuesRanked ¶ added in v0.4.9
func (db *DB) SearchIssuesRanked(query string, opts ListIssuesOptions) ([]SearchResult, error)
SearchIssuesRanked performs search with relevance scoring
func (*DB) SetSchemaVersion ¶
SetSchemaVersion sets the schema version in the database
func (*DB) TagIssueToWorkSession ¶
TagIssueToWorkSession links an issue to a work session
func (*DB) UnlinkFile ¶
UnlinkFile removes a file link
func (*DB) UntagIssueFromWorkSession ¶
UntagIssueFromWorkSession removes an issue from a work session
func (*DB) UpdateIssue ¶
UpdateIssue updates an issue
func (*DB) UpdateWorkSession ¶
func (db *DB) UpdateWorkSession(ws *models.WorkSession) error
UpdateWorkSession updates a work session
type ListIssuesOptions ¶
type ListIssuesOptions struct {
Status []models.Status
Type []models.Type
Priority string
Labels []string
IncludeDeleted bool
OnlyDeleted bool
Search string
Implementer string
Reviewer string
ReviewableBy string // Issues that this session can review
ParentID string
EpicID string // Filter by epic (parent_id matches epic, recursively)
PointsMin int
PointsMax int
CreatedAfter time.Time
CreatedBefore time.Time
UpdatedAfter time.Time
UpdatedBefore time.Time
ClosedAfter time.Time
ClosedBefore time.Time
SortBy string
SortDesc bool
Limit int
IDs []string
}
ListIssuesOptions contains filter options for listing issues
type SearchResult ¶ added in v0.4.9
type SearchResult struct {
Issue models.Issue
Score int // Higher = better match (0-100)
MatchField string // Primary field that matched: 'id', 'title', 'description', 'labels'
}
SearchResult holds an issue with relevance scoring for ranked search
type SecurityEvent ¶ added in v0.5.0
type SecurityEvent struct {
Timestamp time.Time `json:"ts"`
IssueID string `json:"issue_id"`
SessionID string `json:"session_id"`
AgentType string `json:"agent_type,omitempty"`
Reason string `json:"reason"`
}
SecurityEvent represents a security-relevant action (like a self-close exception)
func ReadSecurityEvents ¶ added in v0.5.0
func ReadSecurityEvents(baseDir string) ([]SecurityEvent, error)
ReadSecurityEvents reads all security events from the file