@warpgogol/forge 0.14.0 → 0.15.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 (42) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +58 -5
  3. package/dist/bin/cli.js +0 -0
  4. package/dist/os/core/core.module.d.ts.map +1 -1
  5. package/dist/os/core/core.module.js +9 -0
  6. package/dist/os/core/core.module.js.map +1 -1
  7. package/dist/src/onboarding/create.d.ts.map +1 -1
  8. package/dist/src/onboarding/create.js +5 -2
  9. package/dist/src/onboarding/create.js.map +1 -1
  10. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  11. package/dist/src/onboarding/doctor.js +38 -0
  12. package/dist/src/onboarding/doctor.js.map +1 -1
  13. package/dist/src/onboarding/invariant-engine.d.ts.map +1 -1
  14. package/dist/src/onboarding/invariant-engine.js +14 -7
  15. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  16. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  17. package/dist/src/onboarding/scaffold-project.js +25 -5
  18. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  19. package/dist/src/profiles/profile-schema.d.ts +73 -8
  20. package/dist/src/profiles/profile-schema.d.ts.map +1 -1
  21. package/dist/src/profiles/profile-schema.js +35 -10
  22. package/dist/src/profiles/profile-schema.js.map +1 -1
  23. package/dist/src/profiles/stack-profile.d.ts +26 -2
  24. package/dist/src/profiles/stack-profile.d.ts.map +1 -1
  25. package/dist/src/profiles/stack-profile.js +4 -0
  26. package/dist/src/profiles/stack-profile.js.map +1 -1
  27. package/package.json +162 -60
  28. package/profiles/editframe-templates/composition-agents.md +70 -0
  29. package/profiles/editframe-templates/composition.tsx +33 -0
  30. package/profiles/{editframe-html-templates/composition-agents.md → editframe-templates/html-composition-agents.md} +15 -16
  31. package/profiles/{editframe-html.yaml → editframe.yaml} +170 -56
  32. package/skills/fo/ef-brand-video-generator/SKILL.md +101 -0
  33. package/skills/fo/ef-composition/SKILL.md +147 -0
  34. package/skills/fo/ef-composition-review/SKILL.md +10 -10
  35. package/skills/fo/ef-dev-server/SKILL.md +107 -0
  36. package/skills/fo/ef-editor-gui/SKILL.md +131 -0
  37. package/skills/fo/ef-motion-design/SKILL.md +118 -0
  38. package/skills/fo/ef-onboard/SKILL.md +16 -29
  39. package/skills/fo/ef-render-verify/SKILL.md +2 -2
  40. package/skills/fo/ef-webhooks/SKILL.md +95 -0
  41. package/skills/fo/fo-session-retro/SKILL.md +2 -2
  42. package/profiles/editframe-html-templates/composition.html +0 -32
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: ef-dev-server
3
+ description: "Set up and manage the Editframe dev server for live preview and local asset serving. Use when the operator asks to set up or configure the Editframe dev server."
4
+ invocation: user
5
+ category: fo
6
+ concerns: read-only
7
+ dependsOn: []
8
+ languagePolicy: ref(PREFERENCES.md)
9
+ triggers:
10
+ - "set up editframe dev server"
11
+ - "configure editframe preview"
12
+ - "local asset serving"
13
+ - "dev server not working"
14
+ source: https://editframe.com/skills/dev-server.md
15
+ ---
16
+
17
+ <!-- skill-lint-disable SKILL-17 -->
18
+
19
+ Before starting, read `PREFERENCES.md` at the repository root. If the file is missing or `aiLanguage` is unset, ask the operator once and create the file using the `my-preferences` skill semantics.
20
+
21
+ # Dev Server
22
+
23
+ The Editframe dev server provides JIT video transcoding, local image and caption serving, and a local files API that mirrors the production files API. It integrates with Vite, Next.js, or any framework-agnostic setup.
24
+
25
+ ## Vite setup
26
+
27
+ ```typescript
28
+ // vite.config.ts
29
+ import { defineConfig } from "vite";
30
+ import { vitePluginEditframe } from "@editframe/vite-plugin";
31
+
32
+ export default defineConfig({
33
+ plugins: [
34
+ vitePluginEditframe({
35
+ root: "./src",
36
+ cacheRoot: "./cache",
37
+ }),
38
+ ],
39
+ });
40
+ ```
41
+
42
+ The plugin mounts onto Vite's own dev server. Compositions make same-origin requests. No separate port and no CORS setup are necessary.
43
+
44
+ ## Next.js setup
45
+
46
+ ```javascript
47
+ // next.config.mjs
48
+ import { withEditframe } from "@editframe/nextjs-plugin";
49
+
50
+ export default withEditframe(
51
+ { root: "./src", cacheRoot: "./cache" },
52
+ {
53
+ // your existing Next.js config
54
+ },
55
+ );
56
+ ```
57
+
58
+ `withEditframe` starts a sidecar HTTP server next to `next dev`, on port 3099 by default. Override the port with a `port` option. It also adds `rewrites()` rules that proxy Editframe's requests to that sidecar, so compositions still make same-origin requests. Run `next dev` as usual. No other setup is necessary.
59
+
60
+ The sidecar does not start in production. Deploy against real media (cloud renders, uploaded files) instead.
61
+
62
+ ## Framework-agnostic setup
63
+
64
+ For a toolchain with no Vite or Next.js integration, call `@editframe/dev-server` directly:
65
+
66
+ ```typescript
67
+ import { createEditframeDevServer, createProdEfHandlers } from "@editframe/dev-server";
68
+ import {
69
+ generateTrack,
70
+ generateScrubTrack,
71
+ generateTrackFragmentIndex,
72
+ cacheImage,
73
+ findOrCreateCaptions,
74
+ md5FilePath,
75
+ } from "@editframe/assets";
76
+ import { Client, createURLToken } from "@editframe/api";
77
+
78
+ const server = createEditframeDevServer(
79
+ { root: "./src", cacheRoot: "./cache" },
80
+ { generateTrack, generateScrubTrack, generateTrackFragmentIndex, cacheImage, findOrCreateCaptions, md5FilePath },
81
+ createProdEfHandlers({
82
+ createURLToken,
83
+ getClient: () => new Client(process.env.EF_TOKEN),
84
+ }),
85
+ );
86
+
87
+ server.listen(3001, () => console.log("Editframe dev server running on http://localhost:3001"));
88
+ ```
89
+
90
+ ## What it enables
91
+
92
+ - **JIT video transcoding** — reference a local video file directly (`<Video src="clip.mp4" />`). The dev server transcodes it into streamable segments on first request, then serves cached segments.
93
+ - **Local image and caption serving** — `<Image>` and caption generation work against local files.
94
+ - **A local files API** that mirrors the shape of the production files API.
95
+ - **URL signing** — `ef-configuration`'s default `signing-url` forwards to the real Editframe cloud API. Set `EF_TOKEN` before starting the dev server. Set `EF_HOST` to point at a non-default API host.
96
+
97
+ ## Framework-agnostic middleware integration
98
+
99
+ If your toolchain already exposes a Connect-compatible middleware stack (Express, Connect, or a custom Vite integration), call `createEditframeRouter(...)` with the same three arguments instead. Mount the result with `.use()`. `createEditframeDevServer` wraps that same router in its own standalone `http.Server`, for toolchains with no middleware stack of their own.
100
+
101
+ ## Visual regression testing (Vite only)
102
+
103
+ The Vite plugin supports visual regression testing. Configure snapshot directories and thresholds in the plugin options.
104
+
105
+ ## Debug logging
106
+
107
+ Set `DEBUG=editframe:*` to enable verbose logging from the dev server and plugin.
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: ef-editor-gui
3
+ description: "Configure the Editframe editor GUI for visual composition editing — timeline, scrubber, canvas, preview controls. Use when the operator asks to set up or use the Editframe editor."
4
+ invocation: user
5
+ category: fo
6
+ concerns: read-only
7
+ dependsOn: []
8
+ languagePolicy: ref(PREFERENCES.md)
9
+ triggers:
10
+ - "open editframe editor"
11
+ - "set up editor gui"
12
+ - "add timeline controls"
13
+ - "visual editing"
14
+ source: https://editframe.com/skills/editor-gui.md
15
+ ---
16
+
17
+ <!-- skill-lint-disable SKILL-17 -->
18
+
19
+ Before starting, read `PREFERENCES.md` at the repository root. If the file is missing or `aiLanguage` is unset, ask the operator once and create the file using the `my-preferences` skill semantics.
20
+
21
+ # Editor Toolkit
22
+
23
+ The Editframe editor toolkit provides visual composition editing controls: timeline, scrubber, canvas, preview, playback, and transformation.
24
+
25
+ ## Quick start
26
+
27
+ ```html
28
+ <ef-timegroup id="my-video">
29
+ <ef-video src="/video.mp4"></ef-video>
30
+ </ef-timegroup>
31
+
32
+ <ef-controls target="my-video">
33
+ <ef-toggle-play></ef-toggle-play>
34
+ <ef-scrubber></ef-scrubber>
35
+ <ef-time-display></ef-time-display>
36
+ </ef-controls>
37
+ ```
38
+
39
+ ## Core concepts: target and bridge
40
+
41
+ Each playback control (`ef-play`, `ef-pause`, `ef-toggle-play`, `ef-toggle-loop`, `ef-volume`, `ef-mute`, `ef-scrubber`, `ef-time-display`) resolves the composition it drives in this order:
42
+
43
+ 1. Its own `target="id-or-selector"` attribute, if set.
44
+ 2. Walks up through ancestor `ef-controls`, `ef-preview`, and `ef-configuration` elements. An ancestor with its own `target` resolves there. A bare `ef-configuration` ancestor resolves to itself.
45
+ 3. As a last resort, resolves to the nearest enclosing temporal root.
46
+
47
+ `ef-controls` is a pure proxy — it renders nothing itself but gives descendant controls a shared `target`.
48
+
49
+ ## Preview and canvas
50
+
51
+ - **`ef-preview`** — renders a live preview of the composition
52
+ - **`ef-canvas`** — interactive canvas with selection state
53
+
54
+ ## Playback and display controls
55
+
56
+ - **`ef-play`** / **`ef-pause`** / **`ef-toggle-play`** — playback controls
57
+ - **`ef-toggle-loop`** — toggle loop mode
58
+ - **`ef-volume`** / **`ef-mute`** — audio controls
59
+ - **`ef-time-display`** — current time / total time display
60
+ - **`ef-scrubber`** — seekable timeline scrubber
61
+ - **`ef-fullscreen`** — fullscreen toggle
62
+ - **`ef-pip`** — picture-in-picture toggle
63
+
64
+ ## Timeline
65
+
66
+ - **`ef-timeline`** — timeline container with rows
67
+ - **`ef-timeline-row`** — a single track row
68
+ - **`ef-timeline-ruler`** — time ruler with markers
69
+ - **`ef-composition-thumbnail-strip`** — thumbnail overview of the composition
70
+
71
+ ## Transform and manipulation
72
+
73
+ - **`ef-transform-handles`** — drag, resize, rotate handles for elements
74
+ - **`ef-trim-handles`** — trim start/end of video clips
75
+ - **`ef-fit-scale`** — fit or scale the canvas to the viewport
76
+
77
+ ## Overlay system
78
+
79
+ - **`ef-overlay-layer`** — overlay container
80
+ - **`ef-overlay-item`** — individual overlay panel
81
+
82
+ ## Editor shells
83
+
84
+ - **`ef-workbench`** — full editor layout with panels
85
+ - **`ef-tree`** / **`ef-tree-item`** — hierarchy tree of composition elements
86
+ - **`ef-hierarchy`** / **`ef-hierarchy-item`** — alternative hierarchy view with selection bridge
87
+
88
+ ## Element reference
89
+
90
+ | Element | Purpose |
91
+ | -------------------------------- | ------------------------------------------------ |
92
+ | `ef-canvas` | Interactive composition canvas |
93
+ | `ef-canvas-selection-box` | Selection rectangle overlay on canvas |
94
+ | `ef-composition-thumbnail-strip` | Thumbnail overview of the composition |
95
+ | `ef-controls` | Proxy container for shared target |
96
+ | `ef-dial` | Rotary dial control for parameters |
97
+ | `ef-fit-scale` | Fit or scale canvas to viewport |
98
+ | `ef-fullscreen` | Fullscreen toggle |
99
+ | `ef-hierarchy` | Alternative hierarchy view with selection bridge |
100
+ | `ef-hierarchy-item` | Item in hierarchy view |
101
+ | `ef-mute` | Mute toggle |
102
+ | `ef-overlay-item` | Individual overlay panel |
103
+ | `ef-overlay-layer` | Overlay container |
104
+ | `ef-pause` | Pause button |
105
+ | `ef-pip` | Picture-in-picture toggle |
106
+ | `ef-play` | Play button |
107
+ | `ef-preview` | Live composition preview |
108
+ | `ef-resolution` | Resolution selector |
109
+ | `ef-scrubber` | Seekable timeline scrubber |
110
+ | `ef-thumbnail-strip` | Thumbnail strip for timeline |
111
+ | `ef-time-display` | Time display |
112
+ | `ef-timeline` | Timeline container |
113
+ | `ef-timeline-row` | Single track row in timeline |
114
+ | `ef-timeline-ruler` | Time ruler with markers |
115
+ | `ef-toggle-loop` | Toggle loop mode |
116
+ | `ef-toggle-play` | Play/pause toggle |
117
+ | `ef-transform-handles` | Drag, resize, rotate handles for elements |
118
+ | `ef-tree` | Composition hierarchy tree |
119
+ | `ef-tree-item` | Item in hierarchy tree |
120
+ | `ef-trim-handles` | Trim start/end of video clips |
121
+ | `ef-volume` | Volume control |
122
+ | `ef-waveform-strip` | Audio waveform strip for timeline |
123
+ | `ef-workbench` | Full editor layout with panels |
124
+
125
+ ### `ef-workbench`
126
+
127
+ Composes a hierarchy panel, a canvas and selection view, a timeline, and transport controls into one panel layout (DOM preview mode only).
128
+
129
+ **Attributes:** `rendering` (boolean, collapses to bare stage during native render), `resolution` (string, e.g. `"1920x1080"`).
130
+
131
+ **Methods:** `exportVideo(options?)` — renders the composition to an MP4 through an offscreen clone. Dispatches `export-start`, `export-progress`, `export-complete`, `export-error` events. Options: `width`, `height`, `fps`, `from`, `to`, `videoCodec`, `audioCodec`, `videoBitrate`, `audioBitrate`, `audioSampleRate`.
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: ef-motion-design
3
+ description: "Apply motion design patterns to Editframe compositions — transitions, animations, easing, kinetic typography. Use when the operator asks to add motion design or animation patterns."
4
+ invocation: user
5
+ category: fo
6
+ concerns: read-only
7
+ dependsOn: []
8
+ languagePolicy: ref(PREFERENCES.md)
9
+ triggers:
10
+ - "add motion design"
11
+ - "animate text"
12
+ - "kinetic typography"
13
+ - "transition between scenes"
14
+ source: domain-knowledge
15
+ ---
16
+
17
+ <!-- skill-lint-disable SKILL-17 -->
18
+
19
+ Before starting, read `PREFERENCES.md` at the repository root. If the file is missing or `aiLanguage` is unset, ask the operator once and create the file using the `my-preferences` skill semantics.
20
+
21
+ # Motion Design
22
+
23
+ Motion design patterns for Editframe compositions: transitions, animations, easing, and kinetic typography. These patterns enhance video compositions with professional motion graphics.
24
+
25
+ ## Transitions
26
+
27
+ Use `ef-transition` or the `transition` prop to declare CSS-like transitions between scenes:
28
+
29
+ ```tsx
30
+ <Timegroup mode="sequence">
31
+ <Video src="assets/scene1.mp4" duration="5s" transition="fade" />
32
+ <Video src="assets/scene2.mp4" duration="5s" transition="slide-left" />
33
+ </Timegroup>
34
+ ```
35
+
36
+ ### Transition types
37
+
38
+ - **`fade`** — cross-fade between elements
39
+ - **`slide-left`** / **`slide-right`** — slide in from left/right
40
+ - **`slide-up`** / **`slide-down`** — slide in from top/bottom
41
+ - **`zoom-in`** / **`zoom-out`** — scale transition
42
+ - **`wipe`** — directional wipe
43
+
44
+ ## Kinetic typography
45
+
46
+ Animate text with `ef-text` or the `Text` component using timing and positioning:
47
+
48
+ ```tsx
49
+ <Timegroup mode="sequence">
50
+ <Text text="First" x="50%" y="50%" fontSize="72px" duration="1s" />
51
+ <Text text="Second" x="50%" y="50%" fontSize="72px" duration="1s" />
52
+ <Text text="Third" x="50%" y="50%" fontSize="72px" duration="1s" />
53
+ </Timegroup>
54
+ ```
55
+
56
+ ### Text animation patterns
57
+
58
+ - **Sequential reveal** — words appear one after another in a `mode="sequence"` Timegroup
59
+ - **Position animation** — animate `x`/`y` props across time
60
+ - **Scale animation** — animate `fontSize` across time
61
+ - **Color transitions** — animate `color` across time
62
+
63
+ ## Easing
64
+
65
+ Editframe supports CSS easing functions for transitions and animations:
66
+
67
+ - `ease` (default)
68
+ - `ease-in`
69
+ - `ease-out`
70
+ - `ease-in-out`
71
+ - `linear`
72
+ - `cubic-bezier(x1, y1, x2, y2)` — custom bezier curve
73
+
74
+ ## Pan and zoom
75
+
76
+ Use `ef-pan-zoom` or the `PanZoom` component for Ken Burns-style effects:
77
+
78
+ ```tsx
79
+ <PanZoom
80
+ src="assets/photo.jpg"
81
+ duration="5s"
82
+ startX="0%"
83
+ startY="0%"
84
+ endX="100%"
85
+ endY="100%"
86
+ startScale="1"
87
+ endScale="1.5"
88
+ />
89
+ ```
90
+
91
+ ## Motion blur
92
+
93
+ Apply motion blur to moving elements with `ef-motionblur` or the `MotionBlur` component:
94
+
95
+ ```tsx
96
+ <MotionBlur intensity="0.5">
97
+ <Video src="assets/fast-pan.mp4" duration="3s" />
98
+ </MotionBlur>
99
+ ```
100
+
101
+ ## CSS variables for time-based animation
102
+
103
+ Editframe compositions support CSS custom properties for time-based values, enabling complex animation sequences without JavaScript:
104
+
105
+ ```css
106
+ :root {
107
+ --scene-duration: 5s;
108
+ --transition-duration: 0.5s;
109
+ }
110
+ ```
111
+
112
+ ## Best practices
113
+
114
+ - Keep transitions consistent within a composition — use 1-2 transition types
115
+ - Match transition duration to content pacing (fast cuts for energy, slow for drama)
116
+ - Use kinetic typography sparingly — it draws attention
117
+ - Preview with `ref(forge.yaml bindings.commands.devServer)` before rendering
118
+ - Run `ref(forge.yaml bindings.commands.validate)` to check composition structure
@@ -19,7 +19,7 @@ triggers:
19
19
 
