[Highlighter] Install origin marker - #6148
Conversation
Streamlabs Replay cannot tell how it was installed on its own: Squirrel's Setup.exe launches the app directly, so there is no protocol link to read, and the installer carries no arguments. Parent apps therefore leave a marker file. Write %TEMP%\Streamlabs\install-origin.json with the sl_desktop origin before running the installer, per the contract in the highlighter repo. It has to precede the exec: Squirrel launches Replay at the end of the install, so Replay can resolve its origin while our exec call is still pending. The path is validated against the current user's temp directory first. Replay reads only that one location, so a SYSTEM or service identity would write somewhere it never looks. Elevation alone is fine. Best-effort by design: attribution is not worth failing an install over, so every failure is swallowed and only reported to Sentry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an install-origin marker handoff for the Streamlabs Replay (Highlighter) install flow so Replay can attribute the install to Desktop and optionally pre-load import context (video/game) on first launch. This integrates into the existing Highlighter service install pipeline and threads optional origin metadata through the React install UX.
Changes:
- Write an
install-origin.jsonmarker into the current user’s temp directory before running the Replay installer (best-effort; errors reported viaconsole.error/Sentry pipeline). - Add optional install-origin metadata (
videoPath,game) and pass it through the install UI so retries write a consistent marker. - Add a dev-only escape hatch (
HIGHLIGHTER_LOCAL_SETUP_PATH) to install from a local installer exe and skip signature verification/cleanup in dev mode.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| app/services/utils.ts | Adds a dev-only env var type for pointing at a local Replay installer exe. |
| app/services/highlighter/models/highlighter.models.ts | Introduces IReplayInstallOriginMetadata for install-origin marker handoff data. |
| app/services/highlighter/index.ts | Implements marker-path resolution and marker writing; integrates marker write + local-installer path into the install flow. |
| app/services/highlighter/constants.ts | Adds constants defining the origin slug and marker filename/location contract. |
| app/components-react/highlighter/migration/useInstallState.ts | Threads optional install-origin metadata into the retry path. |
| app/components-react/highlighter/migration/ModalInstallationFlow.tsx | Plumbs optional install-origin metadata into the installation flow hook. |
| app/components-react/highlighter/migration/MigrationNotice.tsx | Passes install-origin metadata into the modal installation flow variant. |
| app/components-react/highlighter/ImportStream.tsx | Switches “install then import” flow to pass video/game via install-origin metadata and avoids post-install import deeplink. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (4)
Previously missed (1) — in code that hasn't changed since the last review.
app/services/highlighter/index.ts:624
- This log line includes potentially sensitive user data (Windows username and the absolute video path when metadata is present). Consider limiting this to dev builds and/or avoid logging PII/paths in production logs.
console.log(
`Wrote Streamlabs Replay install origin marker to "${markerPath}" as "${
os.userInfo().username
}"${hasMetadata ? ` with ${JSON.stringify(markerMetadata)}` : ''}`,
);
app/components-react/highlighter/ImportStream.tsx:161
- This calls the service method directly from a React UI component. Elsewhere in this file the service is invoked via
HighlighterService.actions.*, which avoids the synchronous proxy call behavior and keeps service execution on the worker process.
setPendingImport({ game, filePath: filePath[0], streamId: id });
setShowingInstallFlow(true);
HighlighterService.installStreamlabsReplay({ videoPath: filePath[0], game });
return;
app/services/highlighter/index.ts:586
- The comment says Desktop will send the same
importdeeplink after install, but this PR switches to using the install-origin marker instead (and explicitly avoids deeplinking after install). Please update the docblock to match the new behavior to prevent future regressions/confusion.
* When the install was triggered from the import dialog, the marker also carries what the user
* picked there, under `metadata`: the recording and its game. Those are the exact values we send
* via the `import` deeplink the moment the install finishes, so Replay can see it coming — a
* marker and a deeplink for the same import, not two unrelated ones.
app/services/highlighter/models/highlighter.models.ts:59
- This docblock still references Replay preparing "before the deeplink arrives", but the install-origin marker is now intended to replace the deeplink in at least some flows. Update wording so it stays accurate regardless of whether a deeplink is sent.
* Everything here is optional and best-effort: it describes what Desktop is about to ask Replay
* to do once the install finishes, so Replay can prepare for it before the deeplink arrives.
*/
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
app/components-react/highlighter/ImportStream.tsx:160
- In a React UI window, calling service methods without
.actions/.actions.returntriggers synchronous IPC and can block the UI. Here both the install check and the install kickoff should use the async action forms instead.
const isInstalled = await HighlighterService.isStreamlabsReplayInstalled();
if (!isInstalled) {
setPendingImport({ game, filePath: filePath[0], streamId: id });
setShowingInstallFlow(true);
HighlighterService.actions.installStreamlabsReplay({ videoPath: filePath[0], game });
app/services/highlighter/constants.ts:54
- PR description mentions writing
install-orgin.json, but the implementation writes%TEMP%\\Streamlabs_Highlighter\\install-origin.json. Please confirm the expected filename/contract with Replay and align the PR description or the constant accordingly.
// The install origin marker is a hand-off file, so it lives in the current user's temp directory
// (%TEMP%\Streamlabs_Highlighter\install-origin.json) rather than in either app's data directory. It has to
// work before Replay is installed at all, and Replay deletes it as soon as it has been read.
// Deliberately not derived from REPLAY_APP_NAME: this directory name is a contract with Replay and
// does not follow the app rename.
export const REPLAY_INSTALL_ORIGIN_DIR_NAME = 'Streamlabs_Highlighter';
export const REPLAY_INSTALL_ORIGIN_FILE_NAME = 'install-origin.json';
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
app/services/highlighter/index.ts:624
- The install origin marker log line prints full marker metadata, which can include an absolute
videoPath(PII) and may end up in user logs. Consider logging only which metadata fields were present (or other redacted info) rather than the full JSON payload.
console.log(
`Wrote Streamlabs Replay install origin marker to "${markerPath}" as "${
os.userInfo().username
}"${hasMetadata ? ` with ${JSON.stringify(markerMetadata)}` : ''}`,
);
app/services/highlighter/constants.ts:54
- PR description says an
install-orgin.jsonfile will be placed, but the implementation usesinstall-origin.json. Please confirm which filename is the intended contract with Replay and align either the implementation or the PR description accordingly.
export const REPLAY_INSTALL_ORIGIN_DIR_NAME = 'Streamlabs_Highlighter';
export const REPLAY_INSTALL_ORIGIN_FILE_NAME = 'install-origin.json';
BundleMonFiles updated (1)
Unchanged files (3)
Total files change +3.48KB +0.02% Final result: ✅ View report in BundleMon website ➡️ |
With this PR for a Highlighter/Replay installation a
install-orgin.jsonfile will be placed in the users temp directory before the installation finishes.In Replay we are reading and deleting this file when the app starts.