libretto 0.6.11 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/README.template.md +7 -8
- package/dist/cli/cli.js +0 -22
- package/dist/cli/commands/browser.js +18 -24
- package/dist/cli/commands/execution.js +254 -234
- package/dist/cli/commands/experiments.js +100 -0
- package/dist/cli/commands/setup.js +3 -310
- package/dist/cli/commands/shared.js +10 -0
- package/dist/cli/commands/snapshot.js +46 -64
- package/dist/cli/commands/status.js +1 -40
- package/dist/cli/core/browser.js +303 -124
- package/dist/cli/core/config.js +5 -6
- package/dist/cli/core/context.js +4 -0
- package/dist/cli/core/daemon/config.js +0 -6
- package/dist/cli/core/daemon/daemon.js +497 -90
- package/dist/cli/core/daemon/ipc.js +170 -129
- package/dist/cli/core/daemon/snapshot.js +48 -9
- package/dist/cli/core/experiments.js +39 -0
- package/dist/cli/core/session.js +5 -4
- package/dist/cli/core/skill-version.js +2 -1
- package/dist/cli/core/workflow-runner/runner.js +147 -0
- package/dist/cli/core/workflow-runtime.js +60 -0
- package/dist/cli/index.js +0 -2
- package/dist/cli/router.js +4 -3
- package/dist/shared/debug/pause-handler.d.ts +9 -0
- package/dist/shared/debug/pause-handler.js +15 -0
- package/dist/shared/debug/pause.d.ts +1 -2
- package/dist/shared/debug/pause.js +13 -36
- package/dist/shared/instrumentation/instrument.js +4 -4
- package/dist/shared/ipc/child-process-transport.d.ts +7 -0
- package/dist/shared/ipc/child-process-transport.js +60 -0
- package/dist/shared/ipc/child-process-transport.spec.d.ts +2 -0
- package/dist/shared/ipc/child-process-transport.spec.js +68 -0
- package/dist/shared/ipc/ipc.d.ts +46 -0
- package/dist/shared/ipc/ipc.js +165 -0
- package/dist/shared/ipc/ipc.spec.d.ts +2 -0
- package/dist/shared/ipc/ipc.spec.js +114 -0
- package/dist/shared/ipc/socket-transport.d.ts +9 -0
- package/dist/shared/ipc/socket-transport.js +143 -0
- package/dist/shared/ipc/socket-transport.spec.d.ts +2 -0
- package/dist/shared/ipc/socket-transport.spec.js +117 -0
- package/dist/shared/package-manager.d.ts +7 -0
- package/dist/shared/package-manager.js +60 -0
- package/dist/shared/paths/paths.d.ts +1 -8
- package/dist/shared/paths/paths.js +1 -49
- package/dist/shared/snapshot/capture-snapshot.d.ts +9 -0
- package/dist/shared/snapshot/capture-snapshot.js +463 -0
- package/dist/shared/snapshot/diff-snapshots.d.ts +72 -0
- package/dist/shared/snapshot/diff-snapshots.js +358 -0
- package/dist/shared/snapshot/render-snapshot.d.ts +39 -0
- package/dist/shared/snapshot/render-snapshot.js +651 -0
- package/dist/shared/snapshot/snapshot.spec.d.ts +2 -0
- package/dist/shared/snapshot/snapshot.spec.js +333 -0
- package/dist/shared/snapshot/types.d.ts +40 -0
- package/dist/shared/snapshot/types.js +0 -0
- package/dist/shared/snapshot/wait-for-page-stable.d.ts +17 -0
- package/dist/shared/snapshot/wait-for-page-stable.js +281 -0
- package/dist/shared/state/session-state.d.ts +1 -0
- package/dist/shared/state/session-state.js +1 -0
- package/docs/experiments.md +67 -0
- package/docs/releasing.md +8 -6
- package/package.json +5 -2
- package/skills/libretto/SKILL.md +19 -19
- package/skills/libretto/references/configuration-file-reference.md +6 -12
- package/skills/libretto/references/pages-and-page-targeting.md +1 -1
- package/skills/libretto-readonly/SKILL.md +2 -9
- package/src/cli/AGENTS.md +7 -0
- package/src/cli/cli.ts +0 -23
- package/src/cli/commands/browser.ts +14 -18
- package/src/cli/commands/execution.ts +303 -271
- package/src/cli/commands/experiments.ts +120 -0
- package/src/cli/commands/setup.ts +3 -400
- package/src/cli/commands/shared.ts +20 -0
- package/src/cli/commands/snapshot.ts +54 -94
- package/src/cli/commands/status.ts +1 -48
- package/src/cli/core/browser.ts +372 -150
- package/src/cli/core/config.ts +4 -5
- package/src/cli/core/context.ts +4 -0
- package/src/cli/core/daemon/config.ts +35 -19
- package/src/cli/core/daemon/daemon.ts +645 -107
- package/src/cli/core/daemon/ipc.ts +319 -214
- package/src/cli/core/daemon/snapshot.ts +71 -15
- package/src/cli/core/experiments.ts +56 -0
- package/src/cli/core/resolve-model.ts +5 -0
- package/src/cli/core/session.ts +5 -4
- package/src/cli/core/skill-version.ts +2 -1
- package/src/cli/core/workflow-runner/runner.ts +237 -0
- package/src/cli/core/workflow-runtime.ts +86 -0
- package/src/cli/index.ts +0 -1
- package/src/cli/router.ts +4 -3
- package/src/shared/debug/pause-handler.ts +20 -0
- package/src/shared/debug/pause.ts +14 -48
- package/src/shared/instrumentation/instrument.ts +4 -4
- package/src/shared/ipc/AGENTS.md +24 -0
- package/src/shared/ipc/child-process-transport.spec.ts +86 -0
- package/src/shared/ipc/child-process-transport.ts +96 -0
- package/src/shared/ipc/ipc.spec.ts +161 -0
- package/src/shared/ipc/ipc.ts +288 -0
- package/src/shared/ipc/socket-transport.spec.ts +141 -0
- package/src/shared/ipc/socket-transport.ts +189 -0
- package/src/shared/package-manager.ts +76 -0
- package/src/shared/paths/paths.ts +0 -72
- package/src/shared/snapshot/capture-snapshot.ts +615 -0
- package/src/shared/snapshot/diff-snapshots.ts +579 -0
- package/src/shared/snapshot/render-snapshot.ts +962 -0
- package/src/shared/snapshot/snapshot.spec.ts +388 -0
- package/src/shared/snapshot/types.ts +43 -0
- package/src/shared/snapshot/wait-for-page-stable.ts +425 -0
- package/src/shared/state/session-state.ts +1 -0
- package/dist/cli/commands/ai.js +0 -109
- package/dist/cli/core/ai-model.js +0 -192
- package/dist/cli/core/api-snapshot-analyzer.js +0 -86
- package/dist/cli/core/daemon/index.js +0 -16
- package/dist/cli/core/daemon/spawn.js +0 -90
- package/dist/cli/core/pause-signals.js +0 -29
- package/dist/cli/core/snapshot-analyzer.js +0 -666
- package/dist/cli/workers/run-integration-runtime.js +0 -235
- package/dist/cli/workers/run-integration-worker-protocol.js +0 -17
- package/dist/cli/workers/run-integration-worker.js +0 -64
- package/scripts/summarize-evals.mjs +0 -135
- package/src/cli/commands/ai.ts +0 -143
- package/src/cli/core/ai-model.ts +0 -298
- package/src/cli/core/api-snapshot-analyzer.ts +0 -110
- package/src/cli/core/daemon/index.ts +0 -24
- package/src/cli/core/daemon/spawn.ts +0 -171
- package/src/cli/core/pause-signals.ts +0 -35
- package/src/cli/core/snapshot-analyzer.ts +0 -855
- package/src/cli/workers/run-integration-runtime.ts +0 -326
- package/src/cli/workers/run-integration-worker-protocol.ts +0 -19
- package/src/cli/workers/run-integration-worker.ts +0 -72
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Experiments Framework
|
|
2
|
+
|
|
3
|
+
Use this reference when adding or changing Libretto experiment flags, wiring experiment checks through CLI or daemon internals, or debugging `libretto experiments` behavior.
|
|
4
|
+
|
|
5
|
+
## Purpose and Scope
|
|
6
|
+
|
|
7
|
+
Experiments are boolean feature flags for Libretto internal machinery. They let maintainers enable in-progress CLI or daemon behavior in a workspace without exposing those flags to user workflow code.
|
|
8
|
+
|
|
9
|
+
Do not add experiments to `LibrettoWorkflowContext` in `packages/libretto/src/shared/workflow/workflow.ts`. User workflows should not branch on Libretto experiment flags.
|
|
10
|
+
|
|
11
|
+
## Registry and Workspace State
|
|
12
|
+
|
|
13
|
+
The experiment registry lives in `packages/libretto/src/cli/core/experiments.ts`.
|
|
14
|
+
|
|
15
|
+
- Add each flag to `EXPERIMENTS` with a stable hyphenated slug, title, description, and `defaultValue`.
|
|
16
|
+
- Use the exported `ExperimentName` and `Experiments` types instead of duplicating flag shapes.
|
|
17
|
+
- Use `resolveExperiments()` to read the resolved boolean snapshot.
|
|
18
|
+
- Use `setExperimentEnabled()` to persist an override and reject unknown flag names.
|
|
19
|
+
|
|
20
|
+
Workspace overrides are stored in `.libretto/config.json` under the optional `experiments` record. The config schema is defined in `packages/libretto/src/cli/core/config.ts`; unknown config fields are still passed through.
|
|
21
|
+
|
|
22
|
+
Example workspace state:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"version": 1,
|
|
27
|
+
"experiments": {
|
|
28
|
+
"compact-snapshot-format": true
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## CLI Behavior
|
|
34
|
+
|
|
35
|
+
`libretto experiments` is the CLI surface for inspecting and changing workspace experiment overrides.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx libretto experiments
|
|
39
|
+
npx libretto experiments describe <experiment>
|
|
40
|
+
npx libretto experiments enable <experiment>
|
|
41
|
+
npx libretto experiments disable <experiment>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The command is implemented in `packages/libretto/src/cli/commands/experiments.ts` and registered as a top-level command. Listing prints registered experiments in registry order with their enabled/disabled state and description. `describe` prints the experiment status and full instructions. `enable` persists the override to `.libretto/config.json` and prints the full description with a prelude that the enabled experiment changes expected Libretto usage from the skill. `disable` persists the override and prints deterministic success text.
|
|
45
|
+
|
|
46
|
+
Invalid actions, missing experiment names, and unknown experiment names should fail with actionable usage that includes the available experiment names.
|
|
47
|
+
|
|
48
|
+
## CLI and Daemon Plumbing
|
|
49
|
+
|
|
50
|
+
Use `withExperiments()` from `packages/libretto/src/cli/commands/shared.ts` when a command needs experiment values. It resolves one experiment snapshot for the CLI invocation and adds it to command context as `ctx.experiments`.
|
|
51
|
+
|
|
52
|
+
Daemon-backed startup paths must serialize that snapshot into `DaemonConfig.experiments` in `packages/libretto/src/cli/core/daemon/config.ts`. This currently applies to:
|
|
53
|
+
|
|
54
|
+
- daemon-backed `open`
|
|
55
|
+
- `connect`
|
|
56
|
+
- provider-backed `open`
|
|
57
|
+
- `run`
|
|
58
|
+
|
|
59
|
+
The daemon receives experiments at startup only. Changes made with `libretto experiments enable|disable` apply to new daemon sessions, not already-running sessions.
|
|
60
|
+
|
|
61
|
+
Inside the daemon, experiments are for Libretto machinery only. Keep them in daemon/controller internals; do not pass them into public workflow context objects.
|
|
62
|
+
|
|
63
|
+
## Testing Notes
|
|
64
|
+
|
|
65
|
+
Before adding or changing tests, read `docs/tests-guide.md`.
|
|
66
|
+
|
|
67
|
+
Prefer user-level CLI behavior tests for `libretto experiments` listing and enable/disable flows. Keep a regression test that an enabled experiment is not visible on `LibrettoWorkflowContext` during `run`.
|
package/docs/releasing.md
CHANGED
|
@@ -24,7 +24,7 @@ This repo does not publish from local machines and does not push directly to `ma
|
|
|
24
24
|
|
|
25
25
|
GitHub Actions needs these repository secrets:
|
|
26
26
|
|
|
27
|
-
- `OPENAI_API_KEY`: used by the existing test suite during the release workflow.
|
|
27
|
+
- `OPENAI_API_KEY`: used by the existing test suite during the release workflow and by the eval workflow's default `openai/gpt-5.5` model.
|
|
28
28
|
|
|
29
29
|
The release workflow uses a GitHub Actions environment named `release`. Create that environment in the repository settings (no required reviewers — access is controlled by branch protection on `main` instead).
|
|
30
30
|
|
|
@@ -69,7 +69,7 @@ The root `scripts/prepare-release.sh` script does the following:
|
|
|
69
69
|
6. Commits the version bump.
|
|
70
70
|
7. Pushes the branch and opens a PR to `main` with the `release` label.
|
|
71
71
|
|
|
72
|
-
Release PRs also run the eval workflow. That workflow
|
|
72
|
+
Release PRs also run the eval workflow. That workflow records score, duration, token, cost, and tool-call metrics for review. Scores are informational: low scores do not fail the workflow, but setup/runtime failures and zero completed records do.
|
|
73
73
|
|
|
74
74
|
## Merge behavior
|
|
75
75
|
|
|
@@ -89,11 +89,13 @@ This makes the workflow safe to re-run after partial failures. For example, if n
|
|
|
89
89
|
|
|
90
90
|
`.github/workflows/evals.yml` now runs automatically for release PRs and for qualifying pushes to `main`.
|
|
91
91
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
92
|
+
- It runs `pnpm evals --no-auth --output <runner-temp>/eval-run` so CI only runs cases that do not require local auth profiles.
|
|
93
|
+
- It validates and renders the CI report with `pnpm evals summary <runner-temp>/eval-run`.
|
|
94
|
+
- It writes a GitHub step summary and a sticky PR comment with aggregate score, duration, token, cost, and tool-call metrics.
|
|
95
|
+
- It uploads summary files and per-case result records from the run output directory. Raw transcripts and local profile files are not uploaded.
|
|
96
|
+
- It fails when the eval runner crashes, required setup is missing, result records are malformed, or zero completed records are produced.
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
There is no baseline comparison gate yet. Add one only after the eval records and metrics are stable enough to compare reliably.
|
|
97
99
|
|
|
98
100
|
## Changelog behavior
|
|
99
101
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libretto",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"description": "AI-powered browser automation library and CLI built on Playwright",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://libretto.sh",
|
|
@@ -37,8 +37,10 @@
|
|
|
37
37
|
"sync-skills": "pnpm run sync:mirrors",
|
|
38
38
|
"check:skills": "pnpm run check:mirrors",
|
|
39
39
|
"build": "tsup --config tsup.config.ts",
|
|
40
|
+
"lint": "lintcn lint --tsconfig tsconfig.json",
|
|
40
41
|
"type-check": "tsc --noEmit",
|
|
41
|
-
"test": "vitest
|
|
42
|
+
"test": "turbo run test:vitest --filter=libretto --log-order=grouped",
|
|
43
|
+
"test:vitest": "vitest run",
|
|
42
44
|
"test:watch": "vitest",
|
|
43
45
|
"cli": "node dist/index.js",
|
|
44
46
|
"generate-changelog": "tsx scripts/generate-changelog.ts",
|
|
@@ -78,6 +80,7 @@
|
|
|
78
80
|
"glimpseui": "^0.5.1",
|
|
79
81
|
"google-auth-library": "^10.6.1",
|
|
80
82
|
"openai": "^6.29.0",
|
|
83
|
+
"outdent": "^0.8.0",
|
|
81
84
|
"tsup": "^8.5.1",
|
|
82
85
|
"typescript": "^5.9.3",
|
|
83
86
|
"vitest": "^4.1.5"
|
package/skills/libretto/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: "Browser automation CLI for building, maintaining, and running brow
|
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: saffron-health
|
|
7
|
-
version: "0.6.
|
|
7
|
+
version: "0.6.13"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
## How Libretto Works
|
|
@@ -34,10 +34,12 @@ Full documentation is published at [libretto.sh](https://libretto.sh). Available
|
|
|
34
34
|
|
|
35
35
|
## Setup
|
|
36
36
|
|
|
37
|
-
- Use `npx libretto setup` for first-time workspace onboarding. It installs Chromium
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
- Use `npx libretto setup` for first-time workspace onboarding. It installs Chromium and syncs skills.
|
|
38
|
+
- Use `npx libretto status` to inspect open sessions without triggering setup.
|
|
39
|
+
|
|
40
|
+
## Experiments
|
|
41
|
+
|
|
42
|
+
- Use `npx libretto experiments` to list internal feature flags and `npx libretto experiments describe <name>` for usage notes when an experiment is enabled.
|
|
41
43
|
|
|
42
44
|
## Working Rules
|
|
43
45
|
|
|
@@ -95,20 +97,15 @@ npx libretto session-mode --session my-session
|
|
|
95
97
|
### `snapshot`
|
|
96
98
|
|
|
97
99
|
- Use `snapshot` as the primary page observation tool.
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
+
- Run `snapshot` without `--objective` or `--context`; the command prints a screenshot path and compact accessibility tree for the current page.
|
|
101
|
+
- Run `snapshot <ref>` to inspect a subtree from the latest full snapshot. Use ref forms printed in the tree, such as `l16`; numeric-suffix aliases such as `e16` also match `l16`.
|
|
102
|
+
- Run an unscoped snapshot before using refs. Subtree snapshots capture a fresh screenshot but reuse the latest cached tree.
|
|
100
103
|
- Use it before guessing at selectors, after workflow failures, and whenever the visible page state is unclear.
|
|
101
|
-
- When analysis is involved, expect it to take time. Use a timeout of at least 2 minutes for shell-wrapped calls.
|
|
102
104
|
|
|
103
105
|
```bash
|
|
104
|
-
npx libretto snapshot
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
npx libretto snapshot \
|
|
108
|
-
--session debug-example \
|
|
109
|
-
--page <page-id> \
|
|
110
|
-
--objective "Explain why the table is empty" \
|
|
111
|
-
--context "I opened the referrals page, applied filters, and expected rows to appear."
|
|
106
|
+
npx libretto snapshot --session debug-example
|
|
107
|
+
npx libretto snapshot <ref> --session debug-example
|
|
108
|
+
npx libretto snapshot --session debug-example --page <page-id>
|
|
112
109
|
```
|
|
113
110
|
|
|
114
111
|
### `exec`
|
|
@@ -120,6 +117,7 @@ npx libretto snapshot \
|
|
|
120
117
|
- Let failures throw. Do not hide `exec` failures with `try/catch` or `.catch()`.
|
|
121
118
|
- Do not run multiple `exec` commands in parallel.
|
|
122
119
|
- Do not use `exec` in read-only diagnosis flows. Use `readonly-exec` from the `libretto-readonly` skill for those sessions.
|
|
120
|
+
- After successful mutations, `exec` prints page-change diffs from compact snapshots.
|
|
123
121
|
|
|
124
122
|
```bash
|
|
125
123
|
npx libretto exec "return await page.url()"
|
|
@@ -142,6 +140,7 @@ npx libretto exec --session debug-example --page <page-id> "return await page.ur
|
|
|
142
140
|
|
|
143
141
|
- Use `run` to verify a workflow file after creating it or editing it, preferring `run --headless` for the normal fix/verify loop.
|
|
144
142
|
- Plain `run` defaults to headed mode.
|
|
143
|
+
- Successful runs close the browser by default. Pass `--stay-open-on-success` when you need to inspect the completed state with `pages`, `snapshot`, or `exec`.
|
|
145
144
|
- Pass `--read-only` if the preserved session should come back locked for follow-up terminal inspection after the workflow run.
|
|
146
145
|
- If the workflow fails, Libretto keeps the browser open. Inspect the failed state with `snapshot` and `exec` before editing code.
|
|
147
146
|
- Insert `await pause(session)` statements in the workflow file when you need to stop at specific states for interactive debugging, like breakpoints in the browser flow.
|
|
@@ -151,6 +150,7 @@ npx libretto exec --session debug-example --page <page-id> "return await page.ur
|
|
|
151
150
|
```bash
|
|
152
151
|
npx libretto run ./integration.ts --headless --params '{"status":"open"}'
|
|
153
152
|
npx libretto run ./integration.ts --headless --read-only
|
|
153
|
+
npx libretto run ./integration.ts --headless --stay-open-on-success
|
|
154
154
|
npx libretto run ./integration.ts --auth-profile app.example.com
|
|
155
155
|
```
|
|
156
156
|
|
|
@@ -225,7 +225,7 @@ Key fields: `ts` (ISO timestamp), `method` (HTTP method, e.g. `GET`, `POST`), `u
|
|
|
225
225
|
Assistant: I'll inspect the real site first if needed, but before I finish I'll create `target-workflow.ts` so the task produces reusable automation code.
|
|
226
226
|
Assistant: [Runs `npx libretto open https://target.example.com --headed`]
|
|
227
227
|
Assistant: [Reads `references/site-security-review.md` before choosing between passive network inspection, direct browser fetch calls, and Playwright-first automation]
|
|
228
|
-
Assistant: [Runs `npx libretto snapshot --
|
|
228
|
+
Assistant: [Runs `npx libretto snapshot --session <session>`]
|
|
229
229
|
Assistant: [Uses `snapshot` and `exec` as needed to understand the site and decide the implementation path]
|
|
230
230
|
Assistant: [Reads `references/code-generation-rules.md` before writing production workflow code]
|
|
231
231
|
Assistant: I found the working path. I'll now create the workflow file and verify it.
|
|
@@ -245,7 +245,7 @@ To watch it yourself in a browser, run: npx libretto run ./target-workflow.ts --
|
|
|
245
245
|
Assistant: I'll reproduce the failure first so we can inspect the exact browser state it leaves behind.
|
|
246
246
|
Assistant: [Runs `npx libretto run ./integration.ts --session debug-flow --headed`]
|
|
247
247
|
Assistant: The workflow failed and Libretto kept the browser open. I'll inspect the page state before changing code.
|
|
248
|
-
Assistant: [Runs `npx libretto snapshot --session debug-flow
|
|
248
|
+
Assistant: [Runs `npx libretto snapshot --session debug-flow`]
|
|
249
249
|
Assistant: [Runs `npx libretto exec --session debug-flow "...focused inspection or prototype..."`]
|
|
250
250
|
Assistant: [Reads `references/code-generation-rules.md` before patching the workflow file]
|
|
251
251
|
Assistant: I found the issue. I'll patch the workflow code and verify.
|
|
@@ -259,7 +259,7 @@ To watch it yourself in a browser, run: npx libretto run ./integration.ts --head
|
|
|
259
259
|
|
|
260
260
|
## References
|
|
261
261
|
|
|
262
|
-
- Read `references/configuration-file-reference.md` when you need to inspect or change `.libretto/config.json` for
|
|
262
|
+
- Read `references/configuration-file-reference.md` when you need to inspect or change `.libretto/config.json` for viewport or session defaults.
|
|
263
263
|
- Read `references/site-security-review.md` before reviewing the site's security posture and deciding whether to lead with network requests, passive interception, or Playwright DOM automation on a new site.
|
|
264
264
|
- Read `references/code-generation-rules.md` before writing or editing production workflow files.
|
|
265
265
|
- Read `references/auth-profiles.md` when auth-profile behavior is relevant.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# Configuration File Reference
|
|
2
2
|
|
|
3
|
-
Use this reference when you need to inspect or change
|
|
3
|
+
Use this reference when you need to inspect or change workspace configuration for default browser behavior.
|
|
4
4
|
|
|
5
5
|
## When to Use This
|
|
6
6
|
|
|
7
|
-
- You want to confirm which AI model `snapshot` will use.
|
|
8
7
|
- You want to understand where Libretto stores workspace-level settings.
|
|
9
8
|
- You want a persistent default viewport for `open` or `run`.
|
|
10
9
|
|
|
@@ -12,14 +11,12 @@ Use this reference when you need to inspect or change the workspace configuratio
|
|
|
12
11
|
|
|
13
12
|
Libretto reads workspace config from `.libretto/config.json`.
|
|
14
13
|
|
|
15
|
-
- The file is created by `npx libretto setup` during first-time onboarding
|
|
16
|
-
-
|
|
17
|
-
- Use `npx libretto status` to inspect the current AI configuration and open sessions without changing anything.
|
|
14
|
+
- The file is created by `npx libretto setup` during first-time onboarding.
|
|
15
|
+
- Use `npx libretto status` to inspect open sessions without changing anything.
|
|
18
16
|
- For first-time setup instructions, follow the main `SKILL.md` flow instead of expanding this reference.
|
|
19
17
|
|
|
20
18
|
## Supported Settings
|
|
21
19
|
|
|
22
|
-
- `snapshotModel` selects the configured analysis model for `snapshot`.
|
|
23
20
|
- `viewport` is an optional top-level setting used by `open` and `run` when you do not pass `--viewport`.
|
|
24
21
|
- Viewport precedence is: CLI `--viewport`, then `.libretto/config.json`, then the default `1366x768`.
|
|
25
22
|
- `sessionMode` sets the default session access mode for new sessions created by `open`, `connect`, and `run`. Must be `"read-only"` or `"write-access"`. When omitted, defaults to `"write-access"`. Pass `--read-only` or `--write-access` to `open`, `connect`, or `run` to override when creating a session.
|
|
@@ -29,7 +26,6 @@ Example:
|
|
|
29
26
|
```json
|
|
30
27
|
{
|
|
31
28
|
"version": 1,
|
|
32
|
-
"snapshotModel": "openai/gpt-5.4",
|
|
33
29
|
"viewport": {
|
|
34
30
|
"width": 1280,
|
|
35
31
|
"height": 800
|
|
@@ -41,9 +37,8 @@ Example:
|
|
|
41
37
|
## Common Commands
|
|
42
38
|
|
|
43
39
|
```bash
|
|
44
|
-
npx libretto setup # first-time onboarding
|
|
45
|
-
npx libretto status # inspect
|
|
46
|
-
npx libretto ai configure openai # explicitly change provider/model
|
|
40
|
+
npx libretto setup # first-time onboarding
|
|
41
|
+
npx libretto status # inspect open sessions
|
|
47
42
|
npx libretto open https://example.com --viewport 1440x900
|
|
48
43
|
npx libretto run ./integration.ts --viewport 1440x900
|
|
49
44
|
```
|
|
@@ -51,5 +46,4 @@ npx libretto run ./integration.ts --viewport 1440x900
|
|
|
51
46
|
## Notes
|
|
52
47
|
|
|
53
48
|
- If you want a persistent default viewport for the workspace, add `viewport` to `.libretto/config.json` instead of repeating `--viewport` on every command.
|
|
54
|
-
-
|
|
55
|
-
- Run `npx libretto status` at any time to check which model is active and whether credentials are present.
|
|
49
|
+
- Run `npx libretto status` at any time to check open sessions.
|
|
@@ -19,7 +19,7 @@ Use this reference when a Libretto session has multiple open pages and you need
|
|
|
19
19
|
```bash
|
|
20
20
|
npx libretto pages --session debug-flow
|
|
21
21
|
npx libretto exec --session debug-flow --page <page-id> "return await page.url()"
|
|
22
|
-
npx libretto snapshot --session debug-flow --page <page-id>
|
|
22
|
+
npx libretto snapshot --session debug-flow --page <page-id>
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Notes
|
|
@@ -4,7 +4,7 @@ description: "Read-only Libretto workflow for diagnosing live browser state with
|
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: saffron-health
|
|
7
|
-
version: "0.6.
|
|
7
|
+
version: "0.6.13"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
## How Libretto Read-Only Works
|
|
@@ -49,14 +49,7 @@ npx libretto pages --session failed-job-debug
|
|
|
49
49
|
### `snapshot`
|
|
50
50
|
|
|
51
51
|
- Use `snapshot` as the first high-level observation tool.
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
npx libretto snapshot \
|
|
56
|
-
--session failed-job-debug \
|
|
57
|
-
--objective "Identify the visible failure state and likely blocking UI condition" \
|
|
58
|
-
--context "The workflow already failed and the preserved browser must remain read-only."
|
|
59
|
-
```
|
|
52
|
+
- Run `snapshot <ref>` to inspect a subtree from the latest full snapshot.
|
|
60
53
|
|
|
61
54
|
### `readonly-exec`
|
|
62
55
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CLI Source
|
|
2
|
+
|
|
3
|
+
## Experiments
|
|
4
|
+
|
|
5
|
+
When adding or changing Libretto experiment flags, read `../../docs/experiments.md` for the registry, CLI command, config, and daemon plumbing conventions.
|
|
6
|
+
|
|
7
|
+
Experiments are internal Libretto machinery. Do not expose them on `LibrettoWorkflowContext` or user workflow APIs.
|
package/src/cli/cli.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { resolveAiSetupStatus } from "./core/ai-model.js";
|
|
2
1
|
import { ensureLibrettoSetup } from "./core/context.js";
|
|
3
2
|
import { createCLIApp } from "./router.js";
|
|
4
3
|
import { warnIfInstalledSkillOutOfDate } from "./core/skill-version.js";
|
|
@@ -16,28 +15,6 @@ Docs (agent-friendly): https://libretto.sh/docs
|
|
|
16
15
|
|
|
17
16
|
function printSetupAudit(): void {
|
|
18
17
|
warnIfInstalledSkillOutOfDate();
|
|
19
|
-
|
|
20
|
-
const status = resolveAiSetupStatus();
|
|
21
|
-
switch (status.kind) {
|
|
22
|
-
case "ready":
|
|
23
|
-
console.log(`✓ Snapshot model: ${status.model}`);
|
|
24
|
-
break;
|
|
25
|
-
case "configured-missing-credentials":
|
|
26
|
-
console.log(
|
|
27
|
-
`✗ ${status.provider} configured (model: ${status.model}), but credentials are missing. Run \`npx libretto setup\` to repair.`,
|
|
28
|
-
);
|
|
29
|
-
break;
|
|
30
|
-
case "invalid-config":
|
|
31
|
-
console.log(
|
|
32
|
-
`✗ AI config is invalid. Run \`npx libretto setup\` to reconfigure.`,
|
|
33
|
-
);
|
|
34
|
-
break;
|
|
35
|
-
case "unconfigured":
|
|
36
|
-
console.log(
|
|
37
|
-
`✗ No AI model configured. Run \`npx libretto setup\` or \`npx libretto ai configure\` to set up.`,
|
|
38
|
-
);
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
18
|
}
|
|
42
19
|
|
|
43
20
|
function isRootHelpRequest(rawArgs: readonly string[]): boolean {
|
|
@@ -9,12 +9,10 @@ import {
|
|
|
9
9
|
runPages,
|
|
10
10
|
runSave,
|
|
11
11
|
} from "../core/browser.js";
|
|
12
|
-
import {
|
|
13
|
-
resolveProviderName,
|
|
14
|
-
getCloudProviderApi,
|
|
15
|
-
} from "../core/providers/index.js";
|
|
12
|
+
import { resolveProviderName } from "../core/providers/index.js";
|
|
16
13
|
import { readLibrettoConfig } from "../core/config.js";
|
|
17
|
-
import { createLoggerForSession
|
|
14
|
+
import { createLoggerForSession } from "../core/context.js";
|
|
15
|
+
import { librettoCommand } from "../../shared/package-manager.js";
|
|
18
16
|
import {
|
|
19
17
|
type SessionAccessMode,
|
|
20
18
|
assertSessionAvailableForStart,
|
|
@@ -26,6 +24,7 @@ import { SimpleCLI } from "../framework/simple-cli.js";
|
|
|
26
24
|
import {
|
|
27
25
|
sessionOption,
|
|
28
26
|
withAutoSession,
|
|
27
|
+
withExperiments,
|
|
29
28
|
withRequiredSession,
|
|
30
29
|
} from "./shared.js";
|
|
31
30
|
|
|
@@ -95,7 +94,7 @@ export const openInput = SimpleCLI.input({
|
|
|
95
94
|
})
|
|
96
95
|
.refine(
|
|
97
96
|
(input) => Boolean(input.url),
|
|
98
|
-
`Usage:
|
|
97
|
+
`Usage: ${librettoCommand("open <url> [--headless] [--read-only|--write-access] [--auth-profile <domain>] [--viewport WxH] [--session <name>]")}`,
|
|
99
98
|
)
|
|
100
99
|
.refine(
|
|
101
100
|
(input) => !(input.headed && input.headless),
|
|
@@ -112,6 +111,7 @@ export const openCommand = SimpleCLI.command({
|
|
|
112
111
|
})
|
|
113
112
|
.input(openInput)
|
|
114
113
|
.use(withAutoSession())
|
|
114
|
+
.use(withExperiments())
|
|
115
115
|
.handle(async ({ input, ctx }) => {
|
|
116
116
|
warnIfInstalledSkillOutOfDate();
|
|
117
117
|
assertSessionAvailableForStart(ctx.session, ctx.logger);
|
|
@@ -126,16 +126,16 @@ export const openCommand = SimpleCLI.command({
|
|
|
126
126
|
input.writeAccess,
|
|
127
127
|
),
|
|
128
128
|
authProfileDomain: input.authProfile,
|
|
129
|
+
experiments: ctx.experiments,
|
|
129
130
|
});
|
|
130
131
|
} else {
|
|
131
|
-
const provider = getCloudProviderApi(providerName);
|
|
132
132
|
await runOpenWithProvider(
|
|
133
133
|
input.url!,
|
|
134
134
|
providerName,
|
|
135
|
-
provider,
|
|
136
135
|
ctx.session,
|
|
137
136
|
ctx.logger,
|
|
138
137
|
resolveRequestedSessionMode(input.readOnly, input.writeAccess),
|
|
138
|
+
ctx.experiments,
|
|
139
139
|
);
|
|
140
140
|
}
|
|
141
141
|
});
|
|
@@ -160,7 +160,7 @@ export const connectInput = SimpleCLI.input({
|
|
|
160
160
|
})
|
|
161
161
|
.refine(
|
|
162
162
|
(input) => Boolean(input.cdpUrl),
|
|
163
|
-
`Usage:
|
|
163
|
+
`Usage: ${librettoCommand("connect <cdp-url> [--read-only|--write-access] --session <name>")}`,
|
|
164
164
|
)
|
|
165
165
|
.refine(
|
|
166
166
|
(input) => !(input.readOnly && input.writeAccess),
|
|
@@ -172,6 +172,7 @@ export const connectCommand = SimpleCLI.command({
|
|
|
172
172
|
})
|
|
173
173
|
.input(connectInput)
|
|
174
174
|
.use(withAutoSession())
|
|
175
|
+
.use(withExperiments())
|
|
175
176
|
.handle(async ({ input, ctx }) => {
|
|
176
177
|
warnIfInstalledSkillOutOfDate();
|
|
177
178
|
await runConnectWithLogger(
|
|
@@ -179,6 +180,7 @@ export const connectCommand = SimpleCLI.command({
|
|
|
179
180
|
ctx.session,
|
|
180
181
|
ctx.logger,
|
|
181
182
|
resolveRequestedSessionMode(input.readOnly, input.writeAccess),
|
|
183
|
+
ctx.experiments,
|
|
182
184
|
);
|
|
183
185
|
});
|
|
184
186
|
|
|
@@ -193,7 +195,7 @@ export const saveInput = SimpleCLI.input({
|
|
|
193
195
|
},
|
|
194
196
|
}).refine(
|
|
195
197
|
(input) => Boolean(input.urlOrDomain),
|
|
196
|
-
`Usage:
|
|
198
|
+
`Usage: ${librettoCommand("save <url|domain> --session <name>")}`,
|
|
197
199
|
);
|
|
198
200
|
|
|
199
201
|
export const saveCommand = SimpleCLI.command({
|
|
@@ -264,7 +266,7 @@ export const closeInput = SimpleCLI.input({
|
|
|
264
266
|
},
|
|
265
267
|
}).refine(
|
|
266
268
|
(input) => input.all || input.session,
|
|
267
|
-
`Usage:
|
|
269
|
+
`Usage: ${librettoCommand("close <session>")}\nUsage: ${librettoCommand("close --all [--force]")}`,
|
|
268
270
|
);
|
|
269
271
|
|
|
270
272
|
export const closeCommand = SimpleCLI.command({
|
|
@@ -273,7 +275,7 @@ export const closeCommand = SimpleCLI.command({
|
|
|
273
275
|
.input(closeInput)
|
|
274
276
|
.handle(async ({ input }) => {
|
|
275
277
|
if (input.force && !input.all) {
|
|
276
|
-
throw new Error(`Usage:
|
|
278
|
+
throw new Error(`Usage: ${librettoCommand("close --all [--force]")}`);
|
|
277
279
|
}
|
|
278
280
|
if (input.all) {
|
|
279
281
|
const logger = createLoggerForSession("cli");
|
|
@@ -293,9 +295,3 @@ export const browserCommands = {
|
|
|
293
295
|
"session-mode": sessionModeCommand,
|
|
294
296
|
close: closeCommand,
|
|
295
297
|
};
|
|
296
|
-
|
|
297
|
-
export async function runClose(session: string): Promise<void> {
|
|
298
|
-
await withSessionLogger(session, async (logger) => {
|
|
299
|
-
await runCloseWithLogger(session, logger);
|
|
300
|
-
});
|
|
301
|
-
}
|