20
20
  Before starting, read `PREFERENCES.md` at the repository root. If the file is missing or `aiLanguage` is unset, ask the operator once and create the file using the `my-preferences` skill semantics.
21
21
 
22
- Guide the operator through creating a new Editframe video project within a Forge-managed workspace. The skill covers prerequisites check, discovery, scaffold, Editframe domain skills installation, domain knowledge reading, and build + preview.
22
+ Guide the operator through creating a new Editframe video project within a Forge-managed workspace. The skill covers prerequisites check, discovery, scaffold, domain knowledge reading, and build + preview.
23
23
 
24
24
  ## Process
25
25
 
@@ -45,46 +45,33 @@ Ask the operator:
45
45
  - Website URLs to use as content source — if provided, download and cache all relevant assets locally before building
46
46
  - No existing assets — start from scratch
47
47
 
48
- 3. **Stack preference**:
49
- - Vanilla HTML/CSS/JS (simpler, no build step beyond Vite)
50
- - React + TypeScript (component-based, type-safe)
51
- - No preference — recommend HTML for single videos, React for templates and editors
52
-
53
- 4. **Node.js/React libraries**: Ask if the operator has any libraries in mind (e.g. AnimeJS for animations, Tailwind for styling).
48
+ 3. **Node.js/React libraries**: Ask if the operator has any libraries in mind (e.g. AnimeJS for animations, Tailwind for styling).
54
49
 
