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.
- package/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
- package/assets/devices/ipad-pro-11-m4.json +52 -0
- package/assets/devices/iphone-16-pro.json +53 -0
- package/assets/devices/macbook-air-13.json +45 -0
- package/assets/frames/MacBook Air 13.svg +242 -0
- package/assets/frames/Status bar - iPhone.png +0 -0
- Menu bar- iPad.png +0 -0
- package/assets/frames/iPad Pro M4 11_.png +0 -0
- package/assets/frames/iPhone 16 Pro.png +0 -0
- package/assets/icons/Cellular Connection.svg +3 -0
- package/assets/icons/Union.svg +6 -0
- package/assets/icons/Wifi.svg +3 -0
- package/assets/icons/battery.svg +5 -0
- package/assets/icons/battery_charging.svg +8 -0
- package/assets/skill/SKILL.md +575 -0
- package/dist/abort.d.ts +5 -0
- package/dist/abort.js +44 -0
- package/dist/agent.d.ts +142 -0
- package/dist/agent.js +4504 -0
- package/dist/browser-bar.d.ts +40 -0
- package/dist/browser-bar.js +147 -0
- package/dist/browser-pool.d.ts +34 -0
- package/dist/browser-pool.js +122 -0
- package/dist/browser.d.ts +279 -0
- package/dist/browser.js +2902 -0
- package/dist/cli-utils.d.ts +25 -0
- package/dist/cli-utils.js +80 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +365 -0
- package/dist/clip-orchestrator.d.ts +148 -0
- package/dist/clip-orchestrator.js +950 -0
- package/dist/clip-postprocess.d.ts +42 -0
- package/dist/clip-postprocess.js +192 -0
- package/dist/cookie-dismiss.d.ts +5 -0
- package/dist/cookie-dismiss.js +172 -0
- package/dist/credential-templates.d.ts +5 -0
- package/dist/credential-templates.js +60 -0
- package/dist/element-capture.d.ts +53 -0
- package/dist/element-capture.js +766 -0
- package/dist/hybrid-navigator.d.ts +138 -0
- package/dist/hybrid-navigator.js +468 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +11 -0
- package/dist/llm-usage.d.ts +17 -0
- package/dist/llm-usage.js +45 -0
- package/dist/logger.d.ts +46 -0
- package/dist/logger.js +79 -0
- package/dist/mockup-html.d.ts +119 -0
- package/dist/mockup-html.js +253 -0
- package/dist/mockup.d.ts +94 -0
- package/dist/mockup.js +604 -0
- package/dist/mouse-animation.d.ts +46 -0
- package/dist/mouse-animation.js +100 -0
- package/dist/overlay-utils.d.ts +14 -0
- package/dist/overlay-utils.js +13 -0
- package/dist/posthog.d.ts +4 -0
- package/dist/posthog.js +26 -0
- package/dist/prompt-cache.d.ts +10 -0
- package/dist/prompt-cache.js +24 -0
- package/dist/prompts.d.ts +167 -0
- package/dist/prompts.js +1165 -0
- package/dist/security.d.ts +20 -0
- package/dist/security.js +569 -0
- package/dist/session-profile.d.ts +86 -0
- package/dist/session-profile.js +1471 -0
- package/dist/sf-pro-fonts.d.ts +4 -0
- package/dist/sf-pro-fonts.js +7 -0
- package/dist/status-bar-l10n.d.ts +14 -0
- package/dist/status-bar-l10n.js +177 -0
- package/dist/status-bar.d.ts +44 -0
- package/dist/status-bar.js +336 -0
- package/dist/tools.d.ts +4 -0
- package/dist/tools.js +578 -0
- package/dist/types.d.ts +796 -0
- package/dist/types.js +2 -0
- package/dist/video-agent.d.ts +143 -0
- package/dist/video-agent.js +4783 -0
- package/dist/video-observation.d.ts +36 -0
- package/dist/video-observation.js +192 -0
- package/dist/video-planner.d.ts +12 -0
- package/dist/video-planner.js +500 -0
- package/dist/video-prompts.d.ts +37 -0
- package/dist/video-prompts.js +554 -0
- package/dist/video-tools.d.ts +3 -0
- package/dist/video-tools.js +59 -0
- package/dist/video-variant-state.d.ts +29 -0
- package/dist/video-variant-state.js +80 -0
- package/dist/vision-model.d.ts +17 -0
- package/dist/vision-model.js +74 -0
- package/package.json +165 -0
- 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
|
package/dist/abort.d.ts
ADDED
|
@@ -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
|