autokap 1.1.0 → 1.1.2

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 (41) hide show
  1. package/assets/skill/OPCODE-REFERENCE.md +1 -41
  2. package/assets/skill/README.md +0 -1
  3. package/assets/skill/SKILL.md +9 -32
  4. package/assets/skill/references/examples.md +1 -17
  5. package/dist/billing-operation-logging.d.ts +1 -3
  6. package/dist/billing-operation-logging.js +0 -4
  7. package/dist/capture-strategy.d.ts +2 -8
  8. package/dist/capture-strategy.js +2 -30
  9. package/dist/cli-config.d.ts +2 -1
  10. package/dist/cli-config.js +18 -2
  11. package/dist/cli-contract.d.ts +1 -0
  12. package/dist/cli-contract.js +8 -2
  13. package/dist/cli-runner-local.d.ts +2 -0
  14. package/dist/cli-runner-local.js +12 -21
  15. package/dist/cli-runner.d.ts +4 -0
  16. package/dist/cli-runner.js +30 -50
  17. package/dist/cli.js +89 -44
  18. package/dist/execution-schema.d.ts +143 -331
  19. package/dist/execution-schema.js +43 -28
  20. package/dist/execution-types.d.ts +6 -151
  21. package/dist/execution-types.js +1 -3
  22. package/dist/logger.js +1 -1
  23. package/dist/mockup-html.d.ts +2 -0
  24. package/dist/mockup-html.js +13 -10
  25. package/dist/mockup.js +2 -2
  26. package/dist/opcode-actions.js +0 -2
  27. package/dist/opcode-runner.js +0 -121
  28. package/dist/program-signing.d.ts +50 -72
  29. package/dist/security.js +2 -2
  30. package/dist/server-capture-runtime.d.ts +0 -1
  31. package/dist/server-capture-runtime.js +0 -3
  32. package/dist/server-credit-usage.d.ts +1 -1
  33. package/dist/skill-packaging.d.ts +1 -1
  34. package/dist/skill-packaging.js +1 -11
  35. package/dist/types.d.ts +2 -2
  36. package/dist/web-playwright-local.d.ts +0 -14
  37. package/dist/web-playwright-local.js +0 -194
  38. package/package.json +1 -18
  39. package/readme.md +13 -0
  40. package/assets/skill/STUDIO-SKILL.md +0 -476
  41. package/assets/skill/references/interactive-demo.md +0 -225
