Feature/self hosted runner#326
Conversation
…index - Ensure FFmpeg processes are cleanly killed before spawning new ones to prevent port conflicts and RTMP server rejections. - Adjust z-index of the offline banner so it displays above video effects but below informational overlays (game, clipper name).
|
The preview deployment for clipify is ready. 🟢 Open Preview | Open Build Logs | Open Application Logs Last updated at: 2026-07-14 16:32:24 CET |
There was a problem hiding this comment.
Code Review
This pull request introduces a self-hosted runner feature for Clipify, enabling users to stream overlays from their own hardware via a compiled runner executable. Key additions include runner management APIs, enrollment and heartbeat polling, a background streaming engine using Puppeteer and FFmpeg, and billing integration for the runner add-on. The review feedback highlights several critical security, performance, and reliability issues. These include a hardcoded encryption secret in production, a lack of rate limiting on the bootstrap endpoint, potential memory issues when downloading binaries, the use of an unreliable in-memory cache in serverless environments, sequential database updates, and potential resource leaks or crashes in the runner engine. Additionally, the reviewer noted missing native keyring assets in the pkg configuration, unhandled HTTP redirects in the updater, overlapping polling requests, and misplaced imports.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| while (Date.now() < expiresAt) { | ||
| await sleep(pollIntervalMs); | ||
| const pollResponse = await fetch(`${apiBase}/api/runner/enroll/poll`, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ deviceCode: enrollment.deviceCode }), | ||
| }); | ||
|
|
There was a problem hiding this comment.
If the network drops or the server is temporarily unreachable during enrollment polling, the fetch call will throw an unhandled exception and crash the runner. Wrap the fetch call in a try/catch block to handle transient network errors gracefully.
while (Date.now() < expiresAt) {
await sleep(pollIntervalMs);
let pollResponse;
try {
pollResponse = await fetch(`${apiBase}/api/runner/enroll/poll`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ deviceCode: enrollment.deviceCode }),
});
} catch (error) {
console.warn("[Enrollment] Network error during polling, retrying...", error);
continue;
}
This pull request introduces a new "runner" build system and related infrastructure for cross-platform streaming support, along with several supporting improvements to the codebase, build scripts, and dependencies. The main focus is to enable building, packaging, and managing a standalone runner executable for Windows, Linux, and macOS, as well as to provide server actions and utilities for managing runners and stream sessions.
The most important changes are:
Runner Build System and Packaging:
scripts/build-runner.tsto bundle the runner withesbuild, compile platform-specific executables usingpkg, sign macOS binaries if possible, set Windows executable icons, and generate hashes for version tracking. Output binaries are placed inpublic/downloads/runner/with a manifest (version.json).DockerfileandDockerfile-previewto install theldidtool for macOS ad-hoc signing, and to build both the app and runner in the build process. [1] [2]package.jsonfor runner development and building (runner:dev,runner:build), and configuredpkgassets for native modules. [1] [2]Server Actions and Stream Session Management:
src/app/actions/runner.tswith server actions for runner creation, deletion, unlinking, stream session upserting, state management, and version manifest retrieval, including entitlement checks and editor access.Testing, Utilities, and Extension Handling:
scripts/stream-test.tsto test RTMP streaming using FFmpeg.scripts/bundle-extension.tsto bundle the Puppeteer extension for use with the runner.puppeteer-streamto allow specifying a custom extension path.Dependency and Test Configuration Updates:
@puppeteer/browsers,puppeteer,puppeteer-stream,fluent-ffmpeg,esbuild,pkg, etc.), and patchedpuppeteer-stream. [1] [2] [3] [4] [5]src/**/__tests__/.