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.
Files changed (130) hide show
  1. package/README.md +7 -8
  2. package/README.template.md +7 -8
  3. package/dist/cli/cli.js +0 -22
  4. package/dist/cli/commands/browser.js +18 -24
  5. package/dist/cli/commands/execution.js +254 -234
  6. package/dist/cli/commands/experiments.js +100 -0
  7. package/dist/cli/commands/setup.js +3 -310
  8. package/dist/cli/commands/shared.js +10 -0
  9. package/dist/cli/commands/snapshot.js +46 -64
  10. package/dist/cli/commands/status.js +1 -40
  11. package/dist/cli/core/browser.js +303 -124
  12. package/dist/cli/core/config.js +5 -6
  13. package/dist/cli/core/context.js +4 -0
  14. package/dist/cli/core/daemon/config.js +0 -6
  15. package/dist/cli/core/daemon/daemon.js +497 -90
  16. package/dist/cli/core/daemon/ipc.js +170 -129
  17. package/dist/cli/core/daemon/snapshot.js +48 -9
  18. package/dist/cli/core/experiments.js +39 -0
  19. package/dist/cli/core/session.js +5 -4
  20. package/dist/cli/core/skill-version.js +2 -1
  21. package/dist/cli/core/workflow-runner/runner.js +147 -0
  22. package/dist/cli/core/workflow-runtime.js +60 -0
  23. package/dist/cli/index.js +0 -2
  24. package/dist/cli/router.js +4 -3
  25. package/dist/shared/debug/pause-handler.d.ts +9 -0
  26. package/dist/shared/debug/pause-handler.js +15 -0
  27. package/dist/shared/debug/pause.d.ts +1 -2
  28. package/dist/shared/debug/pause.js +13 -36
  29. package/dist/shared/instrumentation/instrument.js +4 -4
  30. package/dist/shared/ipc/child-process-transport.d.ts +7 -0
  31. package/dist/shared/ipc/child-process-transport.js +60 -0
  32. package/dist/shared/ipc/child-process-transport.spec.d.ts +2 -0
  33. package/dist/shared/ipc/child-process-transport.spec.js +68 -0
  34. package/dist/shared/ipc/ipc.d.ts +46 -0
  35. package/dist/shared/ipc/ipc.js +165 -0
  36. package/dist/shared/ipc/ipc.spec.d.ts +2 -0
  37. package/dist/shared/ipc/ipc.spec.js +114 -0
  38. package/dist/shared/ipc/socket-transport.d.ts +9 -0
  39. package/dist/shared/ipc/socket-transport.js +143 -0
  40. package/dist/shared/ipc/socket-transport.spec.d.ts +2 -0
  41. package/dist/shared/ipc/socket-transport.spec.js +117 -0
  42. package/dist/shared/package-manager.d.ts +7 -0
  43. package/dist/shared/package-manager.js +60 -0
  44. package/dist/shared/paths/paths.d.ts +1 -8
  45. package/dist/shared/paths/paths.js +1 -49
  46. package/dist/shared/snapshot/capture-snapshot.d.ts +9 -0
  47. package/dist/shared/snapshot/capture-snapshot.js +463 -0
  48. package/dist/shared/snapshot/diff-snapshots.d.ts +72 -0
  49. package/dist/shared/snapshot/diff-snapshots.js +358 -0
  50. package/dist/shared/snapshot/render-snapshot.d.ts +39 -0
  51. package/dist/shared/snapshot/render-snapshot.js +651 -0
  52. package/dist/shared/snapshot/snapshot.spec.d.ts +2 -0
  53. package/dist/shared/snapshot/snapshot.spec.js +333 -0
  54. package/dist/shared/snapshot/types.d.ts +40 -0
  55. package/dist/shared/snapshot/types.js +0 -0
  56. package/dist/shared/snapshot/wait-for-page-stable.d.ts +17 -0
  57. package/dist/shared/snapshot/wait-for-page-stable.js +281 -0
  58. package/dist/shared/state/session-state.d.ts +1 -0
  59. package/dist/shared/state/session-state.js +1 -0
  60. package/docs/experiments.md +67 -0
  61. package/docs/releasing.md +8 -6
  62. package/package.json +5 -2
  63. package/skills/libretto/SKILL.md +19 -19
  64. package/skills/libretto/references/configuration-file-reference.md +6 -12
  65. package/skills/libretto/references/pages-and-page-targeting.md +1 -1
  66. package/skills/libretto-readonly/SKILL.md +2 -9
  67. package/src/cli/AGENTS.md +7 -0
  68. package/src/cli/cli.ts +0 -23
  69. package/src/cli/commands/browser.ts +14 -18
  70. package/src/cli/commands/execution.ts +303 -271
  71. package/src/cli/commands/experiments.ts +120 -0
  72. package/src/cli/commands/setup.ts +3 -400
  73. package/src/cli/commands/shared.ts +20 -0
  74. package/src/cli/commands/snapshot.ts +54 -94
  75. package/src/cli/commands/status.ts +1 -48
  76. package/src/cli/core/browser.ts +372 -150
  77. package/src/cli/core/config.ts +4 -5
  78. package/src/cli/core/context.ts +4 -0
  79. package/src/cli/core/daemon/config.ts +35 -19
  80. package/src/cli/core/daemon/daemon.ts +645 -107
  81. package/src/cli/core/daemon/ipc.ts +319 -214
  82. package/src/cli/core/daemon/snapshot.ts +71 -15
  83. package/src/cli/core/experiments.ts +56 -0
  84. package/src/cli/core/resolve-model.ts +5 -0
  85. package/src/cli/core/session.ts +5 -4
  86. package/src/cli/core/skill-version.ts +2 -1
  87. package/src/cli/core/workflow-runner/runner.ts +237 -0
  88. package/src/cli/core/workflow-runtime.ts +86 -0
  89. package/src/cli/index.ts +0 -1
  90. package/src/cli/router.ts +4 -3
  91. package/src/shared/debug/pause-handler.ts +20 -0
  92. package/src/shared/debug/pause.ts +14 -48
  93. package/src/shared/instrumentation/instrument.ts +4 -4
  94. package/src/shared/ipc/AGENTS.md +24 -0
  95. package/src/shared/ipc/child-process-transport.spec.ts +86 -0
  96. package/src/shared/ipc/child-process-transport.ts +96 -0
  97. package/src/shared/ipc/ipc.spec.ts +161 -0
  98. package/src/shared/ipc/ipc.ts +288 -0
  99. package/src/shared/ipc/socket-transport.spec.ts +141 -0
  100. package/src/shared/ipc/socket-transport.ts +189 -0
  101. package/src/shared/package-manager.ts +76 -0
  102. package/src/shared/paths/paths.ts +0 -72
  103. package/src/shared/snapshot/capture-snapshot.ts +615 -0
  104. package/src/shared/snapshot/diff-snapshots.ts +579 -0
  105. package/src/shared/snapshot/render-snapshot.ts +962 -0
  106. package/src/shared/snapshot/snapshot.spec.ts +388 -0
  107. package/src/shared/snapshot/types.ts +43 -0
  108. package/src/shared/snapshot/wait-for-page-stable.ts +425 -0
  109. package/src/shared/state/session-state.ts +1 -0
  110. package/dist/cli/commands/ai.js +0 -109
  111. package/dist/cli/core/ai-model.js +0 -192
  112. package/dist/cli/core/api-snapshot-analyzer.js +0 -86
  113. package/dist/cli/core/daemon/index.js +0 -16
  114. package/dist/cli/core/daemon/spawn.js +0 -90
  115. package/dist/cli/core/pause-signals.js +0 -29
  116. package/dist/cli/core/snapshot-analyzer.js +0 -666
  117. package/dist/cli/workers/run-integration-runtime.js +0 -235
  118. package/dist/cli/workers/run-integration-worker-protocol.js +0 -17
  119. package/dist/cli/workers/run-integration-worker.js +0 -64
  120. package/scripts/summarize-evals.mjs +0 -135
  121. package/src/cli/commands/ai.ts +0 -143
  122. package/src/cli/core/ai-model.ts +0 -298
  123. package/src/cli/core/api-snapshot-analyzer.ts +0 -110
  124. package/src/cli/core/daemon/index.ts +0 -24
  125. package/src/cli/core/daemon/spawn.ts +0 -171
  126. package/src/cli/core/pause-signals.ts +0 -35
  127. package/src/cli/core/snapshot-analyzer.ts +0 -855
  128. package/src/cli/workers/run-integration-runtime.ts +0 -326
  129. package/src/cli/workers/run-integration-worker-protocol.ts +0 -19
  130. package/src/cli/workers/run-integration-worker.ts +0 -72