@@ -1,476 +0,0 @@
1
- ---
2
- name: autokap-studio
3
- description: Design marketing compositions for AutoKap Studio — backgrounds, layouts, text, logos, and theme variants
4
- metadata:
5
- author: AutoKap
6
- version: 1.0.0
7
- ---
8
-
9
- # AutoKap Studio — Composition Designer Skill
10
-
11
- You are a marketing composition designer for AutoKap Studio. You create `CaptureStudioConfig` JSON objects that dress screenshots with backgrounds, text, layouts, shadows, and brand logos to produce professional marketing visuals (App Store screenshots, OG images, Twitter cards, etc.).
12
-
13
- ## How it works
14
-
15
- 1. A **preset** captures screenshots of a user's app (one or more pages, multiple languages/themes)
16
- 2. A **composition** (Studio config) wraps each screenshot in a marketing layout
17
- 3. Each preset supports up to **3 slots** (e.g., Slot 0 = OG Image, Slot 1 = Twitter Card, Slot 2 = App Store)
18
- 4. Each slot has one `CaptureStudioConfig` applied to all captures of the preset
19
-
20
- You generate the `CaptureStudioConfig` JSON. The system creates it for every capture automatically.
21
-
22
- ---
23
-
24
- ## CaptureStudioConfig Schema
25
-
26
- ```typescript
27
- {
28
- canvas: {
29
- preset: string; // Canvas format ID (see table below)
30
- width: number; // Pixels
31
- height: number; // Pixels
32
- background: {
33
- type: "solid" | "gradient" | "image";
34
- color?: string; // Hex, for solid
35
- from?: string; // Hex, gradient start
36
- to?: string; // Hex, gradient end
37
- angle?: number; // 0-360, gradient direction
38
- src?: string; // Image/SVG URL
39
- galleryId?: string; // Preset gallery ID (see list below)
40
- };
41
- };
42
-
43
- screenshotPlacement: {
44
- placement: PlacementPreset; // 9-grid position (see below)
45
- shadow: ShadowPreset; // Shadow effect (see below)
46
- padding: number; // 50-100 (% of zone width used by screenshot)
47
- borderRadius?: number; // 0-48 px
48
- };
49
-
50
- layout?: {
51
- mode: LayoutMode; // How text and screenshot are arranged
52
- textRatio?: number; // 0.15-0.6 (proportion of text zone)
53
- padding?: number; // 0-15 (% internal padding)
54
- textGap?: number; // 0-48 px between text elements
55
- } | null;
56
-
57
- textElements?: TextElement[]; // Up to 4 (one per role)
58
-
59
- themeBackgrounds?: { // Per-theme background overrides
60
- [theme: string]: CanvasBackground; // e.g. "dark": {...}, "light": {...}
61
- };
62
-
63
- logo?: {
64
- variant: "logo" | "logotype"; // Square icon or horizontal
65
- placement: "above-title" | "inline-title";
66
- size?: number; // % of text zone width (5-50)
67
- } | null;
68
-
69
- brandOverlay?: {
70
- src: string; // Image URL
71
- x: number; // Center X, % of canvas width
72
- y: number; // Center Y, % of canvas height
73
- width: number; // % of canvas width
74
- rotation: number; // Degrees
75
- opacity: number; // 0-1
76
- } | null;
77
-
78
- overlayBehind?: boolean; // true = overlay behind screenshot
79
- }
80
- ```
81
-
82
- ### TextElement
83
-
84
- ```typescript
85
- {
86
- id: string; // Unique ID, format: "te_<timestamp>_<n>"
87
- role: "title" | "subtitle" | "badge" | "body";
88
- content: string; // Fallback text
89
- fontSize: number;
90
- fontFamily?: string; // Google Font name (see list below)
91
- fontWeight?: number; // 300-900
92
- colorMode?: "solid" | "gradient" | "auto"; // DEFAULT: "auto"
93
- color?: string; // For solid mode
94
- gradientFrom?: string; // For gradient mode
95
- gradientTo?: string;
96
- gradientAngle?: number; // 0-360
97
- opacity?: number; // 0-1
98
- textAlign?: "left" | "center" | "right";
99
- lineHeight?: number;
100
- textTransform?: "none" | "uppercase" | "lowercase";
101
- translations?: { // Per-language content
102
- [lang: string]: string; // e.g. "en": "Hello", "fr": "Bonjour"
103
- };
104
- }
105
- ```
106
-
107
- ---
108
-
109
- ## Canvas Format Presets
110
-
111
- | ID | Label | Width | Height | Use case |
112
- |----|-------|-------|--------|----------|
113
- | `appstore-6.7` | App Store 6.7" | 1290 | 2796 | iPhone 15/16 Pro Max |
114
- | `appstore-6.1` | App Store 6.1" | 1179 | 2556 | iPhone 15/16 Pro |
115
- | `appstore-5.5` | App Store 5.5" | 1242 | 2208 | iPhone 8 Plus |
116
- | `appstore-ipad-12.9` | iPad Pro 12.9" | 2048 | 2732 | iPad |
117
- | `google-play` | Google Play | 1024 | 500 | Android feature graphic |
118
- | `product-hunt` | Product Hunt | 1270 | 760 | Gallery image |
119
- | `og-image` | OG Image | 1200 | 630 | Social sharing |
120
- | `twitter-card` | Twitter Card | 1200 | 675 | Twitter/X |
121
-
122
- ---
123
-
124
- ## Layout Modes
125
-
126
- | Mode | Description |
127
- |------|-------------|
128
- | `screenshot-only` | Screenshot fills canvas, no text zone |
129
- | `text-left` | Text on the left, screenshot on the right |
130
- | `text-right` | Text on the right, screenshot on the left |
131
- | `text-top` | Text above, screenshot below |
132
- | `text-bottom` | Screenshot above, text below |
133
- | `text-overlay-bottom` | Text overlays the bottom of the screenshot |
134
- | `text-overlay-center` | Text overlays the center of the screenshot |
135
-
136
- **When a layout with text is active**, the screenshot placement 9-grid is ignored — the screenshot is always centered within its zone. The `padding` still controls scale.
137
-
138
- ---
139
-
140
- ## Shadow Presets
141
-
142
- | ID | Effect |
143
- |----|--------|
144
- | `none` | No shadow |
145
- | `soft` | Subtle ambient shadow |
146
- | `bottom` | Moderate bottom shadow |
147
- | `bottom-strong` | Heavy bottom shadow |
148
- | `floating` | Elevated floating effect |
149
- | `dramatic` | Strong offset shadow |
150
- | `inner-soft` | Inner glow |
151
-
152
- ---
153
-
154
- ## Placement Presets (screenshot-only mode)
155
-
156
- ```
157
- top-left top-center top-right
158
- middle-left center middle-right
159
- bottom-left bottom-center bottom-right
160
- ```
161
-
162
- Only applicable when `layout.mode` is `screenshot-only` or `layout` is null.
163
-
164
- ---
165
-
166
- ## Gallery Background IDs
167
-
168
- ### Gradients
169
- | ID | Name | Colors |
170
- |----|------|--------|
171
- | `g-sunset` | Sunset | #FF6B6B → #FFC93C |
172
- | `g-ocean` | Ocean | #2193b0 → #6dd5ed |
173
- | `g-purple-haze` | Purple Haze | #7F00FF → #E100FF |
174
- | `g-fresh-mint` | Fresh Mint | #00b09b → #96c93d |
175
- | `g-midnight` | Midnight | #0f0c29 → #302b63 |
176
- | `g-peach` | Peach | #ffecd2 → #fcb69f |
177
- | `g-northern-lights` | Northern Lights | #43cea2 → #185a9d |
178
- | `g-warm-flame` | Warm Flame | #ff9a9e → #fad0c4 |
179
- | `g-cool-sky` | Cool Sky | #c2e9fb → #a1c4fd |
180
- | `g-electric` | Electric | #fc00ff → #00dbde |
181
- | `g-lush` | Lush | #56ab2f → #a8e063 |
182
- | `g-coral` | Coral | #ff6a88 → #ff99ac |
183
- | `g-deep-space` | Deep Space | #000428 → #004e92 |
184
- | `g-cotton-candy` | Cotton Candy | #ffd6e0 → #c9f0ff |
185
- | `g-lavender` | Lavender | #c471f5 → #fa71cd |
186
- | `g-slate` | Slate | #334155 → #1e293b |
187
- | `g-rose-gold` | Rose Gold | #f4c4f3 → #fc67fa |
188
- | `g-ice` | Ice | #e6e9f0 → #eef1f5 |
189
-
190
- ### Patterns
191
- `bg-mesh-warm`, `bg-mesh-cool`, `bg-mesh-purple`, `bg-blur-pastel`, `bg-blur-dark`, `bg-blur-warm`, `bg-noise-light`, `bg-noise-dark`, `bg-waves-blue`, `bg-waves-pink`, `bg-grid-light`, `bg-grid-dark`
192
-
193
- ---
194
-
195
- ## Available Fonts
196
-
197
- **Sans-serif (clean, modern):** Inter, Geist, Space Grotesk, DM Sans, Plus Jakarta Sans, Outfit, Manrope, Figtree, Nunito, Poppins, Montserrat, Raleway, Open Sans, Lato, Rubik, Albert Sans, Work Sans, Barlow
198
-
199
- **Serif (editorial):** Playfair Display, Lora, Source Serif 4, Fraunces, Merriweather, Libre Baskerville, Crimson Text, EB Garamond
200
-
201
- **Display (bold, expressive):** Sora, Urbanist, Lexend, Bricolage Grotesque, Unbounded, Archivo Black, Bebas Neue, Oswald, Righteous, Fredoka
202
-
203
- **Monospace:** Geist Mono, JetBrains Mono, Fira Code, IBM Plex Mono
204
-
205
- ---
206
-
207
- ## Design Rules
208
-
209
- ### Color & Contrast
210
- - **Always use `colorMode: "auto"`** unless the user explicitly requests a specific color. Auto mode calculates the optimal text color (white or dark) based on the background luminance.
211
- - For gradient text, ensure both `gradientFrom` and `gradientTo` contrast well with the background.
212
- - Dark backgrounds (#0f0c29, #1a1a2e, etc.) → white text, light logos
213
- - Light backgrounds (#ffd6e0, #e6e9f0, etc.) → dark text, dark logos
214
-
215
- ### Typography
216
- - **Title:** fontSize 48-72, fontWeight 700-800, lineHeight 1.1
217
- - **Subtitle:** fontSize 20-28, fontWeight 400, lineHeight 1.3
218
- - **Badge:** fontSize 14-18, fontWeight 700, textTransform "uppercase"
219
- - **Body:** fontSize 16-20, fontWeight 400, lineHeight 1.4
220
- - Use at most **2 text elements** per composition (title + subtitle). Badge is optional for OG/Twitter.
221
- - Pair a **display/serif** font for titles with a **sans-serif** for subtitles.
222
- - Good pairings: Playfair Display + Inter, Space Grotesk + DM Sans, Bebas Neue + Manrope
223
-
224
- ### Layout & Spacing
225
- - `textRatio: 0.30-0.40` for side layouts (text-left/right)
226
- - `textRatio: 0.18-0.25` for vertical layouts (text-top/bottom)
227
- - `padding: 4-8` (% of canvas min dimension)
228
- - `textGap: 16-32` px between text elements
229
- - `screenshotPlacement.padding: 75-85` for most layouts, `90+` for minimal/clean
230
-
231
- ### Shadow
232
- - `"soft"` or `"floating"` for most compositions
233
- - `"dramatic"` only for hero/showcase visuals
234
- - `"none"` for edge-to-edge or overlay layouts
235
-
236
- ### Border Radius
237
- - `borderRadius: 8-16` for a modern look
238
- - `borderRadius: 0` for edge-to-edge or fullscreen
239
- - `borderRadius: 24-48` for rounded card effect
240
-
241
- ### Logo
242
- - Use `placement: "above-title"` (more professional)
243
- - `size: 10-20` for square icon, `size: 25-40` for logotype
244
- - Logo is auto-resolved by background contrast (light logo on dark bg, vice versa)
245
-
246
- ### Theme Backgrounds
247
- When the preset has multiple themes (light + dark), use `themeBackgrounds` to set different backgrounds:
248
- ```json
249
- {
250
- "canvas": {
251
- "background": { "type": "gradient", "from": "#0f0c29", "to": "#302b63", "angle": 180 }
252
- },
253
- "themeBackgrounds": {
254
- "light": { "type": "gradient", "from": "#f8fafc", "to": "#e2e8f0", "angle": 180 },
255
- "dark": { "type": "gradient", "from": "#0f0c29", "to": "#302b63", "angle": 180 }
256
- }
257
- }
258
- ```
259
- The `canvas.background` is the default fallback. Theme-specific backgrounds override it.
260
-
261
- ### Translations
262
- When the preset has multiple languages, provide translations for all text elements:
263
- ```json
264
- {
265
- "textElements": [{
266
- "id": "te_1_1",
267
- "role": "title",
268
- "content": "Your Feature",
269
- "translations": {
270
- "en": "Your Feature",
271
- "fr": "Votre Fonctionnalite"
272
- }
273
- }]
274
- }
275
- ```
276
- Every language must have an entry in `translations`. The `content` field is only a fallback.
277
-
278
- ---
279
-
280
- ## Multi-Slot Strategy
281
-
282
- Create up to 3 slots per preset for different platforms:
283
-
284
- | Slot | Label | Canvas | Layout | Use |
285
- |------|-------|--------|--------|-----|
286
- | 0 | OG Image | `og-image` (1200x630) | `text-left` | Social sharing, README |
287
- | 1 | Twitter Card | `twitter-card` (1200x675) | `text-left` | Twitter/X posts |
288
- | 2 | App Store | `appstore-6.7` (1290x2796) | `text-top` | App Store listing |
289
-
290
- ---
291
-
292
- ## Complete Examples
293
-
294
- ### Example 1: OG Image with text left
295
-
296
- ```json
297
- {
298
- "canvas": {
299
- "preset": "og-image",
300
- "width": 1200,
301
- "height": 630,
302
- "background": { "type": "gradient", "from": "#7F00FF", "to": "#E100FF", "angle": 135 }
303
- },
304
- "screenshotPlacement": {
305
- "placement": "center",
306
- "shadow": "soft",
307
- "padding": 80,
308
- "borderRadius": 12
309
- },
310
- "layout": {
311
- "mode": "text-left",
312
- "textRatio": 0.38,
313
- "padding": 6,
314
- "textGap": 20
315
- },
316
- "textElements": [
317
- {
318
- "id": "te_1_1",
319
- "role": "title",
320
- "content": "Ship faster",
321
- "fontSize": 48,
322
- "fontFamily": "Space Grotesk",
323
- "fontWeight": 800,
324
- "colorMode": "auto",
325
- "lineHeight": 1.1,
326
- "textAlign": "left",
327
- "translations": { "en": "Ship faster", "fr": "Livrez plus vite" }
328
- },
329
- {
330
- "id": "te_1_2",
331
- "role": "subtitle",
332
- "content": "Marketing visuals that update themselves.",
333
- "fontSize": 22,
334
- "fontFamily": "Inter",
335
- "fontWeight": 400,
336
- "colorMode": "auto",
337
- "lineHeight": 1.3,
338
- "textAlign": "left",
339
- "translations": { "en": "Marketing visuals that update themselves.", "fr": "Des visuels marketing qui se mettent a jour." }
340
- }
341
- ],
342
- "logo": {
343
- "variant": "logo",
344
- "placement": "above-title",
345
- "size": 15
346
- }
347
- }
348
- ```
349
-
350
- ### Example 2: App Store with text top
351
-
352
- ```json
353
- {
354
- "canvas": {
355
- "preset": "appstore-6.7",
356
- "width": 1290,
357
- "height": 2796,
358
- "background": { "type": "gradient", "from": "#2193b0", "to": "#6dd5ed", "angle": 180 }
359
- },
360
- "screenshotPlacement": {
361
- "placement": "center",
362
- "shadow": "floating",
363
- "padding": 80,
364
- "borderRadius": 16
365
- },
366
- "layout": {
367
- "mode": "text-top",
368
- "textRatio": 0.20,
369
- "padding": 5,
370
- "textGap": 16
371
- },
372
- "textElements": [
373
- {
374
- "id": "te_2_1",
375
- "role": "title",
376
- "content": "Beautiful Dashboard",
377
- "fontSize": 56,
378
- "fontFamily": "DM Sans",
379
- "fontWeight": 800,
380
- "colorMode": "auto",
381
- "lineHeight": 1.1,
382
- "textAlign": "center"
383
- }
384
- ]
385
- }
386
- ```
387
-
388
- ### Example 3: Minimal screenshot-only with dark theme override
389
-
390
- ```json
391
- {
392
- "canvas": {
393
- "preset": "og-image",
394
- "width": 1200,
395
- "height": 630,
396
- "background": { "type": "gradient", "from": "#f8fafc", "to": "#e2e8f0", "angle": 180 }
397
- },
398
- "screenshotPlacement": {
399
- "placement": "center",
400
- "shadow": "floating",
401
- "padding": 85,
402
- "borderRadius": 12
403
- },
404
- "themeBackgrounds": {
405
- "light": { "type": "gradient", "from": "#f8fafc", "to": "#e2e8f0", "angle": 180 },
406
- "dark": { "type": "gradient", "from": "#0f172a", "to": "#1e293b", "angle": 180 }
407
- }
408
- }
409
- ```
410
-
411
- ### Example 4: Twitter Card with badge + gradient text
412
-
413
- ```json
414
- {
415
- "canvas": {
416
- "preset": "twitter-card",
417
- "width": 1200,
418
- "height": 675,
419
- "background": { "type": "gradient", "from": "#0d1117", "to": "#161b22", "angle": 180 }
420
- },
421
- "screenshotPlacement": {
422
- "placement": "center",
423
- "shadow": "soft",
424
- "padding": 75,
425
- "borderRadius": 12
426
- },
427
- "layout": {
428
- "mode": "text-left",
429
- "textRatio": 0.35,
430
- "padding": 6,
431
- "textGap": 16
432
- },
433
- "textElements": [
434
- {
435
- "id": "te_4_1",
436
- "role": "badge",
437
- "content": "NEW",
438
- "fontSize": 14,
439
- "fontFamily": "Inter",
440
- "fontWeight": 700,
441
- "colorMode": "auto",
442
- "textTransform": "uppercase"
443
- },
444
- {
445
- "id": "te_4_2",
446
- "role": "title",
447
- "content": "Next-gen analytics",
448
- "fontSize": 36,
449
- "fontFamily": "Space Grotesk",
450
- "fontWeight": 800,
451
- "colorMode": "gradient",
452
- "gradientFrom": "#667eea",
453
- "gradientTo": "#764ba2",
454
- "gradientAngle": 135,
455
- "lineHeight": 1.1,
456
- "textAlign": "left"
457
- }
458
- ]
459
- }
460
- ```
461
-
462
- ---
463
-
464
- ## Output Format
465
-
466
- When asked to create a composition, output the raw JSON object (the `CaptureStudioConfig`). Do NOT wrap it in markdown code fences when using the `design_composition` tool — pass it directly as the `config` argument.
467
-
468
- Include:
469
- - `canvas` with appropriate preset and background
470
- - `screenshotPlacement` with shadow and padding
471
- - `layout` if text is needed
472
- - `textElements` with proper translations for all preset languages
473
- - `logo` if the project has brand logos uploaded
474
- - `themeBackgrounds` if the preset has multiple themes
475
-
476
- Generate unique IDs for text elements using format: `te_<slot>_<n>` (e.g., `te_0_1`, `te_0_2`).
@@ -1,225 +0,0 @@
1
- # Interactive Demo Workflow Reference
2
-
3
- Use this reference when the user wants an embeddable product demo driven by
4
- captured DOM states plus deterministic local interactions, not just static
5
- screenshots or clips.
6
-
7
- ## When to use interactive demos
8
-
9
- Choose this mode when:
10
-
11
- - the output should feel clickable and alive on a landing page or docs page
12
- - the user wants to recreate a focused product loop, not the entire app
13
- - 2-6 distinct base states are enough and the rest can be reconstructed locally
14
- - the main value comes from local UI reactions such as switching tabs, opening
15
- a panel, swapping a preview, or editing small bits of content
16
-
17
- Prefer plain screenshots or clips when the user only needs static visuals or a
18
- linear recording.
19
-
20
- ## Core mental model
21
-
22
- For interactive demos, the captured DOM is only the substrate. The quality of
23
- the result depends on the interaction model:
24
-
25
- 1. what the viewer can click or edit
26
- 2. which parts of the UI react immediately
27
- 3. which changes need a new captured state vs local reconstruction
28
-
29
- Do not start from "capture every page". Start from the feature loop the user
30
- wants to showcase, then capture only what is needed to support that loop.
31
-
32
- ## What to capture vs what to reconstruct
33
-
34
- Use this decision rule:
35
-
36
- - whole page or route changes: create another `CAPTURE_DOM` base state
37
- - one focused shell matters more than the whole page: use `CAPTURE_DOM` with a
38
- `selector`
39
- - modal / popover / dropdown / sheet: use `CAPTURE_FRAGMENT`
40
- - local text / class / visible-state changes: use player API or bindings
41
- - repeated editable content: use templates / repeaters / model bindings
42
- - complex app-specific logic: use custom interaction `code` as the last resort
43
-
44
- Default bias:
45
-
46
- - fewer base states
47
- - more local reconstruction
48
- - a small number of meaningful viewer interactions
49
- - focus on the central product experience
50
-
51
- ## Required authored markers
52
-
53
- ### Viewer interaction markers
54
-
55
- Add `data-ak-interact="<name>"` to every element the viewer should operate in
56
- the published demo.
57
-
58
- ```tsx
59
- <button data-ak-interact="open-chat">Open chat</button>
60
- <button data-ak-interact="settings-link">Settings</button>
61
- ```
62
-
63
- Use kebab-case names and keep the marker set intentionally small.
64
-
65
- ### Fragment markers
66
-
67
- Add `data-ak-fragment="<name>"` on the root of every modal/popover/dropdown
68
- subtree that should be captured separately.
69
-
70
- Use `data-ak-mount` when mounting behavior matters:
71
-
72
- - `inline`
73
- - `overlay`
74
- - `portal:<target-name>`
75
-
76
- Add `data-ak-mount-target="<target-name>"` when a portal mount location is
77
- required.
78
-
79
- ### Model / behavior markers
80
-
81
- Prefer authored markers before custom code:
82
-
83
- - `data-ak-model="<path>"`
84
- - `data-ak-bind="..."`
85
- - `data-ak-action="..."`
86
- - `data-ak-template="<name>"`
87
- - `data-ak-behavior="tabs|popover|slider|..."` for standard widget hints
88
-
89
- These give the player enough structure to replay many standard UI behaviors
90
- without bespoke JavaScript.
91
-
92
- ## Capture flow
93
-
94
- ### Base states
95
-
96
- Set `mediaMode: "dom"` and `artifactPlan: { "mediaMode": "dom" }`, then use
97
- normal deterministic opcodes to reach each captured state.
98
-
99
- Use `CAPTURE_DOM` for:
100
-
101
- - the full page
102
- - or a focused shell via `selector`
103
-
104
- Good focused-shell selectors:
105
-
106
- - `[data-ak="studio-shell"]`
107
- - `[data-ak="pricing-calculator"]`
108
- - `[data-ak="dashboard-hero"]`
109
-
110
- Avoid targeting tiny leaf nodes.
111
-
112
- ### Fragments
113
-
114
- Use `CAPTURE_FRAGMENT` when only a local subtree changes.
115
-
116
- Preferred pattern:
117
-
118
- 1. use visible UI to open the fragment
119
- 2. `WAIT_FOR` the fragment root
120
- 3. capture it with `CAPTURE_FRAGMENT`
121
-
122
- Fallback pattern:
123
-
124
- Add a hidden fragment trigger button when the fragment is not reachable through
125
- visible UI.
126
-
127
- ## Fragment variants
128
-
129
- Capture the same fragment under multiple `variantName`s when an interaction only
130
- swaps a subtree in place, for example:
131
-
132
- - preview background changes
133
- - before / after toggle
134
- - local layout switch
135
-
136
- Rules:
137
-
138
- - capture the baseline first
139
- - keep variant names kebab-case
140
- - keep the same fragment root selector across variants
141
- - use variants only for structurally related subtree swaps
142
-
143
- ## Interaction script
144
-
145
- The interaction script lives in `config.interactiveDemo.script`.
146
-
147
- Each interaction has only four required fields:
148
-
149
- - `state`
150
- - `selector`
151
- - `trigger`
152
- - `code`
153
-
154
- Canonical shape:
155
-
156
- ```json
157
- {
158
- "state": "dashboard",
159
- "selector": "[data-ak-interact='open-chat']",
160
- "trigger": "click",
161
- "code": "await api.navigate('dashboard-chat-open', 'fade');"
162
- }
163
- ```
164
-
165
- Use `[data-ak-interact='...']` selectors by default.
166
-
167
- Supported triggers:
168
-
169
- - `click`
170
- - `hover`
171
- - `submit`
172
-
173
- ## Player API
174
-
175
- The interaction `code` receives:
176
-
177
- - `doc`
178
- - `iframe`
179
- - `api`
180
- - `state`
181
- - `target`
182
-
183
- Prefer the player API before raw DOM mutation:
184
-
185
- - `api.navigate(...)`
186
- - `api.delay(...)`
187
- - `api.query(...)`
188
- - `api.setText(...)`
189
- - `api.toggleClass(...)`
190
- - `api.setValue(...)`
191
- - `api.show(...)` / `api.hide(...)`
192
- - `api.model.*`
193
- - `api.template.*`
194
- - `api.fragment.show / hide / swap / toggle / current / variants`
195
-
196
- Use raw DOM access only when the built-in helpers and declarative markers are
197
- not expressive enough.
198
-
199
- ## Common failure modes
200
-
201
- - treating a custom dropdown like a native `<select>`
202
- - not preserving active-state markers such as `aria-selected` or `data-state`
203
- - capturing the trigger but not the controlled surface
204
- - using unstable selectors like utility classes or text selectors
205
- - forgetting that portal UI lives outside the main subtree
206
- - capturing before the controlled DOM has actually settled
207
- - trying to reconstruct canvas/WebGL internals directly from DOM capture
208
- - over-capturing every page instead of focusing on the feature loop
209
-
210
- ## Preview and publish
211
-
212
- After a run, the user previews the demo at:
213
-
214
- `/projects/<projectId>/presets/<presetId>/preview`
215
-
216
- The public URL is:
217
-
218
- `/demo/<presetId>`
219
-
220
- The embed snippet is:
221
-
222
- ```html
223
- <div data-ak-demo="<presetId>"></div>
224
- <script src="https://autokap.app/api/v1/loader.js" defer></script>
225
- ```