Skip to content

Add scheduled reminders with one-shot, interval, and cron support#144

Merged
Aaronontheweb merged 5 commits into
devfrom
claude-wt-reminders
Mar 5, 2026
Merged

Add scheduled reminders with one-shot, interval, and cron support#144
Aaronontheweb merged 5 commits into
devfrom
claude-wt-reminders

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a complete reminder subsystem: schedule prompts to execute at a future time (one-shot), on a recurring interval, or via cron expressions
  • Integrates with akka-reminders for durable scheduling and Akka Streams session pipeline for execution
  • Includes CLI commands (netclaw reminder list/cancel), REST API endpoints, and LLM tools (set_reminder, cancel_reminder, list_reminders)
  • Supports self-targeting (reminders post back to the originating Slack thread) and channel-targeted delivery
  • Adds concurrency limiting, automatic failure-based cancellation, and configurable execution timeouts
  • Fixes 9 code quality issues: protobuf serialization attributes, dead code removal, TimeProvider wiring, config injection, anemic test deletion, server-side filtering for single-reminder fetch, and DTO layering

Test plan

  • dotnet build — 0 errors, 0 warnings
  • dotnet test --filter Reminders — 21 tests pass (3 manager actor + 7 tool + 11 cron helper)
  • dotnet test — full suite passes (710 tests)
  • dotnet slopwatch analyze — 0 issues

Implement the reminders subsystem (PRD-008) using Aaron.Akka.Reminders
for durable scheduling with Cronos for cron expression parsing.

Two reminder modes:
- Self-targeting: re-injects prompt into originating Slack thread
- Autonomous: creates fresh session, posts to configured channel

Core components:
- ReminderManagerActor: singleton actor handling schedule/cancel/list
  with concurrency limits, failure tracking, and auto-cancel threshold
- ReminderExecutionActor: short-lived child per execution, creates
  MaterializedSession via SessionPipeline
- CronScheduleHelper: Cronos wrapper for next-fire computation
- LLM tools: set_reminder, cancel_reminder, list_reminders
- REST API: GET/POST/DELETE /api/reminders endpoints
- CLI: netclaw reminder list|create|cancel|show subcommands

Uses in-memory storage for MVP (reminders do not survive restarts).
…ering

- Add protobuf serialization attributes to ReminderPayload, ReminderSchedule,
  ReminderId, and ReminderScheduleType to prevent silent empty bytes on
  durable storage. Convert record types to sealed classes with proper
  timestamp storage (long ms/ticks) and computed properties.
- Wire TimeProvider through ReminderExecutionActor, replacing two
  DateTimeOffset.UtcNow violations.
- Add try-catch to ReminderExecutionActor.PostStop to prevent disposal
  exceptions from propagating to the guardian.
- Inject ReminderConfig into SetReminderTool, replacing hardcoded 60s
  minimum interval with config-driven MinIntervalSeconds.
- Add GetReminderCommand/GetReminderResponse to move single-reminder
  filtering from REST layer to domain layer.
- Move CreateReminderRequest DTO from domain protocol to Program.cs
  where it belongs (only used by one REST endpoint).
- Delete anemic List_empty_returns_empty test that only asserted NotNull
  on a property that can never be null.
- Replace DateTimeOffset.UtcNow with TimeProvider.System.GetUtcNow() in
  test helper. Remove unused variable in REST POST endpoint.
Move reminder execution to file-backed definitions with pointer payloads, durable SQLite scheduling, and CLI/daemon lifecycle operations so reminders survive restarts and can be safely validated, imported, enabled, disabled, or deleted.
Introduce a six-step reminder builder with textarea-based instruction fields and wire bare reminder CLI invocation to the new Termina page. Extend daemon reminder create requests to accept explicit notify instructions from the UI flow.
@Aaronontheweb Aaronontheweb merged commit 444b868 into dev Mar 5, 2026
4 checks passed
@Aaronontheweb Aaronontheweb deleted the claude-wt-reminders branch March 5, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant