feat(cli): keyframes command (surface GSAP/CSS/Anime keyframes + 3D onion-skin --shot) (#1603)

Renames the motion-surfacing tool from `hyperframes keyframes` to `hyperframes motion`,
renames the implementation from keyframes*.ts to motion*.ts (keeping the keyframe data
model name where still accurate), and renames the shipped skill from
hyperframes-keyframes to hyperframes-motion. Expands the skill from a command
reference into a full motion-design workflow: reading motion, 3D angle verification,
layered GSAP motion, one-shot reference reproduction, diagnostic checks, and
eval-derived craft guidance.
This commit is contained in:
Miguel Ángel
2026-07-01 19:51:55 -07:00
committed by GitHub
parent 145c71e837
commit a908af11a8
34 changed files with 3973 additions and 159 deletions
+32
View File
@@ -666,6 +666,38 @@ body {
const finding = result.findings.find((f) => f.code === "timeline_id_mismatch");
expect(finding).toBeUndefined();
});
it("accepts object-literal timeline registration and extracts its keys", async () => {
const html = `
<html><body>
<div data-composition-id="comp-1" data-width="1920" data-height="1080"></div>
<script>
const tl = gsap.timeline({ paused: true });
window.__timelines = { "comp-1": tl };
</script>
</body></html>`;
const result = await lintHyperframeHtml(html);
expect(result.findings.find((f) => f.code === "missing_timeline_registry")).toBeUndefined();
expect(
result.findings.find((f) => f.code === "timeline_registry_missing_init"),
).toBeUndefined();
expect(result.findings.find((f) => f.code === "timeline_id_mismatch")).toBeUndefined();
});
it("reports mismatched object-literal timeline registration keys", async () => {
const html = `
<html><body>
<div data-composition-id="comp-1" data-width="1920" data-height="1080"></div>
<script>
const tl = gsap.timeline({ paused: true });
window.__timelines = { main: tl };
</script>
</body></html>`;
const result = await lintHyperframeHtml(html);
const finding = result.findings.find((f) => f.code === "timeline_id_mismatch");
expect(finding).toBeDefined();
expect(finding?.message).toContain('Timeline registered as "main"');
});
});
it("warns when a timeline-visible element has no stable id for Studio editing", async () => {