fix(skills,producer): terminate ffprobe options in shipped skill scripts

The contract test only walked packages/*/src and only .ts, so it could not see
the shipped agent tools under skills/**, which are .mjs/.cjs. 19 call sites
there and in package tests were still missing `--` immediately before the
input while the suite reported the bug class closed — a dash-prefixed filename
is parsed as an option and fails the same way.

Sweeps packages/, skills/ and scripts/ now, including .mjs/.cjs and test
files (dither.test.mjs was one of the broken sites). Excludes only the
contract test itself, which documents the contract with example argvs
including a deliberately misordered one.

Two guards were fixed while widening: the terminator must never be inserted
after `-i`, which consumes the next token (a blind pass hit an ffmpeg input
and a base64 -i), and comment prose describing a spawn is not a spawn.

Also routes every audioPadTrim probe failure through one sanitizer at the
boundary. runFfprobeJson scrubbed its own stderr, but
defaultProbeVideoFrameInfo threw `no video stream in ${videoPath}` raw into
the public PadTrimAudioResult.error, and an injected probe can throw anything.
The redaction unit tests all passed with the caller wiring deleted; the new
public-path regressions fail without it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-08-04 02:23:35 -07:00
co-authored by Claude Opus 5
parent e79ab3ab31
commit 255cf92915
22 changed files with 155 additions and 24 deletions
@@ -44,6 +44,7 @@ function probeMedia(mediaPath, ffprobePath) {
"stream=color_space,color_transfer,color_primaries,pix_fmt,duration:format=duration",
"-of",
"json",
"--",
mediaPath,
],
{ encoding: "utf8", timeout: 5_000, stdio: ["ignore", "pipe", "pipe"] },
+1 -1
View File
@@ -12,7 +12,7 @@ export function probe(filePath) {
// can't break out of the quoting — filePath is passed as a literal argv entry.
const raw = execFileSync(
"ffprobe",
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filePath],
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "--", filePath],
{ encoding: "utf8", timeout: 5000 },
);
const info = JSON.parse(raw);
@@ -17,7 +17,7 @@ function probeDurationSeconds(file) {
try {
const out = execFileSync(
"ffprobe",
["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", file],
["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", "--", file],
{ encoding: "utf8", timeout: 15000 },
);
const d = parseFloat(String(out).trim());