libretto 0.1.4 → 0.2.0

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 (183) hide show
  1. package/README.md +213 -17
  2. package/bin/libretto.mjs +18 -0
  3. package/dist/cli/cli.js +201 -0
  4. package/dist/cli/commands/ai.js +21 -0
  5. package/dist/cli/commands/browser.js +56 -0
  6. package/dist/cli/commands/execution.js +407 -0
  7. package/dist/cli/commands/logs.js +65 -0
  8. package/dist/cli/commands/snapshot.js +99 -0
  9. package/dist/cli/core/ai-config.js +149 -0
  10. package/dist/cli/core/browser.js +687 -0
  11. package/dist/cli/core/context.js +113 -0
  12. package/dist/cli/core/pause-signals.js +29 -0
  13. package/dist/cli/core/session.js +183 -0
  14. package/dist/cli/core/snapshot-analyzer.js +492 -0
  15. package/dist/cli/core/telemetry.js +350 -0
  16. package/dist/cli/index.js +13 -0
  17. package/dist/cli/workers/run-integration-runtime.js +204 -0
  18. package/dist/cli/workers/run-integration-worker-protocol.js +0 -0
  19. package/dist/cli/workers/run-integration-worker.js +83 -0
  20. package/dist/index.cjs +127 -0
  21. package/dist/index.d.cts +22 -0
  22. package/dist/index.d.ts +22 -0
  23. package/dist/index.js +110 -0
  24. package/dist/runtime/download/download.cjs +70 -0
  25. package/dist/runtime/download/download.d.cts +35 -0
  26. package/dist/runtime/download/download.d.ts +35 -0
  27. package/dist/runtime/download/download.js +45 -0
  28. package/dist/runtime/download/index.cjs +30 -0
  29. package/dist/runtime/download/index.d.cts +3 -0
  30. package/dist/runtime/download/index.d.ts +3 -0
  31. package/dist/runtime/download/index.js +8 -0
  32. package/dist/runtime/extract/extract.cjs +87 -0
  33. package/dist/runtime/extract/extract.d.cts +23 -0
  34. package/dist/runtime/extract/extract.d.ts +23 -0
  35. package/dist/runtime/extract/extract.js +63 -0
  36. package/dist/runtime/extract/index.cjs +28 -0
  37. package/dist/runtime/extract/index.d.cts +5 -0
  38. package/dist/runtime/extract/index.d.ts +5 -0
  39. package/dist/runtime/extract/index.js +4 -0
  40. package/dist/runtime/network/index.cjs +28 -0
  41. package/dist/runtime/network/index.d.cts +4 -0
  42. package/dist/runtime/network/index.d.ts +4 -0
  43. package/dist/runtime/network/index.js +6 -0
  44. package/dist/runtime/network/network.cjs +91 -0
  45. package/dist/runtime/network/network.d.cts +28 -0
  46. package/dist/runtime/network/network.d.ts +28 -0
  47. package/dist/runtime/network/network.js +67 -0
  48. package/dist/runtime/recovery/agent.cjs +218 -0
  49. package/dist/runtime/recovery/agent.d.cts +13 -0
  50. package/dist/runtime/recovery/agent.d.ts +13 -0
  51. package/dist/runtime/recovery/agent.js +194 -0
  52. package/dist/runtime/recovery/errors.cjs +122 -0
  53. package/dist/runtime/recovery/errors.d.cts +31 -0
  54. package/dist/runtime/recovery/errors.d.ts +31 -0
  55. package/dist/runtime/recovery/errors.js +98 -0
  56. package/dist/runtime/recovery/index.cjs +34 -0
  57. package/dist/runtime/recovery/index.d.cts +7 -0
  58. package/dist/runtime/recovery/index.d.ts +7 -0
  59. package/dist/runtime/recovery/index.js +10 -0
  60. package/dist/runtime/recovery/recovery.cjs +53 -0
  61. package/dist/runtime/recovery/recovery.d.cts +12 -0
  62. package/dist/runtime/recovery/recovery.d.ts +12 -0
  63. package/dist/runtime/recovery/recovery.js +29 -0
  64. package/dist/runtime/step/index.cjs +31 -0
  65. package/dist/runtime/step/index.d.cts +7 -0
  66. package/dist/runtime/step/index.d.ts +7 -0
  67. package/dist/runtime/step/index.js +6 -0
  68. package/dist/runtime/step/runner.cjs +208 -0
  69. package/dist/runtime/step/runner.d.cts +16 -0
  70. package/dist/runtime/step/runner.d.ts +16 -0
  71. package/dist/runtime/step/runner.js +187 -0
  72. package/dist/runtime/step/step.cjs +67 -0
  73. package/dist/runtime/step/step.d.cts +23 -0
  74. package/dist/runtime/step/step.d.ts +23 -0
  75. package/dist/runtime/step/step.js +43 -0
  76. package/dist/runtime/step/types.cjs +16 -0
  77. package/dist/runtime/step/types.d.cts +72 -0
  78. package/dist/runtime/step/types.d.ts +72 -0
  79. package/dist/runtime/step/types.js +0 -0
  80. package/dist/shared/config/config.cjs +44 -0
  81. package/dist/shared/config/config.d.cts +10 -0
  82. package/dist/shared/config/config.d.ts +10 -0
  83. package/dist/shared/config/config.js +18 -0
  84. package/dist/shared/config/index.cjs +32 -0
  85. package/dist/shared/config/index.d.cts +1 -0
  86. package/dist/shared/config/index.d.ts +1 -0
  87. package/dist/shared/config/index.js +10 -0
  88. package/dist/shared/debug/index.cjs +32 -0
  89. package/dist/shared/debug/index.d.cts +2 -0
  90. package/dist/shared/debug/index.d.ts +2 -0
  91. package/dist/shared/debug/index.js +10 -0
  92. package/dist/shared/debug/pause.cjs +56 -0
  93. package/dist/shared/debug/pause.d.cts +23 -0
  94. package/dist/shared/debug/pause.d.ts +23 -0
  95. package/dist/shared/debug/pause.js +30 -0
  96. package/dist/shared/instrumentation/errors.cjs +81 -0
  97. package/dist/shared/instrumentation/errors.d.cts +12 -0
  98. package/dist/shared/instrumentation/errors.d.ts +12 -0
  99. package/dist/shared/instrumentation/errors.js +57 -0
  100. package/dist/shared/instrumentation/index.cjs +35 -0
  101. package/dist/shared/instrumentation/index.d.cts +6 -0
  102. package/dist/shared/instrumentation/index.d.ts +6 -0
  103. package/dist/shared/instrumentation/index.js +12 -0
  104. package/dist/shared/instrumentation/instrument.cjs +206 -0
  105. package/dist/shared/instrumentation/instrument.d.cts +32 -0
  106. package/dist/shared/instrumentation/instrument.d.ts +32 -0
  107. package/dist/shared/instrumentation/instrument.js +190 -0
  108. package/dist/shared/llm/client.cjs +139 -0
  109. package/dist/shared/llm/client.d.cts +6 -0
  110. package/dist/shared/llm/client.d.ts +6 -0
  111. package/dist/shared/llm/client.js +115 -0
  112. package/dist/shared/llm/index.cjs +28 -0
  113. package/dist/shared/llm/index.d.cts +3 -0
  114. package/dist/shared/llm/index.d.ts +3 -0
  115. package/dist/shared/llm/index.js +4 -0
  116. package/dist/shared/llm/types.cjs +16 -0
  117. package/dist/shared/llm/types.d.cts +34 -0
  118. package/dist/shared/llm/types.d.ts +34 -0
  119. package/dist/shared/llm/types.js +0 -0
  120. package/dist/shared/logger/index.cjs +35 -0
  121. package/dist/shared/logger/index.d.cts +2 -0
  122. package/dist/shared/logger/index.d.ts +2 -0
  123. package/dist/shared/logger/index.js +12 -0
  124. package/dist/shared/logger/logger.cjs +200 -0
  125. package/dist/shared/logger/logger.d.cts +70 -0
  126. package/dist/shared/logger/logger.d.ts +70 -0
  127. package/dist/shared/logger/logger.js +176 -0
  128. package/dist/shared/logger/sinks.cjs +160 -0
  129. package/dist/shared/logger/sinks.d.cts +9 -0
  130. package/dist/shared/logger/sinks.d.ts +9 -0
  131. package/dist/shared/logger/sinks.js +124 -0
  132. package/dist/shared/paths/paths.cjs +104 -0
  133. package/dist/shared/paths/paths.d.cts +10 -0
  134. package/dist/shared/paths/paths.d.ts +10 -0
  135. package/dist/shared/paths/paths.js +73 -0
  136. package/dist/shared/run/api.cjs +35 -0
  137. package/dist/shared/run/api.d.cts +3 -0
  138. package/dist/shared/run/api.d.ts +3 -0
  139. package/dist/shared/run/api.js +12 -0
  140. package/dist/shared/run/browser.cjs +98 -0
  141. package/dist/shared/run/browser.d.cts +22 -0
  142. package/dist/shared/run/browser.d.ts +22 -0
  143. package/dist/shared/run/browser.js +74 -0
  144. package/dist/shared/state/index.cjs +38 -0
  145. package/dist/shared/state/index.d.cts +2 -0
  146. package/dist/shared/state/index.d.ts +2 -0
  147. package/dist/shared/state/index.js +16 -0
  148. package/dist/shared/state/session-state.cjs +85 -0
  149. package/dist/shared/state/session-state.d.cts +34 -0
  150. package/dist/shared/state/session-state.d.ts +34 -0
  151. package/dist/shared/state/session-state.js +56 -0
  152. package/dist/shared/visualization/ghost-cursor.cjs +174 -0
  153. package/dist/shared/visualization/ghost-cursor.d.cts +37 -0
  154. package/dist/shared/visualization/ghost-cursor.d.ts +37 -0
  155. package/dist/shared/visualization/ghost-cursor.js +145 -0
  156. package/dist/shared/visualization/highlight.cjs +134 -0
  157. package/dist/shared/visualization/highlight.d.cts +22 -0
  158. package/dist/shared/visualization/highlight.d.ts +22 -0
  159. package/dist/shared/visualization/highlight.js +108 -0
  160. package/dist/shared/visualization/index.cjs +45 -0
  161. package/dist/shared/visualization/index.d.cts +3 -0
  162. package/dist/shared/visualization/index.d.ts +3 -0
  163. package/dist/shared/visualization/index.js +24 -0
  164. package/dist/shared/workflow/workflow.cjs +47 -0
  165. package/dist/shared/workflow/workflow.d.cts +33 -0
  166. package/dist/shared/workflow/workflow.d.ts +33 -0
  167. package/dist/shared/workflow/workflow.js +21 -0
  168. package/package.json +123 -26
  169. package/.npmignore +0 -2
  170. package/bin/libretto +0 -31
  171. package/lib/connect.js +0 -34
  172. package/lib/export.js +0 -224
  173. package/lib/import.js +0 -168
  174. package/lib/index.js +0 -8
  175. package/lib/log.js +0 -9
  176. package/lib/validate.js +0 -20
  177. package/makefile +0 -8
  178. package/src/connect.coffee +0 -25
  179. package/src/export.coffee +0 -222
  180. package/src/import.coffee +0 -171
  181. package/src/index.coffee +0 -3
  182. package/src/log.coffee +0 -3
  183. package/src/validate.coffee +0 -10
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var ghost_cursor_exports = {};
20
+ __export(ghost_cursor_exports, {
21
+ ensureGhostCursor: () => ensureGhostCursor,
22
+ getGhostCursorPosition: () => getGhostCursorPosition,
23
+ ghostClick: () => ghostClick,
24
+ hideGhostCursor: () => hideGhostCursor,
25
+ moveGhostCursor: () => moveGhostCursor,
26
+ moveGhostCursorWithDistance: () => moveGhostCursorWithDistance
27
+ });
28
+ module.exports = __toCommonJS(ghost_cursor_exports);
29
+ const DEFAULTS = {
30
+ style: "minimal",
31
+ color: "rgba(255, 70, 70, 0.9)",
32
+ size: 20,
33
+ zIndex: 2147483646,
34
+ easing: "cubic-bezier(0.16, 1, 0.3, 1)",
35
+ minDurationMs: 100,
36
+ maxDurationMs: 600,
37
+ speedPxPerMs: 1.5
38
+ };
39
+ const CURSOR_ID = "__libretto_ghost_cursor__";
40
+ function buildCursorSvg(style, color, size) {
41
+ if (style === "dot") {
42
+ return `<div style="width:${size}px;height:${size}px;border-radius:50%;background:${color};"></div>`;
43
+ }
44
+ if (style === "screenstudio") {
45
+ return `<div style="width:${size * 1.4}px;height:${size * 1.4}px;border-radius:50%;background:${color};box-shadow:0 0 ${size * 0.6}px ${color};opacity:0.7;"></div>`;
46
+ }
47
+ return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
48
+ <path d="M5 3L19 12L12 13L9 20L5 3Z" fill="${color}" stroke="rgba(0,0,0,0.3)" stroke-width="1"/>
49
+ </svg>`;
50
+ }
51
+ function buildInitScript(opts) {
52
+ const svg = buildCursorSvg(opts.style, opts.color, opts.size);
53
+ return `
54
+ (function() {
55
+ if (document.getElementById("${CURSOR_ID}")) return;
56
+ var el = document.createElement("div");
57
+ el.id = "${CURSOR_ID}";
58
+ el.style.cssText = "position:fixed;top:0;left:0;z-index:${opts.zIndex};pointer-events:none;transform:translate3d(-100px,-100px,0);transition:none;will-change:transform,opacity;opacity:0;";
59
+ el.innerHTML = ${JSON.stringify(svg)};
60
+ document.documentElement.appendChild(el);
61
+ })();
62
+ `;
63
+ }
64
+ const installedPages = /* @__PURE__ */ new WeakSet();
65
+ async function ensureGhostCursor(page, options) {
66
+ const existingOpts = page.__librettoGhostCursorOpts;
67
+ const opts = { ...DEFAULTS, ...existingOpts ?? {}, ...options };
68
+ const initScript = buildInitScript(opts);
69
+ if (!installedPages.has(page)) {
70
+ installedPages.add(page);
71
+ await page.addInitScript({ content: initScript });
72
+ }
73
+ page.__librettoGhostCursorOpts = opts;
74
+ try {
75
+ await page.evaluate(new Function(initScript));
76
+ } catch {
77
+ }
78
+ }
79
+ async function moveGhostCursor(page, target) {
80
+ const opts = page.__librettoGhostCursorOpts ?? DEFAULTS;
81
+ const durationMs = target.durationMs ?? Math.min(
82
+ opts.maxDurationMs,
83
+ Math.max(opts.minDurationMs, 200)
84
+ // default ~200ms if no distance info
85
+ );
86
+ try {
87
+ await page.evaluate(
88
+ ({ id, x, y, duration, easing }) => {
89
+ const el = document.getElementById(id);
90
+ if (!el) return;
91
+ el.style.opacity = "1";
92
+ el.style.transition = `transform ${duration}ms ${easing}`;
93
+ el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
94
+ },
95
+ { id: CURSOR_ID, x: target.x, y: target.y, duration: durationMs, easing: opts.easing }
96
+ );
97
+ await page.waitForTimeout(durationMs);
98
+ } catch {
99
+ }
100
+ }
101
+ async function moveGhostCursorWithDistance(page, from, to) {
102
+ const opts = page.__librettoGhostCursorOpts ?? DEFAULTS;
103
+ const dx = to.x - from.x;
104
+ const dy = to.y - from.y;
105
+ const distance = Math.sqrt(dx * dx + dy * dy);
106
+ const durationMs = Math.min(
107
+ opts.maxDurationMs,
108
+ Math.max(opts.minDurationMs, distance / opts.speedPxPerMs)
109
+ );
110
+ await moveGhostCursor(page, { x: to.x, y: to.y, durationMs });
111
+ }
112
+ async function ghostClick(page, target) {
113
+ try {
114
+ await page.evaluate(
115
+ ({ id, x, y }) => {
116
+ const el = document.getElementById(id);
117
+ if (!el) return;
118
+ el.style.transform = `translate3d(${x}px, ${y}px, 0) scale(0.93)`;
119
+ el.style.transition = "transform 80ms ease-out";
120
+ },
121
+ { id: CURSOR_ID, x: target.x, y: target.y }
122
+ );
123
+ await page.waitForTimeout(100);
124
+ await page.evaluate(
125
+ ({ id, x, y }) => {
126
+ const el = document.getElementById(id);
127
+ if (!el) return;
128
+ el.style.transform = `translate3d(${x}px, ${y}px, 0) scale(1)`;
129
+ el.style.transition = "transform 120ms ease-out";
130
+ },
131
+ { id: CURSOR_ID, x: target.x, y: target.y }
132
+ );
133
+ await page.waitForTimeout(130);
134
+ } catch {
135
+ }
136
+ }
137
+ async function hideGhostCursor(page) {
138
+ try {
139
+ await page.evaluate(
140
+ ({ id }) => {
141
+ const el = document.getElementById(id);
142
+ if (!el) return;
143
+ el.style.transition = "opacity 300ms ease-out";
144
+ el.style.opacity = "0";
145
+ },
146
+ { id: CURSOR_ID }
147
+ );
148
+ } catch {
149
+ }
150
+ }
151
+ async function getGhostCursorPosition(page) {
152
+ try {
153
+ return await page.evaluate(({ id }) => {
154
+ const el = document.getElementById(id);
155
+ if (!el) return null;
156
+ const match = el.style.transform.match(
157
+ /translate3d\(\s*([\d.-]+)px\s*,\s*([\d.-]+)px/
158
+ );
159
+ if (!match) return null;
160
+ return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
161
+ }, { id: CURSOR_ID });
162
+ } catch {
163
+ return null;
164
+ }
165
+ }
166
+ // Annotate the CommonJS export names for ESM import in node:
167
+ 0 && (module.exports = {
168
+ ensureGhostCursor,
169
+ getGhostCursorPosition,
170
+ ghostClick,
171
+ hideGhostCursor,
172
+ moveGhostCursor,
173
+ moveGhostCursorWithDistance
174
+ });
@@ -0,0 +1,37 @@
1
+ import { Page } from 'playwright';
2
+
3
+ type GhostCursorStyle = "minimal" | "dot" | "screenstudio";
4
+ type GhostCursorOptions = {
5
+ style?: GhostCursorStyle;
6
+ color?: string;
7
+ size?: number;
8
+ zIndex?: number;
9
+ easing?: string;
10
+ minDurationMs?: number;
11
+ maxDurationMs?: number;
12
+ speedPxPerMs?: number;
13
+ };
14
+ declare function ensureGhostCursor(page: Page, options?: GhostCursorOptions): Promise<void>;
15
+ declare function moveGhostCursor(page: Page, target: {
16
+ x: number;
17
+ y: number;
18
+ durationMs?: number;
19
+ }): Promise<void>;
20
+ declare function moveGhostCursorWithDistance(page: Page, from: {
21
+ x: number;
22
+ y: number;
23
+ }, to: {
24
+ x: number;
25
+ y: number;
26
+ }): Promise<void>;
27
+ declare function ghostClick(page: Page, target: {
28
+ x: number;
29
+ y: number;
30
+ }): Promise<void>;
31
+ declare function hideGhostCursor(page: Page): Promise<void>;
32
+ declare function getGhostCursorPosition(page: Page): Promise<{
33
+ x: number;
34
+ y: number;
35
+ } | null>;
36
+
37
+ export { type GhostCursorOptions, type GhostCursorStyle, ensureGhostCursor, getGhostCursorPosition, ghostClick, hideGhostCursor, moveGhostCursor, moveGhostCursorWithDistance };
@@ -0,0 +1,37 @@
1
+ import { Page } from 'playwright';
2
+
3
+ type GhostCursorStyle = "minimal" | "dot" | "screenstudio";
4
+ type GhostCursorOptions = {
5
+ style?: GhostCursorStyle;
6
+ color?: string;
7
+ size?: number;
8
+ zIndex?: number;
9
+ easing?: string;
10
+ minDurationMs?: number;
11
+ maxDurationMs?: number;
12
+ speedPxPerMs?: number;
13
+ };
14
+ declare function ensureGhostCursor(page: Page, options?: GhostCursorOptions): Promise<void>;
15
+ declare function moveGhostCursor(page: Page, target: {
16
+ x: number;
17
+ y: number;
18
+ durationMs?: number;
19
+ }): Promise<void>;
20
+ declare function moveGhostCursorWithDistance(page: Page, from: {
21
+ x: number;
22
+ y: number;
23
+ }, to: {
24
+ x: number;
25
+ y: number;
26
+ }): Promise<void>;
27
+ declare function ghostClick(page: Page, target: {
28
+ x: number;
29
+ y: number;
30
+ }): Promise<void>;
31
+ declare function hideGhostCursor(page: Page): Promise<void>;
32
+ declare function getGhostCursorPosition(page: Page): Promise<{
33
+ x: number;
34
+ y: number;
35
+ } | null>;
36
+
37
+ export { type GhostCursorOptions, type GhostCursorStyle, ensureGhostCursor, getGhostCursorPosition, ghostClick, hideGhostCursor, moveGhostCursor, moveGhostCursorWithDistance };
@@ -0,0 +1,145 @@
1
+ const DEFAULTS = {
2
+ style: "minimal",
3
+ color: "rgba(255, 70, 70, 0.9)",
4
+ size: 20,
5
+ zIndex: 2147483646,
6
+ easing: "cubic-bezier(0.16, 1, 0.3, 1)",
7
+ minDurationMs: 100,
8
+ maxDurationMs: 600,
9
+ speedPxPerMs: 1.5
10
+ };
11
+ const CURSOR_ID = "__libretto_ghost_cursor__";
12
+ function buildCursorSvg(style, color, size) {
13
+ if (style === "dot") {
14
+ return `<div style="width:${size}px;height:${size}px;border-radius:50%;background:${color};"></div>`;
15
+ }
16
+ if (style === "screenstudio") {
17
+ return `<div style="width:${size * 1.4}px;height:${size * 1.4}px;border-radius:50%;background:${color};box-shadow:0 0 ${size * 0.6}px ${color};opacity:0.7;"></div>`;
18
+ }
19
+ return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
20
+ <path d="M5 3L19 12L12 13L9 20L5 3Z" fill="${color}" stroke="rgba(0,0,0,0.3)" stroke-width="1"/>
21
+ </svg>`;
22
+ }
23
+ function buildInitScript(opts) {
24
+ const svg = buildCursorSvg(opts.style, opts.color, opts.size);
25
+ return `
26
+ (function() {
27
+ if (document.getElementById("${CURSOR_ID}")) return;
28
+ var el = document.createElement("div");
29
+ el.id = "${CURSOR_ID}";
30
+ el.style.cssText = "position:fixed;top:0;left:0;z-index:${opts.zIndex};pointer-events:none;transform:translate3d(-100px,-100px,0);transition:none;will-change:transform,opacity;opacity:0;";
31
+ el.innerHTML = ${JSON.stringify(svg)};
32
+ document.documentElement.appendChild(el);
33
+ })();
34
+ `;
35
+ }
36
+ const installedPages = /* @__PURE__ */ new WeakSet();
37
+ async function ensureGhostCursor(page, options) {
38
+ const existingOpts = page.__librettoGhostCursorOpts;
39
+ const opts = { ...DEFAULTS, ...existingOpts ?? {}, ...options };
40
+ const initScript = buildInitScript(opts);
41
+ if (!installedPages.has(page)) {
42
+ installedPages.add(page);
43
+ await page.addInitScript({ content: initScript });
44
+ }
45
+ page.__librettoGhostCursorOpts = opts;
46
+ try {
47
+ await page.evaluate(new Function(initScript));
48
+ } catch {
49
+ }
50
+ }
51
+ async function moveGhostCursor(page, target) {
52
+ const opts = page.__librettoGhostCursorOpts ?? DEFAULTS;
53
+ const durationMs = target.durationMs ?? Math.min(
54
+ opts.maxDurationMs,
55
+ Math.max(opts.minDurationMs, 200)
56
+ // default ~200ms if no distance info
57
+ );
58
+ try {
59
+ await page.evaluate(
60
+ ({ id, x, y, duration, easing }) => {
61
+ const el = document.getElementById(id);
62
+ if (!el) return;
63
+ el.style.opacity = "1";
64
+ el.style.transition = `transform ${duration}ms ${easing}`;
65
+ el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
66
+ },
67
+ { id: CURSOR_ID, x: target.x, y: target.y, duration: durationMs, easing: opts.easing }
68
+ );
69
+ await page.waitForTimeout(durationMs);
70
+ } catch {
71
+ }
72
+ }
73
+ async function moveGhostCursorWithDistance(page, from, to) {
74
+ const opts = page.__librettoGhostCursorOpts ?? DEFAULTS;
75
+ const dx = to.x - from.x;
76
+ const dy = to.y - from.y;
77
+ const distance = Math.sqrt(dx * dx + dy * dy);
78
+ const durationMs = Math.min(
79
+ opts.maxDurationMs,
80
+ Math.max(opts.minDurationMs, distance / opts.speedPxPerMs)
81
+ );
82
+ await moveGhostCursor(page, { x: to.x, y: to.y, durationMs });
83
+ }
84
+ async function ghostClick(page, target) {
85
+ try {
86
+ await page.evaluate(
87
+ ({ id, x, y }) => {
88
+ const el = document.getElementById(id);
89
+ if (!el) return;
90
+ el.style.transform = `translate3d(${x}px, ${y}px, 0) scale(0.93)`;
91
+ el.style.transition = "transform 80ms ease-out";
92
+ },
93
+ { id: CURSOR_ID, x: target.x, y: target.y }
94
+ );
95
+ await page.waitForTimeout(100);
96
+ await page.evaluate(
97
+ ({ id, x, y }) => {
98
+ const el = document.getElementById(id);
99
+ if (!el) return;
100
+ el.style.transform = `translate3d(${x}px, ${y}px, 0) scale(1)`;
101
+ el.style.transition = "transform 120ms ease-out";
102
+ },
103
+ { id: CURSOR_ID, x: target.x, y: target.y }
104
+ );
105
+ await page.waitForTimeout(130);
106
+ } catch {
107
+ }
108
+ }
109
+ async function hideGhostCursor(page) {
110
+ try {
111
+ await page.evaluate(
112
+ ({ id }) => {
113
+ const el = document.getElementById(id);
114
+ if (!el) return;
115
+ el.style.transition = "opacity 300ms ease-out";
116
+ el.style.opacity = "0";
117
+ },
118
+ { id: CURSOR_ID }
119
+ );
120
+ } catch {
121
+ }
122
+ }
123
+ async function getGhostCursorPosition(page) {
124
+ try {
125
+ return await page.evaluate(({ id }) => {
126
+ const el = document.getElementById(id);
127
+ if (!el) return null;
128
+ const match = el.style.transform.match(
129
+ /translate3d\(\s*([\d.-]+)px\s*,\s*([\d.-]+)px/
130
+ );
131
+ if (!match) return null;
132
+ return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
133
+ }, { id: CURSOR_ID });
134
+ } catch {
135
+ return null;
136
+ }
137
+ }
138
+ export {
139
+ ensureGhostCursor,
140
+ getGhostCursorPosition,
141
+ ghostClick,
142
+ hideGhostCursor,
143
+ moveGhostCursor,
144
+ moveGhostCursorWithDistance
145
+ };
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var highlight_exports = {};
20
+ __export(highlight_exports, {
21
+ clearHighlights: () => clearHighlights,
22
+ ensureHighlightLayer: () => ensureHighlightLayer,
23
+ showHighlight: () => showHighlight
24
+ });
25
+ module.exports = __toCommonJS(highlight_exports);
26
+ const HIGHLIGHT_DEFAULTS = {
27
+ color: "rgba(59, 130, 246, 0.25)",
28
+ zIndex: 2147483645
29
+ };
30
+ const LAYER_ID = "__libretto_highlight_layer__";
31
+ function buildHighlightInitScript(opts) {
32
+ return `
33
+ (function() {
34
+ if (document.getElementById("${LAYER_ID}")) return;
35
+ var el = document.createElement("div");
36
+ el.id = "${LAYER_ID}";
37
+ el.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100%;z-index:${opts.zIndex};pointer-events:none;overflow:hidden;";
38
+ document.documentElement.appendChild(el);
39
+ })();
40
+ `;
41
+ }
42
+ const installedPages = /* @__PURE__ */ new WeakSet();
43
+ async function ensureHighlightLayer(page, options) {
44
+ const existingOpts = page.__librettoHighlightOpts;
45
+ const zIndex = options?.zIndex ?? existingOpts?.zIndex ?? HIGHLIGHT_DEFAULTS.zIndex;
46
+ const initScript = buildHighlightInitScript({ zIndex });
47
+ if (!installedPages.has(page)) {
48
+ installedPages.add(page);
49
+ await page.addInitScript({ content: initScript });
50
+ }
51
+ page.__librettoHighlightOpts = {
52
+ color: options?.color ?? existingOpts?.color ?? HIGHLIGHT_DEFAULTS.color,
53
+ zIndex
54
+ };
55
+ try {
56
+ await page.evaluate(new Function(initScript));
57
+ } catch {
58
+ }
59
+ }
60
+ async function showHighlight(page, params) {
61
+ const opts = page.__librettoHighlightOpts ?? HIGHLIGHT_DEFAULTS;
62
+ const color = params.color ?? opts.color;
63
+ const durationMs = params.durationMs ?? 350;
64
+ try {
65
+ await page.evaluate(
66
+ ({ layerId, box, color: color2, label, durationMs: durationMs2 }) => {
67
+ const layer = document.getElementById(layerId);
68
+ if (!layer) return;
69
+ const rect = document.createElement("div");
70
+ rect.className = "__libretto_highlight_rect__";
71
+ rect.style.cssText = `
72
+ position:absolute;
73
+ left:${box.x}px;
74
+ top:${box.y}px;
75
+ width:${box.width}px;
76
+ height:${box.height}px;
77
+ background:${color2};
78
+ border:2px solid ${color2.replace(/[\d.]+\)$/, "0.6)")};
79
+ border-radius:3px;
80
+ pointer-events:none;
81
+ transition:opacity 200ms ease-out;
82
+ opacity:1;
83
+ `;
84
+ if (label) {
85
+ const labelEl = document.createElement("div");
86
+ labelEl.textContent = label;
87
+ labelEl.style.cssText = `
88
+ position:absolute;
89
+ top:-22px;
90
+ left:0;
91
+ font:11px/1.2 -apple-system,BlinkMacSystemFont,sans-serif;
92
+ color:#fff;
93
+ background:rgba(0,0,0,0.7);
94
+ padding:2px 6px;
95
+ border-radius:3px;
96
+ white-space:nowrap;
97
+ pointer-events:none;
98
+ `;
99
+ rect.appendChild(labelEl);
100
+ }
101
+ layer.appendChild(rect);
102
+ setTimeout(() => {
103
+ rect.style.opacity = "0";
104
+ setTimeout(() => rect.remove(), 250);
105
+ }, durationMs2);
106
+ },
107
+ {
108
+ layerId: LAYER_ID,
109
+ box: params.box,
110
+ color,
111
+ label: params.label,
112
+ durationMs
113
+ }
114
+ );
115
+ } catch {
116
+ }
117
+ }
118
+ async function clearHighlights(page) {
119
+ try {
120
+ await page.evaluate(({ layerId }) => {
121
+ const layer = document.getElementById(layerId);
122
+ if (!layer) return;
123
+ const rects = layer.querySelectorAll(".__libretto_highlight_rect__");
124
+ rects.forEach((r) => r.remove());
125
+ }, { layerId: LAYER_ID });
126
+ } catch {
127
+ }
128
+ }
129
+ // Annotate the CommonJS export names for ESM import in node:
130
+ 0 && (module.exports = {
131
+ clearHighlights,
132
+ ensureHighlightLayer,
133
+ showHighlight
134
+ });
@@ -0,0 +1,22 @@
1
+ import { Page } from 'playwright';
2
+
3
+ type HighlightOptions = {
4
+ color?: string;
5
+ zIndex?: number;
6
+ };
7
+ declare function ensureHighlightLayer(page: Page, options?: HighlightOptions): Promise<void>;
8
+ type ShowHighlightParams = {
9
+ box: {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ };
15
+ label?: string;
16
+ color?: string;
17
+ durationMs?: number;
18
+ };
19
+ declare function showHighlight(page: Page, params: ShowHighlightParams): Promise<void>;
20
+ declare function clearHighlights(page: Page): Promise<void>;
21
+
22
+ export { type HighlightOptions, type ShowHighlightParams, clearHighlights, ensureHighlightLayer, showHighlight };
@@ -0,0 +1,22 @@
1
+ import { Page } from 'playwright';
2
+
3
+ type HighlightOptions = {
4
+ color?: string;
5
+ zIndex?: number;
6
+ };
7
+ declare function ensureHighlightLayer(page: Page, options?: HighlightOptions): Promise<void>;
8
+ type ShowHighlightParams = {
9
+ box: {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ };
15
+ label?: string;
16
+ color?: string;
17
+ durationMs?: number;
18
+ };
19
+ declare function showHighlight(page: Page, params: ShowHighlightParams): Promise<void>;
20
+ declare function clearHighlights(page: Page): Promise<void>;
21
+
22
+ export { type HighlightOptions, type ShowHighlightParams, clearHighlights, ensureHighlightLayer, showHighlight };
@@ -0,0 +1,108 @@
1
+ const HIGHLIGHT_DEFAULTS = {
2
+ color: "rgba(59, 130, 246, 0.25)",
3
+ zIndex: 2147483645
4
+ };
5
+ const LAYER_ID = "__libretto_highlight_layer__";
6
+ function buildHighlightInitScript(opts) {
7
+ return `
8
+ (function() {
9
+ if (document.getElementById("${LAYER_ID}")) return;
10
+ var el = document.createElement("div");
11
+ el.id = "${LAYER_ID}";
12
+ el.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100%;z-index:${opts.zIndex};pointer-events:none;overflow:hidden;";
13
+ document.documentElement.appendChild(el);
14
+ })();
15
+ `;
16
+ }
17
+ const installedPages = /* @__PURE__ */ new WeakSet();
18
+ async function ensureHighlightLayer(page, options) {
19
+ const existingOpts = page.__librettoHighlightOpts;
20
+ const zIndex = options?.zIndex ?? existingOpts?.zIndex ?? HIGHLIGHT_DEFAULTS.zIndex;
21
+ const initScript = buildHighlightInitScript({ zIndex });
22
+ if (!installedPages.has(page)) {
23
+ installedPages.add(page);
24
+ await page.addInitScript({ content: initScript });
25
+ }
26
+ page.__librettoHighlightOpts = {
27
+ color: options?.color ?? existingOpts?.color ?? HIGHLIGHT_DEFAULTS.color,
28
+ zIndex
29
+ };
30
+ try {
31
+ await page.evaluate(new Function(initScript));
32
+ } catch {
33
+ }
34
+ }
35
+ async function showHighlight(page, params) {
36
+ const opts = page.__librettoHighlightOpts ?? HIGHLIGHT_DEFAULTS;
37
+ const color = params.color ?? opts.color;
38
+ const durationMs = params.durationMs ?? 350;
39
+ try {
40
+ await page.evaluate(
41
+ ({ layerId, box, color: color2, label, durationMs: durationMs2 }) => {
42
+ const layer = document.getElementById(layerId);
43
+ if (!layer) return;
44
+ const rect = document.createElement("div");
45
+ rect.className = "__libretto_highlight_rect__";
46
+ rect.style.cssText = `
47
+ position:absolute;
48
+ left:${box.x}px;
49
+ top:${box.y}px;
50
+ width:${box.width}px;
51
+ height:${box.height}px;
52
+ background:${color2};
53
+ border:2px solid ${color2.replace(/[\d.]+\)$/, "0.6)")};
54
+ border-radius:3px;
55
+ pointer-events:none;
56
+ transition:opacity 200ms ease-out;
57
+ opacity:1;
58
+ `;
59
+ if (label) {
60
+ const labelEl = document.createElement("div");
61
+ labelEl.textContent = label;
62
+ labelEl.style.cssText = `
63
+ position:absolute;
64
+ top:-22px;
65
+ left:0;
66
+ font:11px/1.2 -apple-system,BlinkMacSystemFont,sans-serif;
67
+ color:#fff;
68
+ background:rgba(0,0,0,0.7);
69
+ padding:2px 6px;
70
+ border-radius:3px;
71
+ white-space:nowrap;
72
+ pointer-events:none;
73
+ `;
74
+ rect.appendChild(labelEl);
75
+ }
76
+ layer.appendChild(rect);
77
+ setTimeout(() => {
78
+ rect.style.opacity = "0";
79
+ setTimeout(() => rect.remove(), 250);
80
+ }, durationMs2);
81
+ },
82
+ {
83
+ layerId: LAYER_ID,
84
+ box: params.box,
85
+ color,
86
+ label: params.label,
87
+ durationMs
88
+ }
89
+ );
90
+ } catch {
91
+ }
92
+ }
93
+ async function clearHighlights(page) {
94
+ try {
95
+ await page.evaluate(({ layerId }) => {
96
+ const layer = document.getElementById(layerId);
97
+ if (!layer) return;
98
+ const rects = layer.querySelectorAll(".__libretto_highlight_rect__");
99
+ rects.forEach((r) => r.remove());
100
+ }, { layerId: LAYER_ID });
101
+ } catch {
102
+ }
103
+ }
104
+ export {
105
+ clearHighlights,
106
+ ensureHighlightLayer,
107
+ showHighlight
108
+ };