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
@@ -1,18 +1,15 @@
1
- import { readFileSync, writeFileSync } from "node:fs";
2
1
  import { z } from "zod";
3
2
  import type { LoggerApi } from "../../shared/logger/index.js";
4
- import { condenseDom } from "../../shared/condense-dom/condense-dom.js";
5
3
  import { readSessionState } from "../core/session.js";
6
- import {
7
- type InterpretArgs,
8
- type ScreenshotPair,
9
- } from "../core/snapshot-analyzer.js";
10
4
  import { SimpleCLI } from "../framework/simple-cli.js";
11
- import { pageOption, sessionOption, withRequiredSession } from "./shared.js";
12
- import { runApiInterpret } from "../core/api-snapshot-analyzer.js";
13
- import { readSnapshotModel } from "../core/config.js";
14
- import { resolveSnapshotApiModelOrThrow } from "../core/ai-model.js";
15
- import { DaemonClient } from "../core/daemon/index.js";
5
+ import {
6
+ pageOption,
7
+ sessionOption,
8
+ withRequiredSession,
9
+ } from "./shared.js";
10
+ import { DaemonClient } from "../core/daemon/ipc.js";
11
+ import { librettoCommand } from "../../shared/package-manager.js";
12
+ import { renderSnapshot } from "../../shared/snapshot/render-snapshot.js";
16
13
 
17
14
  export const FALLBACK_SNAPSHOT_VIEWPORT = { width: 1280, height: 800 } as const;
18
15
 
@@ -109,107 +106,70 @@ export async function forceSnapshotViewport(
109
106
  });
110
107
  }
111
108
 
