@editframe/create 0.44.0 → 0.45.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 (98) hide show
  1. package/dist/index.js +16 -28
  2. package/dist/index.js.map +1 -1
  3. package/dist/skills/editframe-brand-video-generator/README.md +155 -0
  4. package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
  5. package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
  6. package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
  7. package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
  8. package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
  9. package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
  10. package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
  11. package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
  12. package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
  13. package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
  14. package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
  15. package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
  16. package/dist/skills/editframe-composition/SKILL.md +169 -0
  17. package/dist/skills/editframe-composition/references/audio.md +483 -0
  18. package/dist/skills/editframe-composition/references/captions.md +844 -0
  19. package/dist/skills/editframe-composition/references/composition-model.md +73 -0
  20. package/dist/skills/editframe-composition/references/configuration.md +403 -0
  21. package/dist/skills/editframe-composition/references/css-parts.md +105 -0
  22. package/dist/skills/editframe-composition/references/css-variables.md +640 -0
  23. package/dist/skills/editframe-composition/references/entry-points.md +810 -0
  24. package/dist/skills/editframe-composition/references/events.md +499 -0
  25. package/dist/skills/editframe-composition/references/getting-started.md +259 -0
  26. package/dist/skills/editframe-composition/references/hooks.md +234 -0
  27. package/dist/skills/editframe-composition/references/image.md +241 -0
  28. package/dist/skills/editframe-composition/references/r3f.md +580 -0
  29. package/dist/skills/editframe-composition/references/render-api.md +484 -0
  30. package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
  31. package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
  32. package/dist/skills/editframe-composition/references/scripting.md +606 -0
  33. package/dist/skills/editframe-composition/references/sequencing.md +116 -0
  34. package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
  35. package/dist/skills/editframe-composition/references/surface.md +329 -0
  36. package/dist/skills/editframe-composition/references/text.md +627 -0
  37. package/dist/skills/editframe-composition/references/time-model.md +99 -0
  38. package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
  39. package/dist/skills/editframe-composition/references/timegroup.md +457 -0
  40. package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
  41. package/dist/skills/editframe-composition/references/transcription.md +47 -0
  42. package/dist/skills/editframe-composition/references/transitions.md +608 -0
  43. package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
  44. package/dist/skills/editframe-composition/references/video.md +506 -0
  45. package/dist/skills/editframe-composition/references/waveform.md +327 -0
  46. package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
  47. package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
  48. package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
  49. package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
  50. package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
  51. package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
  52. package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
  53. package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
  54. package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
  55. package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
  56. package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
  57. package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
  58. package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
  59. package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
  60. package/dist/skills/editframe-editor-gui/references/play.md +370 -0
  61. package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
  62. package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
  63. package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
  64. package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
  65. package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
  66. package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
  67. package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
  68. package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
  69. package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
  70. package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
  71. package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
  72. package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
  73. package/dist/skills/editframe-motion-design/SKILL.md +101 -0
  74. package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
  75. package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
  76. package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
  77. package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
  78. package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
  79. package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
  80. package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
  81. package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
  82. package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
  83. package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
  84. package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
  85. package/dist/skills/editframe-webhooks/SKILL.md +126 -0
  86. package/dist/skills/editframe-webhooks/references/events.md +382 -0
  87. package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
  88. package/dist/skills/editframe-webhooks/references/security.md +418 -0
  89. package/dist/skills/editframe-webhooks/references/testing.md +409 -0
  90. package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
  91. package/dist/templates/html/AGENTS.md +13 -0
  92. package/dist/templates/react/AGENTS.md +13 -0
  93. package/dist/utils.js +15 -16
  94. package/dist/utils.js.map +1 -1
  95. package/package.json +1 -1
  96. package/tsdown.config.ts +4 -0
  97. package/dist/detectAgent.js +0 -89
  98. package/dist/detectAgent.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: JIT Transcoding
