Files
gems/opal-task/README.md
T
joakim 5d01c9f564 refactor: implement configurable directory structure with XDG support
Separate configuration from data storage and make paths configurable
via environment variables and command-line flags. This improves
Unix/Linux compliance and supports both development and production
deployments.

Key changes:
- Separate config dir (opal.yml) from data dir (database, logs)
- Support XDG Base Directory specification
- Add --config-dir and --data-dir flags
- Environment variables: OPAL_CONFIG_DIR, OPAL_DATA_DIR, OPAL_DB_PATH
- Smart fallback: /etc/opal, /var/lib/opal -> ~/.config/opal, ~/.local/share/opal
- Server mode validates required OAuth/JWT environment variables
- Update naming from 'jade' to 'opal' throughout
- Update systemd service name to 'opal.service'
- Add migration guide in README

Default paths:
- Config: /etc/opal (fallback: ~/.config/opal)
- Data: /var/lib/opal (fallback: ~/.local/share/opal)

Files modified:
- internal/engine/config.go: New directory resolution logic
- internal/engine/database.go: Auto-create data directory
- cmd/root.go: Add global flags for directory overrides
- cmd/server.go: Add configuration validation
- cmd/sync.go, internal/sync/*: Use new path helper functions
- tests: Update to use directory overrides
- docs: Update deployment guide and README
2026-01-06 20:46:29 +01:00

4.6 KiB

Opal task manager

This is the counterpart to jade, where we track tasks.

Syntax

opal [<filter>] [<command>] [<modifier>]

Filters the Task to run a command on. Adressing a set of subtasks. opal +home -garden status:pending list - lists all tasks with the +home tag and status pending, but excludes +garden tags. This is a compound filter with implicit AND.

add - Creates a new task done - Completes a task list - Lists task count - Counts number of tasks

Modifies atributes of tasks.

Task

A task has multiple atributes: status - pending, completed, deleted, recurring description - One line summary start - the most recent time at which this task was started (a task with no start key is not active) end - if present, the time at which this task was completed or deleted due - Use a due date to specify the exact date by which a task must be completed.created - Time task created schedueled - represents the earliest opportunity to work on a task. If a task has a scheduled date, then once that date passes, the task is considered ready. Tasks with no scheduled is considered always ready. wait - a wait date for a task, which has the effect of hiding the task from you until that date. until - the point at which to mark task as deleted. an expiration date.

Recurrence

A task can be recurring. Then we have a template task and instances of that task. opal add Change sheets due:sun recur:1w - A task to be done every sunday. A recurring task is given a status of recurring which hides it from view. The recurring task you create is called the template task, from which recurring tasks instances are created. So the template remains hidden, and the recurring instances that spawn from it are the tasks that you will see and complete.

Storage

Configuration: ~/.config/opal/opal.yml (or $XDG_CONFIG_HOME/opal/opal.yml)
Database: ~/.local/share/opal/opal.db (or $XDG_DATA_HOME/opal/opal.db)

Customizing Storage Locations

Override default locations using environment variables or command-line flags:

Environment Variables:

  • OPAL_CONFIG_DIR - Override config directory location
  • OPAL_DATA_DIR - Override data directory location
  • OPAL_DB_PATH - Override database file path specifically
  • XDG_CONFIG_HOME - Standard XDG config directory (defaults to ~/.config)
  • XDG_DATA_HOME - Standard XDG data directory (defaults to ~/.local/share)

Command-Line Flags:

opal --config-dir /custom/config --data-dir /custom/data list

Production Server Setup:

# Use system-wide paths for production
OPAL_CONFIG_DIR=/etc/opal OPAL_DATA_DIR=/var/lib/opal opal server start

Migrating from Old Paths

If you previously used ~/.config/jade/, you can migrate your data:

# Backup first (recommended)
cp -r ~/.config/jade ~/.config/jade.backup

# Create new directories
mkdir -p ~/.config/opal ~/.local/share/opal

# Copy config
cp ~/.config/jade/opal.yml ~/.config/opal/

# Move database and sync data
mv ~/.config/jade/opal.db ~/.local/share/opal/
mv ~/.config/jade/sync_*.* ~/.local/share/opal/ 2>/dev/null || true

# Test that everything works
opal list

# Remove old directory after confirming it works
rm -rf ~/.config/jade

Server & Sync

Opal-task includes a REST API server for syncing tasks across multiple devices.

Quick Start

Server Setup:

# Build
go build -o opal main.go

# Generate API key
./opal server keygen --name "My Device" --db /var/lib/opal/opal.db

# Start server
./opal server start --addr :8080 --db /var/lib/opal/opal.db

Client Setup:

# Configure sync
opal sync init --url https://opal.yourdomain.com --key oak_abc123...

# Sync tasks
opal sync now

# Initial merge (for existing local database)
opal sync merge

Sync Commands

  • opal sync init - Configure sync with server
  • opal sync status - Show sync configuration and status
  • opal sync now - Bidirectional sync
  • opal sync up - Push local changes to server
  • opal sync down - Pull server changes from server
  • opal sync merge - Initial database merge (for first-time sync)
  • opal sync log - View conflict resolution log

Features

  • Offline support - Queue changes when server is unreachable
  • Conflict resolution - Automatic conflict handling (last-write-wins by default)
  • Change tracking - Full change log with configurable retention
  • API key authentication - Secure bcrypt-hashed keys
  • Household sharing - Single shared database for all family members

See srv/README.md for detailed server deployment instructions.