package/README.md CHANGED
@@ -30,19 +30,14 @@ https://github.com/user-attachments/assets/9b9a0ab3-5133-4b20-b3be-459943349d18
30
30
  ```bash
31
31
  npm install libretto
32
32
 
33
- # First-time onboarding: install skill, download Chromium, and pin the default snapshot model
33
+ # First-time onboarding: install skills and download Chromium
34
34
  npx libretto setup
35
35
 
36
36
  # Check workspace readiness at any time
37
37
  npx libretto status
38
-
39
- # Manually change the snapshot analysis model (advanced override)
40
- npx libretto ai configure <openai | anthropic | gemini | vertex>
41
38
  ```
42
39
 
43
- `setup` detects available provider credentials (e.g. `OPENAI_API_KEY`) and automatically pins the default model to `.libretto/config.json`. Re-running `setup` on a healthy workspace shows the current configuration instead of re-prompting. If credentials are missing for a previously configured provider, `setup` offers an interactive repair flow.
44
-
45
- Use `ai configure` when you want to explicitly switch providers or set a custom model string.
40
+ `setup` creates the `.libretto/` directory, installs agent skills, and downloads Chromium unless you pass `--skip-browsers`.
46
41
 
47
42
  ## Use cases
48
43
 
@@ -78,11 +73,15 @@ You can also use Libretto directly from the command line. All commands accept `-
78
73
 
79
74
  ```bash
