Skip to content

feat(studio-bridge): add Linux/Wine support for headless Studio#672

Merged
Quenty merged 40 commits into
feat/studio-bridgefrom
feat/studio-bridge-linux
Apr 24, 2026
Merged

feat(studio-bridge): add Linux/Wine support for headless Studio#672
Quenty merged 40 commits into
feat/studio-bridgefrom
feat/studio-bridge-linux

Conversation

@Quenty
Copy link
Copy Markdown
Owner

@Quenty Quenty commented Mar 2, 2026

Adds Linux/Wine support for running Roblox Studio headlessly, with a pre-built Docker image for fast CI. The linux setup, linux auth, and linux status commands handle Wine + Studio installation, credential injection, and health checks. A nightly Docker build workflow bakes everything into a container image so the E2E workflow starts in seconds instead of re-installing from scratch each run.

Shared auth code (cookie resolution, CSRF handling) moved from nevermore-cli to nevermore-cli-helpers so both CLIs can use it. The process manager gained a Linux/Wine launch path using Xvfb + D3D11 rendering, and the bridge server now syncs dynamic action modules (like execute.luau) to the plugin before first use, fixing UNKNOWN_REQUEST errors on the v2 protocol path.

image

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 2, 2026

Deploy Results

ℹ️ No tests to run

No changed packages with deploy targets were discovered for this PR.

View logs

Test Results

ℹ️ No tests to run

No changed packages with test targets were discovered for this PR.

View logs

@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 045302e to 2073c26 Compare March 2, 2026 19:01
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 2073c26 to cad437e Compare March 2, 2026 20:58
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from cad437e to 6b4733f Compare March 2, 2026 21:04
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 6b4733f to e67f532 Compare March 2, 2026 21:32
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 796ac70 to 0f6ff94 Compare March 2, 2026 21:52
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 0f6ff94 to a6ed2fc Compare March 3, 2026 00:39
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from a6ed2fc to cdf2030 Compare March 3, 2026 00:41
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from cdf2030 to d3d3b04 Compare March 3, 2026 00:55
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from d3d3b04 to 7a03ca0 Compare March 3, 2026 01:44
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 7a03ca0 to 89adb59 Compare March 3, 2026 01:50
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from 89adb59 to c980e52 Compare March 3, 2026 02:00
Adds the linux/ module tree for running Roblox Studio under Wine on
Linux, including virtual display management, shader patching, FFlag
configuration, credential injection, and headless launch. Pre-registers
ExecuteAction in the plugin at boot so execute messages work without
needing registerAction. Accepts empty heartbeat payloads with defaults,
surfaces plugin errors in the script execution listener, and extracts
captured output from scriptComplete responses.
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from c980e52 to f05fcd2 Compare March 3, 2026 02:31
@Quenty Quenty force-pushed the feat/studio-bridge-linux branch from c45ce08 to 23c26b0 Compare March 6, 2026 18:52
The Wine prefix init step starts Xvfb on :99 and kills it, but leaves
/tmp/.X99-lock baked into the image. This causes the entrypoint to
fail when starting Xvfb at runtime. Also adds concurrency groups and
continue-on-error for the cleanup step.
Quenty added 6 commits April 23, 2026 22:37
- Remove branches: [main] restriction so feature branch pushes trigger builds
- Add pull_request trigger for PR-based canary builds
- Include tools/studio-bridge/src/** in paths to catch TS source changes
- Append commit SHA to canary tag for unique versions per commit
- Warn when local Docker image is stale (>7 days old)
Move all authentication code (cookie + API key) into
nevermore-cli-helpers so both CLIs import from one place.

- validateCookieAsync returns typed result instead of process.exit(1)
- fetchWithCsrfAsync captures cookie rotation from set-cookie headers
- Move credential-store.ts from nevermore-cli into helpers package
- Remove re-export shim in nevermore-cli/utils/auth/roblox-auth
Rename auth/roblox-auth/ to auth/cookie/ and auth/credential-store.ts
to auth/open-cloud/credential-store.ts. Makes the two distinct auth
domains clear: cookie (session auth with CSRF, rotation, platform
stores) vs open-cloud (static API key storage).
… 429 retry

- Forward rotated cookie from create response to subsequent rename request
  in createPlaceInUniverseAsync
- Add single retry with backoff on 429 rate limit responses
- Verified against live Roblox API: CSRF exchange, cookie validation,
  and place rename all working
…ials`

The old name was ambiguous — both CLIs had "auth" commands doing
completely different things. The new name describes what it actually
does: inject a .ROBLOSECURITY cookie into Wine's Credential Manager.
Quenty added 2 commits April 23, 2026 23:08
Combines studio-linux-docker-build and studio-linux-e2e into
studio-linux-ci. Build job runs first, E2E uses its output image tag
via needs:, fixing the version tear that caused rojo ENOENT.
Quenty added 14 commits April 24, 2026 00:23
env context is not available in container.image at job level.
GitHub Actions overrides HOME to /github/home, so ~/.wine resolves
to the wrong path. Use $WINEPREFIX instead.
Wine's nsiproxy can't enumerate adapters through Docker's network
namespace, causing DnsResolve failures. Host networking bypasses
Docker's iptables-based DNS proxy so Wine sees real interfaces.
--network host conflicts with GitHub Actions' container networking.
Use --dns to bypass Docker's iptables-based DNS proxy and --cap-add
NET_RAW so Wine's nsiproxy can enumerate network interfaces.
Wine prefix initialized during docker build has stale network config.
Running wineboot -u at runtime re-detects network interfaces so Wine
can resolve DNS in the container's actual network namespace.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant