diff --git a/.github/workflows/quest-studio-integration.yml b/.github/workflows/quest-studio-integration.yml new file mode 100644 index 0000000..1ab431b --- /dev/null +++ b/.github/workflows/quest-studio-integration.yml @@ -0,0 +1,60 @@ +name: StreamLink Quest Studio Integration + +on: + pull_request: + branches: [main, iwsdk-streamlink-integration, iwsdk-backend-port] + paths: + - "streamlink-server/quest-competition/**" + - "streamlink-server/Dockerfile" + - "streamlink-server/server.js" + - ".github/workflows/quest-studio-integration.yml" + push: + branches: [iwsdk-streamlink-integration, iwsdk-backend-port, iwsdk-full-quest-experience] + +jobs: + build-quest-studio: + runs-on: ubuntu-latest + defaults: + run: + working-directory: streamlink-server/quest-competition + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm install + - run: npm run typecheck + - run: npm run build + - name: Build the complete StreamLink Docker image + working-directory: streamlink-server + run: docker build -t streamlink-xr-ci . + - name: Smoke-test the Quest route and legacy redirect + working-directory: . + shell: bash + run: | + docker run -d --name streamlink-xr-ci -p 3000:3000 -e PORT=3000 streamlink-xr-ci + trap 'docker rm -f streamlink-xr-ci >/dev/null 2>&1 || true' EXIT + ready=false + for attempt in {1..30}; do + quest_code=$(curl -sS -o /tmp/quest.html -w '%{http_code}' http://localhost:3000/quest/ || true) + if [ "$quest_code" = "200" ]; then ready=true; break; fi + running=$(docker inspect -f '{{.State.Running}}' streamlink-xr-ci 2>/dev/null || echo false) + if [ "$running" != "true" ]; then break; fi + sleep 2 + done + config_code=$(curl -sS -o /tmp/config.js -w '%{http_code}' http://localhost:3000/config.js || true) + platforms_code=$(curl -sS -o /tmp/platforms.json -w '%{http_code}' http://localhost:3000/platforms || true) + legacy_code=$(curl -sS -o /dev/null -w '%{http_code}' --max-redirs 0 http://localhost:3000/app || true) + redirect=$(curl -sSI http://localhost:3000/app 2>/dev/null | awk 'tolower($1)=="location:" {gsub("\\r", "", $2); print $2}' || true) + echo "Quest route: $quest_code; config route: $config_code; platforms route: $platforms_code; legacy route: $legacy_code; redirect: $redirect" + echo "--- StreamLink container logs ---" + docker logs streamlink-xr-ci || true + docker inspect -f 'container state: {{.State.Status}} exit={{.State.ExitCode}}' streamlink-xr-ci || true + test "$ready" = "true" + grep -q 'StreamLink XR' /tmp/quest.html + test "$config_code" = "200" + grep -q '__SUPABASE__' /tmp/config.js + test "$platforms_code" = "200" + grep -q 'youtube' /tmp/platforms.json + test "$legacy_code" = "308" + test "$redirect" = "/quest/" diff --git a/COMPETITION_READINESS.md b/COMPETITION_READINESS.md new file mode 100644 index 0000000..4b0a9bb --- /dev/null +++ b/COMPETITION_READINESS.md @@ -0,0 +1,56 @@ +# Meta VR Start Developer Competition 2026 — StreamLink XR Readiness + +## Eligibility checklist + +The official rules require the entrant (or every team member, where applicable) to: +- Be at least 18 and the age of majority in their jurisdiction. +- Have an active Meta account with Developer Access enabled by submission. +- Have the submitting representative be a member in good standing of Meta VR Start by submission. +- Reside in an eligible location and satisfy the banking / sanctions restrictions in the official rules. +- Submit only one entry as an individual or team representative. + +Kenya is not named among the excluded locations in the competition rules. Entrant eligibility still depends on the individual requirements above. + +Before submission, the entrant must personally confirm: age requirement, Developer Access status, Start membership in good standing, Devpost registration, and correct individual/team representative status. + +## Recommended project positioning + +- Project: StreamLink XR — a hands-first spatial creator studio for controlling and monitoring live broadcasts, with an original in-world VR Arena. +- Track recommendation: Productivity. The primary product is a creator workspace; Arena is an interactive onboarding / engagement mode. The sponsor can reassign track placement. +- Division recommendation: The repository's earliest visible commit is September 28, 2026, which is inside the September 24–November 18 competition window. If no earlier codebase, prototype, early-access build, or published app existed elsewhere before September 24, choose New Experience. If StreamLink or its underlying code existed before September 24, choose Adapted / Significantly Updated Experience; the IWSDK Quest port, hands-first spatial controls, and Arena are substantial competition-window updates. The sponsor makes the final division determination. +- Originality: The core spatial workspace and Arena remain useful without third-party streaming destinations or the AI agent. Those services extend the project; they are not the entire project. + +## Submission requirements + +- A working IWSDK/WebXR URL that judges can open and test; this project is hosted on the existing StreamLink domain. +- A public demonstration video under 3 minutes, showing actual Quest / XR Simulator / equivalent emulator footage. +- Devpost project name, 140-character tagline, track, division, inspiration, implementation approach, future plans, and target launch date. +- For an adapted project, a clear summary of the new competition-window features, with screenshots / changelog / video recommended. +- Describe hands-first interactions and what is exciting about future VR (optional field). +- Keep the project free and accessible through the winner announcement (December 11, 2026). +- Submission deadline: November 18, 2026 at 12:00 PM Pacific (11:00 PM East Africa Time). + +## Technical acceptance checklist + +### Automated checks +- [ ] TypeScript typecheck passes. +- [ ] IWSDK production build passes. +- [ ] Docker image builds with the nested Quest build step. +- [ ] Express serves /quest/ and redirects /app to /quest/. +- [ ] Existing /config.js, Supabase auth, platform credentials, stream APIs, FFmpeg and Socket.IO remain functional. + +### XR / gameplay checks +- [ ] Run the IWSDK development server with `cd streamlink-server/quest-competition && npm install && npm run dev`; use the injected IWER Quest 3 emulator to enter XR and test hands / pointers on desktop. +- [ ] Quest Browser opens the app over HTTPS and enters immersive VR. +- [ ] Hands are available without pairing controllers. +- [ ] Pinch and poke operate every in-world control. +- [ ] Control panel can be grabbed and repositioned. +- [ ] Arena starts, spawns five targets, scores +10 per hit, counts down from 45 seconds, stops cleanly, and can restart. +- [ ] Seated use works within a comfortable reach / narrow field of view. +- [ ] Focus, Comfort and Reset controls work. +- [ ] Start / Stop, quality, destination entry and telemetry are tested end-to-end. +- [ ] Pause / resume and session exit do not leave camera, microphone, stream or timer resources running. +- [ ] Measure frame rate on Quest; target at least 60 FPS. +- [ ] Confirm free, reliable judge access without requiring a developer login or private invitation. + +Important: A successful desktop CI build does not prove headset hand tracking, comfort, frame rate, or end-to-end streaming. Those require XR emulator and/or physical Quest validation. \ No newline at end of file diff --git a/streamlink-server/.dockerignore b/streamlink-server/.dockerignore new file mode 100644 index 0000000..5f46438 --- /dev/null +++ b/streamlink-server/.dockerignore @@ -0,0 +1,7 @@ +# Keep local dependencies and generated assets out of the Docker build context. +node_modules/ +**/node_modules/ +quest-competition/dist/ +public/quest/ +.git/ +*.log diff --git a/streamlink-server/Dockerfile b/streamlink-server/Dockerfile index c4486c5..6994768 100644 --- a/streamlink-server/Dockerfile +++ b/streamlink-server/Dockerfile @@ -1,9 +1,5 @@ -# Portable container for the StreamLink relay backend — works on Render, -# Fly.io, DigitalOcean App Platform, or Railway (Railway accepts Dockerfiles -# too, if you ever come back). Installs ffmpeg at the OS level, which is the -# one thing a plain Node buildpack won't give you for free. - -FROM node:20-slim +# StreamLink XR backend and same-origin IWSDK Quest Studio. +FROM node:22-slim RUN apt-get update \ && apt-get install -y --no-install-recommends ffmpeg \ @@ -16,8 +12,11 @@ RUN npm install --omit=dev COPY . . -# Render (and most platforms) inject PORT at runtime; server.js already -# reads process.env.PORT with a fallback, so nothing to change there. -EXPOSE 3000 +# Build the Quest experience into the Express public directory so /quest +# shares this service's HTTPS origin, auth configuration, and backend APIs. +RUN npm --prefix quest-competition install \ + && npm --prefix quest-competition run typecheck \ + && npm --prefix quest-competition run build +EXPOSE 3000 CMD ["node", "server.js"] diff --git a/streamlink-server/public/index.html b/streamlink-server/public/index.html index 3e9e672..9cddd3f 100644 --- a/streamlink-server/public/index.html +++ b/streamlink-server/public/index.html @@ -79,7 +79,7 @@ Profile Messages Docs - VR room + Quest Studio Account @@ -92,7 +92,7 @@

One control room. Every platform. Control it with both hands or your phone.<
Go live from your phone Gamey - Try it in VR + Try it in VR
@@ -199,7 +199,7 @@

Simple pricing

  • 720p max quality
  • Basic stream health
  • - Start free + Start free
    Studio
    @@ -230,8 +230,8 @@

    Simple pricing

    Ready to run your broadcast from inside it?

    -

    Set up your platforms once. Let the co-pilot handle the rest.

    - Get started +

    Set up your destinations once. Control your creator workspace in Quest.

    + Get started