mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
fix(core,figma-skill): address PR feedback — regex key escaping, no-shell psnr probe
- motionContextToDocs: escape regex metacharacters in arrayAfterKey / scalarAfterKey key interpolation (safe today for \\w+ keys; now safe for any future caller), and document balancedBlock's no-strings invariant. - verify-motion.mjs: execSync shell string -> spawnSync with array args (JSON.stringify is not shell escaping); verifier re-calibrated unchanged (faithful render still PASS at min 20.30dB). - command-failure-tracking: rebase folded the group-delegation skip into upstream's recursive wrapCommand (HF#2033) — leaf commands now assert their own flag tables, so `figma component --namee` is rejected at the leaf while `--name` passes the group; heuristic invariant documented. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a2243f7586
commit
3d59dcc694
@@ -58,7 +58,15 @@ export interface MotionContextToDocsOptions {
|
||||
/** motion.dev property → GSAP property. */
|
||||
const PROPERTY_MAP: Record<string, string> = { rotate: "rotation" };
|
||||
|
||||
/** Extract the balanced `{...}` body following `marker` in `src`. */
|
||||
/** Escape regex metacharacters — keys are `\w+` property names today, but a
|
||||
* future caller passing anything else must not silently misparse. */
|
||||
function escapeRegExp(text: string): string {
|
||||
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
/** Extract the balanced `{...}` body following `marker` in `src`. Brace
|
||||
* counting does not skip string literals — sound for motion.dev output
|
||||
* (numeric arrays + named eases, never arbitrary strings containing `}`). */
|
||||
function balancedBlock(src: string, marker: string): string | null {
|
||||
const at = src.indexOf(marker);
|
||||
if (at === -1) return null;
|
||||
@@ -77,7 +85,7 @@ function balancedBlock(src: string, marker: string): string | null {
|
||||
|
||||
/** Extract a balanced `[...]` immediately after `key:` inside `src`. */
|
||||
function arrayAfterKey(src: string, key: string): string | null {
|
||||
const re = new RegExp(`${key}\\s*:\\s*\\[`);
|
||||
const re = new RegExp(`${escapeRegExp(key)}\\s*:\\s*\\[`);
|
||||
const m = re.exec(src);
|
||||
if (!m) return null;
|
||||
const start = m.index + m[0].length - 1;
|
||||
@@ -93,7 +101,7 @@ function arrayAfterKey(src: string, key: string): string | null {
|
||||
}
|
||||
|
||||
function scalarAfterKey(src: string, key: string): string | null {
|
||||
const m = new RegExp(`${key}\\s*:\\s*("[^"]*"|[\\w.]+)`).exec(src);
|
||||
const m = new RegExp(`${escapeRegExp(key)}\\s*:\\s*("[^"]*"|[\\w.]+)`).exec(src);
|
||||
return m?.[1] ?? null;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"files": 18
|
||||
},
|
||||
"figma": {
|
||||
"hash": "e84abcb652194f57",
|
||||
"hash": "3172ad95070aaecc",
|
||||
"files": 2
|
||||
},
|
||||
"general-video": {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* frame. Measure it from the render (the card's left/top edge + scaled
|
||||
* size), don't guess: a wrong crop reads as motion divergence.
|
||||
*/
|
||||
import { execFileSync, execSync } from "node:child_process";
|
||||
import { execFileSync, spawnSync } from "node:child_process";
|
||||
import { mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
@@ -72,8 +72,9 @@ const frame = (src, t, vf, dst) => {
|
||||
const diff = (a, b, dst) =>
|
||||
execFileSync("ffmpeg", ["-y", "-v", "error", "-i", a, "-i", b, "-filter_complex", "blend=all_mode=difference", dst]);
|
||||
const psnr = (a, b) => {
|
||||
const err = execSync(`ffmpeg -i ${JSON.stringify(a)} -i ${JSON.stringify(b)} -lavfi psnr -f null - 2>&1`).toString();
|
||||
const m = err.match(/average:([\d.]+|inf)/);
|
||||
// spawnSync with array args (no shell): psnr stats land on stderr
|
||||
const r = spawnSync("ffmpeg", ["-i", a, "-i", b, "-lavfi", "psnr", "-f", "null", "-"], { encoding: "utf8" });
|
||||
const m = (r.stderr || "").match(/average:([\d.]+|inf)/);
|
||||
return m ? (m[1] === "inf" ? 99 : Number(m[1])) : NaN;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user