`motionContextToDocs`: `y` track copies `opacity` when a node animates both (key lookup has no word boundary)

Cerrado Apto para principiantes
#6,756 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Muzzy5150 ya está trabajando en esto.

Desde el 30/10/2026.

  • #6800 de @Muzzy5150 — abierto
  • #6810 de @MoonPointer-Byte — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
node.js, typescript
Área
backend, testing

Línea de trabajo

Empieza con dist/figma/motionContextToDocs.js e inspecciona arrayAfterKey, scalarAfterKey y la búsqueda de balancedBlock descrita en el issue. Ejecuta la reproducción proporcionada con el paquete y comprueba la pista y emitida. El trabajo está terminado cuando sus valores y tiempos coinciden con los arrays esperados cuando opacity e y aparecen juntos.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Describe the bug

In @hyperframes/core (dist/figma/motionContextToDocs.js), arrayAfterKey, scalarAfterKey and the
balancedBlock(transition, ${prop}: {) lookup search for the key with a plain regex or substring,
with no word boundary. When a Figma node animates opacity and y together, the search for y: [
matches inside opacity: [ (and y: { inside opacity: {), so the y track gets the opacity values
and timing. Letters that should rise 120px move 1px. Any key that ends another key is exposed the same
way.

The verify-motion.mjs check in the /figma skill passes the wrong translation: on our test it
scored the broken output higher than the corrected one (16.28 dB against 15.89 dB worst segment),
because the fade dominates the motion energy it compares.

Minimal reproduction
// repro.mjs — run: node repro.mjs <path to an installed @hyperframes/core>
const core = process.argv[2];
const { motionContextToDocs } = await import(core + "/dist/figma/index.js");
const snippet = '<motion.div initial={{ opacity: 0, y: 120, }} animate={{ opacity: [0, 0, 1, 1], y: [120, 120, 0, 0], }} transition={{ opacity: { duration: 4.5, times: [0, 0.0444, 0.1333, 1], ease: ["linear", "easeOut", "linear"], repeat: Infinity }, y: { duration: 4.5, times: [0, 0.0444, 0.2222, 1], ease: ["linear", "easeOut", "linear"], repeat: Infinity }, }} />';
const response = {
  nodes: [{ nodeId: "1:2", nodeName: "Box", nodeType: "FRAME", codeSnippets: { motionDev: snippet } }],
  timelineCohorts: [{ rootNodeId: "1:1", durationMs: 4500, loopMode: "loop", memberNodeIds: ["1:2"] }],
};
console.log(JSON.stringify(motionContextToDocs(response, { selectorFor: () => "#box" }), null, 1));

The snippet has the same shape as what get_motion_context returns for a layer with a fade and a
rise in Figma Motion.

Steps to reproduce
  1. npm pack @hyperframes/[email protected] && tar xzf hyperframes-core-0.8.217.tgz && (cd package && npm install --omit=dev)
  2. node repro.mjs ./package
  3. Look at the y track.
Expected behavior

y track: values [120, 120, 0, 0], times [0, 0.0444, 0.2222, 1].

Actual behavior

y track: values [0, 0, 1, 1], times [0, 0.0444, 0.1333, 1]: the opacity track, copied.

Environment
✓ Version          CLI 0.8.181 (plugin) · @hyperframes/core 0.8.181 and 0.8.217 both affected
✓ Node.js          v24.22.0 (darwin arm64)
✓ CPU              8 cores · Apple M3
✓ FFmpeg           ffmpeg 6.0
✓ Chrome           chrome-headless-shell mac_arm 152.0.7977.30
Additional context

A fix that keeps the current parsing: anchor the key so it cannot match inside a longer identifier,
for example new RegExp(`(?<![\\w$])${escapeRegExp(key)}\\s*:\\s*\\[`) in arrayAfterKey, the same
in scalarAfterKey, and the same guard in the balancedBlock lookup for ${prop}: {. Our workaround
until then is to reorder the snippet so the y entry comes before opacity, which changes no value.
It would also help if verify-motion.mjs compared the emitted tweens property by property against
the get_motion_context keyframes, since a frame-energy score cannot see a swapped track.

Lenguaje dominante
TypeScript
Estrellas
54.1k
Forks
4.9k
Merge medio
6 h 8 min
PR fusionados (30 d)
797

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de heygen-com/hyperframes

Todos los issues de heygen-com/hyperframes

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.