npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@voyant-travel/workflow-runs

v0.122.18

Published

Workflow run recording, admin routes, and rerun/resume dispatch primitives for Voyant operator apps.

Readme

@voyant-travel/workflow-runs

Workflow run recording, admin routes, and rerun/resume dispatch primitives for Voyant operator apps.

Install

pnpm add @voyant-travel/workflow-runs

The package is independently published with the rest of the workflows release cohort.

For the matching importable React admin surface, install @voyant-travel/workflows-react/ui and point its API client at the routes mounted by this package:

import {
  createWorkflowRunsApiClient,
  WorkflowRunsPage,
} from "@voyant-travel/workflows-react/ui"

const workflowRunsApi = createWorkflowRunsApiClient({ apiBase: "/api" })

export function WorkflowsRoute() {
  return <WorkflowRunsPage api={workflowRunsApi} />
}

Selected graph composition

When @voyant-travel/workflow-runs is selected in a Voyant project, its package contributor creates the runner registry and its graph runtime mounts the admin routes. Other selected packages register executable workflows through the workflows.runner-registry runtime port; the generic Node host does not need Workflow Runs-specific wiring.

Agent Tools

The package owns staff-only Tools for listing run summaries, reading one run with its ordered steps, triggering an explicitly registered workflow, and retrying a recorded run through rerun or failed-step resume. Read Tools use the package's recorded-run service. Write Tools dispatch only through the selected workflows.runner-registry port and require explicit workflows:trigger or workflows:retry grants, confirmation, action-ledger recording, and approval.

Workflow management remains owned by the selected deployment provider. Trigger and retry Tools run only when deployment.providers.workflows is self-hosted; managed-cloud, disabled, missing, and unknown selections fail closed. Tool discovery may still describe these operations so remote clients can explain the requirement before invocation.

Trigger and retry are classified at the worst-case critical risk level. The runner port does not yet publish per-workflow side-effect metadata, so callers must not infer a narrower risk from the selected workflow name.

Cancellation is intentionally not exposed. The package's provider-neutral runner port currently has no cancellation capability, and changing a recorded row would not cancel underlying execution. Add cancellation only after the runtime port can prove that the selected provider can cancel a live run.

Direct composition

mountWorkflowRunsAdminRoutes adds the workflow-run list, detail, rerun, and resume endpoints under /v1/admin/workflow-runs, plus an explicit trigger endpoint at POST /v1/admin/workflows/:name/runs.

Applications that do not use the selected deployment graph can still compose the registry and routes directly:

import { mountWorkflowRunsAdminRoutes, WorkflowRunnerRegistry } from "@voyant-travel/workflow-runs"
import { createSelfHostWorkflowClient } from "@voyant-travel/workflows-orchestrator/selfhost"

const workflowRunnerRegistry = new WorkflowRunnerRegistry()
const workflowServer = createSelfHostWorkflowClient({
  baseUrl: process.env.WORKFLOW_SERVER_URL!,
})

workflowRunnerRegistry.register({
  name: "checkout-finalize",
  idempotency: "unsafe",
  description:
    "Confirms the booking and issues the final invoice. Use Resume to retry from a failed step.",
  trigger: async (input, ctx) => {
    const saved = await workflowServer.trigger({
      workflowId: "checkout-finalize",
      input,
      tags: ctx.tags,
      triggeredByUserId: ctx.triggeredByUserId,
    })
    return { runId: saved.id }
  },
  rerun: async (input, ctx) => {
    const saved = await workflowServer.trigger({
      workflowId: "checkout-finalize",
      input,
      tags: [...ctx.tags, "rerun:true"],
    })
    return { runId: saved.id }
  },
  resume: async (input, ctx) => {
    const { saved } = await workflowServer.resume(ctx.parentRunId, {
      workflowId: "checkout-finalize",
      input,
      resumeFromStep: ctx.resumeFromStep,
      seedResults: ctx.seedResults,
      tags: [...ctx.tags, "resume:true"],
      triggeredByUserId: ctx.triggeredByUserId,
    })
    return { runId: saved.id }
  },
})

mountWorkflowRunsAdminRoutes(hono, {
  runners: workflowRunnerRegistry,
  adminSurface: "tenant",
})

adminSurface controls tenant-admin workflow management actions:

  • tenant keeps local/self-host trigger, rerun, and resume routes available.
  • cloud keeps read routes available but rejects tenant-admin trigger, rerun, and resume routes because the Voyant Cloud dashboard is the workflow control plane for managed deployments.
  • disabled keeps read routes available and disables tenant-admin management actions completely.

Direct composition defaults to tenant when adminSurface is omitted. Selected graph composition derives the surface from deployment.providers.workflows: self-hosted maps to tenant, voyant-cloud maps to cloud, and none maps to disabled. Environment variables never select the admin surface or imply provider ownership.

Triggerable workflows must opt in by implementing trigger(...) on their registered runner. This keeps rerun/resume-only workflows closed to arbitrary admin dispatch while still allowing operators, cron jobs, queues, and API keys with workflows:trigger permission to call:

POST /v1/admin/workflows/checkout-finalize/runs
Content-Type: application/json

{
  "input": { "bookingId": "bk_123" },
  "idempotencyKey": "checkout-finalize:bk_123",
  "correlationId": "bk_123",
  "tags": ["source:admin"]
}

The route returns 202 Accepted with the queued run id:

{
  "data": {
    "runId": "wfrn_...",
    "workflowName": "checkout-finalize",
    "status": "queued"
  }
}

For self-hosted workflow services, keep runner registration close to the code that mounts the workflow service. The registry should dispatch to your external workflow server instead of importing worker-only runtime code into the admin API process. The resume path sends ctx.resumeFromStep plus ctx.seedResults; the self-host server starts a new run, pre-populates the journal with the seeded step outputs, and executes from the failed step onward.

Record @voyant-travel/workflows executions

Use recordedWorkflow as a drop-in replacement for workflow(...) when a workflow should appear in the workflow runs admin UI. The helper records start, success, and failure rows in workflow_runs without repeating recorder boilerplate in every workflow body.

import { recordedWorkflow } from "@voyant-travel/workflow-runs"

export const generatePdfWorkflow = recordedWorkflow({
  id: "products.generate-pdf",
  tags: ["products"],
  async run(input, ctx) {
    const renderer = ctx.services.resolve("products:pdf-renderer")
    return renderer.generate(input)
  },
})

By default, recordedWorkflow resolves a Drizzle database from ctx.services.resolve("db"). It records the workflow id, trigger, run id as the correlation id, configured/runtime tags, input, result, parent run id for child workflow triggers, and errors. Recording is best-effort: database or serializer failures do not fail the workflow execution.

You can customize the database service key or payload serializers:

export const syncCatalogWorkflow = recordedWorkflow(
  {
    id: "catalog.sync",
    async run(input, ctx) {
      return ctx.services.resolve("catalog:sync").run(input)
    },
  },
  {
    dbServiceName: "postgres",
    input: ({ input }) => ({ catalogId: input.catalogId }),
    result: ({ output }) => ({ changed: output.changed }),
  },
)

This helper only records observability data. Trigger, rerun, and resume support still uses WorkflowRunnerRegistry registration so apps can choose which workflows are safe to dispatch from the admin UI.