Beevibe Beevibe
Docs menu
Docs
Packages
Project

@beevibe/scheduler

Server-side fallback. Picks up sessions when no daemon will, reaps orphans, handles cancellation.

The scheduler is the safety net. When a mesh ask targets an agent whose daemon is offline, the scheduler runs the session on the server. When a session crashes and leaves an orphan row, the scheduler cleans it up. It runs server-side, polls every 30 seconds, and is stateless — restart it whenever.

What it does, per cycle

1. Reap PID orphans

Sessions whose in-process worker died (process gone, no SIGCHLD picked up) get marked failed and released.

2. Claim server-fallback sessions

Pulls the next session whose target daemon is offline or whose dispatch is flagged for server-side spawn.

3. Check capacity

If the agent is at its max_task_sessions ceiling, the row goes back to pending for the next pass.

4. Provision and dispatch

Sets up the workspace and spawns the run via DispatchService. Streams events back through the same API endpoints the daemon uses.

Cancellation

Cancellation is wired through Postgres notifications. A POST /task/:id/cancel fires NOTIFY cancel_task. A dedicated Postgres client listens for those, finds the matching in-process session by its AbortController, and aborts. The CLI subprocess gets SIGTERM.

Post-dispatch nudges

Two automatic interventions:

Run it

pnpm --filter @beevibe/scheduler build
pnpm --filter @beevibe/scheduler start    # node dist/main.js
pnpm --filter @beevibe/scheduler dev      # watch mode
bash

Override the poll interval with POLL_INTERVAL_MS. Defaults to 30 seconds.

Health endpoint

GET /health returns a JSON snapshot. ok=false with HTTP 503 if polling has stopped or the last successful poll is more than 3× the interval ago.

{
  "ok": true,
  "polling": true,
  "last_poll_at": "2026-05-16T15:42:11Z",
  "in_flight_count": 2,
  "poll_interval_ms": 30000
}
json

Source

For the worker-loop internals, capacity SQL, and PID-reaping logic, see packages/scheduler/README.md on GitHub.