> ## Documentation Index
> Fetch the complete documentation index at: https://libretto.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
npx libretto run ./integration.ts
npx libretto run ./integration.ts --headless
```

#### Syntax

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
npx libretto run <file> [flags]
```

* `<file>`: path to the TypeScript workflow file. The file must have a default-exported `workflow()`.

#### Flags

<ParamField path="--headless" type="boolean">
  Run the browser in headless mode. Use this for the normal fix-and-verify loop.
</ParamField>

<ParamField path="--headed" type="boolean">
  Run the browser in headed (visible) mode. This is the default when neither
  flag is passed.
</ParamField>

<ParamField path="--session" type="string">
  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.
</ParamField>

<ParamField path="--params" type="string">
  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"}'`.
</ParamField>

<ParamField path="--params-file" type="string">
  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`.
</ParamField>

<ParamField path="--viewport" type="string">
  Viewport size in `WIDTHxHEIGHT` format, for example `1920x1080`. Falls back to
  `.libretto/config.json`, then `1366x768`.
</ParamField>

<ParamField path="--tsconfig" type="string">
  Path to a `tsconfig.json` file for module resolution during workflow
  compilation.
</ParamField>

<ParamField path="--no-visualize" type="boolean">
  Disable ghost cursor and element highlight visualization in headed mode.
</ParamField>

<ParamField path="--provider" type="string">
  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`.
</ParamField>

<Info>
  To keep local debugging and workflow runs on the same browser provider, set
  `provider` in `.libretto/config.json`. See [Alternative
  providers](/alternative-providers/overview) for Kernel, Browserbase, Steel, AWS, and
  GCP setup.
</Info>

#### 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.

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
# 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:

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
# 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

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
# 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
```

***

### 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.

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
npx libretto resume --session debug-example
```

#### Flags

<ParamField path="--session" type="string" required>
  The session name of the paused workflow to resume.
</ParamField>

#### 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.

```typescript theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
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 };
  },
);
```

<Note>
  `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.
</Note>

#### Complete debugging flow

<Steps>
  <Step title="Run the workflow and let it fail (or pause)">
    ```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    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.
  </Step>

  <Step title="Inspect the paused page state">
    ```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    npx libretto snapshot --session debug-flow

    npx libretto exec --session debug-flow "await page.url()"
    ```
  </Step>

  <Step title="Resume the workflow">
    ```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    npx libretto resume --session debug-flow
    ```

    Keep running `resume` until the workflow prints `Integration completed.` or fails with an error.
  </Step>

  <Step title="Fix the code and re-run">
    Edit the workflow file to fix any issues found during inspection, then re-run:

    ```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
    npx libretto run ./integration.ts --headless
    ```
  </Step>
</Steps>

<CardGroup cols={2}>
  <Card title="snapshot" icon="camera" href="./snapshot">
    Inspect page state after a failure or pause.
  </Card>

  <Card title="exec" icon="code" href="./exec">
    Prototype fixes against the paused browser before editing code.
  </Card>
</CardGroup>