55
50
  Prioritize getting all answers before starting to build. This minimizes wait time for the operator.
56
51
 
57
52
  ### 3. Scaffold
58
53
 
59
- Run `forge create --profile editframe-html` to scaffold the project with Forge governance (invariants, AGENTS.md templates, forge skills).
60
-
61
- The `editframe-html` profile currently targets HTML compositions only — it does not support a `--template react` flag. If the operator chose React, scaffold with `forge create --profile editframe-html`, then instruct the agent to install `@editframe/react` manually (`pnpm add @editframe/react`) after scaffold.
54
+ Run `forge create --profile editframe` to scaffold the project with Forge governance (invariants, AGENTS.md templates, forge skills). The `editframe` profile scaffolds a React + TypeScript + Vite project with `@editframe/react` pre-configured.
62
55
 
63
56
  If `forge create` fails (missing profile, network error, permission issue), report the error to the operator and stop. Do not proceed to subsequent steps without a scaffolded project.
64
57
 
65
- ### 4. Install Editframe domain skills
66
-
67
- Editframe publishes domain skills via `npm create @editframe`. To make them available alongside forge skills:
68
-
69
- 1. Run `npm create @editframe@latest` in the project directory. This installs Editframe's domain skills to `.agents/skills/editframe-*/`.
70
- 2. Report which skills were installed.
71
- 3. If the command fails (network issues, npm errors, unsupported flags), fall back to referencing the online documentation: direct the agent to read `https://editframe.com/llms.txt` and `https://editframe.com/skills/composition.md` before building. Do not use unverified CLI flags — if `npm create @editframe` prompts interactively, answer the prompts based on the operator's discovery answers from Step 2.
72
-
73
- ### 5. Read domain knowledge
58
+ ### 4. Read domain knowledge
74
59
 
