summaryrefslogtreecommitdiff
path: root/internal/store
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-28 23:32:26 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-28 23:32:26 -1000
commitd39220eac03fbc5b714bde989665ed1c92dd24a5 (patch)
tree03e1985745043b9af6e7442ac21fdcd5d843146f /internal/store
parent05b1930e04ac222d73ffb2f45c1b1febb69f893d (diff)
Expand agent context API with completed log and calendar view
- Add completed_tasks table to log task completions with title, due date, and completion timestamp - Extend agent context date range: 7 days back to 14 days forward - Add completed_log to API response (last 50 completed tasks) - Add day_section field to timeline items (overdue/today/tomorrow/later) - Add calendar-style view for today's schedule (6am-10pm hourly grid) - Add tabbed interface for Timeline vs Completed Log in HTML view Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/store')
-rw-r--r--internal/store/sqlite.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go
index b324e9f..48bcae5 100644
--- a/internal/store/sqlite.go
+++ b/internal/store/sqlite.go
@@ -1141,3 +1141,55 @@ func (s *Store) CheckAgentTrust(name, agentID string) (models.AgentTrustLevel, e
return models.AgentTrustNew, nil
}
+
+// Completed tasks log
+
+// SaveCompletedTask logs a completed task
+func (s *Store) SaveCompletedTask(source, sourceID, title string, dueDate *time.Time) error {
+ var dueDateStr sql.NullString
+ if dueDate != nil {
+ dueDateStr = sql.NullString{String: dueDate.Format(time.RFC3339), Valid: true}
+ }
+ _, err := s.db.Exec(`
+ INSERT OR REPLACE INTO completed_tasks (source, source_id, title, due_date, completed_at)
+ VALUES (?, ?, ?, ?, datetime('now', 'localtime'))
+ `, source, sourceID, title, dueDateStr)
+ return err
+}
+
+// GetCompletedTasks retrieves recently completed tasks
+func (s *Store) GetCompletedTasks(limit int) ([]models.CompletedTask, error) {
+ rows, err := s.db.Query(`
+ SELECT id, source, source_id, title, due_date, completed_at
+ FROM completed_tasks
+ ORDER BY completed_at DESC
+ LIMIT ?
+ `, limit)
+ if err != nil {
+ return nil, err
+ }
+ defer func() { _ = rows.Close() }()
+
+ var tasks []models.CompletedTask
+ for rows.Next() {
+ var task models.CompletedTask
+ var dueDate sql.NullString
+ var completedAt string
+
+ if err := rows.Scan(&task.ID, &task.Source, &task.SourceID, &task.Title, &dueDate, &completedAt); err != nil {
+ return nil, err
+ }
+
+ if dueDate.Valid {
+ if t, err := time.Parse(time.RFC3339, dueDate.String); err == nil {
+ task.DueDate = &t
+ }
+ }
+ if t, err := time.Parse("2006-01-02 15:04:05", completedAt); err == nil {
+ task.CompletedAt = t
+ }
+
+ tasks = append(tasks, task)
+ }
+ return tasks, rows.Err()
+}