Agent-readable docs index: /docs/llms.txt. Full docs in one file: /docs/llms-full.txt. Download /docs/docs.zip to grep all markdown files locally.

run & resume

Execute a workflow file and resume paused workflows.

run

The run command executes the default export from a TypeScript workflow file against a live browser. Use it to verify a workflow after creating or editing it.
npx libretto run ./integration.ts npx libretto run ./integration.ts --headless

Syntax

npx libretto run <file> [flags]
  • <file>: path to the TypeScript workflow file. The file must have a default-exported workflow().

Flags

path --headlessboolean
Run the browser in headless mode. Use this for the normal fix-and-verify loop.
path --headedboolean
Run the browser in headed (visible) mode. This is the default when neither flag is passed.
path --sessionstring
Name for this run session. Auto-generated if omitted. Use an explicit name to target the session with exec, snapshot, or resume after a failure or pause.
path --paramsstring
Inline JSON input for the workflow, passed as a quoted string. When the workflow uses Zod schemas, Libretto validates this input against schemas.input before the handler runs. Example: --params '{"status":"open"}'.
path --params-filestring
Path to a JSON file to use as workflow input. Cannot be used together with --params. When the workflow uses Zod schemas, the file contents are validated against schemas.input.
path --viewportstring
Viewport size in WIDTHxHEIGHT format, for example 1920x1080. Falls back to .libretto/config.json, then 1366x768.
path --tsconfigstring
Path to a tsconfig.json file for module resolution during workflow compilation.
path --no-visualizeboolean
Disable ghost cursor and element highlight visualization in headed mode.
path --providerstring
Browser provider to use for this run. Must be local, kernel, browserbase, steel, or libretto-cloud. Overrides LIBRETTO_PROVIDER and the provider setting in .libretto/config.json. Cannot be combined with --cdp.
path --cdpstring
Connect to an existing Chrome DevTools Protocol endpoint instead of launching a browser. Use this for Electron apps or Chrome started with --remote-debugging-port. Cannot be combined with --provider, --headed, --headless, or --viewport. Libretto attaches to the selected page without navigating to workflow startUrl, so the existing URL and authentication state stay intact. Closing the Libretto session disconnects from CDP and does not terminate the remote browser.
path --pagestring
When using --cdp, target a specific discovered page id such as page-0 or page-1. Omit to use the default (last operational page). Requires --cdp.
To keep local debugging and workflow runs on the same browser provider, set provider in .libretto/config.json. See Alternative providers for Kernel, Browserbase, Steel, AWS, and GCP setup.

Run against an external CDP browser

Use --cdp when the browser already exists (Electron, remote debugging Chrome, CI browser). Use interactive connect to explore with exec / snapshot; use run --cdp to execute a workflow file against that same endpoint. Unlike a normal run, --cdp does not open workflow startUrl — put the browser on the page you want before the run, or navigate inside the handler.
# Chrome or Electron started with --remote-debugging-port=9222 npx libretto run ./integration.ts --cdp http://127.0.0.1:9222 # Target a specific window/page (ids from `libretto pages` on a connect session) npx libretto run ./integration.ts --cdp http://127.0.0.1:9222 --page page-1

Behavior on failure

When a workflow fails, Libretto keeps the browser open at the point of failure. You can then use snapshot and exec to inspect the live page state before editing the workflow code.
# Workflow fails, browser stays open npx libretto run ./integration.ts --session debug-flow --headed # Inspect the failure state npx libretto snapshot --session debug-flow # Prototype a fix npx libretto exec --session debug-flow "await page.locator('.error-message').textContent()" # Re-run after fixing the code npx libretto run ./integration.ts --headless

Validation loop

Prefer run --headless for the normal fix-and-verify loop. When the headless run passes, do a final headed run if you or the user wants to watch the finished workflow:
# Fix/verify loop, fast, no visible browser npx libretto run ./integration.ts --headless # Final confirmation run, shows the browser npx libretto run ./integration.ts --headed

Examples

# Basic run npx libretto run ./integration.ts # Headless run with inline params npx libretto run ./integration.ts --headless --params '{"status":"open"}' # Run with a params file npx libretto run ./integration.ts --params-file ./params.json # Run with explicit session name for post-failure inspection npx libretto run ./integration.ts --session debug-flow --headed # Run against an external CDP / Electron browser npx libretto run ./integration.ts --cdp http://127.0.0.1:9222

resume

The resume command unpauses a workflow that has stopped at an await pause(session) call. Use it repeatedly until the workflow completes or pauses again at the next breakpoint.
npx libretto resume --session debug-example

Flags

path --sessionstringrequired
The session name of the paused workflow to resume.

The pause() API

Insert await pause(session) calls in your workflow file to create interactive breakpoints, similar to debugger breakpoints in the browser flow. The workflow stops at each pause() call and waits for resume before continuing.
import { workflow, pause } from "libretto"; import { z } from "zod"; export default workflow( "myWorkflow", { input: z.object({}), output: z.object({ done: z.boolean(), }), }, async (ctx) => { const { session, page } = ctx; await page.goto("https://linkedin.com"); // Pause here for inspection await pause(session); await page.locator("#submit").click(); // Pause again before the final step await pause(session); return { done: true }; }, );
pause() is a no-op when NODE_ENV === "production". You can leave pause() calls in your workflow code during development and they will be silently skipped in production.

Complete debugging flow

  1. Run the workflow and let it fail (or pause)
    npx libretto run ./integration.ts --session debug-flow --headed
    If the workflow hits a pause(), it prints Workflow paused. and returns. The browser stays open.
  2. Inspect the paused page state
    npx libretto snapshot --session debug-flow npx libretto exec --session debug-flow "await page.url()"
  3. Resume the workflow
    npx libretto resume --session debug-flow
    Keep running resume until the workflow prints Integration completed. or fails with an error.
  4. Fix the code and re-run
    Edit the workflow file to fix any issues found during inspection, then re-run:
    npx libretto run ./integration.ts --headless