75
- Before building, the agent MUST read the `editframe-composition` skill (either from `.agents/skills/editframe-composition/SKILL.md` if installed, or from `https://editframe.com/skills/composition.md`). This provides domain knowledge about:
60
+ Before building, the agent MUST read the vendored Editframe domain skills. These are bundled with `@warpgogol/forge` and available in `.agents/skills/`:
76
61
 
77
- - Time model (`ef-timegroup`, modes, duration, offset)
78
- - Media elements (`ef-video`, `ef-audio`, `ef-image`, `ef-text`, `ef-captions`)
79
- - CSS animations and transitions
80
- - Rendering pipeline
62
+ - **ef-composition** — time model, media elements, rendering pipeline
63
+ - **ef-dev-server** Vite plugin setup, local asset serving
64
+ - **ef-editor-gui** editor toolkit for visual composition editing
65
+ - **ef-webhooks** — webhook notifications for render completion
66
+ - **ef-brand-video-generator** — brand video generation templates
67
+ - **ef-motion-design** — motion design patterns, transitions, kinetic typography
81
68
 
82
- The agent should also read `editframe-dev-server` if the project uses the dev server.
69
+ The agent should also read **ef-composition-review** and **ef-render-verify** for quality assurance workflows.
83
70
 
84
- ### 6. Build and preview
71
+ ### 5. Build and preview
85
72
 
