@editframe/create 0.44.0 → 0.45.1
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/dist/index.js +16 -28
- package/dist/index.js.map +1 -1
- package/dist/skills/editframe-brand-video-generator/README.md +155 -0
- package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
- package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
- package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
- package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
- package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
- package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
- package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
- package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
- package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
- package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
- package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
- package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
- package/dist/skills/editframe-composition/SKILL.md +169 -0
- package/dist/skills/editframe-composition/references/audio.md +483 -0
- package/dist/skills/editframe-composition/references/captions.md +844 -0
- package/dist/skills/editframe-composition/references/composition-model.md +73 -0
- package/dist/skills/editframe-composition/references/configuration.md +403 -0
- package/dist/skills/editframe-composition/references/css-parts.md +105 -0
- package/dist/skills/editframe-composition/references/css-variables.md +640 -0
- package/dist/skills/editframe-composition/references/entry-points.md +810 -0
- package/dist/skills/editframe-composition/references/events.md +499 -0
- package/dist/skills/editframe-composition/references/getting-started.md +259 -0
- package/dist/skills/editframe-composition/references/hooks.md +234 -0
- package/dist/skills/editframe-composition/references/image.md +241 -0
- package/dist/skills/editframe-composition/references/r3f.md +580 -0
- package/dist/skills/editframe-composition/references/render-api.md +484 -0
- package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
- package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
- package/dist/skills/editframe-composition/references/scripting.md +606 -0
- package/dist/skills/editframe-composition/references/sequencing.md +116 -0
- package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
- package/dist/skills/editframe-composition/references/surface.md +329 -0
- package/dist/skills/editframe-composition/references/text.md +627 -0
- package/dist/skills/editframe-composition/references/time-model.md +99 -0
- package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
- package/dist/skills/editframe-composition/references/timegroup.md +457 -0
- package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
- package/dist/skills/editframe-composition/references/transcription.md +47 -0
- package/dist/skills/editframe-composition/references/transitions.md +608 -0
- package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
- package/dist/skills/editframe-composition/references/video.md +506 -0
- package/dist/skills/editframe-composition/references/waveform.md +327 -0
- package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
- package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
- package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
- package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
- package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
- package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
- package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
- package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
- package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
- package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
- package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
- package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
- package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
- package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
- package/dist/skills/editframe-editor-gui/references/play.md +370 -0
- package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
- package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
- package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
- package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
- package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
- package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
- package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
- package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
- package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
- package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
- package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
- package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
- package/dist/skills/editframe-motion-design/SKILL.md +101 -0
- package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
- package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
- package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
- package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
- package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
- package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
- package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
- package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
- package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
- package/dist/skills/editframe-webhooks/SKILL.md +126 -0
- package/dist/skills/editframe-webhooks/references/events.md +382 -0
- package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
- package/dist/skills/editframe-webhooks/references/security.md +418 -0
- package/dist/skills/editframe-webhooks/references/testing.md +409 -0
- package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
- package/dist/templates/html/AGENTS.md +13 -0
- package/dist/templates/react/AGENTS.md +13 -0
- package/dist/utils.js +15 -16
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/tsdown.config.ts +4 -0
- package/dist/detectAgent.js +0 -89
- package/dist/detectAgent.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { getStartCommand, getUserPkgManager, installAgentSkills, installDependencies } from "./utils.js";
|
|
3
|
-
import { getAgentChoices } from "./detectAgent.js";
|
|
4
3
|
import { access, cp, readdir } from "node:fs/promises";
|
|
5
4
|
import path from "node:path";
|
|
6
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -18,7 +17,6 @@ ${chalk.bold("Options:")}
|
|
|
18
17
|
-d, --directory <name> Project directory name
|
|
19
18
|
--skip-install Skip dependency installation
|
|
20
19
|
--skip-skills Skip agent skills installation
|
|
21
|
-
--agent <name> Specify AI agent (cursor, claude, vscode, etc.)
|
|
22
20
|
-y, --yes Skip all prompts, use defaults
|
|
23
21
|
-h, --help Show this help message
|
|
24
22
|
|
|
@@ -33,7 +31,7 @@ ${chalk.bold("Examples:")}
|
|
|
33
31
|
npm create @editframe -- react
|
|
34
32
|
|
|
35
33
|
${chalk.dim("# Full non-interactive")}
|
|
36
|
-
npm create @editframe -- react -d my-app
|
|
34
|
+
npm create @editframe -- react -d my-app -y
|
|
37
35
|
|
|
38
36
|
${chalk.dim("# Skip auto-installation")}
|
|
39
37
|
npm create @editframe -- react --skip-install --skip-skills
|
|
@@ -71,7 +69,6 @@ async function main() {
|
|
|
71
69
|
type: "boolean",
|
|
72
70
|
default: false
|
|
73
71
|
},
|
|
74
|
-
agent: { type: "string" },
|
|
75
72
|
yes: {
|
|
76
73
|
type: "boolean",
|
|
77
74
|
short: "y",
|
|
@@ -88,7 +85,6 @@ async function main() {
|
|
|
88
85
|
const cliDirectory = values.directory;
|
|
89
86
|
const skipInstall = values.skipInstall;
|
|
90
87
|
const skipSkills = values.skipSkills;
|
|
91
|
-
const cliAgent = values.agent;
|
|
92
88
|
const nonInteractive = values.yes;
|
|
93
89
|
if (cliTemplate && !templates.includes(cliTemplate)) {
|
|
94
90
|
process.stderr.write(chalk.red(`Error: Template "${cliTemplate}" does not exist.\n\n`));
|
|
@@ -113,22 +109,12 @@ async function main() {
|
|
|
113
109
|
value: template
|
|
114
110
|
}))
|
|
115
111
|
});
|
|
116
|
-
if (!skipSkills && !
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
initial: true
|
|
123
|
-
});
|
|
124
|
-
promptQuestions.push({
|
|
125
|
-
type: (_prev, values$1) => values$1.installSkills ? "select" : null,
|
|
126
|
-
name: "agent",
|
|
127
|
-
message: "Which AI coding agent are you using?",
|
|
128
|
-
choices: agentChoices,
|
|
129
|
-
initial: 0
|
|
130
|
-
});
|
|
131
|
-
}
|
|
112
|
+
if (!skipSkills && !nonInteractive) promptQuestions.push({
|
|
113
|
+
type: "confirm",
|
|
114
|
+
name: "installSkills",
|
|
115
|
+
message: "Install AI agent skills for better coding assistance?",
|
|
116
|
+
initial: true
|
|
117
|
+
});
|
|
132
118
|
const answers = promptQuestions.length > 0 ? await prompts(promptQuestions) : {};
|
|
133
119
|
if (!cliDirectory && !nonInteractive && !answers.directoryName || !cliTemplate && !nonInteractive && !answers.templateName) {
|
|
134
120
|
process.stderr.write(chalk.red("\nCancelled\n"));
|
|
@@ -136,8 +122,7 @@ async function main() {
|
|
|
136
122
|
}
|
|
137
123
|
const directoryName = cliDirectory || answers.directoryName || "my-project";
|
|
138
124
|
const templateName = cliTemplate || answers.templateName || templates[0];
|
|
139
|
-
|
|
140
|
-
if (!skipSkills && !selectedAgent && nonInteractive) selectedAgent = "cursor";
|
|
125
|
+
const installSkills = !skipSkills && (nonInteractive || answers.installSkills !== false);
|
|
141
126
|
const targetDir = path.join(process.cwd(), directoryName);
|
|
142
127
|
const templateDir = path.join(__dirname, "templates", templateName);
|
|
143
128
|
if (await checkDirectoryExists(targetDir)) {
|
|
@@ -160,10 +145,10 @@ async function main() {
|
|
|
160
145
|
let depsInstalled = false;
|
|
161
146
|
let skillsInstalled = false;
|
|
162
147
|
if (!skipInstall) depsInstalled = await installDependencies(targetDir);
|
|
163
|
-
if (
|
|
148
|
+
if (installSkills) skillsInstalled = await installAgentSkills(targetDir);
|
|
164
149
|
process.stderr.write(chalk.green.bold("\n✓ Project created successfully!\n"));
|
|
165
150
|
if (depsInstalled) process.stderr.write(chalk.green("✓ Dependencies installed\n"));
|
|
166
|
-
if (skillsInstalled) process.stderr.write(chalk.green(
|
|
151
|
+
if (skillsInstalled) process.stderr.write(chalk.green("✓ AI agent skills installed\n"));
|
|
167
152
|
process.stderr.write(chalk.bold("\nYour project is ready! 🎉\n\n"));
|
|
168
153
|
process.stderr.write(chalk.bold("Next steps:\n"));
|
|
169
154
|
process.stderr.write(chalk.cyan(` cd ${directoryName}\n`));
|
|
@@ -171,9 +156,12 @@ async function main() {
|
|
|
171
156
|
process.stderr.write(chalk.cyan(` ${getStartCommand(pkgManager)}\n`));
|
|
172
157
|
if (skillsInstalled) {
|
|
173
158
|
process.stderr.write(chalk.bold("\nAI Agent Skills installed:\n"));
|
|
174
|
-
process.stderr.write(chalk.dim(" •
|
|
175
|
-
process.stderr.write(chalk.dim(" •
|
|
176
|
-
process.stderr.write(chalk.dim(" •
|
|
159
|
+
process.stderr.write(chalk.dim(" • editframe-composition\n"));
|
|
160
|
+
process.stderr.write(chalk.dim(" • editframe-motion-design\n"));
|
|
161
|
+
process.stderr.write(chalk.dim(" • editframe-brand-video-generator\n"));
|
|
162
|
+
process.stderr.write(chalk.dim(" • editframe-editor-gui\n"));
|
|
163
|
+
process.stderr.write(chalk.dim(" • editframe-vite-plugin\n"));
|
|
164
|
+
process.stderr.write(chalk.dim(" • editframe-webhooks\n"));
|
|
177
165
|
process.stderr.write(chalk.bold("\nTry asking your AI agent:\n"));
|
|
178
166
|
process.stderr.write(chalk.dim(" \"Create a 5-second video with fade-in text\"\n"));
|
|
179
167
|
process.stderr.write(chalk.dim(" \"Add a waveform visualization\"\n"));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["path","promptQuestions: prompts.PromptObject[]","values"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { access, cp, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport {\n getUserPkgManager,\n installDependencies,\n installAgentSkills,\n getStartCommand,\n} from \"./utils.js\";\nimport { getAgentChoices } from \"./detectAgent.js\";\n\nfunction showHelp(templates: string[]) {\n const usage = `\n${chalk.bold(\"Usage:\")}\n npm create @editframe -- [template] [options]\n\n${chalk.bold(\"Options:\")}\n -d, --directory <name> Project directory name\n --skip-install Skip dependency installation\n --skip-skills Skip agent skills installation\n --agent <name> Specify AI agent (cursor, claude, vscode, etc.)\n -y, --yes Skip all prompts, use defaults\n -h, --help Show this help message\n\n${chalk.bold(\"Available Templates:\")}\n${templates.map((t) => ` - ${t}`).join(\"\\n\")}\n\n${chalk.bold(\"Examples:\")}\n ${chalk.dim(\"# Interactive mode (recommended)\")}\n npm create @editframe\n\n ${chalk.dim(\"# Specify template\")}\n npm create @editframe -- react\n\n ${chalk.dim(\"# Full non-interactive\")}\n npm create @editframe -- react -d my-app --agent cursor -y\n\n ${chalk.dim(\"# Skip auto-installation\")}\n npm create @editframe -- react --skip-install --skip-skills\n`;\n\n process.stdout.write(usage);\n}\n\nasync function checkDirectoryExists(path: string) {\n try {\n await access(path);\n return true;\n } catch (_error) {\n return false;\n }\n}\n\nasync function main() {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n // List of available starter templates\n const templates = await readdir(path.join(__dirname, \"templates\"));\n\n // Parse command line arguments\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: {\n type: \"boolean\",\n short: \"h\",\n default: false,\n },\n directory: {\n type: \"string\",\n short: \"d\",\n },\n skipInstall: {\n type: \"boolean\",\n default: false,\n },\n skipSkills: {\n type: \"boolean\",\n default: false,\n },\n agent: {\n type: \"string\",\n },\n yes: {\n type: \"boolean\",\n short: \"y\",\n default: false,\n },\n },\n allowPositionals: true,\n });\n\n // Show help if requested\n if (values.help) {\n showHelp(templates);\n process.exit(0);\n }\n\n // Extract CLI arguments\n const cliTemplate = positionals[0];\n const cliDirectory = values.directory;\n const skipInstall = values.skipInstall;\n const skipSkills = values.skipSkills;\n const cliAgent = values.agent;\n const nonInteractive = values.yes;\n\n // Validate template if provided\n if (cliTemplate && !templates.includes(cliTemplate)) {\n process.stderr.write(\n chalk.red(`Error: Template \"${cliTemplate}\" does not exist.\\n\\n`),\n );\n process.stderr.write(chalk.bold(\"Available templates:\\n\"));\n for (const t of templates) {\n process.stderr.write(` - ${t}\\n`);\n }\n process.stderr.write(\n chalk.dim(\"\\nRun with --help for more information.\\n\"),\n );\n process.exit(1);\n }\n\n // Build prompts array - ask ALL questions upfront before any network calls\n const promptQuestions: prompts.PromptObject[] = [];\n\n if (!cliDirectory && !nonInteractive) {\n promptQuestions.push({\n type: \"text\",\n name: \"directoryName\",\n message: \"Enter the name of the directory to generate into:\",\n initial: \"my-project\",\n });\n }\n\n if (!cliTemplate && !nonInteractive) {\n promptQuestions.push({\n type: \"select\",\n name: \"templateName\",\n message: \"Choose a starter template:\",\n choices: templates.map((template) => ({\n title: template,\n value: template,\n })),\n });\n }\n\n // Ask about agent skills upfront (unless skipped via CLI)\n if (!skipSkills && !cliAgent && !nonInteractive) {\n // Get agent choices sorted by detection\n const agentChoices = await getAgentChoices();\n\n promptQuestions.push({\n type: \"confirm\",\n name: \"installSkills\",\n message: \"Install AI agent skills for better coding assistance?\",\n initial: true,\n });\n\n promptQuestions.push({\n type: (_prev, values) => (values.installSkills ? \"select\" : null),\n name: \"agent\",\n message: \"Which AI coding agent are you using?\",\n choices: agentChoices,\n initial: 0,\n });\n }\n\n // Prompt for all missing information at once\n const answers =\n promptQuestions.length > 0 ? await prompts(promptQuestions) : {};\n\n // Handle user cancellation\n if (\n (!cliDirectory && !nonInteractive && !answers.directoryName) ||\n (!cliTemplate && !nonInteractive && !answers.templateName)\n ) {\n process.stderr.write(chalk.red(\"\\nCancelled\\n\"));\n process.exit(1);\n }\n\n // Use CLI args or prompted values (with defaults for non-interactive mode)\n const directoryName = cliDirectory || answers.directoryName || \"my-project\";\n const templateName = cliTemplate || answers.templateName || templates[0];\n\n // Determine agent selection from CLI or prompts\n let selectedAgent = cliAgent || answers.agent;\n\n // Default to cursor in non-interactive mode if skills not skipped\n if (!skipSkills && !selectedAgent && nonInteractive) {\n selectedAgent = \"cursor\";\n }\n\n const targetDir = path.join(process.cwd(), directoryName);\n const templateDir = path.join(__dirname, \"templates\", templateName);\n\n const exists = await checkDirectoryExists(targetDir);\n\n if (exists) {\n process.stderr.write(\n chalk.yellow(`Directory ${targetDir} already exists.\\n`),\n );\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: \"Directory already exists. Do you want to overwrite it?\",\n initial: false,\n });\n\n if (!overwrite) {\n process.stderr.write(chalk.red(\"Aborting...\\n\"));\n process.exit(1);\n }\n }\n\n process.stderr.write(`\\nCreating project in directory: ${targetDir}\\n`);\n process.stderr.write(`Using template: ${templateName}\\n\\n`);\n\n // Copy the selected template to the target directory\n await cp(templateDir, targetDir, { recursive: true });\n\n const pkgManager = getUserPkgManager();\n let depsInstalled = false;\n let skillsInstalled = false;\n\n // All questions have been asked - now do the work\n\n // Install dependencies unless skipped\n if (!skipInstall) {\n depsInstalled = await installDependencies(targetDir);\n }\n\n // Install agent skills if an agent was selected\n if (!skipSkills && selectedAgent && selectedAgent !== \"skip\") {\n skillsInstalled = await installAgentSkills(targetDir, selectedAgent);\n }\n\n // Success message\n process.stderr.write(chalk.green.bold(\"\\n✓ Project created successfully!\\n\"));\n\n if (depsInstalled) {\n process.stderr.write(chalk.green(\"✓ Dependencies installed\\n\"));\n }\n\n if (skillsInstalled) {\n process.stderr.write(\n chalk.green(`✓ Agent skills installed (${selectedAgent})\\n`),\n );\n }\n\n process.stderr.write(chalk.bold(\"\\nYour project is ready! 🎉\\n\\n\"));\n\n // Next steps\n process.stderr.write(chalk.bold(\"Next steps:\\n\"));\n process.stderr.write(chalk.cyan(` cd ${directoryName}\\n`));\n\n if (!depsInstalled) {\n process.stderr.write(chalk.cyan(` ${pkgManager} install\\n`));\n }\n\n process.stderr.write(chalk.cyan(` ${getStartCommand(pkgManager)}\\n`));\n\n // Skills info\n if (skillsInstalled) {\n process.stderr.write(chalk.bold(\"\\nAI Agent Skills installed:\\n\"));\n process.stderr.write(\n chalk.dim(\" • elements-composition - HTML/Web Components\\n\"),\n );\n process.stderr.write(\n chalk.dim(\" • react-composition - React components\\n\"),\n );\n process.stderr.write(\n chalk.dim(\" • motion-design - Animation principles\\n\"),\n );\n\n process.stderr.write(chalk.bold(\"\\nTry asking your AI agent:\\n\"));\n process.stderr.write(\n chalk.dim(' \"Create a 5-second video with fade-in text\"\\n'),\n );\n process.stderr.write(chalk.dim(' \"Add a waveform visualization\"\\n'));\n process.stderr.write(\n chalk.dim(' \"Animate this element with spring physics\"\\n'),\n );\n }\n\n process.stderr.write(\n chalk.dim(\"\\nDocumentation: https://editframe.com/docs\\n\"),\n );\n process.stderr.write(chalk.dim(\"Happy coding! 🎬\\n\\n\"));\n}\n\nmain();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["path","promptQuestions: prompts.PromptObject[]"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { access, cp, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport {\n getUserPkgManager,\n installDependencies,\n installAgentSkills,\n getStartCommand,\n} from \"./utils.js\";\n\nfunction showHelp(templates: string[]) {\n const usage = `\n${chalk.bold(\"Usage:\")}\n npm create @editframe -- [template] [options]\n\n${chalk.bold(\"Options:\")}\n -d, --directory <name> Project directory name\n --skip-install Skip dependency installation\n --skip-skills Skip agent skills installation\n -y, --yes Skip all prompts, use defaults\n -h, --help Show this help message\n\n${chalk.bold(\"Available Templates:\")}\n${templates.map((t) => ` - ${t}`).join(\"\\n\")}\n\n${chalk.bold(\"Examples:\")}\n ${chalk.dim(\"# Interactive mode (recommended)\")}\n npm create @editframe\n\n ${chalk.dim(\"# Specify template\")}\n npm create @editframe -- react\n\n ${chalk.dim(\"# Full non-interactive\")}\n npm create @editframe -- react -d my-app -y\n\n ${chalk.dim(\"# Skip auto-installation\")}\n npm create @editframe -- react --skip-install --skip-skills\n`;\n\n process.stdout.write(usage);\n}\n\nasync function checkDirectoryExists(path: string) {\n try {\n await access(path);\n return true;\n } catch (_error) {\n return false;\n }\n}\n\nasync function main() {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n // List of available starter templates\n const templates = await readdir(path.join(__dirname, \"templates\"));\n\n // Parse command line arguments\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: {\n type: \"boolean\",\n short: \"h\",\n default: false,\n },\n directory: {\n type: \"string\",\n short: \"d\",\n },\n skipInstall: {\n type: \"boolean\",\n default: false,\n },\n skipSkills: {\n type: \"boolean\",\n default: false,\n },\n yes: {\n type: \"boolean\",\n short: \"y\",\n default: false,\n },\n },\n allowPositionals: true,\n });\n\n // Show help if requested\n if (values.help) {\n showHelp(templates);\n process.exit(0);\n }\n\n // Extract CLI arguments\n const cliTemplate = positionals[0];\n const cliDirectory = values.directory;\n const skipInstall = values.skipInstall;\n const skipSkills = values.skipSkills;\n const nonInteractive = values.yes;\n\n // Validate template if provided\n if (cliTemplate && !templates.includes(cliTemplate)) {\n process.stderr.write(\n chalk.red(`Error: Template \"${cliTemplate}\" does not exist.\\n\\n`),\n );\n process.stderr.write(chalk.bold(\"Available templates:\\n\"));\n for (const t of templates) {\n process.stderr.write(` - ${t}\\n`);\n }\n process.stderr.write(\n chalk.dim(\"\\nRun with --help for more information.\\n\"),\n );\n process.exit(1);\n }\n\n // Build prompts array - ask ALL questions upfront before any network calls\n const promptQuestions: prompts.PromptObject[] = [];\n\n if (!cliDirectory && !nonInteractive) {\n promptQuestions.push({\n type: \"text\",\n name: \"directoryName\",\n message: \"Enter the name of the directory to generate into:\",\n initial: \"my-project\",\n });\n }\n\n if (!cliTemplate && !nonInteractive) {\n promptQuestions.push({\n type: \"select\",\n name: \"templateName\",\n message: \"Choose a starter template:\",\n choices: templates.map((template) => ({\n title: template,\n value: template,\n })),\n });\n }\n\n // Ask about agent skills upfront (unless skipped via CLI)\n if (!skipSkills && !nonInteractive) {\n promptQuestions.push({\n type: \"confirm\",\n name: \"installSkills\",\n message: \"Install AI agent skills for better coding assistance?\",\n initial: true,\n });\n }\n\n // Prompt for all missing information at once\n const answers =\n promptQuestions.length > 0 ? await prompts(promptQuestions) : {};\n\n // Handle user cancellation\n if (\n (!cliDirectory && !nonInteractive && !answers.directoryName) ||\n (!cliTemplate && !nonInteractive && !answers.templateName)\n ) {\n process.stderr.write(chalk.red(\"\\nCancelled\\n\"));\n process.exit(1);\n }\n\n // Use CLI args or prompted values (with defaults for non-interactive mode)\n const directoryName = cliDirectory || answers.directoryName || \"my-project\";\n const templateName = cliTemplate || answers.templateName || templates[0];\n\n // Determine if skills should be installed\n const installSkills =\n !skipSkills && (nonInteractive || answers.installSkills !== false);\n\n const targetDir = path.join(process.cwd(), directoryName);\n const templateDir = path.join(__dirname, \"templates\", templateName);\n\n const exists = await checkDirectoryExists(targetDir);\n\n if (exists) {\n process.stderr.write(\n chalk.yellow(`Directory ${targetDir} already exists.\\n`),\n );\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: \"Directory already exists. Do you want to overwrite it?\",\n initial: false,\n });\n\n if (!overwrite) {\n process.stderr.write(chalk.red(\"Aborting...\\n\"));\n process.exit(1);\n }\n }\n\n process.stderr.write(`\\nCreating project in directory: ${targetDir}\\n`);\n process.stderr.write(`Using template: ${templateName}\\n\\n`);\n\n // Copy the selected template to the target directory\n await cp(templateDir, targetDir, { recursive: true });\n\n const pkgManager = getUserPkgManager();\n let depsInstalled = false;\n let skillsInstalled = false;\n\n // All questions have been asked - now do the work\n\n // Install dependencies unless skipped\n if (!skipInstall) {\n depsInstalled = await installDependencies(targetDir);\n }\n\n // Install agent skills unless skipped\n if (installSkills) {\n skillsInstalled = await installAgentSkills(targetDir);\n }\n\n // Success message\n process.stderr.write(chalk.green.bold(\"\\n✓ Project created successfully!\\n\"));\n\n if (depsInstalled) {\n process.stderr.write(chalk.green(\"✓ Dependencies installed\\n\"));\n }\n\n if (skillsInstalled) {\n process.stderr.write(chalk.green(\"✓ AI agent skills installed\\n\"));\n }\n\n process.stderr.write(chalk.bold(\"\\nYour project is ready! 🎉\\n\\n\"));\n\n // Next steps\n process.stderr.write(chalk.bold(\"Next steps:\\n\"));\n process.stderr.write(chalk.cyan(` cd ${directoryName}\\n`));\n\n if (!depsInstalled) {\n process.stderr.write(chalk.cyan(` ${pkgManager} install\\n`));\n }\n\n process.stderr.write(chalk.cyan(` ${getStartCommand(pkgManager)}\\n`));\n\n // Skills info\n if (skillsInstalled) {\n process.stderr.write(chalk.bold(\"\\nAI Agent Skills installed:\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-composition\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-motion-design\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-brand-video-generator\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-editor-gui\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-vite-plugin\\n\"));\n process.stderr.write(chalk.dim(\" • editframe-webhooks\\n\"));\n\n process.stderr.write(chalk.bold(\"\\nTry asking your AI agent:\\n\"));\n process.stderr.write(\n chalk.dim(' \"Create a 5-second video with fade-in text\"\\n'),\n );\n process.stderr.write(chalk.dim(' \"Add a waveform visualization\"\\n'));\n process.stderr.write(\n chalk.dim(' \"Animate this element with spring physics\"\\n'),\n );\n }\n\n process.stderr.write(\n chalk.dim(\"\\nDocumentation: https://editframe.com/docs\\n\"),\n );\n process.stderr.write(chalk.dim(\"Happy coding! 🎬\\n\\n\"));\n}\n\nmain();\n"],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Brand Video Generator Skill
|
|
2
|
+
|
|
3
|
+
A comprehensive Agent Skill for generating strategic video composition plans from brand websites.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
This skill analyzes a brand's website and generates a complete video production plan including:
|
|
8
|
+
|
|
9
|
+
1. **Brand Analysis**
|
|
10
|
+
- Visual identity (colors, typography, design language)
|
|
11
|
+
- Voice and messaging tone
|
|
12
|
+
- Content hierarchy and key messages
|
|
13
|
+
|
|
14
|
+
2. **Creative Strategy**
|
|
15
|
+
- Video objective and target audience
|
|
16
|
+
- Core message and emotional arc
|
|
17
|
+
- Visual treatment recommendations
|
|
18
|
+
|
|
19
|
+
3. **Scene Planning**
|
|
20
|
+
- Scene-by-scene breakdown with timing
|
|
21
|
+
- Visual content specifications
|
|
22
|
+
- Motion and transition recommendations
|
|
23
|
+
|
|
24
|
+
4. **Asset Requirements**
|
|
25
|
+
- Visual assets needed
|
|
26
|
+
- Motion graphics specifications
|
|
27
|
+
- Audio recommendations
|
|
28
|
+
|
|
29
|
+
## How It Works
|
|
30
|
+
|
|
31
|
+
The skill combines all analysis phases into a single workflow:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Website URL → Analysis → Creative Brief → Scene Plan → Asset List → Implementation Guide
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Instead of separate skills for each phase (as originally proposed), this unified approach:
|
|
38
|
+
- Provides complete end-to-end planning in one session
|
|
39
|
+
- Maintains context across all phases
|
|
40
|
+
- Delivers a cohesive, actionable plan
|
|
41
|
+
- Can be refined iteratively
|
|
42
|
+
|
|
43
|
+
## Reference Library
|
|
44
|
+
|
|
45
|
+
The skill includes extensive reference materials:
|
|
46
|
+
|
|
47
|
+
### [color-psychology.md](references/color-psychology.md)
|
|
48
|
+
Emotional associations with colors, color combinations, and how to apply them in video. Includes:
|
|
49
|
+
- Primary and secondary color meanings
|
|
50
|
+
- Color combinations by mood
|
|
51
|
+
- Video-specific color usage
|
|
52
|
+
- Brand personality color mapping
|
|
53
|
+
|
|
54
|
+
### [typography-personalities.md](references/typography-personalities.md)
|
|
55
|
+
What font choices signal about brand personality and how to use them in video. Includes:
|
|
56
|
+
- Font category personalities (serif, sans-serif, display, monospace)
|
|
57
|
+
- Font pairing principles
|
|
58
|
+
- Video-specific typography guidelines
|
|
59
|
+
- Animation styles by font type
|
|
60
|
+
|
|
61
|
+
### [video-archetypes.md](references/video-archetypes.md)
|
|
62
|
+
Common video patterns and structures by industry and video type. Includes:
|
|
63
|
+
- Industry-specific patterns (SaaS, e-commerce, B2B, finance, etc.)
|
|
64
|
+
- Video type structures (demo, explainer, launch, testimonial, etc.)
|
|
65
|
+
- Length and pacing guidelines
|
|
66
|
+
- Platform-specific considerations
|
|
67
|
+
|
|
68
|
+
### [emotional-arcs.md](references/emotional-arcs.md)
|
|
69
|
+
Proven narrative structures that guide viewer emotions. Includes:
|
|
70
|
+
- 10 core emotional arc patterns
|
|
71
|
+
- When to use each arc
|
|
72
|
+
- How to pace emotional progression
|
|
73
|
+
- Matching arcs to brand personality
|
|
74
|
+
|
|
75
|
+
### [transition-styles.md](references/transition-styles.md)
|
|
76
|
+
Types of transitions, their emotional impact, and when to use them. Includes:
|
|
77
|
+
- 13+ transition types with specifications
|
|
78
|
+
- Duration guidelines
|
|
79
|
+
- Brand personality matching
|
|
80
|
+
- Platform considerations
|
|
81
|
+
|
|
82
|
+
### [visual-metaphors.md](references/visual-metaphors.md)
|
|
83
|
+
How to represent abstract concepts visually. Includes:
|
|
84
|
+
- 15+ common abstract concepts (speed, security, growth, trust, etc.)
|
|
85
|
+
- Visual metaphor options for each
|
|
86
|
+
- Animation and color recommendations
|
|
87
|
+
- Cultural considerations
|
|
88
|
+
|
|
89
|
+
### [composition-patterns.md](references/composition-patterns.md)
|
|
90
|
+
Common structural patterns for video composition with Editframe Elements. Includes:
|
|
91
|
+
- 14+ composition patterns with code examples
|
|
92
|
+
- Complete video structure templates
|
|
93
|
+
- Best practices for timing, layering, accessibility
|
|
94
|
+
- Quick reference table
|
|
95
|
+
|
|
96
|
+
## Usage
|
|
97
|
+
|
|
98
|
+
Provide the skill with:
|
|
99
|
+
- **URL**: Brand website to analyze
|
|
100
|
+
- **Video Type**: launch, product-demo, explainer, brand-awareness, social
|
|
101
|
+
- **Duration Target**: 15s, 30s, 60s, 90s (optional)
|
|
102
|
+
- **Platform**: web, instagram, tiktok, youtube, linkedin (optional)
|
|
103
|
+
|
|
104
|
+
The skill will generate a comprehensive plan including all phases.
|
|
105
|
+
|
|
106
|
+
## Example
|
|
107
|
+
|
|
108
|
+
See [EXAMPLE.md](EXAMPLE.md) for a complete walkthrough using Stripe.com as the example brand, including:
|
|
109
|
+
- Full brand analysis
|
|
110
|
+
- Creative brief
|
|
111
|
+
- Scene-by-scene breakdown
|
|
112
|
+
- Asset manifest
|
|
113
|
+
- Implementation notes
|
|
114
|
+
- Starter Editframe code
|
|
115
|
+
|
|
116
|
+
## Integration with Other Skills
|
|
117
|
+
|
|
118
|
+
This skill works alongside:
|
|
119
|
+
- **elements-composition**: Use to implement the video plan with HTML/Web Components
|
|
120
|
+
- **react-composition**: Use to implement with React components
|
|
121
|
+
- **motion-design**: Apply motion principles to the planned animations
|
|
122
|
+
|
|
123
|
+
## Workflow
|
|
124
|
+
|
|
125
|
+
Typical workflow:
|
|
126
|
+
1. Use `brand-video-generator` to analyze website and create plan
|
|
127
|
+
2. Review and refine the plan
|
|
128
|
+
3. Gather or create required assets
|
|
129
|
+
4. Use `elements-composition` or `react-composition` to build the video
|
|
130
|
+
5. Apply `motion-design` principles for animations
|
|
131
|
+
6. Iterate and refine
|
|
132
|
+
|
|
133
|
+
## Future Enhancements
|
|
134
|
+
|
|
135
|
+
Potential additions (not yet implemented):
|
|
136
|
+
- Industry-specific analysis patterns
|
|
137
|
+
- Competitive analysis integration
|
|
138
|
+
- Automated asset generation suggestions
|
|
139
|
+
- A/B testing recommendations
|
|
140
|
+
- Multi-language considerations
|
|
141
|
+
- Accessibility scoring
|
|
142
|
+
|
|
143
|
+
## Philosophy
|
|
144
|
+
|
|
145
|
+
This skill embodies several key principles:
|
|
146
|
+
|
|
147
|
+
1. **Strategic First**: Start with strategy before execution
|
|
148
|
+
2. **Brand-Aligned**: Every decision should reflect brand personality
|
|
149
|
+
3. **Audience-Focused**: Consider who's watching and why
|
|
150
|
+
4. **Actionable**: Provide specific, implementable recommendations
|
|
151
|
+
5. **Comprehensive**: Cover all aspects from analysis to implementation
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
MIT
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: editframe-brand-video-generator
|
|
3
|
+
title: Brand Video Generator
|
|
4
|
+
description: Generate video compositions from brand websites or descriptions. Produces an inspectable creative brief before generating HTML.
|
|
5
|
+
status: draft
|
|
6
|
+
order: 50
|
|
7
|
+
license: MIT
|
|
8
|
+
metadata:
|
|
9
|
+
author: editframe
|
|
10
|
+
version: "4.0"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Brand Video Generator
|
|
14
|
+
|
|
15
|
+
Two-pass pipeline. First produce an inspectable brief. Then generate the composition from it.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Step 0 — Fetch the brand (do this first, before anything else)
|
|
20
|
+
|
|
21
|
+
**If a URL is supplied**: immediately fetch it with WebFetch or your browser tool — before reading any further instructions, before thinking about the brief, before any other action. Extract exact hex codes from the page's CSS. Download or note 3–5 brand assets (logo, product screenshots, key imagery). Do not proceed until you have done this.
|
|
22
|
+
|
|
23
|
+
**If you cannot access the URL**: stop here. Report the failure and ask whether to proceed from a text description instead.
|
|
24
|
+
|
|
25
|
+
**If only a text description is supplied**: ask the user for anything critical that's missing — specific product names, hex codes, recognizable visual marks — before generating the brief.
|
|
26
|
+
|
|
27
|
+
Do not infer colors or visual language from memory or text descriptions of a site. Only exact values from the live page are acceptable.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Input
|
|
32
|
+
|
|
33
|
+
- **Brand**: URL or text description
|
|
34
|
+
- **Video Type**: `launch` | `product-demo` | `explainer` | `brand-awareness` | `social`
|
|
35
|
+
- **Duration**: `15s` | `30s` | `60s` | `90s` (optional)
|
|
36
|
+
- **Platform**: `web` | `instagram` | `tiktok` | `youtube` | `linkedin` (optional)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Pass 1 — The Brief
|
|
41
|
+
|
|
42
|
+
Answer these four questions. Output them as a readable document the developer can inspect, correct, or approve before generation begins.
|
|
43
|
+
|
|
44
|
+
**Do not skip to HTML. The brief is required output.**
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### 1. Structural truth
|
|
49
|
+
|
|
50
|
+
One thing true of this brand that is false of any direct competitor.
|
|
51
|
+
|
|
52
|
+
Not a marketing claim. A material fact: a decision the brand made, a relationship it has, a mechanism it invented. The truth must be structural — if a well-funded competitor could claim the same thing next year, dig deeper.
|
|
53
|
+
|
|
54
|
+
**Substitute test**: swap the brand name into the statement. Does it still hold? If yes, it's not specific enough.
|
|
55
|
+
|
|
56
|
+
Output:
|
|
57
|
+
```
|
|
58
|
+
Structural truth: [one sentence]
|
|
59
|
+
Substitute test: [why this fails for Competitor A and Competitor B]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### 2. Formal constraint
|
|
65
|
+
|
|
66
|
+
What the structural truth forces on the video's *mechanics* — not its subject matter.
|
|
67
|
+
|
|
68
|
+
Structure means timing, motion logic, and compositional form. If the truth is about removal, scenes must subtract elements. If it's about unification, the same visual element must thread through multiple contexts. If it's about community, real faces must appear.
|
|
69
|
+
|
|
70
|
+
State it as a rule: "Because [truth], this video [does X mechanically]."
|
|
71
|
+
|
|
72
|
+
Output:
|
|
73
|
+
```
|
|
74
|
+
Formal constraint: [one rule in motion terms]
|
|
75
|
+
Single argument: "This video argues [X] by showing [Y]."
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If [Y] could illustrate a different argument, the form isn't embodying the truth yet — rewrite.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### 3. Authorial angle
|
|
83
|
+
|
|
84
|
+
What the video argues that the brand's own marketing does not say.
|
|
85
|
+
|
|
86
|
+
Complete: *"This video argues [X] which this brand's marketing never says because [Y]."*
|
|
87
|
+
|
|
88
|
+
If [X] is already on their homepage, the composition is illustration, not argument. Find the interpretation: what tension does this truth create? What does it reveal about the audience? What norm does it contradict?
|
|
89
|
+
|
|
90
|
+
**Category truth vs. brand angle:** If the authorial angle could be claimed by any direct competitor in the same category, it's a category truth, not an angle. 'Unification beats fragmentation' is true of ALL payment aggregators. A valid angle must reference something only THIS brand can claim:
|
|
91
|
+
- Their specific customer roster or market position
|
|
92
|
+
- Their specific technical decision that shaped the product's architecture
|
|
93
|
+
- Their specific philosophy made visible in a product choice competitors didn't make
|
|
94
|
+
|
|
95
|
+
**For payments APIs specifically**: 'Unified API' is category-level. Valid angles include: built unified from day one (vs. acquired-and-integrated competitors), developer-first design philosophy (documentation as product), specific mission statements ('increase GDP of the internet'), or the decision to expose primitives rather than hide complexity. State which architectural philosophy the video will argue.
|
|
96
|
+
|
|
97
|
+
Rewrite until the angle fails the substitute test.
|
|
98
|
+
|
|
99
|
+
**Category trap**: "fragmentation is bad, unification is good" is a category-level narrative any competitor can use. "This specific brand's unification works because [architectural reason no competitor has]" is a brand angle. If the argument could be the headline of a competitor's ad campaign, dig deeper.
|
|
100
|
+
|
|
101
|
+
Output:
|
|
102
|
+
```
|
|
103
|
+
Authorial angle: [one sentence]
|
|
104
|
+
Why the brand wouldn't say this: [one sentence]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### 4. Felt arc
|
|
110
|
+
|
|
111
|
+
The emotional journey from frame 1 to the last frame.
|
|
112
|
+
|
|
113
|
+
Name the emotion at entry and at exit. They must differ. Then define the minimum path — the fewest distinct state changes required to move between them.
|
|
114
|
+
|
|
115
|
+
Scene budget: `floor(duration_seconds / 10)` maximum. 15s → 2 scenes. 30s → 3. 60s → 6.
|
|
116
|
+
|
|
117
|
+
Output:
|
|
118
|
+
```
|
|
119
|
+
Entry state: [what the viewer feels at frame 1]
|
|
120
|
+
Exit state: [what the viewer feels at the last frame]
|
|
121
|
+
Arc: [entry] → [intermediate state if needed] → [exit]
|
|
122
|
+
Scene budget: [N scenes maximum]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Brief checkpoint
|
|
128
|
+
|
|
129
|
+
After outputting the brief, pause and ask:
|
|
130
|
+
|
|
131
|
+
> "Does this brief look right? I'll generate the composition once you confirm, or adjust any section now."
|
|
132
|
+
|
|
133
|
+
If the user confirms or says to proceed: move to Pass 2.
|
|
134
|
+
If the user corrects any section: revise that section only, then ask again before generating.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Pass 2 — The Composition
|
|
139
|
+
|
|
140
|
+
Generate HTML from the confirmed brief. Every decision traces back to the brief's formal constraint.
|
|
141
|
+
|
|
142
|
+
### The single gate
|
|
143
|
+
|
|
144
|
+
Before placing any element — scene, visual, canvas animation, line of text — ask:
|
|
145
|
+
|
|
146
|
+
> **Could a direct competitor's marketing team use this exact element unchanged?**
|
|
147
|
+
|
|
148
|
+
If yes: delete it and find what only this brand could use. Apply recursively.
|
|
149
|
+
|
|
150
|
+
### Scene rules
|
|
151
|
+
|
|
152
|
+
- Each scene earns its place by changing the viewer's emotional state. State the transition for every scene: "viewer enters feeling [X], exits feeling [Y]." Information-only scenes get cut.
|
|
153
|
+
- No two adjacent scenes may leave the viewer in the same state.
|
|
154
|
+
- Feature sequences must build causally — if scenes can be reordered without loss, they're a list, not an argument.
|
|
155
|
+
- Prove, don't assert: "unified" is shown by one element appearing in multiple contexts, not by text saying "unified."
|
|
156
|
+
|
|
157
|
+
### Hard stops
|
|
158
|
+
|
|
159
|
+
**Colors**: Use exact hex codes from the brief (extracted from CSS or provided). Do not estimate.
|
|
160
|
+
|
|
161
|
+
**Canvas**:
|
|
162
|
+
- Use `addFrameTask`, never `requestAnimationFrame`. Callback: `(info) => { const { ownCurrentTimeMs, durationMs } = info; }`
|
|
163
|
+
- A canvas without a complete `addFrameTask` script renders nothing — delete the scene rather than ship broken code
|
|
164
|
+
- If approaching output length, cut canvas scenes or replace with CSS animation; a working 3-scene video beats a broken 4-scene one
|
|
165
|
+
- Canvas visual state at second 1 must differ visibly from second 20
|
|
166
|
+
|
|
167
|
+
**People**: Circles and gradient blobs cannot represent faces. Use real photography or draw recognizable facial features.
|
|
168
|
+
|
|
169
|
+
**Logo geometry**: Render from the brand's actual geometry. `fillRect()` for clothing or organic forms is prohibited.
|
|
170
|
+
|
|
171
|
+
**Named products**: At least one specific product name (not a category description) must appear.
|
|
172
|
+
|
|
173
|
+
### Completeness check
|
|
174
|
+
|
|
175
|
+
Before outputting:
|
|
176
|
+
- [ ] Scene durations sum to target duration EXACTLY (e.g., 60s request = 60s total)
|
|
177
|
+
- [ ] No canvas element without a complete `addFrameTask` script
|
|
178
|
+
- [ ] Output ends with `</ef-timegroup>`, `</script>`, `</style>` — verify closing tags are present
|
|
179
|
+
- [ ] Every scene passes the substitutability gate
|
|
180
|
+
- [ ] The single argument is traceable through every scene
|
|
181
|
+
- [ ] **Final scene exists**: Composition must include a closing/CTA scene (typically 4-8s) that resolves the arc
|
|
182
|
+
- [ ] **Duration accounting**: List each scene's duration in a comment before output to verify sum: `<!-- Scene 1: 8s, Scene 2: 12s, Scene 3: 24s, Scene 4: 16s = 60s total -->`
|
|
183
|
+
|
|
184
|
+
**If approaching output length limits:** Stop adding scenes. A complete 45s video is better than a truncated 60s video. Reduce scene count or simplify canvas animations rather than producing incomplete code.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Reference Files
|
|
189
|
+
|
|
190
|
+
- [references/brand-examples.md](references/brand-examples.md) — Structural truths, false differentiators, visual specificity by category
|
|
191
|
+
- [references/composition-patterns.md](references/composition-patterns.md) — Canvas patterns, frameTask API, visual specificity requirements
|
|
192
|
+
- [references/genre-selection.md](references/genre-selection.md) — Genre palette and fitness checks
|
|
193
|
+
- [references/emotional-arcs.md](references/emotional-arcs.md) — Arc patterns, short-form compression
|
|
194
|
+
- [references/editing.md](references/editing.md) — What to cut
|
|
195
|
+
- [references/visual-metaphors.md](references/visual-metaphors.md) — Visual metaphor library
|
|
196
|
+
- [references/video-archetypes.md](references/video-archetypes.md) — Industry patterns
|
|
197
|
+
- [references/typography-personalities.md](references/typography-personalities.md) — Font personality and timing
|
|
198
|
+
- [references/video-fundamentals.md](references/video-fundamentals.md) — Transitions, arcs, brand basics
|
|
199
|
+
|
|
200
|
+
### Factual verification requirement
|
|
201
|
+
|
|
202
|
+
Every statistic, figure, or quantified claim in the brief MUST be:
|
|
203
|
+
1. Directly sourced from the brand's website, press releases, or official communications
|
|
204
|
+
2. Attributed with specific context (what, where, when)
|
|
205
|
+
3. If no verifiable figure exists, state the structural truth qualitatively rather than fabricating a number
|
|
206
|
+
|
|
207
|
+
**Do not invent statistics.** When in doubt, quote the brand's own language verbatim rather than paraphrasing into invented specifics. The brand's actual tagline is more verifiable and more powerful than a plausible-sounding invented metric.
|