80
75
  npx libretto open <url> # launch browser and open a URL
81
- npx libretto snapshot --objective "..." # capture PNG + HTML and analyze with an LLM
76
+ npx libretto run ./integration.ts --headless # run a workflow and close on success
77
+ npx libretto run ./integration.ts --headless --stay-open-on-success # keep a successful run inspectable
78
+ npx libretto snapshot --session <name> # capture a screenshot and compact accessibility tree
82
79
  npx libretto exec "<code>" # execute Playwright TypeScript against the open page
83
80
  npx libretto close # close the browser
84
81
  ```
85
82
 
83
+ `run` sessions are inspectable through the same daemon-backed commands as `open` sessions. Successful runs close the browser by default; pass `--stay-open-on-success` to keep the browser open for `pages`, `snapshot`, and `exec`. Failed or paused workflows keep the browser open so you can inspect the exact page state before fixing or resuming the workflow.
84
+
86
85
  Run `npx libretto help` for the full list of commands.
87
86
 
88
87
  ## Configuration
@@ -28,19 +28,14 @@ https://github.com/user-attachments/assets/9b9a0ab3-5133-4b20-b3be-459943349d18
28
28
  ```bash
29
29
  npm install libretto
30
30
 
31
- # First-time onboarding: install skill, download Chromium, and pin the default snapshot model
31
+ # First-time onboarding: install skills and download Chromium
32
32
  npx libretto setup
33
33
 
34
34
  # Check workspace readiness at any time
35
35
  npx libretto status
36
-
37
- # Manually change the snapshot analysis model (advanced override)
38
- npx libretto ai configure <openai | anthropic | gemini | vertex>
39
36
  ```
40
37
 
41
- `setup` detects available provider credentials (e.g. `OPENAI_API_KEY`) and automatically pins the default model to `.libretto/config.json`. Re-running `setup` on a healthy workspace shows the current configuration instead of re-prompting. If credentials are missing for a previously configured provider, `setup` offers an interactive repair flow.
42
-
43
- Use `ai configure` when you want to explicitly switch providers or set a custom model string.
38
+ `setup` creates the `.libretto/` directory, installs agent skills, and downloads Chromium unless you pass `--skip-browsers`.
44
39
 
45
40
  ## Use cases
46
41
 
@@ -76,11 +71,15 @@ You can also use Libretto directly from the command line. All commands accept `-
76
71
 
