diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 75c9d76114..91934a9ad5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -97,8 +97,9 @@ RUN ln -s /usr/local/bin/bun /usr/local/bin/bunx # runner (web/tests/e2e) forks worker processes that require Node — running it # under bun alone hangs the runner. Daily JS tooling (Claude Code, opencode) # still runs under bun; Node is here only as the runtime for the test runner. -# The chromium browser binary is installed at test time (web global-setup), not -# baked here, so its version tracks web/package.json's floating @playwright/test. +# The test runner's chromium binary is installed at test time, not baked here, +# so its version tracks web/package.json's floating @playwright/test (the +# chromium baked further down serves only the pinned Playwright MCP server). # # Copied from the official node image (digest-pinned in the node_source stage at the # top, routed through BASE_IMAGE_REGISTRY) instead of fetched from nodejs.org, so a @@ -115,18 +116,28 @@ RUN ln -s ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ # the web-search open_url tool. The browser binary itself is downloaded # from the integration test conftest's _install_playwright fixture so # the version always matches the lockfile's playwright-python. -# -# Playwright doesn't ship Chromium builds for Ubuntu 26.04 yet, so spoof -# the host platform to the binary-compatible Ubuntu 24.04 build. Arch -# is detected from dpkg so both arm64 CI runners and x64 dev machines -# work; we don't bake the override into ENV because that would leak -# into interactive dev shells where it might mask real problems. RUN apt-get update \ - && PW_ARCH=$(case $(dpkg --print-architecture) in amd64) echo x64;; arm64) echo arm64;; esac) \ - && PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=ubuntu24.04-${PW_ARCH} \ - uvx --quiet --from playwright playwright install-deps chromium \ + && uvx --quiet --from playwright playwright install-deps chromium \ && apt-get clean && rm -rf /var/lib/apt/lists/* +# Give Playwright's browser cache a fixed, user-independent path. The default +# (~/.cache/ms-playwright) would be shadowed by the devcontainer's per-user +# cache volume and differ between root and dev, so revisions baked below would +# be invisible at runtime. Test-time installs (web e2e, the integration +# conftest) land their own revisions alongside the baked one. +ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright + +# Bake the chromium build for the Playwright MCP server. Playwright browser +# builds are revision-coupled to the playwright version that installs them, so +# resolve the exact playwright the pinned MCP bundles and install with that — +# a chromium installed by any other version would not be found. Keep the pin +# in sync with .mcp.json. World-writable so test-time installs run as the dev +# user can add their own revisions next to it. +ARG PLAYWRIGHT_MCP_VERSION=0.0.78 +RUN PW_VERSION=$(npm view "@playwright/mcp@${PLAYWRIGHT_MCP_VERSION}" dependencies.playwright) \ + && npx --yes "playwright@${PW_VERSION}" install chromium \ + && chmod -R 777 /opt/ms-playwright + # Install Python 3.13 via uv into a stable, image-level path so venvs # created in bind-mounted workspaces survive across `docker run`s. ENV UV_PYTHON_INSTALL_DIR=/opt/uv/python diff --git a/.devcontainer/claude-code/CLAUDE.md b/.devcontainer/claude-code/CLAUDE.md index 4616407555..ec440915af 100644 --- a/.devcontainer/claude-code/CLAUDE.md +++ b/.devcontainer/claude-code/CLAUDE.md @@ -33,3 +33,8 @@ In dev mode the frontend proxies `/api/*` straight to the backend (the dev-only handler at `web/src/app/api/[...path]/route.ts`), so **`localhost:3000` serves both the UI and `/api`** — no reverse proxy needed. You can also hit the backend directly at `localhost:8080` (note: **no** `/api` prefix there — e.g. `/health`, `/auth/type`). + +**Stop the dev servers when you're finished with them:** + +- frontend: `pkill -f "next dev"; pkill -f next-server` +- backend: `pkill -f "uvicorn onyx.main:app"` diff --git a/.mcp.json b/.mcp.json index 2254d56f20..3e0da924b6 100644 --- a/.mcp.json +++ b/.mcp.json @@ -2,7 +2,13 @@ "mcpServers": { "playwright": { "command": "npx", - "args": ["@playwright/mcp@0.0.75", "--headless", "--isolated"] + "args": [ + "@playwright/mcp@0.0.78", + "--headless", + "--isolated", + "--browser", + "chromium" + ] }, "agent-wiki": { "type": "http", diff --git a/tools/ods/cmd/web.go b/tools/ods/cmd/web.go index 1cc652bbd2..f987b208b3 100644 --- a/tools/ods/cmd/web.go +++ b/tools/ods/cmd/web.go @@ -1,14 +1,18 @@ package cmd import ( + "crypto/sha256" + "encoding/hex" "encoding/json" "errors" "fmt" + "io/fs" "os" "os/exec" "path/filepath" "sort" "strings" + "time" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -26,7 +30,7 @@ func NewWebCommand() *cobra.Command { Use: "web