3
+ description: On-demand video transcoding during local development for instant browser-compatible playback of any input video format.
4
+ type: reference
5
+ nav:
6
+ parent: "Features"
7
+ priority: 20
8
+ api:
9
+ endpoints:
10
+ - path: /api/v1/transcode/manifest.json
11
+ method: GET
12
+ description: Returns a JIT manifest describing available renditions and segments
13
+ - path: /api/v1/transcode/{rendition}/init.mp4
14
+ method: GET
15
+ description: Returns the initialization segment for a rendition
16
+ - path: /api/v1/transcode/{rendition}/{segmentId}.mp4
17
+ method: GET
18
+ description: Returns a media segment as a standalone playable file
19
+ - path: /api/v1/transcode/{rendition}/{segmentId}.m4s
20
+ method: GET
21
+ description: Returns a media segment fragment for streaming
22
+ ---
23
+
24
+ # JIT Transcoding
25
+
26
+ The Vite plugin transcodes video files on-demand during development. When a composition references a local video, the plugin splits it into streamable ISOBMFF segments and serves them through a local transcode API that mirrors the production endpoint structure.
27
+
28
+ ## How It Works
29
+
30
+ When a video is first requested, the plugin:
31
+
32
+ 1. Generates a **fragment index** describing every track (video, audio, scrub) with byte offsets and durations
33
+ 2. Creates separated track files cached in the `cacheRoot` directory
34
+ 3. Serves individual segments by streaming the correct byte ranges from cached track files
35
+
36
+ Subsequent requests for the same video skip transcoding entirely and serve directly from cache.
37
+
38
+ ## Manifest Endpoint
39
+
40
+ The manifest describes available renditions and their segments:
41
+
42
+ ```
43
+ GET /api/v1/transcode/manifest.json?url=http://localhost:5173/src/assets/clip.mp4
44
+ ```
45
+
46
+ The response includes video renditions (`high`, `scrub`), audio renditions, per-segment duration arrays, codec strings, and endpoint templates for fetching init and media segments.
47
+
48
+ ## Segment Serving
49
+
50
+ Init segments and media segments are served by extracting byte ranges from the cached track file:
51
+
52
+ ```
53
+ GET /api/v1/transcode/high/init.mp4?url=... # Initialization segment
54
+ GET /api/v1/transcode/high/1.m4s?url=... # Fragment (moof+mdat only)
55
+ GET /api/v1/transcode/high/1.mp4?url=... # Standalone playable (init+moof+mdat)
56
+ ```
57
+
58
+ The `.m4s` extension returns raw fragments for streaming playback. The `.mp4` extension prepends the init segment so the file is independently playable, which is useful for testing.
59
+
60
+ ## Renditions
61
+
62
+ The plugin creates three rendition types from each video:
63
+
64
+ - **high** -- Full resolution video track (track ID 1)
65
+ - **scrub** -- Low-resolution 320px-wide video for timeline scrubbing (track ID -1)
66
+ - **audio** -- Audio track extracted separately (track ID 2, or track ID 1 for audio-only files)
67
+
68
+ ## Cache Management
69
+
70
+ Transcoded assets are stored under `{cacheRoot}/.cache/`. To clear the cache programmatically:
71
+
72
+ ```
73
+ DELETE /@ef-clear-cache/
74
+ ```
75
+
76
+ The cache clear uses retry logic with backoff to handle race conditions during concurrent test runs. ENOENT errors are treated as success (cache already cleared), and ENOTEMPTY errors trigger retries.
77
+
78
+ ## Remote URL Support
79
+
80
+ The `url` parameter can reference either local or remote files. The plugin resolves the URL by checking the hostname:
81
+
82
+ - **Local URLs** (localhost, 127.0.0.1, *.localhost) are resolved to file paths relative to `root`
83
+ - **Remote URLs** are passed directly to ffprobe, which supports HTTP/HTTPS natively
84
+
85
+ ## Debug Logging
86
+
87
+ Enable debug output for the transcode middleware:
88
+
89
+ ```bash
90
+ DEBUG=ef:vite-plugin:jit npm run dev
91
+ ```
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: Local Assets API
3
+ description: Local development endpoints for asset management, image thumbnail caching, and automatic caption file generation.
4
+ type: reference
5
+ nav:
6
+ parent: "Features"
7
+ priority: 30
8
+ api:
9
+ endpoints:
10
+ - path: /api/v1/assets/image
11
+ method: GET
12
+ description: Caches and serves a local or remote image file
13
+ - path: /api/v1/assets/captions
14
+ method: GET
15
+ description: Generates or retrieves cached captions for an audio/video file
16
+ ---
17
+
18
+ # Local Assets API
19
+
20
+ The plugin serves local images and captions through endpoints that mirror the production asset API. This allows compositions to use the same asset-fetching logic in both development and production without conditional paths.
21
+
22
+ ## Image Caching
23
+
24
+ The image endpoint caches and serves image files with proper MIME types and ETags:
25
+
26
+ ```
27
+ GET /api/v1/assets/image?src=assets/background.png
28
+ ```
29
+
30
+ The `src` parameter accepts both local paths (resolved relative to the plugin `root` directory) and remote `http`/`https` URLs. Remote images are fetched server-side and returned as same-origin responses, preventing canvas CORS taint when compositions serialize to image. Local files are processed through `cacheImage(cacheRoot, absolutePath)` and served with an MD5-based ETag.
31
+
32
+ ## Caption Generation
33
+
34
+ The captions endpoint generates or retrieves cached transcription data for audio and video files:
35
+
36
+ ```
37
+ GET /api/v1/assets/captions?src=assets/interview.mp4
38
+ ```
39
+
40
+ This calls `findOrCreateCaptions(cacheRoot, absolutePath)` which either returns existing cached captions or generates new ones using the assets package transcription pipeline. The result is served as JSON with cache headers.
41
+
42
+ ## Path Resolution
43
+
44
+ All `src` parameters follow the same resolution logic:
45
+
46
+ 1. If `src` starts with `http://` or `https://`, it is fetched server-side and proxied to the browser as same-origin
47
+ 2. Otherwise, `src` is joined with the plugin `root` option
48
+ 3. Any `dist/` prefix in the resolved path is replaced with `src/` to support source-mapped development
49
+
50
+ ```typescript
51
+ // Example: root = "./dev-projects/src"
52
+ // src = "assets/photo.jpg"
53
+ // Resolved: ./dev-projects/src/assets/photo.jpg
54
+ ```
55
+
56
+ ## Response Format
57
+
58
+ All asset responses are streamed from the cache with:
59
+
60
+ - **Content-Type** determined by file extension via the `mime` package
61
+ - **ETag** set to the MD5 hash of the cached file
62
+ - **Cache-Control** set to `max-age=3600`
63
+ - **Range request** support for partial content (HTTP 206)
64
+
65
+ ## Error Handling
66
+
67
+ - Missing `src` parameter returns `400` with `{ error: "src parameter is required" }`
68
+ - File not found returns `404` with plain text body
69
+ - Other errors return `500` with `{ error: "..." }` JSON
70
+
71
+ ## Debug Logging
72
+
73
+ ```bash
74
+ DEBUG=ef:vite-plugin:assets npm run dev
75
+ ```
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: Visual Testing
3
+ description: Automated visual regression testing for Editframe compositions, comparing rendered frames against stored baseline images.
4
+ type: reference
5
+ nav:
6
+ parent: "Features"
7
+ priority: 50
8
+ api:
9
+ endpoints:
10
+ - path: "/@ef-write-snapshot"
11
+ method: POST
12
+ description: Writes a snapshot image (baseline or actual) to disk
13
+ - path: "/@ef-compare-snapshot"
14
+ method: POST
15
+ description: Compares a screenshot against a stored baseline using odiff
16
+ - path: "/@ef-compare-two-images"
17
+ method: POST
18
+ description: Compares two arbitrary images using odiff
19
+ ---
20
+
21
+ # Visual Testing
22
+
23
+ The Vitest entry point (`@editframe/vite-plugin/src/index.vitest.js`) adds server-side image comparison endpoints powered by [odiff-bin](https://github.com/nicolo-ribaudo/odiff-bin). Tests running in the browser capture screenshots and POST them to the Vite server, which performs pixel-level comparison on the server where native binaries are available.
24
+
25
+ ## Setup
26
+
27
+ Use the Vitest-specific import in your `vitest.config.ts`:
28
+
29
+ ```typescript
30
+ import { defineConfig } from "vitest/config";
31
+
32
+ export default defineConfig(async () => {
33
+ const { vitePluginEditframe } = await import(
34
+ "@editframe/vite-plugin/src/index.vitest.js"
35
+ );
36
+
37
+ return {
38
+ plugins: [
39
+ vitePluginEditframe({
40
+ root: "./test-assets",
41
+ cacheRoot: "./test-assets",
42
+ }),
43
+ ],
44
+ test: {
45
+ browser: {
46
+ enabled: true,
47
+ provider: "playwright",
48
+ },
49
+ },
50
+ };
51
+ });
52
+ ```
53
+
54
+ ## Snapshot Comparison
55
+
56
+ The `/@ef-compare-snapshot` endpoint compares a screenshot against a stored baseline:
57
+
58
+ ```typescript
59
+ const response = await fetch("/@ef-compare-snapshot", {
60
+ method: "POST",
61
+ body: JSON.stringify({
62
+ testName: "my-component",
63
+ snapshotName: "default-state",
64
+ dataUrl: canvas.toDataURL("image/png"),
65
+ threshold: 0.1,
66
+ antialiasing: true,
67
+ acceptableDiffPercentage: 1.0,
68
+ }),
69
+ });
70
+ const result = await response.json();
71
+ // { match: true, diffCount: 0, diffPercentage: 0 }
72
+ ```
73
+
74
+ ### First Run Behavior
75
+
76
+ When no baseline exists, the actual image is automatically saved as the baseline and the comparison returns `{ match: true, baselineCreated: true }`. Subsequent runs compare against this stored baseline.
77
+
78
+ ### Comparison Parameters
79
+
80
+ - **threshold** (default `0.1`) -- Color distance threshold passed to odiff. Lower values are stricter.
81
+ - **antialiasing** (default `true`) -- When true, odiff ignores antialiasing differences between images.
82
+ - **acceptableDiffPercentage** (default `1.0`) -- Maximum percentage of differing pixels before the comparison is considered a failure.
83
+
84
+ ## Two-Image Comparison
85
+
86
+ The `/@ef-compare-two-images` endpoint compares any two images without baseline management:
87
+
88
+ ```typescript
89
+ const response = await fetch("/@ef-compare-two-images", {
90
+ method: "POST",
91
+ body: JSON.stringify({
92
+ testName: "animation-test",
93
+ comparisonName: "frame-1-vs-frame-2",
94
+ dataUrl1: frame1Canvas.toDataURL("image/png"),
95
+ dataUrl2: frame2Canvas.toDataURL("image/png"),
96
+ threshold: 0.1,
97
+ acceptableDiffPercentage: 5.0,
98
+ }),
99
+ });
100
+ ```
101
+
102
+ Both images are written to the snapshot directory and compared with odiff. This is useful for verifying that two frames of an animation are visually distinct or within tolerance.
103
+
104
+ ## Snapshot Storage
105
+
106
+ Snapshots are stored under `{root}/test/__snapshots__/{testName}/`:
107
+
108
+ ```
109
+ test/__snapshots__/my-component/
110
+ default-state.baseline.png # Reference image
111
+ default-state.actual.png # Latest capture
112
+ default-state.diff.png # Pixel diff (generated on mismatch)
113
+ ```
114
+
115
+ The `/@ef-write-snapshot` endpoint can write a baseline or actual image directly:
116
+
117
+ ```typescript
118
+ await fetch("/@ef-write-snapshot", {
119
+ method: "POST",
120
+ body: JSON.stringify({
121
+ testName: "my-component",
122
+ snapshotName: "default-state",
123
+ dataUrl: canvas.toDataURL("image/png"),
124
+ isBaseline: true,
125
+ }),
126
+ });
127
+ ```
128
+
129
+ ## Diff Output
130
+
131
+ When images differ beyond the acceptable threshold, odiff generates a diff image highlighting changed pixels. The response includes:
132
+
133
+ - **match** -- `false` when the diff exceeds the threshold
134
+ - **diffCount** -- Total number of differing pixels
135
+ - **diffPercentage** -- Percentage of the image area that differs
136
+ - **error** -- Set to `"Images have different dimensions"` when a layout diff is detected
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: editframe-webhooks
3
+ title: Webhooks
4
+ description: Webhook notifications for render completion and file processing events. Configure endpoints, verify HMAC signatures, and handle real-time status payloads.
5
+ order: 35
6
+ license: MIT
7
+ metadata:
8
+ author: editframe
9
+ version: "2.0"
10
+ ---
11
+
12
+ # Webhooks
13
+
14
+ Receive real-time HTTP notifications when renders complete, files finish processing, or other asynchronous events occur in your Editframe account.
15
+
16
+ ## Setup
17
+
18
+ Webhooks are configured on an API key, not separately. The webhook URL and events you want to receive are set at API key creation time.
19
+
20
+ **Step 1**: Create an API key with webhook configuration via the Editframe dashboard (editframe.com → API Keys → Create), or via your application's API key management endpoint. The dashboard returns a webhook secret — store it securely.
21
+
22
+ **Step 2**: Handle webhook requests:
23
+
24
+ ```typescript
25
+ // 3. Handle webhook requests
26
+ app.post("/webhooks/editframe", async (req, res) => {
27
+ const signature = req.headers["x-webhook-signature"];
28
+ const payload = JSON.stringify(req.body);
29
+ const webhookSecret = process.env.EDITFRAME_WEBHOOK_SECRET;
30
+
31
+ // Verify signature — always verify before processing
32
+ const expectedSignature = crypto
33
+ .createHmac("sha256", webhookSecret)
34
+ .update(payload)
35
+ .digest("hex");
36
+
37
+ if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
38
+ return res.status(401).send("Invalid signature");
39
+ }
40
+
41
+ // Respond quickly, process asynchronously
42
+ res.status(200).send("OK");
43
+
44
+ const { topic, data } = req.body;
45
+ if (topic === "render.completed") {
46
+ console.log(`Render ${data.id} completed. Download: ${data.download_url}`);
47
+ }
48
+ });
49
+ ```
50
+
51
+ **Critical:** Hash the raw request body string (`JSON.stringify(req.body)`), not the parsed object. Use `timingSafeEqual` to prevent timing attacks.
52
+
53
+ ## Event Topics
54
+
55
+ Webhooks are triggered for specific event topics:
56
+
57
+ ### Render Events
58
+ - `render.created` — Render job created
59
+ - `render.pending` — Render queued for processing
60
+ - `render.rendering` — Render is actively processing
61
+ - `render.completed` — Render successfully finished
62
+ - `render.failed` — Render encountered an error
63
+
64
+ ### File Events
65
+ - `file.created` — File record created
66
+ - `file.uploading` — File is being uploaded
67
+ - `file.processing` — File is being processed (video only)
68
+ - `file.ready` — File is ready for use
69
+ - `file.failed` — File processing failed
70
+
71
+ ### Legacy Events
72
+ - `unprocessed_file.created` — Unprocessed file created (deprecated)
73
+
74
+ ## Configuration
75
+
76
+ Configure webhooks when creating or updating an API key:
77
+
78
+ **Webhook URL**: The HTTPS endpoint where Editframe will send POST requests
79
+ **Webhook Events**: Array of event topics you want to receive
80
+ **Webhook Secret**: Auto-generated HMAC secret for signature verification
81
+
82
+ See [references/getting-started.md](references/getting-started.md) for detailed setup instructions.
83
+
84
+ ## Security
85
+
86
+ All webhook requests include an `X-Webhook-Signature` header containing an HMAC-SHA256 signature. Always verify this signature before processing webhook payloads.
87
+
88
+ See [references/security.md](references/security.md) for signature verification implementation.
89
+
90
+ ## Delivery Guarantees
91
+
92
+ - Webhooks are delivered via HTTP POST with JSON payload
93
+ - Automatic retry with exponential backoff (3 attempts)
94
+ - 30-second timeout per attempt
95
+ - Events marked as failed after retry exhaustion
96
+ - Delivery history tracked for debugging
97
+
98
+ ## Testing
99
+
100
+ Test your webhook endpoint before going live:
101
+
102
+ ```bash
103
+ # Use the Editframe dashboard to send test webhooks
104
+ # Or trigger test events via the API
105
+ ```
106
+
107
+ See [references/testing.md](references/testing.md) for testing strategies including local development with ngrok.
108
+
109
+ ## Troubleshooting
110
+
111
+ Common issues and solutions:
112
+
113
+ - **Signature verification fails**: Ensure you're hashing the raw request body, not parsed JSON
114
+ - **Timeout errors**: Respond with 200 OK quickly, process events asynchronously
115
+ - **Missed webhooks**: Check delivery logs in the Editframe dashboard
116
+ - **Duplicate events**: Implement idempotency using event IDs
117
+
118
+ See [references/troubleshooting.md](references/troubleshooting.md) for detailed debugging guidance.
119
+
120
+ ## Reference Documentation
121
+
122
+ - [references/getting-started.md](references/getting-started.md) — Set up your first webhook
123
+ - [references/events.md](references/events.md) — Event types and payload structures
124
+ - [references/security.md](references/security.md) — HMAC signature verification
125
+ - [references/testing.md](references/testing.md) — Test webhooks locally and in production
126
+ - [references/troubleshooting.md](references/troubleshooting.md) — Debug common issues