From b019deecd2b61f883aca30302e2a02a948c12b18 Mon Sep 17 00:00:00 2001 From: Sam Rolfe Date: Wed, 4 Mar 2026 16:06:48 +1100 Subject: [PATCH] Add script and desscription --- task-due-notify.sh | 91 ++++++++++++++++ tasks_alerts.md | 260 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100755 task-due-notify.sh create mode 100644 tasks_alerts.md diff --git a/task-due-notify.sh b/task-due-notify.sh new file mode 100755 index 0000000..f5e4321 --- /dev/null +++ b/task-due-notify.sh @@ -0,0 +1,91 @@ +#!/nix/store/x12lw455sq6qy2wcya85d7rb88ybc3df-bash-interactive-5.3p9/bin/bash + +# Simple Taskwarrior Notification Script +# Just checks: if time_until_due <= reminder_time, send notification + +NTFY_URL="https://ntfy.lab.audasmedia.com.au/tasks" +NOW=$(date -u +%s) + +# Auto-add +notify to tasks with due dates or remind tags +task status:pending '( due.any: or tags.has:remindMins or tags.has:remindHours or tags.has:remindDays or tags.has:remindWeeks or tags.has:remindMonths )' -notify export 2>/dev/null | \ + /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.[].uuid' 2>/dev/null | \ + while read -r uuid; do + /nix/store/syqlfcifpih00fknzailx8xxn4cnv42d-taskwarrior-3.4.2/bin/task "$uuid" modify +notify 2>/dev/null + done + +# Process tasks with +notify +task status:pending +notify export 2>/dev/null | \ + /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -c '.[] | select(.due) | {uuid: .uuid, description: .description, due: .due, tags: .tags}' 2>/dev/null | \ + while read -r task_json; do + + uuid=$(echo "$task_json" | /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.uuid') + desc=$(echo "$task_json" | /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.description') + due_date=$(echo "$task_json" | /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.due') + tags=$(echo "$task_json" | /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.tags[]? // empty' 2>/dev/null) + + # Convert due date (UTC) to epoch + formatted_date=$(echo "$due_date" | /nix/store/ryz8kcrm2bxpccllfqlb7qldsfnqp5c2-gnused-4.9/bin/sed 's/T/ /; s/Z$//; s/^\(....\)\(..\)\(..\)/\1-\2-\3/; s/ \(..\)\(..\)\(..\)$/ \1:\2:\3/') + due_epoch=$(/nix/store/i2vmgx46q9hd3z6rigaiman3wl3i2gc4-coreutils-9.9/bin/date -d "$formatted_date UTC" +%s 2>/dev/null || echo 0) + + if [ "$due_epoch" = "0" ]; then + continue + fi + + time_until_due=$((due_epoch - NOW)) + + # Check reminder tags + echo "$tags" | /nix/store/02vv0r262agf9j5n2y1gmbjvdf12zkl0-gnugrep-3.12/bin/grep -E '^remind(Mins|Hours|Days|Weeks|Months)' 2>/dev/null | \ + while read -r remind_tag; do + + # Parse: remindMins2, remindHours1, etc + if [[ "$remind_tag" =~ ^remind(Mins|Hours|Days|Weeks|Months)([0-9]+)$ ]]; then + unit="${BASH_REMATCH[1]}" + num="${BASH_REMATCH[2]}" + + # Convert to seconds + case "$unit" in + Mins) remind_secs=$((num * 60)); time_str="$num minutes" ;; + Hours) remind_secs=$((num * 3600)); time_str="$num hours" ;; + Days) remind_secs=$((num * 86400)); time_str="$num days" ;; + Weeks) remind_secs=$((num * 604800)); time_str="$num weeks" ;; + Months) remind_secs=$((num * 2592000)); time_str="$num months" ;; + esac + + # SIMPLE: If time until due <= reminder time AND still in future, send it + if [ $time_until_due -le $remind_secs ] && [ $time_until_due -gt 0 ]; then + /nix/store/xgdl4gzjzwj7ixs83f17sqppd08lfd03-libnotify-0.8.7/bin/notify-send -u normal "Reminder" "🔔 $desc - Due in $time_str" + /nix/store/jqfr3p49g3lch84y45jfzw9fshlv8jyp-curl-8.17.0-bin/bin/curl -s -d "Reminder: $desc - Due in $time_str" "$NTFY_URL" >/dev/null 2>&1 & + /nix/store/syqlfcifpih00fknzailx8xxn4cnv42d-taskwarrior-3.4.2/bin/task "$uuid" modify -"$remind_tag" 2>/dev/null + fi + fi + done + + # Check if task is due (overdue) + if [ $time_until_due -le 0 ] && ! echo "$tags" | /nix/store/02vv0r262agf9j5n2y1gmbjvdf12zkl0-gnugrep-3.12/bin/grep -q "^notified$"; then + /nix/store/xgdl4gzjzwj7ixs83f17sqppd08lfd03-libnotify-0.8.7/bin/notify-send -u critical "Task Due" "⚠️ $desc" + /nix/store/jqfr3p49g3lch84y45jfzw9fshlv8jyp-curl-8.17.0-bin/bin/curl -s -d "Task due: $desc" "$NTFY_URL" >/dev/null 2>&1 & + /nix/store/syqlfcifpih00fknzailx8xxn4cnv42d-taskwarrior-3.4.2/bin/task "$uuid" modify +notified 2>/dev/null + fi + done + +# Cleanup: Remove notification tags from completed/deleted tasks +task '( status:completed or status:deleted )' '( +notify or +notified or tags.has:remindMins or tags.has:remindHours or tags.has:remindDays or tags.has:remindWeeks or tags.has:remindMonths )' export 2>/dev/null | \ + /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.[].uuid' 2>/dev/null | \ + while read -r uuid; do + tags=$(/nix/store/syqlfcifpih00fknzailx8xxn4cnv42d-taskwarrior-3.4.2/bin/task "$uuid" export 2>/dev/null | /nix/store/qnaw7i777j52fpgbl5pgmzkq85znp083-jq-1.8.1-bin/bin/jq -r '.[0].tags[]? // empty' 2>/dev/null) + + remove_args="" + echo "$tags" | /nix/store/02vv0r262agf9j5n2y1gmbjvdf12zkl0-gnugrep-3.12/bin/grep -q "^notify$" && remove_args="$remove_args -notify" + echo "$tags" | /nix/store/02vv0r262agf9j5n2y1gmbjvdf12zkl0-gnugrep-3.12/bin/grep -q "^notified$" && remove_args="$remove_args -notified" + + remind_tags=$(echo "$tags" | /nix/store/02vv0r262agf9j5n2y1gmbjvdf12zkl0-gnugrep-3.12/bin/grep "^remind(Mins|Hours|Days|Weeks|Months)" 2>/dev/null || true) + if [ -n "$remind_tags" ]; then + while read -r tag; do + remove_args="$remove_args -$tag" + done <<< "$remind_tags" + fi + + if [ -n "$remove_args" ]; then + /nix/store/syqlfcifpih00fknzailx8xxn4cnv42d-taskwarrior-3.4.2/bin/task "$uuid" modify $remove_args 2>/dev/null + fi + done diff --git a/tasks_alerts.md b/tasks_alerts.md new file mode 100644 index 0000000..17820c4 --- /dev/null +++ b/tasks_alerts.md @@ -0,0 +1,260 @@ +# Taskwarrior Notification System - Implementation Plan + +**Date:** 2026-03-03 +**Status:** READY TO IMPLEMENT +**Approach:** Tag-Based Notifications with Relative Reminders + +--- + +## Overview + +Replace the separate state file system with **Taskwarrior native tags**. Tasks with due dates or reminder tags get automatic notification tracking. + +### Key Features +- **Tag-based tracking**: No more `~/.local/share/task-notified` file +- **Relative reminders**: `+remind1hour`, `+remind30min`, `+remind2days`, etc. +- **Auto-cleanup**: Notification tags removed when task completed +- **5-minute polling**: Unchanged from current setup +- **Multiple reminders**: Support multiple reminder tags per task + +--- + +## Tag System + +### Core Tags + +| Tag | Purpose | Auto-Added? | Auto-Removed? | +|-----|---------|-------------|---------------| +| `+notify` | Mark task for notification tracking | Yes (if due date or +remind*) | Yes (on completion) | +| `+notified` | Task has been notified (due time reached) | Yes (when due) | Yes (on completion) | + +### Reminder Tags + +| Tag | Time Before Due | Example Task | +|-----|-----------------|--------------| +| `+remind5min` | 5 minutes | Quick reminders | +| `+remind10min` | 10 minutes | Short prep time | +| `+remind15min` | 15 minutes | Meeting prep | +| `+remind30min` | 30 minutes | Standard reminder | +| `+remind1hour` | 1 hour | Important tasks | +| `+remind2hours` | 2 hours | Preparation needed | +| `+remind4hours` | 4 hours | Workday planning | +| `+remind8hours` | 8 hours | Next-day prep | +| `+remind12hours` | 12 hours | Half-day warning | +| `+remind1day` | 1 day | Daily planning | +| `+remind2days` | 2 days | Medium-term tasks | +| `+remind3days` | 3 days | Project deadlines | +| `+remind1week` | 1 week | Long-term planning | +| `+remind2weeks` | 2 weeks | Monthly reviews | +| `+remind3weeks` | 3 weeks | Quarterly prep | +| `+remind1month` | 1 month | Annual planning | + +--- + +## Workflow + +### 1. Task Creation + +```bash +# Standard task - gets +notify automatically +task add "Call dentist" due:tomorrow + +# Task with reminders +task add "Client meeting" due:friday +remind1day +remind1hour +remind15min + +# Long-term project +task add "Quarterly report" due:2026-04-01 +remind1month +remind1week +``` + +### 2. Notification Lifecycle + +``` +Task Created + ↓ +Auto-add +notify (if due date or +remind* present) + ↓ +Every 5 minutes script checks: + - Reminder tags within window → Send reminder, remove tag + - Due tasks without +notified → Send due notification, add +notified + ↓ +Task Completed + ↓ +Remove ALL notification tags (+notify, +notified, +remind*) + ↓ +Task remains in Taskwarrior history (completed tasks list) +``` + +### 3. Notification Types + +**Reminder Notifications:** +- Message: "🔔 Reminder: [description] - Due in [time]" +- Urgency: normal +- Removes the triggered reminder tag + +**Due Notifications:** +- Message: "⚠️ Task Due: [description]" +- Urgency: critical (stays visible) +- Adds +notified tag +- Also sends to ntfy push server + +--- + +## Script Implementation + +**File:** `/etc/nixos/home/sam/bin/task-due-notify.sh` + +**Key Logic:** + +1. **Auto-tag pending tasks** + - Find tasks with due dates OR +remind* tags that don't have +notify + - Add +notify tag to them + +2. **Process reminders** + - For each +remind* tag, calculate if we're within that window + - Send reminder notification + - Remove the reminder tag + +3. **Process due tasks** + - Find tasks due before now without +notified + - Send due notification + - Add +notified tag + +4. **Cleanup completed tasks** + - Remove all notification tags from completed/deleted tasks + - This keeps history clean but preserves task in Taskwarrior + +--- + +## Usage Examples + +### Add Tasks with Reminders + +```bash +# Meeting tomorrow with advance warning +task add "Team standup" due:tomorrow9am +remind15min + +# Important deadline with multiple warnings +task add "Project launch" due:friday +remind1week +remind2days +remind1hour + +# Simple task - just notify when due +task add "Buy milk" due:6pm + +# Add reminder to existing task +task 42 modify +remind30min + +# Remove a reminder +task 42 modify -remind1hour +``` + +### View Tasks + +```bash +# All tasks needing notifications +task +notify list + +# Tasks due now (overdue) +task due.before:now status:pending list + +# Tasks with specific reminder +task +remind1hour list + +# Tasks already notified +task +notified list + +# All reminders (any +remind*) +task tags.has:remind list +``` + +--- + +## Files Modified + +### 1. Notification Script (MODIFIED) +**Path:** `/etc/nixos/home/sam/bin/task-due-notify.sh` + +**Changes:** +- Remove state file dependency +- Add reminder tag processing +- Add auto-tagging logic +- Add cleanup for completed tasks + +### 2. Home Configuration (NO CHANGES NEEDED) +**Path:** `/etc/nixos/home/sam/home.nix` + +Timer and service configuration remain the same: +- 5-minute polling interval +- Same systemd service setup + +### 3. Other Files (NO CHANGES) +- Waybar config: Unchanged +- Niri config: Unchanged +- NixOS config: Unchanged + +--- + +## Migration from State File + +**Step 1:** Deploy new script +**Step 2:** Remove old state file: +```bash +rm ~/.local/share/task-notified +``` +**Step 3:** Run script manually to auto-tag existing tasks: +```bash +~/.local/bin/task-due-notify +``` + +--- + +## Testing Checklist + +- [ ] Add task with due date - verify +notify auto-added +- [ ] Add task with +remind30min - verify +notify auto-added +- [ ] Wait for reminder - verify notification sent, tag removed +- [ ] Wait for due time - verify notification sent, +notified added +- [ ] Complete task - verify all notification tags removed +- [ ] Check ntfy still receives push notifications +- [ ] Verify no duplicate notifications + +--- + +## Commands Reference + +```bash +# Manual script run +~/.local/bin/task-due-notify + +# Check timer +systemctl --user status task-due-notify.timer + +# View notified tasks +task +notified list + +# View tasks with reminders +task tags.has:remind list + +# Add reminder to existing task +task modify +remind1hour + +# Complete task +task done + +# View completed tasks (history preserved) +task status:completed list +``` + +--- + +## Benefits Over State File System + +1. **No file corruption** - Tags are part of task database +2. **Sync-friendly** - Tags sync with taskserver +3. **Queryable** - Can filter/view by notification status +4. **Multiple reminders** - Not limited to one notification +5. **Flexible** - Add/remove reminders anytime +6. **Clean history** - Tags auto-removed, task stays in history +7. **Visible** - See notification status in task info + +--- + +*Next agent should read this file and implement the script changes outlined above.*