libretto 0.6.11 → 0.6.12

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 (119) hide show
  1. package/README.md +4 -0
  2. package/README.template.md +4 -0
  3. package/dist/cli/cli.js +4 -3
  4. package/dist/cli/commands/ai.js +3 -2
  5. package/dist/cli/commands/browser.js +17 -17
  6. package/dist/cli/commands/execution.js +254 -234
  7. package/dist/cli/commands/experiments.js +100 -0
  8. package/dist/cli/commands/setup.js +20 -34
  9. package/dist/cli/commands/shared.js +10 -0
  10. package/dist/cli/commands/snapshot.js +81 -9
  11. package/dist/cli/commands/status.js +5 -4
  12. package/dist/cli/core/ai-model.js +6 -3
  13. package/dist/cli/core/browser.js +300 -121
  14. package/dist/cli/core/config.js +4 -2
  15. package/dist/cli/core/context.js +4 -0
  16. package/dist/cli/core/daemon/config.js +0 -6
  17. package/dist/cli/core/daemon/daemon.js +535 -89
  18. package/dist/cli/core/daemon/ipc.js +170 -129
  19. package/dist/cli/core/daemon/snapshot.js +72 -6
  20. package/dist/cli/core/experiments.js +66 -0
  21. package/dist/cli/core/session.js +5 -4
  22. package/dist/cli/core/skill-version.js +2 -1
  23. package/dist/cli/core/snapshot-analyzer.js +4 -3
  24. package/dist/cli/core/workflow-runner/runner.js +147 -0
  25. package/dist/cli/core/workflow-runtime.js +60 -0
  26. package/dist/cli/router.js +4 -1
  27. package/dist/shared/debug/pause-handler.d.ts +9 -0
  28. package/dist/shared/debug/pause-handler.js +15 -0
  29. package/dist/shared/debug/pause.d.ts +1 -2
  30. package/dist/shared/debug/pause.js +13 -36
  31. package/dist/shared/ipc/child-process-transport.d.ts +7 -0
  32. package/dist/shared/ipc/child-process-transport.js +60 -0
  33. package/dist/shared/ipc/child-process-transport.spec.d.ts +2 -0
  34. package/dist/shared/ipc/child-process-transport.spec.js +68 -0
  35. package/dist/shared/ipc/ipc.d.ts +46 -0
  36. package/dist/shared/ipc/ipc.js +165 -0
  37. package/dist/shared/ipc/ipc.spec.d.ts +2 -0
  38. package/dist/shared/ipc/ipc.spec.js +114 -0
  39. package/dist/shared/ipc/socket-transport.d.ts +9 -0
  40. package/dist/shared/ipc/socket-transport.js +143 -0
  41. package/dist/shared/ipc/socket-transport.spec.d.ts +2 -0
  42. package/dist/shared/ipc/socket-transport.spec.js +117 -0
  43. package/dist/shared/package-manager.d.ts +7 -0
  44. package/dist/shared/package-manager.js +60 -0
  45. package/dist/shared/paths/paths.d.ts +1 -8
  46. package/dist/shared/paths/paths.js +1 -49
  47. package/dist/shared/snapshot/capture-snapshot.d.ts +9 -0
  48. package/dist/shared/snapshot/capture-snapshot.js +463 -0
  49. package/dist/shared/snapshot/diff-snapshots.d.ts +72 -0
  50. package/dist/shared/snapshot/diff-snapshots.js +358 -0
  51. package/dist/shared/snapshot/render-snapshot.d.ts +39 -0
  52. package/dist/shared/snapshot/render-snapshot.js +651 -0
  53. package/dist/shared/snapshot/snapshot.spec.d.ts +2 -0
  54. package/dist/shared/snapshot/snapshot.spec.js +333 -0
  55. package/dist/shared/snapshot/types.d.ts +40 -0
  56. package/dist/shared/snapshot/types.js +0 -0
  57. package/dist/shared/snapshot/wait-for-page-stable.d.ts +17 -0
  58. package/dist/shared/snapshot/wait-for-page-stable.js +281 -0
  59. package/dist/shared/state/session-state.d.ts +1 -0
  60. package/dist/shared/state/session-state.js +1 -0
  61. package/docs/experiments.md +67 -0
  62. package/package.json +4 -2
  63. package/skills/libretto/SKILL.md +3 -1
  64. package/skills/libretto-readonly/SKILL.md +1 -1
  65. package/src/cli/AGENTS.md +7 -0
  66. package/src/cli/cli.ts +4 -3
  67. package/src/cli/commands/ai.ts +3 -2
  68. package/src/cli/commands/browser.ts +13 -11
  69. package/src/cli/commands/execution.ts +303 -271
  70. package/src/cli/commands/experiments.ts +120 -0
  71. package/src/cli/commands/setup.ts +18 -36
  72. package/src/cli/commands/shared.ts +20 -0
  73. package/src/cli/commands/snapshot.ts +99 -11
  74. package/src/cli/commands/status.ts +5 -4
  75. package/src/cli/core/ai-model.ts +6 -3
  76. package/src/cli/core/browser.ts +369 -147
  77. package/src/cli/core/config.ts +3 -1
  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 +686 -106
  81. package/src/cli/core/daemon/ipc.ts +330 -214
  82. package/src/cli/core/daemon/snapshot.ts +106 -8
  83. package/src/cli/core/experiments.ts +85 -0
  84. package/src/cli/core/session.ts +5 -4
  85. package/src/cli/core/skill-version.ts +2 -1
  86. package/src/cli/core/snapshot-analyzer.ts +4 -3
  87. package/src/cli/core/workflow-runner/runner.ts +237 -0
  88. package/src/cli/core/workflow-runtime.ts +85 -0
  89. package/src/cli/router.ts +4 -1
  90. package/src/shared/debug/pause-handler.ts +20 -0
  91. package/src/shared/debug/pause.ts +14 -48
  92. package/src/shared/ipc/AGENTS.md +24 -0
  93. package/src/shared/ipc/child-process-transport.spec.ts +86 -0
  94. package/src/shared/ipc/child-process-transport.ts +96 -0
  95. package/src/shared/ipc/ipc.spec.ts +161 -0
  96. package/src/shared/ipc/ipc.ts +288 -0
  97. package/src/shared/ipc/socket-transport.spec.ts +141 -0
  98. package/src/shared/ipc/socket-transport.ts +189 -0
  99. package/src/shared/package-manager.ts +76 -0
  100. package/src/shared/paths/paths.ts +0 -72
  101. package/src/shared/snapshot/capture-snapshot.ts +615 -0
  102. package/src/shared/snapshot/diff-snapshots.ts +579 -0
  103. package/src/shared/snapshot/render-snapshot.ts +962 -0
  104. package/src/shared/snapshot/snapshot.spec.ts +388 -0
  105. package/src/shared/snapshot/types.ts +43 -0
  106. package/src/shared/snapshot/wait-for-page-stable.ts +425 -0
  107. package/src/shared/state/session-state.ts +1 -0
  108. package/dist/cli/core/daemon/index.js +0 -16
  109. package/dist/cli/core/daemon/spawn.js +0 -90
  110. package/dist/cli/core/pause-signals.js +0 -29
  111. package/dist/cli/workers/run-integration-runtime.js +0 -235
  112. package/dist/cli/workers/run-integration-worker-protocol.js +0 -17
  113. package/dist/cli/workers/run-integration-worker.js +0 -64
  114. package/src/cli/core/daemon/index.ts +0 -24
  115. package/src/cli/core/daemon/spawn.ts +0 -171
  116. package/src/cli/core/pause-signals.ts +0 -35
  117. package/src/cli/workers/run-integration-runtime.ts +0 -326
  118. package/src/cli/workers/run-integration-worker-protocol.ts +0 -19
  119. package/src/cli/workers/run-integration-worker.ts +0 -72
