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>
Add relative date formatting (today, tomorrow, in 3d, etc.) for list and
detail views. Add structured feedback helpers for add/complete/delete
operations showing display IDs and parsed modifiers. Change Complete() to
return spawned recurring instance so callers can display recurrence info.
Add AppendTask to working set for immediate display ID assignment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix latent API bug where multi-word fields (RecurrenceDuration, ParentUUID,
CreatedAt) serialized as PascalCase, breaking the frontend. Add explicit
snake_case json tags and custom MarshalJSON/UnmarshalJSON on Task, Status,
and APIKey to emit unix timestamps and string status codes.
Add Urgency float64 as a derived field on Task, populated via
PopulateUrgency helper in all handlers before serialization. The report
engine's sortByUrgency now also retains the computed score.
Frontend updated with urgency type, color-coded badge in TaskItem, and
mock data values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement complete key:value format parsing for change log entries and fix
critical tag synchronization issue from server to client.
Key Changes:
1. Shared Key:Value Parser (NEW: internal/engine/parser.go)
- Created ParseKeyValueFormat() for both edit and sync operations
- Supports flexible whitespace: 'key:value' and 'key: value'
- Handles comment skipping for edit files
- Consolidates parsing logic (DRY principle)
2. Database Triggers - Tags Support (internal/engine/database.go)
- Added tags to track_task_create trigger
- Added tags to track_task_update trigger
- Tags sorted alphabetically via SQL ORDER BY
- Format: 'tags: alpha,bravo,charlie'
3. Task Creation - Tag Update Fix (internal/engine/task.go)
- CreateTaskWithModifier() now triggers update after adding tags
- Ensures tags appear in change log (UPDATE entry)
- Fixes missing tags in initial CREATE entries
4. Edit Command - Use Shared Parser (cmd/edit.go)
- Replaced custom parseEditedFile() with shared ParseKeyValueFormat()
- Added tag sorting in parseTags()
- Removed ~30 lines, improved maintainability
5. Sync Client - Complete Implementation (internal/sync/client.go)
- NEW: applyChangeDataToTask() - parses all fields from change log
- NEW: Helper functions for status, priority, tag parsing
- FIXED: parseChanges() - sort by timestamp+ID before grouping
- Added parent/child task ordering (prevents FK violations)
- Enhanced tag sync in merge loop with task reload
- Specific validation error messages per field
Critical Bug Fix:
- When CREATE and UPDATE have same timestamp, old code kept CREATE (no tags)
- New code sorts by ID as tiebreaker, ensuring UPDATE (with tags) is used
- Verified: Server->client tag sync now works correctly
Validation:
- Description must not be empty (both edit and sync)
- Recurrence validated (not negative, max 100 years)
- All timestamps parsed correctly (Unix epoch)
- Tags sorted alphabetically in all contexts
Testing:
- Fresh pull from server: ✅ All tags present
- API-created tasks: ✅ Tags sync correctly
- Local->server->client round-trip: ✅ No data loss
- Same-second CREATE+UPDATE: ✅ Correct entry processed
- Parent/child tasks: ✅ Correct ordering
Files Changed:
- NEW: internal/engine/parser.go (+44 lines)
- Modified: internal/engine/database.go (+10 lines)
- Modified: internal/engine/task.go (+8 lines)
- Modified: cmd/edit.go (-25 lines net)
- Modified: internal/sync/client.go (+280 lines)
- Modified: srv/README.md (+1 line)
Total: +318 lines added, -25 removed, net +293 lines
This completes Phase 6: Full bidirectional sync with complete tag support.