Skip to content

feat: seed reminders from config so modulex.toml is the single source of truth on first run #54

Description

@hartsock

Summary

Allow reminders (and countdowns) to be declared in modulex.toml and automatically synced into the SQLite store on startup, so the config file can serve as the authoritative source rather than requiring every reminder to be added imperatively via modulex remind add.

Motivation

Today reminders live in two places:

  • Store (~/.modulex/store.db): the runtime source for the reminders step, populated via modulex remind add or MCP reminder_add.
  • Config-adjacent files (e.g. a YAML morning config from a previous tool): what users actually maintain, because it's version-controllable and diff-friendly.

When migrating from another tool, or when a user wants to check their reminders into version control alongside the rest of their config, there is no path from config → store. They must re-enter every reminder imperatively.

Proposed design

New top-level config tables:

# Declarative reminders — synced into the store on startup.
# Store-only reminders (added via CLI/MCP) are unaffected.
[[config_reminders]]
label    = "weekly review"
note     = "Review open tickets and triage anything stale."
recur    = "weekly"            # none | daily | weekday | weekly | monthly
due      = "2026-06-16"        # optional first occurrence

[[config_reminders]]
label    = "project deadline nag"
note     = "Check status before the end of the sprint."
until_resolved = true          # stays active until dismissed

# Declarative countdowns — synced into the store on startup.
[[config_countdowns]]
label            = "project ramp"
start_date       = "2026-06-01"
end_date         = "2026-07-15"
total_work_days  = 30
display          = "{label}: work day {n} of {total}"

Sync semantics:

  • On engine init, diff config reminders against the store by label (the stable key).
  • Add entries present in config but missing from the store.
  • Update entries where the config value differs from the stored value.
  • Leave alone store-only entries (added via CLI/MCP) — this is not a destructive sync.
  • A config entry that is later removed from modulex.toml is NOT auto-deleted from the store; modulex remind done <label> or modulex store export/import handles pruning.

Migration helper:

modulex store seed --from <path>   # bulk-import from a YAML/TOML reminders file

Parses a simple flat structure (label, note, due, recur) and inserts missing entries into the store, skipping duplicates. Enables one-time migration without requiring a config-file edit.

Alternatives considered

  • Imperative-only via CLI/MCP: the current behavior; fine for new users but creates friction for migration and makes the config non-authoritative.
  • Config replaces store entirely: too disruptive; agents and the CLI both write to the store dynamically — the store must remain the runtime source.

Acceptance criteria

  • [[config_reminders]] and [[config_countdowns]] parsed from modulex.toml
  • Add-or-update sync on engine init (non-destructive)
  • Store-only entries untouched
  • modulex store seed --from <path> migration helper
  • modulex doctor reports count of config-seeded vs store-only reminders
  • Unit test: config entry absent from store → added; config entry present → updated; store-only entry → unchanged

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions