autokap 1.0.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 (93) hide show
  1. package/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
  2. package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
  3. package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
  4. package/assets/devices/ipad-pro-11-m4.json +52 -0
  5. package/assets/devices/iphone-16-pro.json +53 -0
  6. package/assets/devices/macbook-air-13.json +45 -0
  7. package/assets/frames/MacBook Air 13.svg +242 -0
  8. package/assets/frames/Status bar - iPhone.png +0 -0
  9. Menu bar- iPad.png +0 -0
  10. package/assets/frames/iPad Pro M4 11_.png +0 -0
  11. package/assets/frames/iPhone 16 Pro.png +0 -0
  12. package/assets/icons/Cellular Connection.svg +3 -0
  13. package/assets/icons/Union.svg +6 -0
  14. package/assets/icons/Wifi.svg +3 -0
  15. package/assets/icons/battery.svg +5 -0
  16. package/assets/icons/battery_charging.svg +8 -0
  17. package/assets/skill/SKILL.md +575 -0
  18. package/dist/abort.d.ts +5 -0
  19. package/dist/abort.js +44 -0
  20. package/dist/agent.d.ts +142 -0
  21. package/dist/agent.js +4504 -0
  22. package/dist/browser-bar.d.ts +40 -0
  23. package/dist/browser-bar.js +147 -0
  24. package/dist/browser-pool.d.ts +34 -0
  25. package/dist/browser-pool.js +122 -0
  26. package/dist/browser.d.ts +279 -0
  27. package/dist/browser.js +2902 -0
  28. package/dist/cli-utils.d.ts +25 -0
  29. package/dist/cli-utils.js +80 -0
  30. package/dist/cli.d.ts +4 -0
  31. package/dist/cli.js +365 -0
  32. package/dist/clip-orchestrator.d.ts +148 -0
  33. package/dist/clip-orchestrator.js +950 -0
  34. package/dist/clip-postprocess.d.ts +42 -0
  35. package/dist/clip-postprocess.js +192 -0
  36. package/dist/cookie-dismiss.d.ts +5 -0
  37. package/dist/cookie-dismiss.js +172 -0
  38. package/dist/credential-templates.d.ts +5 -0
  39. package/dist/credential-templates.js +60 -0
  40. package/dist/element-capture.d.ts +53 -0
  41. package/dist/element-capture.js +766 -0
  42. package/dist/hybrid-navigator.d.ts +138 -0
  43. package/dist/hybrid-navigator.js +468 -0
  44. package/dist/index.d.ts +15 -0
  45. package/dist/index.js +11 -0
  46. package/dist/llm-usage.d.ts +17 -0
  47. package/dist/llm-usage.js +45 -0
  48. package/dist/logger.d.ts +46 -0
  49. package/dist/logger.js +79 -0
  50. package/dist/mockup-html.d.ts +119 -0
  51. package/dist/mockup-html.js +253 -0
  52. package/dist/mockup.d.ts +94 -0
  53. package/dist/mockup.js +604 -0
  54. package/dist/mouse-animation.d.ts +46 -0
  55. package/dist/mouse-animation.js +100 -0
  56. package/dist/overlay-utils.d.ts +14 -0
  57. package/dist/overlay-utils.js +13 -0
  58. package/dist/posthog.d.ts +4 -0
  59. package/dist/posthog.js +26 -0
  60. package/dist/prompt-cache.d.ts +10 -0
  61. package/dist/prompt-cache.js +24 -0
  62. package/dist/prompts.d.ts +167 -0
  63. package/dist/prompts.js +1165 -0
  64. package/dist/security.d.ts +20 -0
  65. package/dist/security.js +569 -0
  66. package/dist/session-profile.d.ts +86 -0
  67. package/dist/session-profile.js +1471 -0
  68. package/dist/sf-pro-fonts.d.ts +4 -0
  69. package/dist/sf-pro-fonts.js +7 -0
  70. package/dist/status-bar-l10n.d.ts +14 -0
  71. package/dist/status-bar-l10n.js +177 -0
  72. package/dist/status-bar.d.ts +44 -0
  73. package/dist/status-bar.js +336 -0
  74. package/dist/tools.d.ts +4 -0
  75. package/dist/tools.js +578 -0
  76. package/dist/types.d.ts +796 -0
  77. package/dist/types.js +2 -0
  78. package/dist/video-agent.d.ts +143 -0
  79. package/dist/video-agent.js +4783 -0
  80. package/dist/video-observation.d.ts +36 -0
  81. package/dist/video-observation.js +192 -0
  82. package/dist/video-planner.d.ts +12 -0
  83. package/dist/video-planner.js +500 -0
  84. package/dist/video-prompts.d.ts +37 -0
  85. package/dist/video-prompts.js +554 -0
  86. package/dist/video-tools.d.ts +3 -0
  87. package/dist/video-tools.js +59 -0
  88. package/dist/video-variant-state.d.ts +29 -0
  89. package/dist/video-variant-state.js +80 -0
  90. package/dist/vision-model.d.ts +17 -0
  91. package/dist/vision-model.js +74 -0
  92. package/package.json +165 -0
  93. package/readme.md +61 -0
@@ -0,0 +1,575 @@
1
+ ---
2
+ name: autokap-preset
3
+ description: Generate AutoKap preset configurations for automated screenshot, clip, and video capture of web applications
4
+ metadata:
5
+ author: AutoKap
6
+ version: 1.0.0
7
+ ---
8
+
9
+ # AutoKap Preset Creation Skill
10
+
11
+ ## What is AutoKap
12
+
13
+ AutoKap is a screenshot and video capture automation platform. It uses an AI agent inside a headless browser (Playwright) to navigate web applications and capture screenshots, clips (short animated GIFs/MP4s), or demo videos.
14
+
15
+ A **preset** defines what to capture: which pages, which viewports/devices, which languages and themes, and how to navigate to the right state. A single preset can generate dozens of assets — one per combination of (page x target x language x theme).
16
+
17
+ ## Your Task
18
+
19
+ You are being asked to create one or more AutoKap presets for the user's project. Your job is to:
20
+
21
+ 1. **Analyze the project** — look at the codebase (routes, pages, components, UI structure) to understand what the application looks like and how it's organized
22
+ 2. **Generate a complete preset configuration** in JSON format that AutoKap can import directly
23
+ 3. **Write precise navigation prompts** — the capture agent sees a screenshot + accessibility tree and follows your instructions to reach the right page state
24
+
25
+ You know this project intimately. Use that knowledge to write prompts that are specific to the actual UI — reference real navigation elements, real page routes, real UI components.
26
+
27
+ ### Variants (CRITICAL)
28
+
29
+ The prompt will include a "Variants" section specifying the exact `langs`, `themes`, and `targets` to use. **You MUST copy these values exactly into the preset config** — do not change, add, or remove any value. The user has already chosen their desired languages, themes, and device viewports. Your job is only to write the capture prompts (what to navigate to, what to capture).
30
+
31
+ **Targets and mockupOptions**: The targets include `viewport`, `deviceFrame`, and `mockupOptions` (orientation, status bar, dock, safe areas, etc.) that the user has specifically configured. Copy each target object exactly as-is into the preset's `targets` array. Do not modify `mockupOptions` — if the user chose landscape orientation, keep landscape. If they configured a status bar, keep it.
32
+
33
+ If the variants include multiple languages, you must provide `langInstructions` based on how the app actually switches language (look at the i18n setup in the code).
34
+ If the variants include both light and dark themes, you must provide `themeInstructions` based on the actual theme toggle mechanism in the code.
35
+
36
+ ---
37
+
38
+ ## PresetConfig Schema
39
+
40
+ The output must conform to this TypeScript schema. All fields are documented below.
41
+
42
+ ```typescript
43
+ /** Top-level preset object for import */
44
+ interface PresetImport {
45
+ name: string; // Display name (e.g. "Homepage Hero", "Pricing Page")
46
+ description: string; // What this preset captures and why
47
+ config: PresetConfig;
48
+ }
49
+
50
+ /** The full preset configuration */
51
+ type PresetConfig = {
52
+ /** The application URL (root URL of the project) */
53
+ url?: string;
54
+
55
+ /**
56
+ * Main capture prompt — natural language instructions for the agent.
57
+ * Ignored when `pages` is defined (each page has its own prompt).
58
+ */
59
+ prompt: string;
60
+
61
+ /** Device/viewport targets for capture */
62
+ targets: CaptureTarget[];
63
+
64
+ /** Output resolution multiplier. Default: 2 */
65
+ outputScale?: number;
66
+
67
+ /** Languages to capture. E.g. ["en", "fr", "de"] */
68
+ langs: string[];
69
+
70
+ /** Themes to capture */
71
+ themes: Array<"light" | "dark">;
72
+
73
+ /** Max agent iterations before giving up. Default: 60 */
74
+ maxIterations: number;
75
+
76
+ /**
77
+ * How to switch language in the UI.
78
+ * Must describe actual UI controls, not abstract instructions.
79
+ * Example: "Click the language dropdown in the footer and select the target language"
80
+ * If the app uses URL-based locale (e.g. /fr/pricing), say so.
81
+ */
82
+ langInstructions?: string;
83
+
84
+ /**
85
+ * How to switch theme in the UI.
86
+ * Must describe actual UI controls.
87
+ * Example: "Click the sun/moon icon in the top-right header to toggle dark mode"
88
+ */
89
+ themeInstructions?: string;
90
+
91
+ /** General navigation instructions applied to ALL captures (prepended to each page prompt) */
92
+ navigationInstructions?: string;
93
+
94
+ /**
95
+ * Login credentials. The agent handles login automatically before running page prompts.
96
+ * Only email/password auth is supported. OAuth, SSO, MFA, magic links are NOT supported.
97
+ */
98
+ credentials?: {
99
+ loginUrl?: string; // Login page URL
100
+ email?: string;
101
+ password?: string;
102
+ };
103
+
104
+ /**
105
+ * Named capture pages — each page runs its own agent session with its own prompt.
106
+ * When defined, the top-level `prompt` field is ignored.
107
+ * CRITICAL: Each page runs independently with NO memory of other pages.
108
+ */
109
+ pages?: CapturePage[];
110
+
111
+ /**
112
+ * Isolated UI elements to extract from captured pages.
113
+ * Each element is cropped from the full page capture.
114
+ */
115
+ elements?: IsolatedElement[];
116
+
117
+ /**
118
+ * Network interception: replace API responses with LLM-generated mock data.
119
+ * Useful for showing populated UIs without real data.
120
+ */
121
+ mockData?: MockDataConfig;
122
+
123
+ /** Capture mode. Default: "screenshot" */
124
+ captureMode?: "screenshot" | "clip" | "video";
125
+
126
+ /** Clip definitions (when captureMode === "clip") */
127
+ clips?: ClipDefinition[];
128
+
129
+ /** Clip export options */
130
+ clipOptions?: ClipOptions;
131
+ };
132
+
133
+ interface CaptureTarget {
134
+ /** Unique identifier for this target */
135
+ id: string;
136
+ /** Display label */
137
+ label: string;
138
+ /** Browser viewport dimensions */
139
+ viewport: { width: number; height: number };
140
+ /**
141
+ * Optional device frame for mockup rendering.
142
+ * Available frames: "iphone-16-pro", "ipad-pro-11-m4", "ipad-air-m4",
143
+ * "macbook-air-13", "macbook-pro-16"
144
+ */
145
+ deviceFrame?: string;
146
+ /** Mockup rendering options */
147
+ mockupOptions?: MockupOptions;
148
+ }
149
+
150
+ interface MockupOptions {
151
+ orientation?: "portrait" | "landscape";
152
+ outputScale?: number;
153
+ showStatusBar?: boolean;
154
+ statusBar?: StatusBarConfig;
155
+ showDock?: boolean; // Mac only
156
+ dockScale?: number; // Mac only
157
+ dockMode?: "integrated" | "only-app"; // Mac only
158
+ }
159
+
160
+ interface StatusBarConfig {
161
+ time?: string;
162
+ signalStrength?: number;
163
+ wifiStrength?: number;
164
+ batteryLevel?: number;
165
+ batteryCharging?: boolean;
166
+ colorScheme?: "light" | "dark";
167
+ autoLocale?: boolean; // Auto-adapt status bar to capture language (default: true)
168
+ }
169
+
170
+ interface CapturePage {
171
+ /**
172
+ * Unique slug identifier. MUST match: /^[a-z0-9_-]+$/
173
+ * Use descriptive slugs: "pricing", "dashboard-overview", "settings-billing"
174
+ * AVOID generic slugs: "main", "page1", "page2", "screen1"
175
+ */
176
+ id: string;
177
+ /** Display name shown in the UI */
178
+ name: string;
179
+ /**
180
+ * Navigation prompt for the agent to reach this page/state.
181
+ * MUST be self-contained — the agent has NO memory of other pages.
182
+ * Include: where to navigate, what to click, what state to reach.
183
+ */
184
+ prompt: string;
185
+ /** Optional URL override if this page is at a different URL than the preset root */
186
+ url?: string;
187
+ }
188
+
189
+ interface IsolatedElement {
190
+ /** Element name (used in output filenames) */
191
+ name: string;
192
+ /**
193
+ * Description of the DOM element to crop.
194
+ * Must be visually identifiable — the agent matches against what it sees.
195
+ * GOOD: "The pricing table with 3 plan columns"
196
+ * GOOD: "The blue CTA button in the hero section"
197
+ * BAD: "The main content" (too vague)
198
+ */
199
+ description: string;
200
+ /** Source page id — when the preset has multiple pages, specify which page this element belongs to */
201
+ sourcePageId?: string;
202
+ /** Outscale config for padding around the element */
203
+ outscale?: OutscaleConfig;
204
+ }
205
+
206
+ interface OutscaleConfig {
207
+ /** Uniform padding on all 4 sides (pixels) */
208
+ padding?: number;
209
+ paddingTop?: number;
210
+ paddingRight?: number;
211
+ paddingBottom?: number;
212
+ paddingLeft?: number;
213
+ /** Percentage-based padding relative to element dimensions (0-100) */
214
+ paddingPercent?: number;
215
+ /** Background fill color. Default: transparent */
216
+ backgroundColor?: string;
217
+ }
218
+
219
+ interface MockDataConfig {
220
+ enabled: boolean;
221
+ /**
222
+ * Specific description of what data to generate.
223
+ * GOOD: "5 customer invoices with amounts between $50-500, mix of paid/pending/overdue statuses"
224
+ * BAD: "Some sample data"
225
+ */
226
+ description: string;
227
+ /** Explicitly target specific API endpoints to mock */
228
+ endpoints?: { url: string; method?: string }[];
229
+ }
230
+
231
+ interface ClipDefinition {
232
+ /** Unique slug identifier */
233
+ id: string;
234
+ /** Display name */
235
+ name: string;
236
+ /**
237
+ * What to record — the interaction the clip captures.
238
+ * When navigationScript is also provided, this describes ONLY the recording phase.
239
+ */
240
+ script: string;
241
+ /**
242
+ * Optional: navigation instructions to reach the page BEFORE recording starts.
243
+ * When provided, the navigation agent follows these to reach the page,
244
+ * then the recording system executes `script`.
245
+ */
246
+ navigationScript?: string;
247
+ /** Optional URL override */
248
+ url?: string;
249
+ /** Seconds to freeze the last frame before GIF loops. 0-10. Default: 0 */
250
+ holdLastFrameSec?: number;
251
+ }
252
+
253
+ interface ClipOptions {
254
+ /** Output format. Default: "gif" */
255
+ format?: "gif" | "mp4" | "both";
256
+ /** Max duration in seconds. Default: 8 */
257
+ maxDurationSec?: number;
258
+ /** GIF framerate. Default: 15 */
259
+ gifFps?: number;
260
+ /** GIF max width in pixels. Default: 800 */
261
+ gifMaxWidth?: number;
262
+ /** Show cursor animation. Default: true */
263
+ showCursor?: boolean;
264
+ /** Whether to loop GIF. Default: true */
265
+ loop?: boolean;
266
+ }
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Best Practices (Critical)
272
+
273
+ ### Prompt Writing
274
+ The capture agent's success rate depends heavily on prompt quality. Write prompts with **strong navigation hints**:
275
+
276
+ - **Add location references**: "in the left sidebar", "in the top-right header", "via the navigation bar"
277
+ - **Use visual anchors**: "the blue button labeled 'Save'", "the table with column headers Name/Status/Date"
278
+ - **Specify end-state**: what should be visible when the screenshot is taken
279
+ - **Keep it concise**: 1-3 sentences. The agent handles micro-steps on its own
280
+
281
+ **Bad prompt**: "Go to settings"
282
+ **Good prompt**: "Navigate to the Settings page via the gear icon in the left sidebar. Show the 'General' tab with all form fields visible."
283
+
284
+ ### Named Pages
285
+ - Each page runs as a **separate, independent agent session** with NO memory between pages
286
+ - Page prompts must be **self-contained** — include all navigation steps from the root URL
287
+ - If page B requires authentication, configure `credentials` in the preset — don't describe login steps in the prompt
288
+ - Use **descriptive page IDs** as slugs: `pricing`, `dashboard-analytics`, `user-settings`
289
+ - NEVER use generic IDs: `main`, `page1`, `page2`, `screen1`
290
+
291
+ ### Isolated Elements
292
+ - Descriptions must reference **visually identifiable** DOM landmarks
293
+ - Good: "The hero section containing the main heading and CTA button"
294
+ - Bad: "The main content area"
295
+ - Always specify `sourcePageId` when the preset has multiple pages
296
+
297
+ ### Theme & Language Instructions
298
+ - Must describe **actual UI controls**, not abstract actions
299
+ - Good: "Click the moon/sun toggle icon in the top-right corner of the header"
300
+ - Bad: "Switch to dark mode"
301
+ - If the app uses URL-based locales (e.g. `/fr/pricing`), mention it explicitly
302
+
303
+ ### Mock Data
304
+ - Descriptions must be **specific enough for deterministic generation**
305
+ - Include: number of items, value ranges, status distributions, data types
306
+ - Good: "10 user accounts with realistic names, emails, roles (3 admin, 5 member, 2 viewer), last active dates within the past 30 days"
307
+ - Bad: "Some users"
308
+
309
+ ### Credentials
310
+ - Only email/password authentication is supported
311
+ - OAuth, SSO, MFA, and magic links are NOT supported
312
+ - When credentials are configured, the agent handles login automatically — do NOT repeat login steps in prompts
313
+ - If a page requires auth but no credentials are configured, the capture will fail
314
+
315
+ ### What the Agent CANNOT Do
316
+ - Upload files or handle file inputs
317
+ - Handle OAuth, SSO, MFA, magic link auth
318
+ - Type into non-auth, non-search fields (no form submissions that create data)
319
+ - Delete or modify persistent data
320
+ - Navigate outside the target domain
321
+ - Remember state between separate page runs
322
+
323
+ ---
324
+
325
+ ## Common Targets
326
+
327
+ Here are standard target configurations you can use:
328
+
329
+ ```json
330
+ // Desktop (no device frame)
331
+ { "id": "desktop-1440x900", "label": "Desktop 1440x900", "viewport": { "width": 1440, "height": 900 } }
332
+
333
+ // MacBook Air 13"
334
+ { "id": "macbook-air-13", "label": "MacBook Air 13\"", "viewport": { "width": 1440, "height": 900 }, "deviceFrame": "macbook-air-13", "mockupOptions": { "outputScale": 2 } }
335
+
336
+ // iPhone 16 Pro (portrait)
337
+ { "id": "iphone-16-pro", "label": "iPhone 16 Pro", "viewport": { "width": 402, "height": 778 }, "deviceFrame": "iphone-16-pro", "mockupOptions": { "orientation": "portrait", "outputScale": 2 } }
338
+
339
+ // iPad Pro 11" (landscape)
340
+ { "id": "ipad-pro-11", "label": "iPad Pro 11\" Landscape", "viewport": { "width": 1210, "height": 802 }, "deviceFrame": "ipad-pro-11-m4", "mockupOptions": { "orientation": "landscape", "outputScale": 2 } }
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Output Format
346
+
347
+ ### Option 1: JSON Output (copy-paste)
348
+
349
+ Output the preset as a JSON object. The user will paste this into AutoKap's import dialog.
350
+
351
+ ```json
352
+ {
353
+ "name": "Preset Name",
354
+ "description": "What this preset captures",
355
+ "config": {
356
+ "prompt": "...",
357
+ "targets": [...],
358
+ "langs": ["en"],
359
+ "themes": ["light"],
360
+ "maxIterations": 60,
361
+ "outputScale": 2
362
+ }
363
+ }
364
+ ```
365
+
366
+ For multiple presets, output a JSON array:
367
+ ```json
368
+ [
369
+ { "name": "...", "description": "...", "config": { ... } },
370
+ { "name": "...", "description": "...", "config": { ... } }
371
+ ]
372
+ ```
373
+
374
+ ### Option 2: Direct API Creation
375
+
376
+ If an API key and project ID are provided in the prompt, create the preset directly via the AutoKap API:
377
+
378
+ ```bash
379
+ curl -X POST "https://app.autokap.com/api/v1/presets" \
380
+ -H "Authorization: Bearer YOUR_API_KEY" \
381
+ -H "Content-Type: application/json" \
382
+ -d '{
383
+ "project_id": "YOUR_PROJECT_ID",
384
+ "name": "Preset Name",
385
+ "description": "What this preset captures",
386
+ "config": { ... }
387
+ }'
388
+ ```
389
+
390
+ When both an API key and project ID are available, prefer the API method for a seamless experience. Fall back to JSON output if the API call fails.
391
+
392
+ ---
393
+
394
+ ## Examples
395
+
396
+ ### Example 1: Simple Homepage Screenshot
397
+
398
+ ```json
399
+ {
400
+ "name": "Homepage Hero",
401
+ "description": "Above-the-fold hero section of the landing page",
402
+ "config": {
403
+ "prompt": "Navigate to the homepage. Wait for the hero section to fully load including any animations and images. The page should show the main heading, subheading, and CTA button.",
404
+ "targets": [
405
+ { "id": "desktop-1440x900", "label": "Desktop 1440x900", "viewport": { "width": 1440, "height": 900 } }
406
+ ],
407
+ "langs": ["en"],
408
+ "themes": ["light"],
409
+ "maxIterations": 60,
410
+ "outputScale": 2
411
+ }
412
+ }
413
+ ```
414
+
415
+ ### Example 2: Multi-Page Preset with Themes
416
+
417
+ ```json
418
+ {
419
+ "name": "Marketing Pages",
420
+ "description": "Key marketing pages in light and dark mode",
421
+ "config": {
422
+ "targets": [
423
+ { "id": "desktop-1440x900", "label": "Desktop 1440x900", "viewport": { "width": 1440, "height": 900 } }
424
+ ],
425
+ "langs": ["en"],
426
+ "themes": ["light", "dark"],
427
+ "themeInstructions": "Click the sun/moon toggle icon in the top-right corner of the header navigation bar to switch between light and dark mode.",
428
+ "maxIterations": 60,
429
+ "outputScale": 2,
430
+ "prompt": "",
431
+ "pages": [
432
+ {
433
+ "id": "homepage",
434
+ "name": "Homepage",
435
+ "prompt": "Navigate to the homepage at /. Wait for the hero section to load completely with all images. The page should display the main value proposition heading and the 'Get Started' CTA button."
436
+ },
437
+ {
438
+ "id": "pricing",
439
+ "name": "Pricing Page",
440
+ "prompt": "Navigate to /pricing. Wait for the pricing cards to load. The page should show all plan tiers (Free, Pro, Enterprise) with their prices and feature lists visible. Select the 'Annual' billing toggle if available."
441
+ },
442
+ {
443
+ "id": "features",
444
+ "name": "Features Page",
445
+ "prompt": "Navigate to /features. Wait for the feature grid to fully render. The page should show the feature cards with icons and descriptions."
446
+ }
447
+ ]
448
+ }
449
+ }
450
+ ```
451
+
452
+ ### Example 3: Clip (Animated GIF) Preset
453
+
454
+ ```json
455
+ {
456
+ "name": "Dashboard Demo Clip",
457
+ "description": "Short animated GIF showing the dashboard interaction",
458
+ "config": {
459
+ "captureMode": "clip",
460
+ "targets": [
461
+ { "id": "desktop-1440x900", "label": "Desktop 1440x900", "viewport": { "width": 1440, "height": 900 } }
462
+ ],
463
+ "langs": ["en"],
464
+ "themes": ["light"],
465
+ "maxIterations": 60,
466
+ "outputScale": 2,
467
+ "prompt": "",
468
+ "clips": [
469
+ {
470
+ "id": "dashboard-filter",
471
+ "name": "Dashboard Filter Demo",
472
+ "navigationScript": "Navigate to /dashboard. Wait for the analytics charts to fully load and display data.",
473
+ "script": "Click the 'Date Range' dropdown in the top-right of the dashboard. Select 'Last 30 days'. Wait for the charts to update with the new data range.",
474
+ "holdLastFrameSec": 2
475
+ }
476
+ ],
477
+ "clipOptions": {
478
+ "format": "gif",
479
+ "maxDurationSec": 8,
480
+ "gifMaxWidth": 800,
481
+ "showCursor": true,
482
+ "loop": true
483
+ }
484
+ }
485
+ }
486
+ ```
487
+
488
+ ---
489
+
490
+ ## Integration Endpoints API
491
+
492
+ After creating presets and running captures, you can create **integration endpoints** — stable public URLs that serve your assets. Each endpoint maps to a specific capture (page, element, or clip) and supports dynamic variant selection via query parameters (`lang`, `theme`, `target`).
493
+
494
+ ### Create all endpoints for a preset
495
+
496
+ ```bash
497
+ curl -X POST https://autokap.com/api/v1/endpoints \
498
+ -H "Authorization: Bearer $API_KEY" \
499
+ -H "Content-Type: application/json" \
500
+ -d '{ "preset_id": "PRESET_ID" }'
501
+ ```
502
+
503
+ This creates an endpoint for every page, isolated element, and clip defined in the preset. Existing endpoints are skipped (no duplicates).
504
+
505
+ Response:
506
+ ```json
507
+ {
508
+ "created": [{ "id": "abc123...", "label": "Homepage", "preset_id": "...", "asset_type": "screenshot" }],
509
+ "skipped": 0
510
+ }
511
+ ```
512
+
513
+ ### Create endpoints for a composition
514
+
515
+ ```bash
516
+ curl -X POST https://autokap.com/api/v1/endpoints \
517
+ -H "Authorization: Bearer $API_KEY" \
518
+ -H "Content-Type: application/json" \
519
+ -d '{ "composition_id": "COMPOSITION_ID" }'
520
+ ```
521
+
522
+ ### List endpoints
523
+
524
+ ```bash
525
+ # By preset
526
+ curl "https://autokap.com/api/v1/endpoints?preset_id=PRESET_ID" \
527
+ -H "Authorization: Bearer $API_KEY"
528
+
529
+ # By project
530
+ curl "https://autokap.com/api/v1/endpoints?project_id=PROJECT_ID" \
531
+ -H "Authorization: Bearer $API_KEY"
532
+ ```
533
+
534
+ ### Update endpoint label
535
+
536
+ ```bash
537
+ curl -X PATCH https://autokap.com/api/v1/endpoints/ENDPOINT_ID \
538
+ -H "Authorization: Bearer $API_KEY" \
539
+ -H "Content-Type: application/json" \
540
+ -d '{ "label": "New Label" }'
541
+ ```
542
+
543
+ ### Delete an endpoint
544
+
545
+ ```bash
546
+ curl -X DELETE https://autokap.com/api/v1/endpoints/ENDPOINT_ID \
547
+ -H "Authorization: Bearer $API_KEY"
548
+ ```
549
+
550
+ ### Export endpoints
551
+
552
+ ```bash
553
+ # JSON export
554
+ curl "https://autokap.com/api/v1/endpoints/export?preset_id=PRESET_ID" \
555
+ -H "Authorization: Bearer $API_KEY"
556
+
557
+ # CSV export
558
+ curl "https://autokap.com/api/v1/endpoints/export?preset_id=PRESET_ID&format=csv" \
559
+ -H "Authorization: Bearer $API_KEY"
560
+ ```
561
+
562
+ ### Serve an asset
563
+
564
+ Assets are served publicly without authentication:
565
+
566
+ ```
567
+ https://autokap.com/api/v1/assets/ENDPOINT_ID?lang=en&theme=dark&target=desktop
568
+ ```
569
+
570
+ Query parameters: `lang`, `theme`, `target`, `w` (width), `quality`, `format` (png/webp).
571
+
572
+ ### Required API scopes
573
+
574
+ - `endpoints:read` — list, get, and export endpoints
575
+ - `endpoints:write` — create, update, and delete endpoints
@@ -0,0 +1,5 @@
1
+ export declare function createAbortError(message: string): Error;
2
+ export declare function getAbortMessage(signal: AbortSignal | undefined, fallback: string): string;
3
+ export declare function throwIfAborted(signal: AbortSignal | undefined, fallback?: string): void;
4
+ export declare function isAbortError(error: unknown): boolean;
5
+ export declare function sleepWithAbort(ms: number, signal?: AbortSignal): Promise<void>;
package/dist/abort.js ADDED
@@ -0,0 +1,44 @@
1
+ export function createAbortError(message) {
2
+ const error = new Error(message);
3
+ error.name = 'AbortError';
4
+ return error;
5
+ }
6
+ export function getAbortMessage(signal, fallback) {
7
+ const reason = signal?.reason;
8
+ if (reason instanceof Error && reason.message)
9
+ return reason.message;
10
+ if (typeof reason === 'string' && reason.trim().length > 0)
11
+ return reason;
12
+ return fallback;
13
+ }
14
+ export function throwIfAborted(signal, fallback = 'Operation cancelled.') {
15
+ if (!signal?.aborted)
16
+ return;
17
+ throw createAbortError(getAbortMessage(signal, fallback));
18
+ }
19
+ export function isAbortError(error) {
20
+ return error instanceof Error && error.name === 'AbortError';
21
+ }
22
+ export async function sleepWithAbort(ms, signal) {
23
+ if (!signal) {
24
+ await new Promise((resolve) => setTimeout(resolve, ms));
25
+ return;
26
+ }
27
+ throwIfAborted(signal);
28
+ await new Promise((resolve, reject) => {
29
+ const timeout = setTimeout(() => {
30
+ cleanup();
31
+ resolve();
32
+ }, ms);
33
+ const onAbort = () => {
34
+ clearTimeout(timeout);
35
+ cleanup();
36
+ reject(createAbortError(getAbortMessage(signal, 'Operation cancelled.')));
37
+ };
38
+ const cleanup = () => {
39
+ signal.removeEventListener('abort', onAbort);
40
+ };
41
+ signal.addEventListener('abort', onAbort, { once: true });
42
+ });
43
+ }
44
+ //# sourceMappingURL=abort.js.map