Skip to content

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 09 Mar 18:14
· 6 commits to master since this release

What's New

⏰ Cron System — Scheduled Agent Autonomy

The headline feature of v0.9.0 is the Cron System, giving the MsClaw agent the ability to self-program recurring and one-shot work on a schedule — without human initiation.

Architecture highlights:

  • CronEngine — IHostedService with a 2-second PeriodicTimer that evaluates due jobs and dispatches to the appropriate executor.
  • CronToolProvider — 7 bundled tools (cron_create, cron_list, cron_get, cron_update, cron_delete, cron_pause, cron_resume) registered via IToolProvider, always visible in every session.
  • PromptJobExecutor — creates isolated LLM sessions per execution via SessionPool. Each run gets a fresh cron:{jobId}:{runId} session with full tool access.
  • CommandJobExecutor — runs shell commands via Process.Start() with timeout enforcement. No LLM session, no token cost.
  • CronJobStore — in-memory ConcurrentDictionary cache with atomic write-temp-then-rename persistence to ~/.msclaw/cron/jobs.json.
  • ICronJobExecutor — pluggable executor abstraction. Adding a new job type requires only a new executor and payload variant — zero engine changes.

📅 Three Schedule Types

  • One-shot — "Remind me in 20 minutes" fires once and finalizes
  • Fixed interval — "Check every 30 minutes" fires repeatedly
  • Cron expression — "Weekdays at 9am EST" → 0 9 * * 1-5 with IANA timezone support via Cronos

🛡️ Reliability

  • Transient/permanent error classification via ICronErrorClassifier — exponential backoff (30s → 1m → 5m → 15m → 60m) on transient errors, immediate finalization on permanent errors
  • Atomic persistence — write-temp-then-rename prevents corruption on crash
  • Overdue-on-startup — jobs that missed their window during downtime fire on the first engine tick
  • Concurrency control — configurable limit (default: serial execution) prevents runaway parallel jobs

🎨 UI Integration

Cron job results now appear as purple-striped entries in the browser activity sidebar. Click to expand the full CronRunEvent JSON payload.

Cron result in activity sidebar

📐 Design Refinements

  • ICronRunHistoryStore split from ICronJobStore per Interface Segregation Principle — consumers inject only the interface they need
  • CronJobLifecycle extracted as a pure static helper for state transitions (success/failure/backoff), independently testable from the engine
  • ICronOutputSink decouples the engine from SignalR — future sinks (file logging, webhooks) require no engine changes
  • CronStaggerCalculator applies deterministic per-job offsets to prevent load spikes from jobs at common times

📊 By the Numbers

  • 77 tasks across 6 implementation phases (50 test, 27 impl)
  • 19 source files in Services/Cron/
  • 11 test files with full unit test coverage
  • Built with strict TDD (red → green → refactor) throughout

Full Changelog: v0.8.0...v0.9.0