Files
nanobot-runtime/skills/remind/SKILL.md
2026-06-10 07:10:11 +02:00

3.4 KiB

/remind

Create, list, edit, enable, disable, and remove recurring or one-time reminders.

How it works

  • Storage: SQLite (db/reminders.sqlite) — atomic transactions, no YAML races.
  • Schema: reminders (text, enabled, timezone, timestamps, soft-delete) + schedule_at / schedule_cron / schedule_random + reminder_fires (dedup + audit).
  • Sender: remind_send.py runs every minute from the user crontab. Reads SQLite, finds due fires, sends to Telegram, logs delivery.
  • Deduplication: Every delivery is recorded in reminder_fires with status delivered/failed. One-time at reminders fire exactly once; cron and random fire once per computed slot.
  • Audit: All mutations and deliveries are logged to log/reminder.log.

Commands

Create a reminder

/remind drink water every day at 9:00
/remind stand up every weekday at 9:30
/remind buy milk at 2026-06-15T18:00
/remind stretch randomly 2 times between 08:00 and 20:00
/remind občanka pana Přibyla once daily at random time between 8:00 and 21:00

The LLM parses natural language and calls remind_edit.py add with the appropriate flags:

  • --text "..."
  • --cron "0 9 * * *" (repeatable)
  • --at "2026-06-15T18:00:00" (repeatable)
  • --random-times-per-day N --random-window HH:MM-HH:MM [--random-days DOW] [--random-from YYYY-MM-DD] [--random-until YYYY-MM-DD]

List reminders

/remind list

Calls remind_edit.py list → JSON with all active reminders and their schedules.

Edit a reminder

/remind edit keyword --text "new text"
/remind edit keyword --replace-schedules --cron "0 10 * * *"

Calls remind_edit.py edit --keyword <keyword>. Keyword is matched case-insensitively against reminder text. Ambiguous matches are rejected.

Enable / Disable

/remind disable keyword
/remind enable keyword

Remove a reminder

/remind remove keyword

Soft delete (sets deleted_at). Hard delete happens only via direct DB access.

Files

File Purpose
skills/remind/scripts/db.py Schema, connection factory (get_db), init_db(), audit log_operation()
skills/remind/scripts/remind_edit.py CRUD CLI: list, add, remove, edit, enable, disable
skills/remind/scripts/remind_send.py Sender: reads SQLite, finds due fires, sends Telegram, dedups
skills/remind/scripts/random_times.py Deterministic random time generator (seeded by text + date)
scripts/migrate_yaml_to_sqlite.py One-shot migration from old reminder.yaml to SQLite
skills/remind/tests/ pytest suite: test_db.py, test_remind_edit.py, test_remind_send.py, test_random_times.py

Crontab

* * * * * uv run /home/nanobot/.nanobot/workspace/skills/remind/scripts/remind_send.py >> /home/nanobot/.nanobot/workspace/log/reminder_cron.log 2>&1

Environment

  • REMIND_DB — override SQLite path (used in tests).
  • python3 is required; python is not available in this runtime.

Design decisions

  • SQLite WAL mode — readers don't block writers.
  • Soft delete — preserves history and foreign-key integrity.
  • Deterministic random — same text + date always yields same times, so dedup works across restarts.
  • JSON output — both edit and send scripts emit structured JSON for easy LLM parsing.
  • No YAML — eliminated race conditions, manual string construction, and fragile parsing.