77
72
  ```bash
78
73
  npx libretto open <url> # launch browser and open a URL
79
- npx libretto snapshot --objective "..." # capture PNG + HTML and analyze with an LLM
74
+ npx libretto run ./integration.ts --headless # run a workflow and close on success
75
+ npx libretto run ./integration.ts --headless --stay-open-on-success # keep a successful run inspectable
76
+ npx libretto snapshot --session <name> # capture a screenshot and compact accessibility tree
80
77
  npx libretto exec "<code>" # execute Playwright TypeScript against the open page
81
78
  npx libretto close # close the browser
82
79
  ```
83
80
 
81
+ `run` sessions are inspectable through the same daemon-backed commands as `open` sessions. Successful runs close the browser by default; pass `--stay-open-on-success` to keep the browser open for `pages`, `snapshot`, and `exec`. Failed or paused workflows keep the browser open so you can inspect the exact page state before fixing or resuming the workflow.
82
+
84
83
  Run `npx libretto help` for the full list of commands.
85
84
 
86
85
  ## Configuration
package/dist/cli/cli.js 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";
@@ -14,27 +13,6 @@ Docs (agent-friendly): https://libretto.sh/docs
14
13
  }
15
14
  function printSetupAudit() {
16
15
  warnIfInstalledSkillOutOfDate();
17
- const status = resolveAiSetupStatus();
18
- switch (status.kind) {
19
- case "ready":
20
- console.log(`\u2713 Snapshot model: ${status.model}`);
21
- break;
22
- case "configured-missing-credentials":
23
- console.log(
24
- `\u2717 ${status.provider} configured (model: ${status.model}), but credentials are missing. Run \`npx libretto setup\` to repair.`
25
- );
26
- break;
27
- case "invalid-config":
28
- console.log(
29
- `\u2717 AI config is invalid. Run \`npx libretto setup\` to reconfigure.`
30
- );
31
- break;
32
- case "unconfigured":
33
- console.log(
34
- `\u2717 No AI model configured. Run \`npx libretto setup\` or \`npx libretto ai configure\` to set up.`
35
- );
36
- break;
37
- }
38
16
  }
39
17
  function isRootHelpRequest(rawArgs) {
40
18
  if (rawArgs.length === 0) return true;
@@ -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, withSessionLogger } from "../core/context.js";
14
+ import { createLoggerForSession } from "../core/context.js";
15
+ import { librettoCommand } from "../../shared/package-manager.js";
18
16
  import {
19
17
  assertSessionAvailableForStart,
20
18
  setSessionMode,
@@ -25,6 +23,7 @@ import { SimpleCLI } from "../framework/simple-cli.js";
25
23
  import {
26
24
  sessionOption,
27
25
  withAutoSession,
26
+ withExperiments,
28
27
  withRequiredSession
29
28
  } from "./shared.js";
30
29
  function parseViewportArg(viewportArg) {
@@ -82,7 +81,7 @@ const openInput = SimpleCLI.input({
82
81
  }
83
82
  }).refine(
84
83
  (input) => Boolean(input.url),
85
- `Usage: libretto open <url> [--headless] [--read-only|--write-access] [--auth-profile <domain>] [--viewport WxH] [--session <name>]`
84
+ `Usage: ${librettoCommand("open <url> [--headless] [--read-only|--write-access] [--auth-profile <domain>] [--viewport WxH] [--session <name>]")}`
86
85
  ).refine(
87
86
  (input) => !(input.headed && input.headless),
88
87
  "Cannot pass both --headed and --headless."
@@ -92,7 +91,7 @@ const openInput = SimpleCLI.input({
92
91
  );
93
92
  const openCommand = SimpleCLI.command({
94
93
  description: "Launch browser and open URL (headed by default). Automatically loads a saved auth profile for the URL's domain if one exists."
95
- }).input(openInput).use(withAutoSession()).handle(async ({ input, ctx }) => {
94
+ }).input(openInput).use(withAutoSession()).use(withExperiments()).handle(async ({ input, ctx }) => {
96
95
  warnIfInstalledSkillOutOfDate();
97
96
  assertSessionAvailableForStart(ctx.session, ctx.logger);
98
97
  const providerName = resolveProviderName(input.provider);
@@ -105,17 +104,17 @@ const openCommand = SimpleCLI.command({
105
104
  input.readOnly,
106
105
  input.writeAccess
107
106
  ),
108
- authProfileDomain: input.authProfile
107
+ authProfileDomain: input.authProfile,
108
+ experiments: ctx.experiments
109
109
  });
110
110
  } else {
111
- const provider = getCloudProviderApi(providerName);
112
111
  await runOpenWithProvider(
113
112
  input.url,
114
113
  providerName,
115
- provider,
116
114
  ctx.session,
117
115
  ctx.logger,
118
- resolveRequestedSessionMode(input.readOnly, input.writeAccess)
116
+ resolveRequestedSessionMode(input.readOnly, input.writeAccess),
117
+ ctx.experiments
119
118
  );
120
119
  }
121
120
  });
@@ -138,20 +137,21 @@ const connectInput = SimpleCLI.input({
138
137
  }
139
138
  }).refine(
140
139
  (input) => Boolean(input.cdpUrl),
141
- `Usage: libretto connect <cdp-url> [--read-only|--write-access] --session <name>`
140
+ `Usage: ${librettoCommand("connect <cdp-url> [--read-only|--write-access] --session <name>")}`
142
141
  ).refine(
143
142
  (input) => !(input.readOnly && input.writeAccess),
144
143
  "Cannot pass both --read-only and --write-access."
145
144
  );
