From 6bceeeb284840c5e35f7796898769da45c24b8dd Mon Sep 17 00:00:00 2001 From: sindurigf Date: Tue, 15 Sep 2026 11:03:08 +0200 Subject: [PATCH] Fix: beginner cannot be opened or kept running in a Codespace The level has no vite.config.js, so Vite's host check rejects the forwarded Codespaces domain and the page never loads at all: Blocked request. This host ("shiny-5173.app.github.dev") is not allowed. HTTP 403 Reproduced on current main in a dev container, and fixed and re-verified in the same place: the forwarded host now returns 200, localhost still returns 200, and an unrelated host is still refused, so the check is not switched off. post-start.sh also backgrounded the dev server with a plain `nohup ... &`. On the intermediate level, in a real Codespace, that left the port dead moments after the script printed success and players got a 502 from the forwarded URL. setsid fixed it there. This does not reproduce under the devcontainer CLI, so for beginner it is precaution carried over from that evidence rather than a local reproduction. Two smaller things while here. onAutoForward was openBrowser, the only config in the repo not using notify. And the docs sent players to http://localhost:5173, which does not exist in a browser-based Codespace, where the port is reached from the Ports tab; services now declares port 5173, matching dead-reckoning. No change to the challenge: verify.sh still fails both checks on the broken state, Lighthouse included. Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: sindurigf --- .../devcontainer.json | 2 +- .../post-start.sh | 6 +++++- .../beginner/vite.config.js | 21 +++++++++++++++++++ .../docs/beginner.yaml | 13 ++++++------ 4 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 adventures/accessibility-nightmare/beginner/vite.config.js diff --git a/.devcontainer/accessibility-nightmare_beginner/devcontainer.json b/.devcontainer/accessibility-nightmare_beginner/devcontainer.json index 3f38d11..50d2457 100644 --- a/.devcontainer/accessibility-nightmare_beginner/devcontainer.json +++ b/.devcontainer/accessibility-nightmare_beginner/devcontainer.json @@ -32,7 +32,7 @@ "portsAttributes": { "5173": { "label": "ShopSmart", - "onAutoForward": "openBrowser" + "onAutoForward": "notify" } }, "otherPortsAttributes": { diff --git a/.devcontainer/accessibility-nightmare_beginner/post-start.sh b/.devcontainer/accessibility-nightmare_beginner/post-start.sh index 886029b..d13e344 100755 --- a/.devcontainer/accessibility-nightmare_beginner/post-start.sh +++ b/.devcontainer/accessibility-nightmare_beginner/post-start.sh @@ -12,7 +12,11 @@ LOG_FILE="/tmp/accessibility-nightmare-vite.log" if ! pgrep -f "vite --host 0.0.0.0" >/dev/null 2>&1; then echo "✨ Starting ShopSmart on port 5173" - nohup npm run dev "$LOG_FILE" 2>&1 & + # setsid puts the server in its own session. A plain `nohup ... &` is killed + # when the Codespaces lifecycle command's process group is torn down, which + # leaves the port dead a moment after this script reports success. + setsid nohup npm run dev "$LOG_FILE" 2>&1 & + disown 2>/dev/null || true fi for _ in {1..30}; do diff --git a/adventures/accessibility-nightmare/beginner/vite.config.js b/adventures/accessibility-nightmare/beginner/vite.config.js new file mode 100644 index 0000000..2bc58ef --- /dev/null +++ b/adventures/accessibility-nightmare/beginner/vite.config.js @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite'; + +// In a Codespace the browser reaches the dev server through a forwarded +// hostname, not localhost. Vite rejects unknown Host headers by default, so the +// forwarded domain has to be allowed or the page never loads at all. The +// websocket for hot reload needs the public port too, which only applies there. +const inCodespace = Boolean(process.env.CODESPACES); + +export default defineConfig({ + server: { + host: true, + allowedHosts: ['.app.github.dev'], + ...(inCodespace + ? { hmr: { clientPort: 443, protocol: 'wss' } } + : {}), + }, + preview: { + host: true, + allowedHosts: ['.app.github.dev'], + }, +}); diff --git a/adventures/accessibility-nightmare/docs/beginner.yaml b/adventures/accessibility-nightmare/docs/beginner.yaml index ee6fa6f..3e59470 100644 --- a/adventures/accessibility-nightmare/docs/beginner.yaml +++ b/adventures/accessibility-nightmare/docs/beginner.yaml @@ -96,20 +96,19 @@ toolbox: services: - name: "ShopSmart" - url: "http://localhost:5173" + port: 5173 description: "The intentionally inaccessible React storefront." how_to_play: - id: start title: "Start ShopSmart" content: | - Start the application: + The storefront is already running. Open the **Ports** tab in the editor, + find **ShopSmart** on port 5173, and click the globe icon to open it in a + browser tab. Codespaces serves it from an address ending in + `.app.github.dev`, so there is no localhost to visit. - ```bash - make app - ``` - - Then open port 5173 in your browser. + If it is not running, start it from the level directory with `make app`. - id: explore title: "Explore the Broken Storefront"