Skip to content

<template>-wrapped sub-compositions: data-composition-src loader and compositions CLI report 0 elements / black render (HF 0.4.41) #589

@sidorovanthon

Description

@sidorovanthon

Summary

In HF 0.4.41, the canon-blessed <template id="..."> ... </template> wrapper for sub-compositions loaded via data-composition-src results in:

  1. npx hyperframes compositions reporting 0 elements / 0.0s for the sub-composition.
  2. npx hyperframes snapshot rendering pure black across the entire mount window of the sub-composition.
  3. npx hyperframes lint additionally treating the sub-composition as a root composition (warning root_composition_missing_data_start), suggesting the CLI does not register that the file is meant to be loaded via data-composition-src from a sibling root.

The <template> wrapper is documented as required for sub-compositions in the SKILL.md canon (see "Sub-composition structure", roughly lines 149–185 of the shipped SKILL.md):

Sub-compositions loaded via data-composition-src use a <template> wrapper. Standalone compositions (the main index.html) do NOT use <template> — they put the data-composition-id div directly in <body>. Using <template> on a standalone file hides all content from the browser and breaks rendering.

So the canon mandates <template>, but the CLI loader does not appear to honor it.

Hypothesis

The CLI loader / probe path queries the live document (document.querySelectorAll(...) or equivalent) for [data-composition-id], child elements, GSAP timeline registrations, etc. By HTML spec, the contents of a <template> element live in an inert DocumentFragment (template.content) that is not reachable from the live document tree. So:

  • The wrapper attributes (data-composition-id, data-width, data-height) ARE read because they live on the <template> itself or on the immediate child, and the file's outer HTML is parseable enough to extract them.
  • The inner element count, the timeline registered onto window.__timelines["..."], and any child DOM are invisible to the probe — hence 0 elements / 0.0s and black render.

The two CLI surfaces (compositions reporting and snapshot/render loader) likely share this mechanism.

Bare repro

Verified against HF 0.4.41 on Windows 11 / Node via npx hyperframes. The repro is two files in a fresh npx hyperframes init scaffold.

my-video/index.html — root composition, 10s duration, mounting el-1:

<div id="el-1"
     data-composition-id="foo"
     data-composition-src="compositions/foo.html"
     data-start="0"
     data-duration="3"
     data-track-index="1"></div>

my-video/compositions/foo.html — canon-blessed <template> wrapper, single full-bleed red div, tl.fromTo() opacity 0 → 1 over 0.5s:

<template id="foo-template">
  <div data-composition-id="foo" data-width="1920" data-height="1080">
    <div class="foo-bg" style="position:absolute;inset:0;background:#ff0000;opacity:0;"></div>
    <style>
      [data-composition-id="foo"] { position:relative; width:100%; height:100%; }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
    <script>
      window.__timelines = window.__timelines || {};
      const tl = gsap.timeline({ paused: true });
      tl.fromTo(".foo-bg", { opacity: 0 }, { opacity: 1, duration: 0.5 }, 0);
      window.__timelines["foo"] = tl;
    </script>
  </div>
</template>

CLI evidence

npx hyperframes compositions:

◇  my-video — 2 compositions
   main   3.0s   1920×1080   1 element
   foo    0.0s   1920×1080   0 elements ← compositions/foo.html

npx hyperframes snapshot --at 0.0,0.6,1.5,2.5: all four PNGs are pure black #000 across the full mount window [0, 3]. No red pixels at any timestamp.

npx hyperframes lint: the only error is unrelated; significant warning is root_composition_missing_data_start for foo — the CLI treats the sub-composition as a root.

Expected vs actual

  • Expected: at t=0.6, the rendered frame is fully red #ff0000 (the tl.fromTo opacity sweep finishes at 0.5s). compositions reports ~0.5s / 1 element for foo.
  • Actual: rendered frame is #000. compositions reports 0.0s / 0 elements for foo.

Suggested fix direction

In whatever loader/probe path discovers per-composition elements and timeline registrations: detect <template> at the file root (or by data-composition-id) and walk template.content rather than the live document tree. The same fix likely closes both compositions reporting and the runtime mount path used by snapshot / render.

Happy to follow up with a pre-built failing scaffold tarball if that helps reproduction.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions