Skip to main content

Sessions

Every Libretto session gets its own isolated directory under .libretto/sessions/<name>/. Sessions are git-ignored by default — they contain runtime state and machine-local data that should not be committed. You can run multiple sessions simultaneously. Each session targets a specific browser instance and has its own log files, network capture, and snapshot history.

Starting and ending sessions

# Open a new browser and give the session a name
npx libretto open https://example.com --session my-session

# All commands accept --session to target a specific session
npx libretto snapshot --session my-session --objective "..." --context "..."
npx libretto exec --session my-session "return await page.url()"
npx libretto network --session my-session

# Close a specific session
npx libretto close --session my-session

# Close all open sessions (useful for workspace cleanup)
npx libretto close --all
Treat exploration sessions as disposable unless you explicitly need to keep a session open for continued investigation. Use close --all before starting a fresh automation run to avoid stale browser state.

Session state file

Each session writes a state.json file with metadata about the running browser process:
{
  "version": 1,
  "session": "my-session",
  "port": 9222,
  "pid": 12345,
  "startedAt": "2026-03-26T10:00:00.000Z",
  "status": "active"
}
FieldTypeDescription
versionnumberState file schema version
sessionstringSession name
portnumberChrome DevTools Protocol debug port
pidnumber (optional)Browser process ID
startedAtstringISO 8601 timestamp when the session started
statusstringactive, paused, completed, failed, or exited

Session logs

Each session directory contains several log files you can query directly with jq:
.libretto/
  config.json
  sessions/
    my-session/
      state.json
      logs.jsonl
      network.jsonl
      actions.jsonl
      snapshots/
        snapshot-001.png
        snapshot-001.html
  profiles/
    app.example.com.json

logs.jsonl

Structured CLI and system logs. Contains debug output from Libretto itself — command execution, errors, and internal events.
# View the last 20 log entries
tail -n 20 .libretto/sessions/my-session/logs.jsonl | jq .

actions.jsonl

Recorded user and agent actions. Each line is a JSON object representing one interaction — a click, fill, navigation, or other Playwright action. Libretto records both actions you perform manually in the browser (source: "user") and actions the agent performs programmatically (source: "agent"). Key fields:
FieldDescription
tsISO timestamp
source"user" for captured DOM events, "agent" for Playwright calls
actionAction type: click, fill, goto, reload, etc.
selectorSelector or locator hint (agent entries)
bestSemanticSelectorCanonical selector for user DOM events
successtrue if the action completed, false on failure
valueTyped, selected, or submitted value when the action had one
urlNavigation target for goto-style actions
errorError message when the action failed
# View all recorded actions
tail -n 20 .libretto/sessions/my-session/actions.jsonl | jq .

# Show only failed actions
jq 'select(.success == false)' .libretto/sessions/my-session/actions.jsonl

# Show only user actions
jq 'select(.source == "user")' .libretto/sessions/my-session/actions.jsonl

network.jsonl

Captured HTTP requests and responses. Each line represents one request/response pair. Key fields:
FieldDescription
tsISO timestamp
methodHTTP method: GET, POST, etc.
urlRequest URL
statusHTTP status code
contentTypeResponse content type
responseBodyResponse body string (may be null)
# View all captured network requests
jq . .libretto/sessions/my-session/network.jsonl

# Filter to POST requests only
jq 'select(.method == "POST")' .libretto/sessions/my-session/network.jsonl

# Find requests to a specific API endpoint
jq 'select(.url | contains("/api/"))' .libretto/sessions/my-session/network.jsonl

# View JSON API responses
jq 'select(.contentType | contains("application/json")) | .responseBody' \
  .libretto/sessions/my-session/network.jsonl

snapshots/

The snapshots/ directory contains paired PNG screenshots and HTML files captured by npx libretto snapshot. Each snapshot produces:
  • snapshot-NNN.png — a full-page screenshot
  • snapshot-NNN.html — the full DOM at capture time, used by the AI analysis model

Profiles

Profiles save browser sessions — cookies and localStorage — so you can reuse authenticated state across multiple runs without logging in every time.

Creating a profile

# Open the site in headed mode so you can log in manually
npx libretto open https://app.example.com --headed

# After logging in, save the current session as a profile
npx libretto save app.example.com
The profile is stored at .libretto/profiles/app.example.com.json. It contains:
  • The full cookie jar for the domain
  • localStorage contents for the domain

Using a profile

Pass --auth-profile when running a workflow to inject the saved browser state:
npx libretto run ./workflow.ts main --auth-profile app.example.com
Libretto loads the profile before executing the workflow, so the browser starts in an already-authenticated state.

Profile storage

Profiles are:
  • Stored at .libretto/profiles/<domain>.json
  • Machine-local — not shared between machines
  • Git-ignored — never committed to version control
Sessions can expire. If a profile stops working, repeat the manual login flow and run npx libretto save <domain> again to refresh it.

Best practices

  • Give sessions meaningful names. Use names like debug-login, scrape-run-1, or test-checkout instead of the default. Meaningful names make it easier to identify which browser is which when running npx libretto pages or reading log files.
  • Use profiles to avoid repeated logins. Save authenticated state once and reuse it across runs. This reduces friction during development and avoids login rate limits on the target site.
  • Keep exploration sessions disposable. Unless you explicitly need to return to a browser state, close sessions when you’re done. Stale sessions consume resources and can interfere with fresh runs.
  • Clean up before fresh starts. Run npx libretto close --all before beginning a new automation run to ensure you’re starting with a clean state.
  • Don’t commit profile files. Profiles contain session cookies that are effectively credentials. The .libretto/ directory is already git-ignored, but double-check your .gitignore if you’re storing Libretto state in a non-standard location.

Automation approaches

Compare the four integration strategies and their detection risk profiles.

Bot detection

Understand how sites detect automation and choose approaches that minimize risk.

Build docs developers (and LLMs) love