diff --git a/skills/hypercodemotion/SKILL.md b/skills/hypercodemotion/SKILL.md index 4f467d7..b2365ea 100644 --- a/skills/hypercodemotion/SKILL.md +++ b/skills/hypercodemotion/SKILL.md @@ -1,6 +1,6 @@ --- name: hypercodemotion -description: Turn briefs, images, reference videos, scripts, assets and existing projects into professional, editable HyperCodeMotion JSON. Guides art direction, scene architecture, motion, asset integration, MCP checks and Studio handoff. +description: Create and edit motion graphics videos (launch promos, explainers, social reels, animated titles) as editable HyperCodeMotion projects. Asks the canvas size first, then guides art direction, scenes, motion and assets, and delivers a .hcmotion file through the HyperCodeMotion MCP. --- # HyperCodeMotion — Creative Composition Skill @@ -9,13 +9,22 @@ Use this Skill when asked to create, improve, extend, combine, or troubleshoot e ## Workflow (follow in order) -1. **Brief and inputs** — Identify purpose, audience, distribution format, duration, fps, language, brand, CTA (only when requested), narration and exact data. Analyze user-provided reference images/video, scripts, logos, visual assets and any existing JSON. Distinguish factual content from creative decisions. Ask only for information that blocks progress. -2. **Art direction** — Define visual concept, typography hierarchy, spacing grid, palette, contrast, material, rhythm, transition vocabulary and continuity. Reuse the actual reference's visual intent; do not invent a brand or factual measurements. When the request names a Studio gallery template (an id such as `mix-promo-editorial`), call `get_template` with that id and the video's format, and follow its design: palette, fonts, frame, scene system and motion; replace all its texts. -3. **Storyboard and scenes** — Create sequential beats with one communicative objective each. Decide which objects persist and transform between beats versus which appear only within one scene. Allocate time to reading and transitions; storyboard timing must fit total duration. -4. **Composition plan** — Default to **HTML scenes**: one HTML document per scene in `docs`, each visible piece marked `data-hcm` and animated by its own `html` layer (see [html-scenes](references/html-scenes.md) and [the example](examples/html-scene-launch.json)). Use native layers (`text`, `rect`, `particles`…) when a piece must be edited as geometry or needs per-property keyframes. Plan layer IDs, order, scene boundaries, assets, effects and audio. -5. **JSON generation** — Produce **one complete, standalone composition** with `layers` at the root. To change an existing project, return the whole updated composition (keep unchanged layers, IDs and assets as they were), not a patch: a `.hcmotion` file can only carry a full composition. -6. **MCP validation** — The HyperCodeMotion MCP (`https://mcp.hypercodemotion.com/mcp`) is required. Call `get_capabilities` before selecting layer/effect fields; `validate_json` is optional for drafts. **Do not claim validation if no call occurred.** -7. **Studio handoff** — Call `create_hcmotion` with the finished JSON. If `created` is false, fix every error and call it again. Give the user the two links it returns: `open` (opens the project in Studio) and `download` (the `.hcmotion` file, to keep or load later with «Cargar proyecto»), and say both expire in 24 hours. **Never paste the composition JSON for the user to copy:** Studio only opens `.hcmotion` files. If the MCP is not connected, stop and ask the user to connect it instead of returning JSON. Never claim a perfect render from MCP results alone. +1. **Canvas size first** — Before designing anything, know the canvas. If the request does not state a format or exact pixels, ask the user once, in their language, and wait for the answer: + - 9:16 vertical, 1080×1920 (Reels, TikTok, Shorts) + - 1:1 square, 1080×1080 + - 4:5 portrait, 1080×1350 (feed posts) + - 3:4 portrait, 1080×1440 + - 16:9 horizontal, 1920×1080 (YouTube, presentations) + - Custom: their own width × height in pixels. + + Accept a platform name as the answer («para Reels» means 9:16). Ask this together with any other blocking question, never as a second round. Use the chosen `width` and `height` everywhere: type sizes, margins and the safe area depend on it (see [composition.md](references/composition.md)). Never switch to another format later without asking. Do not ask when the size is already known: an existing project keeps its own `width` and `height`, a prompt copied from Studio states its format, and a gallery recreation follows its brief. +2. **Brief and inputs** — Identify purpose, audience, distribution format, duration, fps, language, brand, CTA (only when requested), narration and exact data. Analyze user-provided reference images/video, scripts, logos, visual assets and any existing JSON. Distinguish factual content from creative decisions. Ask only for information that blocks progress. +3. **Art direction** — Define visual concept, typography hierarchy, spacing grid, palette, contrast, material, rhythm, transition vocabulary and continuity. Reuse the actual reference's visual intent; do not invent a brand or factual measurements. When the request names a Studio gallery template (an id such as `mix-promo-editorial`), call `get_template` with that id and the video's format, and follow its design: palette, fonts, frame, scene system and motion; replace all its texts. +4. **Storyboard and scenes** — Create sequential beats with one communicative objective each. Decide which objects persist and transform between beats versus which appear only within one scene. Allocate time to reading and transitions; storyboard timing must fit total duration. +5. **Composition plan** — Default to **HTML scenes**: one HTML document per scene in `docs`, each visible piece marked `data-hcm` and animated by its own `html` layer (see [html-scenes](references/html-scenes.md) and [the example](examples/html-scene-launch.json)). Use native layers (`text`, `rect`, `particles`…) when a piece must be edited as geometry or needs per-property keyframes. Plan layer IDs, order, scene boundaries, assets, effects and audio. +6. **JSON generation** — Produce **one complete, standalone composition** with `layers` at the root. To change an existing project, return the whole updated composition (keep unchanged layers, IDs and assets as they were), not a patch: a `.hcmotion` file can only carry a full composition. +7. **MCP validation** — The HyperCodeMotion MCP (`https://mcp.hypercodemotion.com/mcp`) is required. Call `get_capabilities` before selecting layer/effect fields; `validate_json` is optional for drafts. **Do not claim validation if no call occurred.** +8. **Studio handoff** — Call `create_hcmotion` with the finished JSON. If `created` is false, fix every error and call it again. Give the user the two links it returns: `open` (opens the project in Studio) and `download` (the `.hcmotion` file, to keep or load later with «Cargar proyecto»), and say both expire in 24 hours. **Never paste the composition JSON for the user to copy:** Studio only opens `.hcmotion` files. If the MCP is not connected, stop and ask the user to connect it instead of returning JSON. Never claim a perfect render from MCP results alone. ## Turning a public video into a gallery template @@ -40,15 +49,15 @@ Load only the applicable reference files instead of pasting all reference conten - Headlines read as separate words: keep letter-spacing at or above `-0.03em` for big type (tighter makes «Escribe menos» look like one word). - Exact textual and numerical facts respected; no placeholder assets masquerading as real images. - Compositions remain editable: descriptive layer names/IDs, coherent layers, keyframes and asset references. -- Layer effects and properties selected from actual Studio capabilities, not guessed APIs. +- Layer effects and properties selected from actual Studio capabilities, not guessed APIs: `fx` slots and easing names as listed in [motion-design.md](references/motion-design.md), and no `UNKNOWN_…` warning left in the `create_hcmotion` result. - An existing Lottie, glTF or GSAP file stays one `runtime` layer (`engine`, asset id, optional text, color, node and clip). Do not redraw it as rects. Sound stays in the audio channels. `validate_json` does not render it. ## Non-negotiable truthfulness -`validate_json` performs **structural preflight** against a source-pinned capability snapshot and rejects measurable text that cannot fit the canvas (`get_capabilities` field `screen`), text that crosses the canvas, and `line-height` below 1. It returns `fullyValidated: false` and **cannot verify appearance or guarantee Studio import/rendering**. Images in a prompt are references; they are not automatically embedded in JSON. The exception is files the user lists by id (photos, cut-outs, a logo, videos kept in their Studio): reference those ids in `image` and `video` layers as [the contract](references/composition.md) describes. Never invent other asset IDs, live external image URLs, render results, tool calls, or successful tests. +`validate_json` performs **structural preflight**. Unknown layer types, properties and effects come back only as warnings (`UNKNOWN_…`), which you must read and fix; easing names and effect values are not checked (`CONTRACT_NOT_CHECKED`). It rejects measurable text that cannot fit the canvas (`get_capabilities` field `screen`), text that crosses the canvas, and `line-height` below 1. It returns `fullyValidated: false` and **cannot verify appearance or guarantee Studio import/rendering**. Images in a prompt are references; they are not automatically embedded in JSON. The exception is files the user lists by id (photos, cut-outs, a logo, videos kept in their Studio): reference those ids in `image` and `video` layers as [the contract](references/composition.md) describes. Never invent other asset IDs, live external image URLs, render results, tool calls, or successful tests. ## Output contract Default: a single composition object with `version: 1`, positive dimensions/fps/duration, `background`, `params`, and a nonempty `layers` array, delivered **only through `create_hcmotion`** as `.hcmotion` links. Do not put commentary inside JSON. -Before output: confirm requested duration, meaningful visibility of every scene, valid asset references and `layers` at the root. If validation could not be completed, say so in your message. +Before output: confirm the canvas size the user chose, requested duration, meaningful visibility of every scene, valid asset references and `layers` at the root. If validation could not be completed, say so in your message. diff --git a/skills/hypercodemotion/references/composition.md b/skills/hypercodemotion/references/composition.md index 73c6f27..183d1dd 100644 --- a/skills/hypercodemotion/references/composition.md +++ b/skills/hypercodemotion/references/composition.md @@ -38,7 +38,7 @@ This is an illustrative sample for this 1080×1920 canvas, not evidence of a suc ## Type size follows the screen -Decide `width` and `height` before any type size. `get_capabilities` returns the rule and the numbers in `screen` (the same figures Studio calls PANTALLA). Fit the words inside that safe area: lower the size or wrap lines when they do not fit. `line-height` is at least 1, so the box wraps the glyphs instead of cropping them. The canvas crops whatever still falls outside the frame. `validate_json` rejects measurable text that does not fit, text that crosses the canvas, and `line-height` below 1. It warns when text sits in the margin. It still does not render the picture (`fullyValidated` stays false). +Decide `width` and `height` before any type size. `get_capabilities` returns the rule and the numbers in `screen` (the same figures Studio calls PANTALLA). The starting sizes in `screen` (title, support, label) are a starting point, neither a minimum nor a maximum: a bigger, disruptive headline is fine when it still fits the safe area. Fit the words inside that safe area: lower the size or wrap lines when they do not fit. `line-height` is at least 1, so the box wraps the glyphs instead of cropping them. The canvas crops whatever still falls outside the frame. `validate_json` rejects measurable text that does not fit, text that crosses the canvas, and `line-height` below 1. It warns when text sits in the margin. It still does not render the picture (`fullyValidated` stays false). ## Layers and timing diff --git a/skills/hypercodemotion/references/motion-design.md b/skills/hypercodemotion/references/motion-design.md index de345c2..84fc705 100644 --- a/skills/hypercodemotion/references/motion-design.md +++ b/skills/hypercodemotion/references/motion-design.md @@ -13,11 +13,38 @@ The source-pinned contract currently lists: - Loop: `float`, `pulse`, `rotate`, `sway`, `shake`, `heartbeat`, `blink`, `breathe` - Style: `glow`, `shadow`, `lift`, `outline`, `neon` -**Not all presets work on all types or slots.** Always query `get_capabilities` and, where necessary, verify restrictions in `presets.ts`. A typical non-destructive preset reference is `"fx":{"in":{"id":"rise","dur":0.5,"amount":1}}`. +**Not all presets work on all types or slots.** `get_capabilities` lists the slots of each preset (`presetSlots`). + +### How to write `fx` + +A layer has at most one effect per slot: `"fx": {"in": FxRef, "out": FxRef, "loop": FxRef, "style": FxRef}`. Every slot uses the same shape, from Studio `presets.ts`: + +- `id`: the preset name. +- `dur`: seconds. For `in` it is the entrance length from the layer's `start`; for `out` the exit length ending at the layer's `end`; for `loop` the period of one cycle. Ignored by `style`. +- `amount`: intensity, `1` is normal. Use about `0.3`–`0.6` for a subtle loop, up to `1.5` for an emphatic entrance. + +```json +"fx": { + "in": {"id": "rise", "dur": 0.6, "amount": 1}, + "out": {"id": "fade", "dur": 0.4, "amount": 1}, + "loop": {"id": "breathe", "dur": 3, "amount": 0.4}, + "style": {"id": "glow", "dur": 0, "amount": 0.8} +} +``` + +An `out` preset is the same movement as its entrance, played backwards. Type limits from `presets.ts`: `wipe` only on `image`, `video` and `html`; `type`, `letters` and `words` only on `text`; `draw` only on `rect`, `ellipse`, `polygon` and `svg`; `outline` and `neon` only on `text`, `rect`, `ellipse` and `polygon`. On another type Studio ignores the effect. ## Keyframes -Use global-second `kf` for physical changes and exact timing. Preserve property continuity across cuts; use eased changes for entering/leaving and restrained loops for ambient details. For a morphing object, keep stable layer identities and animate its attributes rather than repeatedly hiding/redrawing copies. +Use global-second `kf` for physical changes and exact timing. Each keyframe's `ease` is the curve **towards the next** keyframe (the last keyframe's `ease` is unused). Valid names, from Studio `easing.ts`: + +- `linear`, `hold` (jumps at the next keyframe; use it for text that changes) +- `easeInQuad`, `easeOutQuad`, `easeInOutQuad`, `easeInCubic`, `easeOutCubic`, `easeInOutCubic`, `easeInQuart`, `easeOutQuart`, `easeInOutQuart`, `easeInExpo`, `easeOutExpo`, `easeInOutExpo`, `easeInSine`, `easeOutSine`, `easeInOutSine` +- `easeInBack`, `easeOutBack`, `easeInOutBack`, `easeOutElastic`, `easeInOutElastic`, `easeInBounce`, `easeOutBounce` +- `spring`, `springSnappy`, `springBouncy`, `springSmooth`, `springHeavy`, or `spring(damping,stiffness,mass)` +- `cubic-bezier(x1,y1,x2,y2)`, as in CSS. + +No validator checks these names: an unknown one silently becomes `easeInOutCubic`, so copy them exactly. Preserve property continuity across cuts; use eased changes for entering/leaving and restrained loops for ambient details. For a morphing object, keep stable layer identities and animate its attributes rather than repeatedly hiding/redrawing copies. ## Sound and rhythm diff --git a/skills/hypercodemotion/references/validation.md b/skills/hypercodemotion/references/validation.md index bf2dca8..6775034 100644 --- a/skills/hypercodemotion/references/validation.md +++ b/skills/hypercodemotion/references/validation.md @@ -4,14 +4,14 @@ 1. The HyperCodeMotion MCP is required. Call `get_capabilities` before designing layer properties and effects. If it is not connected, ask the user to connect it before generating. 2. Generate one complete composition with `layers` at the root. -3. Optionally call `validate_json` on drafts. +3. Optionally call `validate_json` on drafts. `create_hcmotion` runs the same checks, so a separate `validate_json` call only helps while iterating on a draft you are unsure about. 4. Correct errors and investigate warnings. Validate again after corrections. 5. Call `create_hcmotion`. If `created` is false, fix the listed errors and call it again. Hand the user the `open` and `download` links (valid 24 hours), never the raw JSON. 6. Tell the user to open the `open` link and check the preview; you have not seen the render. ## What validation proves -Current MCP validation is structural preflight against a source-pinned capability snapshot, plus a measurement of whether text can fit the canvas. It rejects measurable native text and HTML pieces that cannot fit the safe area, text that crosses the canvas, and `line-height` below 1. It warns when text sits in the margin. It reports `fullyValidated: false`. Therefore `valid: true` does not certify visual quality, rendering, animation smoothness, exact asset resolution, or acceptance of every feature by Studio. Expressions, parented placement, rotation, shadows and filters are not measured. +Current MCP validation is a structural preflight plus a measurement of whether text can fit the canvas. Errors (which block `create_hcmotion`) cover the root format, timing, references and text fit. Unknown layer types, property names and effect presets are only **warnings** (`UNKNOWN_LAYER_TYPE`, `UNKNOWN_PROPERTY`, `UNKNOWN_EFFECT`): read every warning and fix them, because Studio may drop that layer, property or effect. Keyframe easing names, effect `dur`/`amount` values and asset contents are not checked at all, which is what the `CONTRACT_NOT_CHECKED` warning says. It rejects measurable native text and HTML pieces that cannot fit the safe area, text that crosses the canvas, and `line-height` below 1. It warns when text sits in the margin. It reports `fullyValidated: false`. Therefore `valid: true` does not certify visual quality, rendering, animation smoothness, exact asset resolution, or acceptance of every feature by Studio. Expressions, parented placement, rotation, shadows and filters are not measured. If the MCP is not connected, never claim it was used. If no preview has been inspected, never state that the result rendered successfully. diff --git a/tests/skill.test.js b/tests/skill.test.js index 2175eed..9a306c9 100644 --- a/tests/skill.test.js +++ b/tests/skill.test.js @@ -7,6 +7,13 @@ test("Skill manifest has valid name and description",()=>{ const s=readFileSync(root+"SKILL.md","utf8"); assert.match(s,/^---\nname: hypercodemotion\ndescription: .+\n---/); assert.ok(s.includes("MCP validation")); + assert.match(s,/\.hcmotion/); +}); +test("Skill asks for the canvas size before designing",()=>{ + const s=readFileSync(root+"SKILL.md","utf8"); + const first=s.indexOf("1. **Canvas size first**"); + assert.ok(first>0&&first{ for(const name of ["composition","visual-design","motion-design","html-scenes","validation"])