112
- async function captureSnapshot(
113
- session: string,
114
- logger: LoggerApi,
115
- daemonSocketPath: string,
116
- pageId?: string,
117
- ): Promise<ScreenshotPair> {
118
- logger.info("snapshot-via-daemon", { session, pageId });
119
- const client = new DaemonClient(daemonSocketPath);
120
- const { pngPath, htmlPath, snapshotRunId, pageUrl, title } =
121
- await client.snapshot({ pageId });
122
-
123
- // condenseDom runs in the CLI process, not the daemon.
124
- const htmlContent = readFileSync(htmlPath, "utf8");
125
- const condenseResult = condenseDom(htmlContent);
126
- const condensedHtmlPath = htmlPath.replace(/\.html$/, ".condensed.html");
127
- writeFileSync(condensedHtmlPath, condenseResult.html);
128
-
129
- logger.info("snapshot-daemon-success", {
130
- session,
131
- pageUrl,
132
- title,
133
- pngPath,
134
- htmlPath,
135
- condensedHtmlPath,
136
- snapshotRunId,
137
- domCondenseStats: {
138
- originalLength: condenseResult.originalLength,
139
- condensedLength: condenseResult.condensedLength,
140
- reductions: condenseResult.reductions,
141
- },
142
- });
143
-
144
- return { pngPath, htmlPath, condensedHtmlPath, baseName: snapshotRunId };
145
- }
146
-
147
- async function runSnapshot(
148
- session: string,
149
- logger: LoggerApi,
150
- pageId: string | undefined,
151
- objective: string,
152
- context: string,
109
+ async function runCompactSnapshot(
110
+ args: {
111
+ session: string;
112
+ daemonSocketPath?: string;
113
+ logger: LoggerApi;
114
+ pageId?: string;
115
+ ref?: string;
116
+ },
153
117
  ): Promise<void> {
154
- const normalizedObjective = objective.trim();
155
- const normalizedContext = context.trim();
156
-
157
- const snapshotModel = readSnapshotModel();
158
- resolveSnapshotApiModelOrThrow(snapshotModel);
159
-
160
- const state = readSessionState(session, logger);
161
- if (!state?.daemonSocketPath) {
118
+ if (!args.daemonSocketPath) {
162
119
  throw new Error(
163
- `Session "${session}" has no daemon socket. The browser daemon may have crashed. ` +
164
- `Close and reopen the session: libretto close --session ${session}`,
120
+ `Session "${args.session}" has no daemon socket. The browser daemon may have crashed. ` +
121
+ `Close and reopen the session: ${librettoCommand(`close --session ${args.session}`)}`,
165
122
  );
166
123
  }
167
124
 
168
- const { pngPath, htmlPath, condensedHtmlPath } =
169
- await captureSnapshot(session, logger, state.daemonSocketPath, pageId);
170
-
171
- console.log("Screenshot saved:");
172
- console.log(` PNG: ${pngPath}`);
173
- console.log(` HTML: ${htmlPath}`);
174
- console.log(` Condensed HTML: ${condensedHtmlPath}`);
175
-
176
- const interpretArgs: InterpretArgs = {
177
- objective: normalizedObjective,
178
- session,
179
- context: normalizedContext,
180
- pngPath,
181
- htmlPath,
182
- condensedHtmlPath,
183
- };
125
+ args.logger.info("compact-snapshot-via-daemon", {
126
+ session: args.session,
127
+ pageId: args.pageId,
128
+ ref: args.ref,
129
+ });
184
130
 
185
- // Analysis uses direct API calls via the Vercel AI SDK (see api-snapshot-analyzer.ts).
186
- // The legacy CLI-agent path (spawning codex/claude/gemini as a subprocess) is preserved
187
- // in snapshot-analyzer.ts — to switch back, replace this call with:
188
- // await runInterpret(interpretArgs, logger);
189
- await runApiInterpret(interpretArgs, logger, snapshotModel);
131
+ const client = await DaemonClient.connect(args.daemonSocketPath);
132
+ let result: Awaited<ReturnType<DaemonClient["snapshot"]>>;
133
+ try {
134
+ result = await client.snapshot({
135
+ pageId: args.pageId,
136
+ useCachedSnapshot: args.ref !== undefined,
137
+ });
138
+ } finally {
139
+ client.destroy();
140
+ }
141
+ console.log(`Screenshot at ${result.pngPath}`);
142
+ console.log(renderSnapshot(result.snapshot, args.ref));
143
+ console.log(
144
+ `Hint: Use ${librettoCommand(`snapshot <ref> --session ${args.session}`)} to inspect a subtree.`,
145
+ );
190
146
  }
191
147
 
192
148
  export const snapshotInput = SimpleCLI.input({
193
- positionals: [],
149
+ positionals: [
150
+ SimpleCLI.positional("ref", z.string().optional(), {
151
+ help: "Optional element ref to scope output to that subtree (for example, l16 or e16)",
152
+ }),
153
+ ],
194
154
  named: {
195
155
  session: sessionOption(),
196
156
  page: pageOption(),
197
- objective: SimpleCLI.option(z.string()),
198
- context: SimpleCLI.option(z.string()),
157
+ objective: SimpleCLI.option(z.string().optional()),
158
+ context: SimpleCLI.option(z.string().optional()),
199
159
  },
200
160
  });
201
161
 
202
162
  export const snapshotCommand = SimpleCLI.command({
203
- description: "Capture PNG + HTML and analyze with --objective and --context",
163
+ description: "Capture a screenshot and compact accessibility snapshot",
204
164
  })
205
165
  .input(snapshotInput)
206
166
  .use(withRequiredSession())
207
167
  .handle(async ({ input, ctx }) => {
208
- await runSnapshot(
209
- ctx.session,
210
- ctx.logger,
211
- input.page,
212
- input.objective,
213
- input.context,
214
- );
168
+ await runCompactSnapshot({
169
+ session: ctx.session,
170
+ daemonSocketPath: ctx.sessionState.daemonSocketPath,
171
+ logger: ctx.logger,
172
+ pageId: input.page,
173
+ ref: input.ref,
174
+ });
215
175
  });
@@ -1,50 +1,6 @@
1
- import { LIBRETTO_CONFIG_PATH } from "../core/context.js";
2
- import { type AiSetupStatus, resolveAiSetupStatus } from "../core/ai-model.js";
3
1
  import { listRunningSessions, type SessionState } from "../core/session.js";
4
2
  import { SimpleCLI } from "../framework/simple-cli.js";
5
3
 
6
- // ── AI status printing ──────────────────────────────────────────────────────
7
-
8
- function printAiStatus(status: AiSetupStatus): void {
9
- console.log("AI configuration:");
10
-
11
- switch (status.kind) {
12
- case "ready":
13
- console.log(` ✓ Snapshot model: ${status.model}`);
14
- if (status.source === "config") {
15
- console.log(` Config: ${LIBRETTO_CONFIG_PATH}`);
16
- } else {
17
- console.log(` Source: ${status.source}`);
18
- }
19
- console.log(
20
- " To change: npx libretto ai configure openai | anthropic | gemini | vertex | openrouter",
21
- );
22
- break;
23
-
24
- case "configured-missing-credentials":
25
- console.log(
26
- ` ✗ ${status.provider} is configured (model: ${status.model}), but credentials are missing.`,
27
- );
28
- console.log(" Run `npx libretto setup` to repair.");
29
- break;
30
-
31
- case "invalid-config":
32
- console.log(" ✗ Config is invalid:");
33
- for (const line of status.message.split("\n")) {
34
- console.log(` ${line}`);
35
- }
36
- console.log(" Run `npx libretto setup` to reconfigure.");
37
- break;
38
-
39
- case "unconfigured":
40
- console.log(" ✗ No AI model configured.");
41
- console.log(
42
- " Run `npx libretto setup` or `npx libretto ai configure` to set up.",
43
- );
44
- break;
45
- }
46
- }
47
-
48
4
  // ── Session status printing ─────────────────────────────────────────────────
49
5
 
50
6
  function printOpenSessions(sessions: SessionState[]): void {
@@ -67,13 +23,10 @@ function printOpenSessions(sessions: SessionState[]): void {
67
23
  // ── Command ─────────────────────────────────────────────────────────────────
68
24
 
69
25
  export const statusCommand = SimpleCLI.command({
70
- description: "Show workspace status: AI configuration and open sessions",
26
+ description: "Show workspace status and open sessions",
71
27
  })
72
28
  .input(SimpleCLI.input({ positionals: [], named: {} }))
73
29
  .handle(async () => {
74
- const aiStatus = resolveAiSetupStatus();
75
- printAiStatus(aiStatus);
76
-
77
30
  const sessions = listRunningSessions();
78
31
  printOpenSessions(sessions);
79
32
  });