146
145
  const connectCommand = SimpleCLI.command({
147
146
  description: "Connect to an existing Chrome DevTools Protocol (CDP) endpoint"
148
- }).input(connectInput).use(withAutoSession()).handle(async ({ input, ctx }) => {
147
+ }).input(connectInput).use(withAutoSession()).use(withExperiments()).handle(async ({ input, ctx }) => {
149
148
  warnIfInstalledSkillOutOfDate();
150
149
  await runConnectWithLogger(
151
150
  input.cdpUrl,
152
151
  ctx.session,
153
152
  ctx.logger,
154
- resolveRequestedSessionMode(input.readOnly, input.writeAccess)
153
+ resolveRequestedSessionMode(input.readOnly, input.writeAccess),
154
+ ctx.experiments
155
155
  );
156
156
  });
157
157
  const saveInput = SimpleCLI.input({
@@ -165,7 +165,7 @@ const saveInput = SimpleCLI.input({
165
165
  }
166
166
  }).refine(
167
167
  (input) => Boolean(input.urlOrDomain),
168
- `Usage: libretto save <url|domain> --session <name>`
168
+ `Usage: ${librettoCommand("save <url|domain> --session <name>")}`
169
169
  );
170
170
  const saveCommand = SimpleCLI.command({
171
171
  description: "Save current browser session"
@@ -220,14 +220,14 @@ const closeInput = SimpleCLI.input({
220
220
  }
221
221
  }).refine(
222
222
  (input) => input.all || input.session,
223
- `Usage: libretto close <session>
224
- Usage: libretto close --all [--force]`
223
+ `Usage: ${librettoCommand("close <session>")}
224
+ Usage: ${librettoCommand("close --all [--force]")}`
225
225
  );
226
226
  const closeCommand = SimpleCLI.command({
227
227
  description: "Close the browser"
228
228
  }).input(closeInput).handle(async ({ input }) => {
229
229
  if (input.force && !input.all) {
230
- throw new Error(`Usage: libretto close --all [--force]`);
230
+ throw new Error(`Usage: ${librettoCommand("close --all [--force]")}`);
231
231
  }
232
232
  if (input.all) {
233
233
  const logger2 = createLoggerForSession("cli");
@@ -246,11 +246,6 @@ const browserCommands = {
246
246
  "session-mode": sessionModeCommand,
247
247
  close: closeCommand
248
248
  };
249
- async function runClose(session) {
250
- await withSessionLogger(session, async (logger) => {
251
- await runCloseWithLogger(session, logger);
252
- });
253
- }
254
249
  export {
255
250
  browserCommands,
256
251
  closeCommand,
@@ -262,7 +257,6 @@ export {
262
257
  pagesCommand,
263
258
  pagesInput,
264
259
  parseViewportArg,
265
- runClose,
266
260
  saveCommand,
267
261
  saveInput,
268
262
  sessionModeCommand,