Conversation
0d50ebf to
7320ccd
Compare
Narrated-video pipeline: HTML slides with staged entrance animations, TTS voiceover measured with ffprobe, burned-in subtitles, deterministic frame-stepping capture, ffmpeg assembly, and ASR verification. - 11 Node scripts, no build step; works with mcode connectors or mmx-cli - 13 themes, 17 layout recipes, image framing primitives - Subtitles confined to their own windows (no overlap); 16:9 and 9:16 canvases - Research phase documented: source grading, cross-verification rules, notes template - Discloses dependencies, accounts, network destinations and data handling (bilingual README) - Validation: node scripts/validate.mjs -> OK (exit 0)
7320ccd to
4104572
Compare
Add Plugin: html2video-for-mcode Narrated-video pipeline: HTML slides with staged entrance animations, TTS voiceover measured with ffprobe, burned-in subtitles, deterministic frame-stepping capture, ffmpeg assembly, and ASR verification. - 11 Node scripts, no build step; works with mcode connectors or mmx-cli - 13 themes, 17 layout recipes, image framing primitives - Subtitles confined to their own windows (no overlap); 16:9 and 9:16 canvases - Research phase documented: source grading, cross-verification rules, notes template, plus how to fetch official-site / press-release text (SPA rendering, PDF-first numbers) - Discloses dependencies, accounts, network destinations and data handling (bilingual README) - Validation: node scripts/validate.mjs -> OK (exit 0)
… them to the repo root) Add Plugin: html2video-for-mcode Narrated-video pipeline: HTML slides with staged entrance animations, TTS voiceover measured with ffprobe, burned-in subtitles, deterministic frame-stepping capture, ffmpeg assembly, and ASR verification. - 11 Node scripts, no build step; works with mcode connectors or mmx-cli - 13 themes, 17 layout recipes, image framing primitives - Subtitles confined to their own windows (no overlap); 16:9 and 9:16 canvases - Research phase documented: source grading, cross-verification rules, notes template, plus how to fetch official-site / press-release text (SPA rendering, PDF-first numbers) - Discloses dependencies, accounts, network destinations and data handling (bilingual README) - Validation: node scripts/validate.mjs -> OK (exit 0)
hetaoBackend
left a comment
There was a problem hiding this comment.
Request changes for exact current head 737ee96.
Blocking security and evidence issues:
- Input-derived IDs and paths are not contained.
skills/html2video-for-mcode/scripts/capture.mjs:75-77,228-230usess.htmlands.idto construct paths and recursively deletes the frame directory;build-video.mjs:55-58,191-197usest.idfor output/frame/ASR paths;plan-timings.mjs:47-50andbuild-video.mjs:102-105also consume script-provided paths. An Agent-editablescript.jsonvalue such as../../victimcan escape the intended build directory and trigger out-of-scope reads/writes/deletion. Add strict ID validation, resolve-and-containment checks, symlink checks, and malicious-ID tests. init-project.mjs:7-16,468-477accepts an existing directory and then overwrites project files without a non-empty check or explicit--force.fetch-official-images.mjs:31-32,102-115accepts arbitrary--out-dirand overwrites files;prep-image.mjs:64-87uses ffmpeg-yfor arbitrary output. This contradicts the README claim that writes stay inside the supplied project directory and creates destructive overwrite behavior. Default to refusing existing/non-empty targets and require explicit force, with output containment enforced.asr.mjs:29-32,65-74allows--base-url/MINIMAX_BASE_URLto replace the endpoint without validation while sending the MiniMax API key as a Bearer token. A misconfiguration or prompt-controlled environment can exfiltrate the credential to arbitrary HTTPS/HTTP endpoints. Default to an HTTPS allowlist for official hosts; make custom endpoints an explicit, separately disclosed dangerous opt-in.fetch-official-images.mjs:25-29,40-46,98-115accepts arbitraryhttp:,https:, andfile:URLs and downloads through a browser/request client without protocol, private-address, redirect, or response-size restrictions. This exposes SSRF and local-file-read/copy behavior. Restrict to validated HTTPS public targets, block loopback/private/link-local/metadata addresses and redirects, bound responses, and make local files explicit opt-in with containment.- The PR adds roughly 2,000 lines of executable scripts but no executable test suite;
evals/evals.jsonis prompt/expected-output data and is not run bynpm run check, while the repository validator does not execute these scripts or validate.claude-plugin/plugin.json. Add automated negative and smoke tests for containment, overwrite refusal, endpoint allowlist, SSRF/file rejection, and a minimal render/checker/build dry-run. The current[code]smithcheck is skipped and cannot substitute for this evidence.
Do not approve or merge until these security boundaries and executable test evidence are present on a new head.
|
Thanks for the review — all five blockers were reproduced against the exact head you flagged and are fixed on the new head (v1.1.0). Point-by-point: 1. Input-derived IDs and paths are not contained — fixed. 2. Destructive overwrite behaviour — fixed. 3. Endpoint replacement could exfiltrate the credential — fixed. 4. SSRF / local-file read in 5. No executable test suite — added. Also in this head (non-blocking, from user feedback while the review was open): pure-CSS/SVG chart recipes with entrance-and-growth animations, a one-switch The validator reports |
追加:放映页(可以先自己放一遍再渲染)+ 修一个"文档说能用、闸门说不能用"的类新提交 1. 新增 单文件、零依赖、 为什么不是"直接打开 2. 3. 修 4. 测试 +21 例(共 93,7 个文件):新增 5. 文档漂移修正:插件树 README 此前落后仓库树一轮(缺整个
|
追加:
|
| 情形 | 页面表现 |
|---|---|
有 clauses + 有 timings.json |
列出该张口播文案(P 可开 / 关) |
| 有 clauses、还没对时 | 只列文案,标题标「(未对时)」—— 口播还没做也能先看 HTML |
没有 clauses,或 --no-script |
面板与口播按钮完全不出现,画面占满整宽 |
顺带修掉一个误导标签:底部提示原写成「X 关配音画对比」(本意是「关动效 / 画面对照」),读起来像是在管音频。现在统一写作「X 动效 / 关动效 对照」,测试里加了断言:页面不得出现「配音」字样。
3. 响应式(此前只考虑了桌面)。 原来右侧固定 320px 面板 + 固定行高的顶/底栏,窄窗口和手机上挤成一团。现在:顶栏/底栏可换行、话题名过长省略号截断;窄窗口与手机上口播面板收成底部抽屉并默认收起(画面优先);手机给触摸条按钮 + 左右滑动翻页;总览网格按宽度自动列数;高度用 100dvh(免得被手机地址栏切掉)。
实测(Playwright,五档视口 + 触屏模拟):1600×900 / 1024×600 / 800×600 / 390×844 / 360×640 全部零横向溢出、零控制台报错,触摸条无标签截断;390×844 上左滑确实翻页;窄屏下点「口播」画面从 385→755px 高。
另外把「还没对时」这一档做实用:没有 timings.json 时,副本按 HTML 里实际用到的 stage 等间隔排(0.3/1.3/2.3s),页面顶部黄条如实标注「不是成片时序」—— 占位值会把动画全挤在 2 秒内,那才是真看不懂。
测试 99 例(+6:不做计时器 / 不得出现「配音」字样 / 响应式与触摸 / 口播三态 / 等间隔兜底)。
…vider api REST fallback (1.9.0)
|
1.9.0 — ASR toolchain simplification:
|
…uoting, scrub mmx child env, assert full argv mapping
|
1.9.1 — sixteenth review round fixes (two-axis review over the 1.9.0 increment; every finding personally reproduced before fixing):
Verification: three trees locally 248 tests / 245 pass / 0 fail / 3 capability skips; real end-to-end against mmx 1.0.26 re-run keyless with word-level timestamps (exact transcript, |
…EY assertion regression-proof, disclose Windows-only quoting coverage
|
1.9.2 — seventeenth review round fixes. Both axes caught the same two defects in 1.9.1's own fix; each was personally reproduced before fixing:
Verification: three trees locally 248 tests / 245 pass / 0 fail / 3 capability skips; real keyless end-to-end re-run against mmx 1.0.26 (exact transcript); upstream validator OK; remote trees byte-verified after push (51 + 52 files, zero drift, zero |
hetaoBackend
left a comment
There was a problem hiding this comment.
Request changes for exact current head 4c9926e3d738f5e83a5c16c6712ea32589c51432.
The current source appears to close the previously reported leaf-symlink, ancestor-symlink, ASR output/no-clobber, prep-image contract, SSRF, argument-validation, subtitle, and environment-scrubbing issues. Local plugin tests reported 0 failures. Two release gates still block approval:
- No executable exact-head GitHub evidence. The only check attached to this exact head is
[code]smith = SKIPPED; the fork smoke/CI workflows remain approval-gated and have no jobs for4c9926e3.... The render/security suite contains capability-dependent Chromium/ffmpeg/Windows paths that local macOS execution skipped, so the scoped workflow must actually run on this exact head before merge. - The submitted diff is not clean.
git diff --check origin/main...HEADreports roughly 3,700 trailing-whitespace errors caused by CRLF/line formatting across the newly added files. Normalize the text files and retain a cleangit diff --checkresult on the reviewed head.
Please obtain real exact-head smoke results with ffmpeg, Playwright Chromium and Windows coverage, then request review on the resulting head. [code]smith is not test evidence.
…gn node to the proven mirror config
|
Gate 2 is closed; Gate 1 now covers Windows but needs one approval click that only a maintainer can make. Gate 2 — clean diff. On head Gate 1 — exact-head evidence, now including Windows.
https://github.com/Wzdhehe/html2video-for-mcode/actions/runs/35590708800
One housekeeping note: the PR description's evidence block no longer quotes per-environment counts (they drift every time a release adds tests — the invariant is stated instead, per-version numbers live in the CHANGELOG). |
Exact-head smoke evidence for
|
| job | result | time |
|---|---|---|
| smoke (ubuntu-latest · ffmpeg + chromium) | ✅ 248 / 248 pass, 0 fail, 0 skip | 4m11s |
| smoke (windows-latest · ffmpeg + chromium) | ✅ 248 / 248 pass, 0 fail, 0 skip | 5m45s |
Bonus on the same head: CodeQL analyze ✅.
Gate 2 (clean diff) also verified at this head: git diff --check origin/main...HEAD → 0 findings after 6c360d6 (LF normalization + .gitattributes).
One transparency note: the repo-level CI (validate) job that also triggered shows 2 failures — both in tests/plugins/octopus-meme-maker/smoke.test.mjs (stderr must name --workdir in the error), an unrelated plugin whose error-text assertions depend on the runner's Python stderr format. The full 65-test file passes locally at this exact head (65/65), and upstream main's CI is green, so this is environment drift in that suite, not a regression from this PR.
With both release-gate items now having executable receipts at 9ad80b9, this head is ready for re-review.
|
Correction to my earlier note on the CI (validate) failure — the mechanism I gave ("runner's Python stderr format") was wrong; here is the actual root cause, verified against both trees: The two failing octopus-meme-maker tests die because This is a stale-base artifact, not a regression from this PR:
Remedy: merge current |
hetaoBackend
left a comment
There was a problem hiding this comment.
Request changes for exact current head 9ad80b9d52b482eb149325da511fa7e861105d0b.
The previous source-security findings and the CRLF/trailing-whitespace blocker appear substantially fixed, but the release gate is still open:
- The exact-head Linux/Windows scoped workflow and CodeQL runs are
action_requiredwith no jobs for this head; the only visible check is[code]smith = SKIPPED. Local macOS tests and an author-reported external run cannot replace executable exact-head CI evidence for the claimed Chromium/ffmpeg/Windows paths. Approve/run the workflow on this exact head and retain passing Linux and Windows results. - GitHub reports the PR base as
d592f422893846c2aac48f8b407a92bd0293c6b1, while current main is6481e4ae1e0375a4ddb3d5e9b29845354ab1cead; the branch is behind/diverged from current main. Rebase or otherwise reconcile against current main, then rerun the review and checks on the resulting exact head.
Do not merge while the exact-head workflow is approval-gated and unexecuted. [code]smith is skipped and is not test evidence.
|
Both items addressed on new head Item 2 — reconcile with current main: done. Merged current
Side effect worth noting: the merge picks up #42's Item 1 — exact-head executable evidence: the runs exist and are queued for this head, but the approval itself needs write access to this repository. On Per your standard, we treat neither local tests nor external runs as a substitute for the exact-head checks — the mirror-repo and fork-side runs referenced earlier are offered only as pre-approval rehearsal. On that note, @modacker: your offer to re-run the fork-side evidence on the merged head is welcome as a rehearsal; agreed it does not close the gate — only the approved runs on |
|
The exact-head runs are queued; releasing them takes an admin click, not an author action. We tried to approve them ourselves before asking again — the API refuses, verbatim: Our permission bits on this repository are Everything else on both items is in place: branch reconciled with current main (behind 0, merge-base |
|
1.9.4 — grey/flickering subtitle defect fixed (found in a real production render: "the subtitle appears and goes grey within a second, then stays grey to the end of the slide"). The diagnosis came in as a handoff write-up; every claim in it was reproduced before touching code. Root cause — a keyframe offset collision. For the last clause the generated subtitle keyframes read Fixes (in
Tests: 249 in fourteen files (+1). Tool-level keyframe-shape invariants (no same-offset collision, last clause tail-less, non-last keeps its tail, offsets monotonic within [0%, 100%]); full-brightness + cross-still-leak assertions on spliced stills. Red-proofed against the pre-fix shape (both new checks fail there). One honest disclosure: two render-smoke Verification — the affected project ( Sequencing note for the release gate: this commit moves the head to |
…r subtitle-free (1.9.5)
|
1.9.5 — round-20 review fixed two regressions that 1.9.4's own fix had introduced (found by fresh-eyes review of the increment; both reproduced visually before fixing).
Verification: three trees 249 tests / 246 pass / 0 fail / 3 named skips; the affected project re-rendered — 12 stills at full brightness (235), 1.05s/2.20s frames identical (Δ0), cover visually checked clean (title fully revealed, no subtitle); mirror CI on both platforms at this code: run 35740432546 — ubuntu and windows both 249 / 249 pass, 0 fail, 0 skip. Release-gate sequencing: this moves the head to |
…erflow clipping (1.9.8)
|
1.9.6 + 1.9.7 + 1.9.8 — three field-report fixes (folded into one note so the head only moves once): 1.9.6 — mcode-first tool choice made explicit. An agent in the mcode sandbox reached for mmx-cli and forgot the 1.9.7 — chart-structure gate. An agent's bar chart came out with the bars collapsed/missing and passed screenshot review as "just not rendered yet". The docs carried the warning (bars in a flex column with percentage heights get squeezed by 1.9.8 — layout-overflow protection. A dense table/data-viz slide had its kicker pushed to y≈17px, clipped at the canvas top — and passed screenshot review. Chain (field postmortem, reproduced): content ≈925px inside an 800px content box + plain
Tests +2 (254 in fourteen files) for 1.9.8 (geometry warns on the reproduced shape and stays silent on healthy short content; the scaffold contract is pinned), each guard red-proofed individually. Verification: three trees 254 tests / 251 pass / 0 fail / 3 named skips; mirror CI on both platforms at this code: run 35761250003. (Side note from the same field batch: the reported Windows CLI spawn symptom is real but is Node's Release-gate sequencing: head is now |
…e wrap warning (1.9.9)
|
1.9.9 — cloud-sandbox field batch (sorted by the reporter into skill issues vs environment quirks): 🔴 Entry guard could silently no-op. 🟡 Subtitle wrap warning mis-fired on landscape. The 🟡/🟢 Documented (render.md + symptoms.md): capture runtime scaling with entrance-choreography windows (measured 5×15s ≈ 2250 frames ≈ 6–8 min; quick passes: Tests +2 (256 in fourteen files): Release-gate sequencing: head is now |
…har rule drift (1.9.10)
|
1.9.10 — round-21 review fixes (a two-axis review of 1.9.9 found one hard inconsistency and one wrong baseline; both reproduced before fixing): Rule drift (the hard one). 1.9.9 rewrote the subtitle wrap rule in The published geometry was wrong (correction to the 1.9.9 entry). Its "≈18 CJK per line at 1080, ≈32 at 1920" were the superseded vertical baseline's restatement. The pill's font and padding both scale with Entry guard, per the review: the same-basename fallback now announces on stderr when it fires — the trade is "a loud, self-annotated extra run" vs "a silent no-op" (the silent kind cost a field debugging session); its justification no longer claims cases Tests +1 (257 in fourteen files). Verification: three trees 257 tests / 253 pass / 0 fail / 4 named skips (symlink-capability cases run on Linux CI); mirror CI both platforms: run 35849400871. Release-gate sequencing: head is now |
What changes
Add Plugin:
html2video-for-mcodeatplugins/Wzdhehe/html2video-for-mcode.A Skill that turns a topic, outline, or script into a narrated MP4: HTML slides with staged
entrance animations, a TTS voiceover, burned-in subtitles, and an ASR pass that verifies the
voiceover says what the script says.
User value
After installing, a MiniMax Code user can ask in plain language:
and get:
What makes it more than a slide exporter:
derived from the TTS audio via ffprobe, so the picture can never lag behind the voiceover.
is just a headline.
screen-recording.
images, external resources, or entrance animations without an animation class: the silent
failure modes that otherwise ship a broken-looking video while every script reports success.
Plugin submission checklist
plugins/<github-owner>/<plugin-name>.plugin.jsonname matches the Plugin directory.README.mdincludes a real example prompt and expected result (bilingual:README.md+README.zh-CN.md).LICENSEandplugin.jsondeclare an open-source license (MIT).(Node 18+, ffmpeg/ffprobe, Playwright Chromium; MiniMax API key or Token Plan for voice and
ASR; Windows/macOS/Linux; PowerShell caveat documented).
(
api.minimaxi.com/api.minimax.iofor ASR only when invoked; voice via mcode connectorsor
mmx-cli; image fetching only from URLs the user passes; no telemetry).are included. The ASR script reads its key from an environment variable or CLI flag at
runtime and never writes it.
TODOhas been replaced.publish/validate-plugin.mjs(an authoring-side tool, deliberately not part of the shipped plugin tree): it stages the Plugin tree into the host checkout, verifies every file in the tree is fingerprint-identical (sha256) to the source tree, then runs the upstream validator →OK plugin Wzdhehe/html2video-for-mcode, exit 0. (Validating the host'snpm run checkalone is not sufficient: it scans the staged copy under_official-plugins/plugins/**, so a stale staged copy yields a green result that proves nothing.)Evidence
The validator also prints a
Validated <N> hosted Pluginssummary line; N counts every plugin in the checkout and grows as the host merges unrelated plugins (it grew repeatedly while this PR was open). That line is checkout state, not a property of this PR, so it is not quoted above.The suite reports 0 fail in every environment measured: the development tree, both published trees, and tool-less sandboxes in both link-capability shapes. Skips are capability-dependent and always named: 0 skips with tools on a symlink-capable system; on stock Windows without Developer Mode the file-symlink canaries skip by name; in tool-less environments every tool-needing test skips with its reason. When ffmpeg / ffprobe / Chromium are absent (the monorepo's own root-level
node --testruns in exactly that environment), every test that needs one of them skips with its stated reason — verified in tool-less sandboxes in both link capability shapes: 0 fail, every remaining case skipping with its stated reason (nothing pretends to pass). Skip counts are environment-dependent and drift as each release adds tests — the invariant is stated here, per-version measurements live in the CHANGELOG — and the scoped workflow installs the tools and runs the whole suite for real. The host repository's owntest/hosted-plugins.test.mjscontains a symlink fixture that fails on a Windows checkout without Developer Mode (EPERM: operation not permitted, symlink …); that is a pre-existing host-side issue, it reproduces on a clean checkout without this Plugin, it passes on the CI'subuntu-latest, and this PR does not touch it. The part ofnpm run checkthat inspects Plugins passes with exit code 0 when the staged copy is current.Manual end-to-end test (Windows, Node 24, ffmpeg-static):
plan-timings.mjs→ every slide duration andstage entrance time derived from measured audio.
check-slides.mjscorrectly rejects slides with undefined CSS variables (--coral-a/--coral-b),missing images, external font links, and
data-stagewithout an animation class; clean slides pass.capture.mjs --mode motionproduced 143 frames for an 8.6s slide; frame-diff (PSNR) confirms thestaged entrance actually renders at its scheduled time (
infbefore the entrance, ~14 dB across it).build-video.mjs --asrproduced a 14.20s MP4 matching the expected duration exactly, full decodeclean,
out/subs.srtgenerated, and per-sentence ASR parts produced.#FFB84Don white)is rejected with a non-zero exit code, a compliant one (
#C2410C) passes.traditional characters (Cantonese voice) and mismatched numbers fail with exit code 1.
Full disclosure of dependencies, network access, and data handling is in the Plugin README.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.