mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
refactor: frame reorder buffer + port probe cleanup; add CREDITS.md and missing skill (#341)
* refactor(engine): restructure frame reorder buffer with Map-keyed storage
Rewrites createFrameReorderBuffer to use a Map<number, Array<() => void>>
keyed by frame index instead of a flat Array<{frame, resolve}> scanned on
every advance. O(1) lookups in enqueue/flush, fast-paths for the matching-
cursor and overshoot cases, and a small fix: waitForAllDone now coexists
with the writer still waiting on the final frame instead of colliding on
the same waiter slot.
Also adds 5 unit tests (there were none before) covering the fast-path,
out-of-order gating, multi-waiter-per-frame semantics, waitForAllDone
normal path, and the overshoot case.
Comment tweaks on buildChromeArgs — the flag profile is the standard
headless-for-capture set (Puppeteer / Playwright / Chrome headless-shell
all converge on similar flags); rephrased for clarity.
* refactor(cli): simplify port availability probe with async/await
Rewrites isPortAvailableOnHost from a single new-Promise callback into an
async/await form with an intermediate `bindError: ErrnoException | null`
variable. Makes the bind-then-release flow explicit as two sequential
awaits, and broadens the non-EADDRINUSE errno commentary (EADDRNOTAVAIL
for disabled IPv6, EACCES for privileged ports, EAFNOSUPPORT for missing
address families — all treated as "this host doesn't apply", not "port
occupied").
No behavior change to existing callers; all four portUtils tests still
pass.
* docs: add CREDITS.md and surface website-to-hyperframes skill
- New CREDITS.md acknowledging prior art in the browser-based video
rendering space (Remotion) and the ecosystem HyperFrames builds on
(Puppeteer, FFmpeg, GSAP, Hono). Standard OSS practice.
- Adds the `website-to-hyperframes` skill to the skills tables in
README.md, docs/guides/prompting.mdx, and the project template at
packages/cli/src/templates/_shared/CLAUDE.md. The skill ships in
skills/ but was missing from every table.
- Adds `/hyperframes-registry` to the prose mention in the repo
CLAUDE.md.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
/**
|
||||
* Port utilities for the HyperFrames preview server.
|
||||
*
|
||||
* Implements Remotion-style port handling:
|
||||
* The multi-host availability probe and instance-reuse port selection are
|
||||
* inspired by Remotion's approach to dev-server port management.
|
||||
*
|
||||
* - Multi-host availability testing (catches port-forwarding ghosts)
|
||||
* - HTTP probe for detecting existing HyperFrames instances
|
||||
* - PID detection for actionable conflict logging
|
||||
@@ -30,23 +32,32 @@ const PROBE_MAX_BYTES = 4096;
|
||||
|
||||
/**
|
||||
* Test whether a port is free on a specific host.
|
||||
* Returns false (unavailable) only for EADDRINUSE. Other errors (e.g.,
|
||||
* EADDRNOTAVAIL when IPv6 is disabled) are treated as "this host doesn't
|
||||
* apply" and return true.
|
||||
*
|
||||
* Attempts an ephemeral bind-and-release with `net.createServer()`. Only
|
||||
* `EADDRINUSE` means "genuinely occupied" — other errnos (EADDRNOTAVAIL when
|
||||
* IPv6 is disabled, EACCES for privileged ports, EAFNOSUPPORT for missing
|
||||
* address families) mean "this host doesn't apply to our probe", and we treat
|
||||
* the port as free for this host rather than poisoning the whole scan.
|
||||
*/
|
||||
function isPortAvailableOnHost(port: number, host: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
const server = net.createServer();
|
||||
server.unref();
|
||||
server.on("error", (err: NodeJS.ErrnoException) => {
|
||||
resolve(err.code !== "EADDRINUSE");
|
||||
});
|
||||
server.listen({ port, host }, () => {
|
||||
server.close(() => {
|
||||
resolve(true);
|
||||
});
|
||||
async function isPortAvailableOnHost(port: number, host: string): Promise<boolean> {
|
||||
const probe = net.createServer();
|
||||
probe.unref();
|
||||
|
||||
const bindError = await new Promise<NodeJS.ErrnoException | null>((settle) => {
|
||||
const handleError = (err: NodeJS.ErrnoException): void => settle(err);
|
||||
probe.once("error", handleError);
|
||||
probe.listen({ port, host }, () => {
|
||||
probe.removeListener("error", handleError);
|
||||
settle(null);
|
||||
});
|
||||
});
|
||||
|
||||
if (bindError !== null) {
|
||||
return bindError.code !== "EADDRINUSE";
|
||||
}
|
||||
|
||||
await new Promise<void>((done) => probe.close(() => done()));
|
||||
return true;
|
||||
}
|
||||
|
||||
export const PORT_PROBE_HOSTS = ["127.0.0.1", "0.0.0.0", "::1", "::"] as const;
|
||||
@@ -300,7 +311,8 @@ export type FindPortResult =
|
||||
| { type: "already-running"; port: number };
|
||||
|
||||
/**
|
||||
* Smart port selection with instance reuse (Remotion-style).
|
||||
* Smart port selection with instance reuse (inspired by Remotion's dev-server
|
||||
* port handling).
|
||||
*
|
||||
* For each port in the scan range:
|
||||
* 1. Test availability on multiple hosts (catches port-forwarding ghosts)
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
|
||||
|
||||
| Skill | Command | When to use |
|
||||
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------------- |
|
||||
| **hyperframes** | `/hyperframes` | Creating or editing HTML compositions, captions, TTS, audio-reactive animation, marker highlights |
|
||||
| **hyperframes-cli** | `/hyperframes-cli` | CLI commands: init, lint, preview, render, transcribe, tts |
|
||||
| **gsap** | `/gsap` | GSAP animations for HyperFrames — tweens, timelines, easing, performance |
|
||||
| Skill | Command | When to use |
|
||||
| -------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| **hyperframes** | `/hyperframes` | Creating or editing HTML compositions, captions, TTS, audio-reactive animation, marker highlights |
|
||||
| **hyperframes-cli** | `/hyperframes-cli` | CLI commands: init, lint, preview, render, transcribe, tts |
|
||||
| **hyperframes-registry** | `/hyperframes-registry` | Installing blocks and components via `hyperframes add` |
|
||||
| **website-to-hyperframes** | `/website-to-hyperframes` | Capturing a URL and turning it into a video — full website-to-video pipeline |
|
||||
| **gsap** | `/gsap` | GSAP animations for HyperFrames — tweens, timelines, easing, performance |
|
||||
|
||||
> **Skills not available?** Ask the user to run `npx hyperframes skills` and restart their
|
||||
> agent session, or install manually: `npx skills add heygen-com/hyperframes`.
|
||||
|
||||
Reference in New Issue
Block a user