package/README.md CHANGED
@@ -78,11 +78,15 @@ You can also use Libretto directly from the command line. All commands accept `-
78
78
 
79
79
  ```bash
80
80
  npx libretto open <url> # launch browser and open a URL
81
+ npx libretto run ./integration.ts --headless # run a workflow and close on success
82
+ npx libretto run ./integration.ts --headless --stay-open-on-success # keep a successful run inspectable
81
83
  npx libretto snapshot --objective "..." # capture PNG + HTML and analyze with an LLM
82
84
  npx libretto exec "<code>" # execute Playwright TypeScript against the open page
83
85
  npx libretto close # close the browser
84
86
  ```
85
87
 
88
+ `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.
89
+
86
90
  Run `npx libretto help` for the full list of commands.
87
91
 
88
92
  ## Configuration
@@ -76,11 +76,15 @@ You can also use Libretto directly from the command line. All commands accept `-
76
76
 
77
77
  ```bash
78
78
  npx libretto open <url> # launch browser and open a URL
79
+ npx libretto run ./integration.ts --headless # run a workflow and close on success
80
+ npx libretto run ./integration.ts --headless --stay-open-on-success # keep a successful run inspectable
79
81
  npx libretto snapshot --objective "..." # capture PNG + HTML and analyze with an LLM
