Skip to content
Night Owls.dev
Jump to a page

@nightowlsdev/runner-background

Runner

The durable runner for Night Owls, runs a swarm turn in Trigger.dev v4 or Vercel Workflow so an ask-suspended run can park for days and resume across process death.

What it does

`createBackgroundRunner({ engine, storage, backend })` returns the core `Runner` whose durable task body loops `engine.run`/`engine.resume`, opening a parkable waitpoint (keyed by `followupId`) on each `ask` suspend so a human-in-the-loop turn can park (default `askTimeout` 7d) and resume across process death; `run()` streams live progress over Supabase Realtime rather than an HTTP task stream. The whole vendor surface reduces to a 3-verb `DurableBackend` seam (enqueueRun / createWaitpoint / completeWaitpoint), with three implementations: `createTriggerBackend` (Trigger.dev v4 waitpoints, with `runDurableTask` + `registerBackgroundSwarm`/`getRegisteredSwarm` for the deployed task), `createVercelBackend` (Vercel Workflow hooks, host-injected callables), and an in-memory backend for hermetic tests. `@trigger.dev/sdk` and `workflow` are optional peers (wire exactly one). It asserts the backend is the single retry owner. It never imports `@mastra/*` and re-exports no Mastra types (the engine wall).

Install

pnpm add @nightowlsdev/runner-background

Key exports

  • createBackgroundRunner
  • registerBackgroundSwarm
  • getRegisteredSwarm
  • buildTaskBody
  • createTriggerBackend
  • runDurableTask
  • createVercelBackend
  • createInMemoryBackend
  • InMemoryDurableBackend
  • verifyDurableLifecycle
  • nightOwlsPlugin
  • DurableBackend
  • Waitpoint
  • DurableTaskBody
  • BackgroundRunnerOpts
  • BackgroundSwarm
  • DurableVerifyResult

Usage

runner-background.ts
import { createBackgroundRunner, createTriggerBackend } from "@nightowlsdev/runner-background";

const backend = createTriggerBackend(/* Trigger.dev v4 wiring */);
const runner = createBackgroundRunner({ engine, storage, backend });

// Suspended HITL turns park on a waitpoint and resume across process death.
await runner.run(ctx, { message: "Draft the launch post." });