feat: add annotations, undo system, and schema updates

Add annotations as JSON column on tasks table with Annotate/Denotate
methods and CLI commands. Add undo system backed by change_log with
lightweight undo_stack table (capped at 10 entries). All mutating CLI
commands (add, done, delete, modify, start, stop) now record undo
entries. Undo restores prior task state from change_log data.

Schema changes (in v1 migration):
- annotations TEXT column on tasks
- undo_stack table
- annotations field in change_log triggers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 13:54:58 +01:00
parent 6fb8a40a43
commit 7aaaa86a0a
16 changed files with 753 additions and 76 deletions
+27
View File
@@ -0,0 +1,27 @@
package engine
import "fmt"
// Annotate appends a timestamped annotation to the task and saves.
func (t *Task) Annotate(text string) error {
annotation := Annotation{
Timestamp: timeNow().Unix(),
Text: text,
}
t.Annotations = append(t.Annotations, annotation)
return t.Save()
}
// Denotate removes the most recent annotation from the task and saves.
// Returns the removed annotation, or an error if there are none.
func (t *Task) Denotate() (*Annotation, error) {
if len(t.Annotations) == 0 {
return nil, fmt.Errorf("task has no annotations")
}
removed := t.Annotations[len(t.Annotations)-1]
t.Annotations = t.Annotations[:len(t.Annotations)-1]
if err := t.Save(); err != nil {
return nil, err
}
return &removed, nil
}