86
- 1. Build the initial composition based on the operator's answers from Step 2. Use the discovery answers (project type, assets, stack preference, libraries) to determine composition structure, asset placement, and optional dependencies.
87
- 2. Run `forge dev` to start the preview server (delegates to `editframe preview` per the `editframe-html` profile's `devServer.command`).
73
+ 1. Build the initial composition based on the operator's answers from Step 2. Use the discovery answers (project type, assets, libraries) to determine composition structure, asset placement, and optional dependencies.
74
+ 2. Run `forge dev` to start the preview server (delegates to `editframe preview` per the `editframe` profile's `devServer.command`).
88
75
  3. Report the localhost URL to the operator.
89
- 4. Run `forge doctor` to check all profile invariants on the initial composition. For the `editframe-html` profile, this covers VIDEO-01 through VIDEO-09.
76
+ 4. Run `forge doctor` to check all profile invariants on the initial composition. For the `editframe` profile, this covers VIDEO-01 through VIDEO-09.
90
77
  5. Report any invariant violations and suggest fixes.
@@ -18,7 +18,7 @@ A read-only verification of an Editframe render pipeline. The skill runs validat
18
18
 
19
19
  ## Scope
20
20
 
21
- This skill verifies render output for `.html` composition files using the `editframe-html` stack profile. It uses `forge validate`, `forge build`, and `forge determinism check` — all profile-driven commands.
21
+ This skill verifies render output for `.tsx` composition files using the `editframe` stack profile. It uses `forge validate`, `forge build`, and `forge determinism check` — all profile-driven commands.
22
22
 
23
23
  ## Process
24
24
 
@@ -40,7 +40,7 @@ Check the render output:
40
40
 
41
41
  - Verify the output MP4 file exists at the expected path (`dist/{composition}.mp4`).
42
42
  - Check that the file size is non-zero.
43
- - Check that the duration matches the root `ef-timegroup`'s `duration` attribute (if ffprobe or equivalent is available).
43
+ - Check that the duration matches the root `Timegroup`'s `duration` prop (if ffprobe or equivalent is available).
44
44
 
45
45
  ### 5. Report
46
46
 
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: ef-webhooks
3
+ description: "Configure Editframe webhooks for render completion and file processing notifications. Use when the operator asks to set up webhooks for Editframe events."
4
+ invocation: user
5
+ category: fo
6
+ concerns: read-only
7
+ dependsOn: []
8
+ languagePolicy: ref(PREFERENCES.md)
9
+ triggers:
10
+ - "set up editframe webhooks"
11
+ - "render completion notification"
12
+ - "file processing webhook"
13
+ - "webhook signature verification"
14
+ source: https://editframe.com/skills/webhooks.md
15
+ ---
16
+
17
+ <!-- skill-lint-disable SKILL-17 -->
18
+
19
+ Before starting, read `PREFERENCES.md` at the repository root. If the file is missing or `aiLanguage` is unset, ask the operator once and create the file using the `my-preferences` skill semantics.
20
+
21
+ # Webhooks
22
+
23
+ Use webhooks to receive real-time HTTP POST notifications when a render completes or a file finishes processing. Use them instead of polling `getRenderProgress`/`getFileProcessingProgress`.
24
+
25
+ No SDK function registers a webhook. Configure one on an API key, through the dashboard (Settings → API Keys, or `editframe.com/resource/api_keys`). Set a **Webhook URL** (must use HTTPS). Select which **Webhook Events** (topics) to receive. When you create or update the key, the dashboard generates a **Webhook Secret**, used to sign deliveries. Copy this secret and store it alongside the API key.
26
+
27
+ ## Handling a webhook
28
+
29
+ ```typescript
30
+ import express from "express";
31
+ import crypto from "node:crypto";
32
+
33
+ const app = express();
34
+
35
+ app.post("/webhooks/editframe", express.raw({ type: "*/*" }), (req, res) => {
36
+ const signature = req.headers["x-webhook-signature"] as string;
37
+ const rawBody = req.body as Buffer;
38
+
39
+ const expected = crypto
40
+ .createHmac("sha256", process.env.EDITFRAME_WEBHOOK_SECRET!)
41
+ .update(rawBody)
42
+ .digest("hex");
43
+
44
+ if (!crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"))) {
45
+ return res.status(401).send("Invalid signature");
46
+ }
47
+
48
+ res.status(200).send("OK");
49
+ const payload = JSON.parse(rawBody.toString("utf-8"));
50
+ processWebhookEvent(payload).catch(console.error);
51
+ });
52
+ ```
53
+
54
+ Every request carries an `X-Webhook-Signature` header: `HMAC-SHA256(webhook_secret, raw_json_body)`, hex-encoded. Verify with `crypto.timingSafeEqual`, not `===`.
55
+
56
+ Use `express.raw()`, not `express.json()`. Signature verification needs the exact raw bytes. Re-serializing parsed JSON can reorder keys or change whitespace, which changes the hash and breaks verification.
57
+
58
+ ## Payload
59
+
60
+ ```typescript
61
+ { topic: string, data: {...} }
62
+ ```
63
+
64
+ ### Render topics
65
+
66
+ `render.created`, `render.pending`, `render.rendering`, `render.completed`, `render.failed`
67
+
68
+ `data` includes `id`, `status`, `created_at`, `completed_at`, `failed_at`, `width`, `height`, `fps`, `byte_size`, `duration_ms`, `md5`, `metadata`, `expires_at` (`null` = permanent), `download_url` (populated once complete), `error` (populated on failure).
69
+
70
+ ### File topics
71
+
72
+ `file.created`, `file.uploading`, `file.processing`, `file.ready`, `file.failed`, `file.updated`
73
+
74
+ `data` includes `id`, `type` (`video`/`image`/`caption`), `status`, `filename`, `byte_size`, `md5`, `mime_type`, `width`, `height`, `expires_at`. Editframe sends `file.updated` for a file status change that doesn't match one of the other file topics.
75
+
76
+ ### Legacy topics
77
+
78
+ `image_file.created`, `isobmff_file.created`, `isobmff_track.created`, `unprocessed_file.created`. Do not build new integrations against these.
79
+
80
+ ## Delivery
81
+
82
+ - Each event arrives as one HTTP POST with a JSON body.
83
+ - Editframe retries on a fixed 10-second interval, up to 3 attempts total, with a 30-second timeout per attempt.
84
+ - Editframe may deliver an event more than once. Key side effects off `data.id` to stay idempotent.
85
+ - Always hash the **raw** request body for signature verification.
86
+
87
+ ## Testing
88
+
89
+ ```bash
90
+ npx editframe webhook -t render.completed
91
+ ```
92
+
93
+ This sends a real test event to the URL configured on your API key. There is no `--webhookURL` flag — the target URL always comes from the key's dashboard configuration. The dashboard's API key detail page has an equivalent "Test Webhook" button.
94
+
95
+ For local development, tunnel your dev server (e.g. `ngrok http 3000`) and point the API key's Webhook URL at the tunnel URL.
@@ -9,7 +9,7 @@ languagePolicy: ref(PREFERENCES.md)
9
9
  bindings:
10
10
  requires: []
11
11
  optional: [paths.invariantsFile]
12
- triggers: ["session retrospective", "capture insights from this session", "triage session discoveries", "Завершаем эту сессию", "Завершаем сессию", "Заканчиваем сессию", "Завершить сессию", "End session", "Wrap up", "Session end", "/session-end"]
12
+ triggers: ["session retrospective", "capture insights from this session", "triage session discoveries", "Завершаем сессию", "/session-end"]
13
13
  ---
14
14
 
15
15
  # Session Retro
@@ -261,7 +261,7 @@ When gathering session insights, not every observation deserves to be saved. App
261
261
 
262
262
  **Do NOT save** — the observation is:
263
263
 
264
- - A one-off fact with no future impact (e.g. "RFC-0676 was skipped due to a duplicate"). These are historical events, not knowledge. They do not help future agents work better.
264
+ - A one-off fact with no future impact (e.g. "an RFC was skipped due to a duplicate"). These are historical events, not knowledge. They do not help future agents work better.
265
265
  - A tool quirk already documented elsewhere (check `AGENTS.md` and existing memories first).
266
266
  - A transient state that will be irrelevant by the next session (e.g. "file X was dirty at session end").
267
267
  - A bug that was found and fixed in the same session with no broader lesson.
@@ -1,32 +0,0 @@
1
- <!--
2
- Editframe HTML composition template
3
- Copy this file to start a new composition. Editframe custom elements:
4
- - ef-timegroup: groups elements into a timed sequence
5
- - ef-video: video source with fit mode (contain, cover, fill)
6
- - ef-audio: audio source
7
- - ef-text: text overlay with positioning
8
- - ef-captions: accessibility captions for speech audio
9
- Run `editframe preview` to preview, `editframe render` to produce output.
10
- -->
11
- <ef-timegroup duration="10s">
12
- <ef-video
13
- src="assets/background.mp4"
14
- fit="contain"
15
- duration="10s"
16
- ></ef-video>
17
- <ef-text
18
- text="Your text here"
19
- x="50%"
20
- y="50%"
21
- font-size="48px"
22
- color="white"
23
- text-align="center"
24
- duration="5s"
25
- ></ef-text>
26
- <ef-audio
27
- src="assets/narration.mp3"
28
- ></ef-audio>
29
- <ef-captions
30
- src="assets/captions.vtt"
31
- ></ef-captions>
32
- </ef-timegroup>