@shrimp-kit/scheduler
v0.1.0
Published
> Schedule engine supporting cron, interval, daily, weekly, and monthly tasks with hot-reload, catch-up, night mode, and file-based queuing.
Downloads
50
Readme
@shrimp-kit/scheduler
Schedule engine supporting cron, interval, daily, weekly, and monthly tasks with hot-reload, catch-up, night mode, and file-based queuing.
Install
bun add @shrimp-kit/schedulerFeatures
- 5 schedule types —
daily,interval,weekly,monthly,cron - Hot-reload — Schedule file changes are auto-detected
- Catch-up — Missed tasks (e.g. after sleep/restart) are automatically executed
- Night mode — Different intervals during specified night hours
- Once tasks — Fire once then auto-disable
- Active windows — Restrict execution to specific time ranges
- File-based queue — Pending tasks persisted to JSON
Usage
Schedule File Format
{
"_version": 1,
"tasks": [
{
"id": "health-check",
"enabled": true,
"description": "Run health check every 30 minutes",
"schedule": {
"type": "interval",
"minutes": 30
},
"command": "check-health"
},
{
"id": "morning-report",
"enabled": true,
"description": "Send morning report at 8:05",
"schedule": {
"type": "daily",
"time": "08:05"
},
"command": "morning-report"
},
{
"id": "weekly-backup",
"enabled": true,
"description": "Weekly backup on Monday",
"schedule": {
"type": "weekly",
"day": "monday",
"time": "03:00"
},
"script": "backup.py"
},
{
"id": "dev-session",
"enabled": true,
"description": "Dev session every 4 hours, longer at night",
"schedule": {
"type": "interval",
"hours": 4,
"nightHours": ["00:00", "08:00"],
"nightIntervalHours": 8
},
"command": "dev-work"
}
]
}Starting the Scheduler
import { Logger } from "@shrimp-kit/core";
import { Scheduler } from "@shrimp-kit/scheduler";
const logger = new Logger({ name: "my-agent", level: "info" });
const scheduler = new Scheduler({
schedulePath: "./data/schedule.json",
statePath: "./data/scheduler-state.json",
queuePath: "./data/pending.json",
pollInterval: 30, // seconds
logger,
onTaskQueued: async (taskId, command) => {
console.log(`Task queued: ${taskId} -> ${command}`);
// e.g., send command to terminal via SendInput
},
onScriptComplete: (taskId, success, output) => {
console.log(`Script ${taskId}: ${success ? "OK" : "FAIL"}`);
},
});
await scheduler.start();
// Scheduler now polls every 30s, evaluating and executing due tasks
// Later...
scheduler.stop();Task Evaluation
Use the evaluator directly for custom scheduling logic:
import { isTaskDue } from "@shrimp-kit/scheduler";
const result = isTaskDue(
{ type: "interval", hours: 2 },
{ lastRun: "2026-03-08T10:00:00Z", lastSuccess: true, runCount: 5, failCount: 0 },
new Date(),
);
// → { isDue: true, reason: "interval_elapsed" }State Management
import { StateManager } from "@shrimp-kit/scheduler";
const state = new StateManager("./data/state.json", logger);
await state.load();
state.recordRun("task-id", true);
const taskState = state.getTaskState("task-id");
// → { lastRun: "2026-03-08T...", lastSuccess: true, runCount: 1, failCount: 0 }
await state.save();Task Queue
import { TaskQueue } from "@shrimp-kit/scheduler";
const queue = new TaskQueue("./data/pending.json", logger);
await queue.enqueue("task-id", "run-backup");
const pending = await queue.drain();
// → [{ taskId: "task-id", command: "run-backup", queuedAt: "..." }]Schedule Config Options
| Field | Type | Description |
|-------|------|-------------|
| type | "daily" \| "interval" \| "weekly" \| "monthly" \| "cron" | Schedule type |
| time | string | Time of day "HH:MM" (daily/weekly/monthly) |
| hours | number | Interval hours |
| minutes | number | Interval minutes |
| day | string | Day of week (weekly) |
| dayOfMonth | number | Day of month 1-31 (monthly) |
| cron | string | Cron expression |
| startAfter | string | Active window start "HH:MM" |
| stopBefore | string | Active window end "HH:MM" |
| once | boolean | Fire once then auto-disable |
| nightHours | [string, string] | Night window ["HH:MM", "HH:MM"] |
| nightIntervalHours | number | Longer interval during night |
API Reference
See src/index.ts for all exports.
