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.

One-shot workflow generation

Give your agent a goal and a URL, and get back a complete browser automation script.
One-shot generation is the fastest way to go from an idea to a working automation. You describe what you want in a single prompt, and your coding agent opens a browser, explores the site, and writes a complete workflow file.

Steps

  1. Prompt your agent
    Describe the site, the data or action you want, and the input/output shape you want the workflow to expose as Zod schemas. The more specific you are, the better your results.
    Example prompt
    Use the Libretto skill. Go on https://sfbay.craigslist.org and scrape the first 10 "free stuff" listings for title, location, and link.
    Include "Use the Libretto skill" so your agent uses Libretto's CLI tools instead of writing a Playwright script from scratch.
  2. Log in when the browser opens (if needed)
    The agent opens a browser window on your screen. If the site requires authentication, the agent will ask you to log in manually. Do that, then tell the agent you're done.
    # What the agent runs behind the scenes npx libretto open https://sfbay.craigslist.org --headless --session one-shot-flow
    If the site needs login, make sure your prompt doesn't say --headless. You can mention "I need to log in first" in your prompt to be explicit.
  3. The agent explores the page
    The agent takes snapshots and tests selectors against the live DOM. You'll see it running commands like npx libretto snapshot and npx libretto exec in your terminal.
    You don't need to do anything during this phase, but you can redirect the agent if it seems stuck:
    The listings are in the main content area, not the sidebar.
  4. Review the generated workflow file
    The agent writes a TypeScript file that exports a workflow(). Here's roughly what to expect:
    import { workflow } from "libretto"; import { z } from "zod"; const outputSchema = z.object({ listings: z.array(z.object({ title: z.string(), location: z.string(), link: z.string().url(), })), }); export default workflow( "freeStuff", { input: z.object({}), output: outputSchema, startUrl: "https://sfbay.craigslist.org/search/zip", }, async (ctx) => { const { page } = ctx; await page.waitForSelector(".result-row"); const rows = await page.locator(".result-row").all(); const listings = []; for (const row of rows.slice(0, 10)) { const title = await row.locator(".result-title").textContent(); const link = await row.locator("a").getAttribute("href"); // ... extract location } return { listings }; }, );
    Things to check:
    • startUrl is set to the workflow's entry page
    • Input/output schemas match what you asked for
    • Selectors look reasonable (class names, data attributes, or ARIA roles, not brittle positional selectors)
    • Pagination logic is present if you asked for more items than fit on one page
  5. Check the validation run
    The agent runs the workflow headless and shows you the output. Check that the returned data looks right.
    # What the agent runs npx libretto run ./free-stuff.ts --headless
    If the output is wrong, tell the agent what's off:
    The location is always empty. It looks like it's reading the wrong element.
    The agent will re-inspect the page and fix the issue.

When to use this approach

  • You're automating a site for the first time and don't know its structure
  • The task is self-contained and clearly scoped ("get the first 10 listings")
  • You want a working script with minimal back-and-forth
  • You don't need to demonstrate the workflow manually first

Tips

After you log in, tell the agent to save the session with npx libretto save. Future runs can restore your login state so you don't have to authenticate every time.
Make sure your coding agent has the Libretto skill installed before starting. Run npm create libretto@latest or npx libretto setup in your project root if you haven't already.