@zumer/snapdom-plugins 1.0.2 → 1.0.3

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 CHANGED
@@ -170,6 +170,59 @@ snapdom(el, { plugins: [htmlInCanvas()] });
170
170
 
171
171
  ---
172
172
 
173
+ ### `prompt-export`
174
+
175
+ Adds a `toPrompt()` export method that returns an LLM-ready package: an annotated screenshot, a structured element map with bounding boxes, and a pre-formatted text description. Useful for vision-language models, browser-agent pipelines, visual QA, and any workflow that pairs a capture with structured metadata.
176
+
177
+ ```js
178
+ import { promptExport } from '@zumer/snapdom-plugins/prompt-export';
179
+
180
+ const result = await snapdom(el, { plugins: [promptExport()] });
181
+ const { image, elements, dimensions, prompt } = await result.toPrompt();
182
+ ```
183
+
184
+ The returned object:
185
+
186
+ | Field | Type | Description |
187
+ |-------|------|-------------|
188
+ | `image` | `string` | Data URL of the (optionally annotated) screenshot |
189
+ | `elements` | `Array` | One entry per detected element: `{ id, tag, type, text, bbox, attributes }` |
190
+ | `dimensions` | `{width, height}` | Image dimensions after `maxImageWidth` scaling |
191
+ | `prompt` | `string` | Pre-formatted text describing interactive + semantic elements |
192
+
193
+ `elements` is split into two `type`s:
194
+ - `'interactive'` — buttons, links, inputs, `[role]`/`[tabindex]` targets. These get numbered badges overlaid on the screenshot when `annotate` is on.
195
+ - `'semantic'` — headings, paragraphs, `<nav>`, `<main>`, images with `alt`, table cells, etc. Structural context, not overlaid.
196
+
197
+ Each `bbox` is in pixel coordinates of the returned image (scaled against `maxImageWidth`).
198
+
199
+ ```js
200
+ // Example — feed a vision-capable LLM
201
+ const { image, elements } = await result.toPrompt({ maxImageWidth: 1024 });
202
+
203
+ // image is a data URL → pass as image input
204
+ // elements is JSON → pass as structured context alongside the image
205
+ // "Click element [3]" → look up elements[3].bbox for real coordinates
206
+ ```
207
+
208
+ | Option | Type | Default | Description |
209
+ |--------|------|---------|-------------|
210
+ | `annotate` | `boolean` | `true` | Overlay numbered badges on interactive elements |
211
+ | `imageFormat` | `'png' \| 'jpg' \| 'webp'` | `'png'` | Output image format |
212
+ | `imageQuality` | `number` | `0.8` | Quality for lossy formats (0–1) |
213
+ | `maxImageWidth` | `number` | `1024` | Max width in px; downscales and rescales bboxes if larger |
214
+ | `interactiveSelector` | `string` | see below | CSS selector for the interactive element set |
215
+ | `semanticSelector` | `string` | see below | CSS selector for the semantic element set |
216
+ | `labelStyle` | `object` | `{}` | Override styles for the numbered badges (`position`, `color`, `backgroundColor`, etc.) |
217
+
218
+ Defaults:
219
+ - **interactive**: `a[href], button, input, select, textarea, [role="button"|"link"|"tab"|"menuitem"|"checkbox"|"radio"], [tabindex]:not([tabindex="-1"]), summary, [contenteditable="true"]`
220
+ - **semantic**: `h1–h6, p, li, img[alt], nav, main, article, section, header, footer, label, td, th, figcaption, blockquote, legend`
221
+
222
+ Both per-call options (`opts.imageFormat`, etc.) and constructor options are supported; per-call wins.
223
+
224
+ ---
225
+
173
226
  ## Plugin registration
174
227
 
175
228
  **Global** (applies to all captures):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zumer/snapdom-plugins",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Official plugins for SnapDOM",
5
5
  "type": "module",
6
6
  "exports": {
package/prompt-export.js CHANGED
@@ -43,7 +43,12 @@ export function promptExport(options = {}) {
43
43
 
44
44
  afterClone(ctx) {
45
45
  const meta = extractMetadata(ctx.element, interactiveSelector, semanticSelector);
46
+ // The ctx passed to afterClone is NOT the same object passed to the
47
+ // prompt() export later — snapdom spreads from ctx.options there. Stash
48
+ // on both so (a) standalone tests that pass a minimal ctx still see it
49
+ // and (b) the prompt() call can read it through the shared options ref.
46
50
  ctx.__promptMetadata = meta;
51
+ if (ctx.options) ctx.options.__promptMetadata = meta;
47
52
 
48
53
  if (annotate) {
49
54
  addAnnotations(ctx.clone, meta.elements, labelStyle);