80
82
  npx libretto exec "<code>" # execute Playwright TypeScript against the open page
81
83
  npx libretto close # close the browser
82
84
  ```
83
85
 
86
+ `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.
87
+
84
88
  Run `npx libretto help` for the full list of commands.
85
89
 
86
90
  ## Configuration
package/dist/cli/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { resolveAiSetupStatus } from "./core/ai-model.js";
2
2
  import { ensureLibrettoSetup } from "./core/context.js";
3
+ import { librettoCommand } from "../shared/package-manager.js";
3
4
  import { createCLIApp } from "./router.js";
4
5
  import { warnIfInstalledSkillOutOfDate } from "./core/skill-version.js";
5
6
  import { loadEnv } from "../shared/env/load-env.js";
@@ -21,17 +22,17 @@ function printSetupAudit() {
21
22
  break;
22
23
  case "configured-missing-credentials":
23
24
  console.log(
24
- `\u2717 ${status.provider} configured (model: ${status.model}), but credentials are missing. Run \`npx libretto setup\` to repair.`
25
+ `\u2717 ${status.provider} configured (model: ${status.model}), but credentials are missing. Run \`${librettoCommand("setup")}\` to repair.`
25
26
  );
26
27
  break;
27
28
  case "invalid-config":
28
29
  console.log(
29
- `\u2717 AI config is invalid. Run \`npx libretto setup\` to reconfigure.`
30
+ `\u2717 AI config is invalid. Run \`${librettoCommand("setup")}\` to reconfigure.`
30
31
  );
31
32
  break;
32
33
  case "unconfigured":
33
34
  console.log(
34
- `\u2717 No AI model configured. Run \`npx libretto setup\` or \`npx libretto ai configure\` to set up.`
35
+ `\u2717 No AI model configured. Run \`${librettoCommand("setup")}\` or \`${librettoCommand("ai configure")}\` to set up.`
35
36
  );
36
37
  break;
37
38
  }
@@ -6,6 +6,7 @@ import {
6
6
  } from "../core/config.js";
7
7
  import { LIBRETTO_CONFIG_PATH } from "../core/context.js";
8
8
  import { DEFAULT_SNAPSHOT_MODELS } from "../core/ai-model.js";
9
+ import { librettoCommand } from "../../shared/package-manager.js";
9
10
  import { SimpleCLI } from "../framework/simple-cli.js";
10
11
  const PROVIDER_ALIASES = {
11
12
  claude: DEFAULT_SNAPSHOT_MODELS.anthropic,
@@ -33,7 +34,7 @@ function resolveModelFromInput(input) {
33
34
  return DEFAULT_SNAPSHOT_MODELS[normalized] ?? PROVIDER_ALIASES[normalized] ?? null;
34
35
  }
35
36
  function runAiConfigure(input, options = {}) {
36
- const configureCommandName = options.configureCommandName ?? "npx libretto ai configure";
37
+ const configureCommandName = options.configureCommandName ?? librettoCommand("ai configure");
37
38
  const configPath = options.configPath ?? LIBRETTO_CONFIG_PATH;
38
39
  const presetArg = input.preset?.trim();
39
40
  if (!presetArg && !input.clear) {
@@ -96,7 +97,7 @@ const aiCommands = SimpleCLI.group({
96
97
  preset: input.preset
97
98
  },
98
99
  {
99
- configureCommandName: `libretto ai configure`
100
+ configureCommandName: librettoCommand("ai configure")
100
101
  }
101
102
  );
102
103
  })
@@ -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
14
  import { createLoggerForSession, withSessionLogger } 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");