Commit Graph

10 Commits

Author SHA1 Message Date
joakim f5f7bc3ad7 feat: Complete key:value format implementation and fix tag sync
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.
2026-01-05 18:56:17 +01:00
joakim 40c09d6a8a feat: Phase 4 - Offline & merge enhancements
- Added 'opal sync merge' command for initial database merge
- Support for merge strategies: prefer-local, prefer-server, smart (default)
- Offline queue already implemented in Phase 2
- Conflict warning display already implemented in Phase 2-3
- Full offline mode support with automatic queueing when server unreachable
2026-01-05 16:19:49 +01:00
joakim 944d628ca1 feat: Phase 3 - CLI sync commands
- Created comprehensive sync command suite:
  - 'opal sync init' - Configure sync with server (URL, API key)
  - 'opal sync status' - Show sync configuration and queue status
  - 'opal sync now' - Bidirectional sync with conflict resolution
  - 'opal sync up' - Push local changes to server
  - 'opal sync down' - Pull server changes to local
  - 'opal sync log' - View conflict resolution log
- Added interactive prompts for init (URL and API key)
- Automatic client ID generation (UUID)
- Display user-friendly sync results with emojis
- Support for viewing queued offline changes
- Integration with config system for persistent sync settings
2026-01-05 16:19:00 +01:00
joakim ba0cfc08e3 feat: Phase 1 - Core API server with authentication
- Added database schema for users, api_keys, sync_state, change_log, and sync_config
- Implemented API key generation and validation with bcrypt hashing
- Created Chi-based REST API server with endpoints for:
  - Task CRUD operations (create, read, update, delete)
  - Task actions (complete, start, stop)
  - Tag management (list, add, remove)
  - Projects listing
  - Health check endpoint
- Added middleware for authentication and CORS
- Implemented change log tracking with triggers (key:value format)
- Added configurable change log retention (default 30 days)
- Created server CLI commands (opal server start, opal server keygen)
- Dependencies added: golang.org/x/crypto/bcrypt, github.com/go-chi/chi/v5
2026-01-05 16:14:49 +01:00
joakim 1d55f04a1f Fix recurring task modifier application bug
When creating recurring tasks, modifiers (due, wait, priority, etc) were
not being applied because AttributeOrder was not copied to the temporary
modifier. This caused all date attributes to be ignored.

Refactored addRecurringTask to:
- Create task structs directly instead of using CreateTask (avoiding
  premature saves)
- Use ApplyToNew() instead of Apply() for modifiers before first save
- Properly copy AttributeOrder when building the temporary modifier
- Save template and instance once with all fields correctly set

This ensures recurring tasks now properly have due dates, wait dates,
and other modifiers applied when created via 'opal add' or batch import.
2026-01-05 11:18:43 +01:00
joakim 79eb3bb62a Add info and edit commands for interactive task management
- Add 'opal info' command to display detailed task information
  - Shows all task attributes including UUID, timestamps, and metadata
  - Supports flexible syntax (opal info 2 or opal 2 info)
  - Displays recurrence information and parent UUID for recurring tasks

- Add 'opal edit' command to edit tasks in $EDITOR
  - Opens task in text editor with human-readable format
  - Supports all editable fields with smart date formatting
  - Special handling for recurring tasks (updates parent template)
  - Status changes trigger appropriate methods (Complete/Delete)
  - Auto-saves changes on editor exit without confirmation
  - Clear validation and error messages

- Register new commands in root command dispatcher
2026-01-05 11:05:20 +01:00
joakim 4b59b004f1 Fix help flags to show root help instead of list help
Previously, 'opal -h', 'opal --help', and 'opal help' would show the
list command help instead of the root command help. This was because
the argument preprocessing logic would rewrite these as 'opal list -h'
before Cobra could handle them.

Now we detect help flags/command before preprocessing and let Cobra
handle them naturally. This ensures:
- 'opal -h' and 'opal --help' show root help
- 'opal help' shows root help
- 'opal help <command>' shows command-specific help
- 'opal <command> -h' still shows command-specific help
- All existing flexible syntax continues to work
2026-01-05 10:27:12 +01:00
joakim a68d701d14 Fix three critical UX issues in opal-task
Issue 1: Fix recurrence calculation for overdue tasks
- Use completion date (End) as base for next instance, not original due date
- If task due Monday completed Wednesday, next is Wednesday+7d not Monday+7d
- Fallback to Due date if End is not set
- Update test to verify new behavior

Issue 2: Fix description parsing to work without quotes
- Add parseAddArgs() to extract description from non-modifier words
- Description = all words that don't start with +, -, or contain :
- Enables: opal add buy groceries +shop carrots → 'buy groceries carrots'
- Validate description is required (error if only modifiers)
- Validate recurring tasks require due date

Issue 3: Implement flexible command syntax
- Add preprocessArgs() to parse arguments before Cobra routing
- Detect command position and split filters (left) from modifiers (right)
- Rewrite os.Args so Cobra routes correctly
- Enable both 'opal 2 done' and 'opal done 2' syntax
- Commands without modifiers accept filters on either side
- Commands with modifiers enforce [filters] command [modifiers]
- Add confirmation for modify without filters (modifies all tasks)

All commands updated to use preprocessed ParsedArgs from context.
All tests passing (33 tests).
2026-01-04 21:24:14 +01:00
joakim 6e6c3dbea4 Implement opal-task Phases 6-8: Complete CLI Implementation
Phase 6: Display and Basic Commands
- Add display.go with colored formatting for tasks, projects, tags
- Implement cmd/root.go with Cobra command structure
- Implement cmd/list.go for listing and filtering tasks
- Implement cmd/add.go with support for regular and recurring tasks
- Implement cmd/done.go with bulk completion and confirmation

Phase 7: Advanced Commands
- Implement cmd/modify.go for updating task attributes
- Implement cmd/delete.go with soft delete confirmation
- Implement cmd/start.go and cmd/stop.go for task timing
- Implement cmd/count.go for counting filtered tasks
- Implement cmd/projects.go and cmd/tags.go for aggregation

Phase 8: Integration and Polish
- Update main.go to use CLI commands
- Add colored output with fatih/color
- Format task lists with proper alignment
- Highlight overdue tasks in red, upcoming in yellow
- Test end-to-end workflow: add, list, done, recurring tasks
- Verify recurrence spawning works correctly

All CLI commands functional and tested!
2026-01-04 18:17:04 +01:00
joakim 9b5261b34c Implement opal-task Phase 1: Database foundation
- Add SQLite database with schema for tasks, tags, and working_set
- Implement config management with Viper (opal.yml)
- Create Task struct with proper types (*time.Time, Priority int)
- Add database migration system
- Implement recurrence pattern parsing (1d, 1w, 1m, 1y)
- Setup project structure with cmd/ and internal/engine/
- Add dependencies: sqlite3, uuid, cobra, viper, color
2026-01-04 14:41:16 +01:00