diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index bfe98cafe2e..85e732d322c 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "hyperframes", "description": "HyperFrames by HeyGen. Write HTML, render video. Compositions, GSAP and runtime adapter animations, captions, voiceovers, audio-reactive visuals, and website capture for HyperFrames.", - "version": "0.9.37", + "version": "0.9.38", "author": { "name": "HeyGen", "email": "hyperframes@heygen.com", diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 658e6554212..203ee5c429a 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "hyperframes", "description": "Write HTML, render video. Compositions, Tailwind v4 styles, GSAP and runtime adapter animations, captions, voiceovers, audio-reactive visuals, and website capture for HyperFrames.", - "version": "0.9.37", + "version": "0.9.38", "author": { "name": "HeyGen", "email": "hyperframes@heygen.com", diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index ff4fae628ec..3d1d3476247 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -3,7 +3,7 @@ "name": "hyperframes", "displayName": "HyperFrames by HeyGen", "description": "Write HTML, render video. Compositions, Tailwind v4 styles, GSAP and runtime adapter animations, captions, voiceovers, audio-reactive visuals, and website capture for HyperFrames.", - "version": "0.9.37", + "version": "0.9.38", "author": { "name": "HeyGen", "email": "hyperframes@heygen.com" diff --git a/docs/changelog.mdx b/docs/changelog.mdx index 925127a638f..7370382a75c 100644 --- a/docs/changelog.mdx +++ b/docs/changelog.mdx @@ -8,6 +8,40 @@ Recent HyperFrames releases, including user-facing features, fixes, and migratio {/* New release entries are prepended by `bun run changelog:draft --write`. */} + +The Volume control in Studio now changes the whole clip, a paused video shows the same colors as the playing one on Mac, and edit history records which layer each edit touched. Publish also keeps Library files out for projects on cloud drives, and render servers only load assets from inside the project. + +## Features + +- **Studio:** Record the layer name on each history entry's target ([4fad43db2](https://github.com/heygen-com/hyperframes/commit/4fad43db2010d61002cc9f9296f3c5f8bf2d4210), [#7586](https://github.com/heygen-com/hyperframes/pull/7586)). +- **CLI:** Heygen generate defaults images to nano-banana-2.1 ([fc7cb1aad](https://github.com/heygen-com/hyperframes/commit/fc7cb1aad8d5f01361343d004de1ee7b8143ed20), [#7591](https://github.com/heygen-com/hyperframes/pull/7591)). +- **CLI:** Price and validate minimax-h3-image, and image models at 1.5x ([88e74e088](https://github.com/heygen-com/hyperframes/commit/88e74e088fef82e3dba1f2972e7292e28eab137d), [#7589](https://github.com/heygen-com/hyperframes/pull/7589)). + +## Fixes + +- **Scripts:** Release:prepare refuses a baseline that skips a release whose tag this clone lacks ([f3626e97c](https://github.com/heygen-com/hyperframes/commit/f3626e97c34f18412a089d79a027bd126d8d4dbc)). +- **Studio:** A preview reload survives its pane unmounting mid-load ([5a3e46235](https://github.com/heygen-com/hyperframes/commit/5a3e46235fe1f749006af6bacae01c684f2866ca), [#7590](https://github.com/heygen-com/hyperframes/pull/7590)). +- **Core:** Show a paused video frame with the same color as the playing video on Mac ([303a4c477](https://github.com/heygen-com/hyperframes/commit/303a4c47710a90876e788e47e0fb68615302d12c), [#7584](https://github.com/heygen-com/hyperframes/pull/7584)). +- **Studio:** The Volume control changes the whole clip, fades included ([245904d55](https://github.com/heygen-com/hyperframes/commit/245904d55a916d5dc6b186dd90790c6e10a74c13), [#7587](https://github.com/heygen-com/hyperframes/pull/7587)). +- **CLI:** Publish keeps Library files out for projects on cloud drives ([f7bf5f0c4](https://github.com/heygen-com/hyperframes/commit/f7bf5f0c423565325eb4afea137d629894351d53), [#7582](https://github.com/heygen-com/hyperframes/pull/7582)). +- **Producer:** Render servers only load assets from inside the project ([03ddfb189](https://github.com/heygen-com/hyperframes/commit/03ddfb189f612a733ea37b7d6e907ef9eb7c089c), [#7579](https://github.com/heygen-com/hyperframes/pull/7579)). + +## Performance + +- **Lint:** Parse each style block once per lint instead of once per rule ([32cacab74](https://github.com/heygen-com/hyperframes/commit/32cacab74bb52076efb9e84258f382200b56b19e), [#7593](https://github.com/heygen-com/hyperframes/pull/7593)). + +## Docs & Examples + +- **Skills:** Name the model next to each media-use image price ([748bfe3b2](https://github.com/heygen-com/hyperframes/commit/748bfe3b2beef424c289dd12cc146b8dfcfa019c), [#7592](https://github.com/heygen-com/hyperframes/pull/7592)). +- Every link to hyperframes.studio carries where the visit began, shared with the homepage ([6b602495d](https://github.com/heygen-com/hyperframes/commit/6b602495db862ce60c07aa5d68155c4d2e62dfc6), [#7580](https://github.com/heygen-com/hyperframes/pull/7580)). + +[View the full commit range](https://github.com/heygen-com/hyperframes/compare/v0.9.37...v0.9.38). + + { }); }); +describe("releases found by their commit", () => { + it("reads the version of each release commit, squash-merge suffix or not", () => { + assert.deepEqual( + releaseVersionsInSubjects([ + "fix(core): a change (#1)", + "chore: release v0.9.37 (#7578)", + "chore: release v0.9.36", + "chore: release v0.9.35-alpha.1", + ]), + ["0.9.37", "0.9.36"], + ); + }); + + it("names a release whose tag this clone never fetched", () => { + // The v0.9.38 cut: tags v0.9.32 to v0.9.37 were missing, so describe chose v0.9.31. + const released = releaseVersionsInSubjects(["chore: release v0.9.37 (#7578)"]); + assert.deepEqual(findSkippedReleaseTags(["0.9.31", ...released], "v0.9.31", "0.9.38"), [ + "0.9.37", + ]); + }); +}); + describe("release tags", () => { it("names Release once, even when a commit is scoped to the release itself", () => { const commits = [ diff --git a/scripts/draft-changelog.ts b/scripts/draft-changelog.ts index e8fb84bf63b..078536d0dc8 100644 --- a/scripts/draft-changelog.ts +++ b/scripts/draft-changelog.ts @@ -221,7 +221,7 @@ function resolvePreviousTag(versionTag: string, to: string, version: string) { fail("Could not resolve the previous release tag. Pass --from explicitly."); } // Only guards an auto-resolved baseline; an explicit --from never reaches here. - assertNoSkippedTags(from, version); + assertNoSkippedTags(from, version, ref); return from; } @@ -260,13 +260,27 @@ function listStableTags(): string[] { } } -function assertNoSkippedTags(from: string, version: string) { - const skipped = findSkippedReleaseTags(listStableTags(), from, version); +/** Versions of the `chore: release vX.Y.Z` commits in `subjects`, tagged here or not. */ +export function releaseVersionsInSubjects(subjects: string[]): string[] { + return subjects.flatMap((subject) => { + const match = /^chore: release v(\d+\.\d+\.\d+)(?: \(#\d+\))?$/.exec(subject); + return match ? [match[1]!] : []; + }); +} + +/** Releases whose commit is in `from..ref`, so a clone without their tags still sees them. */ +function listReleasedVersions(from: string, ref: string): string[] { + return releaseVersionsInSubjects(git(["log", "--format=%s", `${from}..${ref}`]).split("\n")); +} + +function assertNoSkippedTags(from: string, version: string, ref: string) { + const known = [...new Set([...listStableTags(), ...listReleasedVersions(from, ref)])]; + const skipped = findSkippedReleaseTags(known, from, version); if (skipped.length === 0) return; const names = skipped.map((tag) => `v${tag}`).join(", "); fail( - `Baseline v${from.replace(/^v/, "")} skips ${names} — tagged locally, but not in this history.\n` + - "Those tags are stale, so the draft would re-list work that already shipped.\n\n" + + `Baseline v${from.replace(/^v/, "")} skips ${names} — released in this history, but the tag is stale or missing here.\n` + + "The draft would re-list work that already shipped.\n\n" + " git fetch origin --tags --force\n\n" + "Then re-run. Pass --from to override when the baseline is deliberate.", );