3.1 KiB
2026-02-23 Session Notes
Scheduled Agent Tasks Feature Plan
Implementing a new "Tasks" dashboard tab that lets users schedule recurring agent prompts via cron expressions. The daemon will poll for due tasks and spawn CLI processes (Claude Code or OpenCode) to execute them.
Scope & Architecture
Feature consists of seven integrated components:
-
Database: Two new tables (
scheduled_tasks,task_runs) with indices on(enabled, next_run_at)and(task_id, status). Migration 012 with backwards-compat via index.ts registration. -
Cron Parsing: Thin wrapper module (
packages/daemon/src/scheduler/cron.ts) aroundcron-parserdependency, exposingcomputeNextRun()andvalidateCron(). Dashboard provides preset shortcuts (15-min, hourly, daily 9am, weekly Monday, custom). -
Scheduler Worker: Polling worker at 15-second interval with max 3 concurrent spawned processes. Uses
Bun.spawnforclaude --dangerously-skip-permissions(Claude Code) andopencode -m(OpenCode) with 10-minute timeout per task. Transactional lease pattern: inserttask_runsrow and updatenext_run_atatomically before spawning. Startup cleanup marks stale running tasks as failed. -
API Routes: CRUD endpoints under
/api/tasks/*— GET all, POST create, GET/PATCH/:id, DELETE, POST/:id/run (manual trigger), GET/:id/runs (paginated history). -
Dashboard UI: Kanban board with four columns (Scheduled, Running, Completed, Failed). Uses existing shadcn-svelte components (Table, Badge, Card, Sheet, Select, Input, Button, ScrollArea, Sonner). New components: TasksTab (header + board), TaskBoard, TaskCard, TaskForm (Sheet with Input/Textarea/Select), TaskDetail, RunLog. Requires adding Switch and Textarea shadcn components.
-
Integration: Wires scheduler worker into daemon startup (line ~7002). Updates navigation store, app-sidebar, and routes in dashboard.
-
Documentation: New SCHEDULING.md covering cron syntax, execution model, security, and troubleshooting. Updates to DASHBOARD.md, API.md, CLAUDE.md, and web/public/skill.md.
Key Decisions
- Polling granularity: 15 seconds (cron minimum is 1 minute, no need for sub-minute precision)
- Concurrency limit: 3 concurrent processes to prevent resource exhaustion
- Process spawning: Via
Bun.spawnwith piped stdout/stderr, capped at 1MB per run - Timeout: 10-minute default per task execution
- Transactional safety: Lease pattern prevents double-execution on scheduler restart
- Kanban columns: Show task states (Scheduled/Running) and recent run states (Completed/Failed) — no drag-and-drop needed
Implementation Order
- Migration + type definitions
- Cron utilities
- Scheduler worker (spawn, worker, index modules)
- API routes wired into daemon.ts
- Dashboard: store, api client, navigation, components (sequential for context retention)
- Documentation
Open Threads
- Confirm which shadcn-svelte components are already installed vs. need
npx shadcn-svelte@next add - Test process timeout behavior and output truncation at 1MB
- Define pagination limit for task_runs queries