Run codegen in the browser: the hosted playground - #7
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The dev dashboard was reachable only by installing and running a command. The site now serves the same product at /playground: paste a spec, upload a file, or point at a URL, and the tools it finds land in the same dashboard, each with its generated source and a form that calls the endpoint. - packages/codegen: a new `dev` subpath holds the pieces both hosts need. dashboardState (a pipeline run, shaped for the UI) and buildToolRequest (a tool call, as a real HTTP request) moved out of dev/server.ts, which now imports them. dashboardHtml takes mode: "playground" for the few lines whose meaning depends on where the dashboard runs. - buildToolRequest concatenates a spec server's base path instead of resolving the path against it, which is what generated callApi(...) does. The run-it test and the shipped tool now hit the same URL: /api/v3 used to be dropped. - site: POST /api/playground runs the real pipeline in a temporary directory and returns dashboard state. The browser reads the spec and makes the test calls, so the site is never a proxy into its own network, and the page says where the limits bite (CORS, sessions). - The landing demo and the playground mount through one helper, so the demo cannot drift from the dashboard it advertises. - Tests: the shared state mapping and request planner in the package, the shadow-root mount and page-side bridge in the site (happy-dom). - Regenerated the landing demo data, which had drifted from the generator.
SouravInsights
force-pushed
the
feat/hosted-playground
branch
from
September 18, 2026 09:34
989f129 to
7cf9c17
Compare
Owner
Author
|
Preview notes: the Vercel preview build and the CI verify job both pass on this branch. The preview URL itself sits behind Vercel deployment protection, so it redirects anonymous requests to SSO and answers 401 for /api/playground. To try the flow on the preview, log in to Vercel or run it locally: |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The dev dashboard was reachable only by installing the CLI and running
webmcp-codegen dev. This adds/playgroundto the site: paste an OpenAPI spec, upload a file, or point at a URL, and the tools it finds land in the same dashboard the CLI serves, each with its generated source and a form that calls the endpoint. GraphiQL's move, for WebMCP tools.Three steps, all real code:
POST /api/playgroundwrites the spec to a temp directory, runsrunGeneratewith the realopenapiandtoolsoutputs in dry-run mode, and returns dashboard state. Nothing is written, the temp directory is deleted before the response returns.dashboardHtml(state, { mode: "playground" })mounts in a shadow root, and a small in-page bridge answers the dashboard's three requests:/api/state,/api/override(edits stay in the tab),/api/run(the call leaves from the visitor's browser).Why this shape
The site never fetches a visitor's URL, and never proxies their calls. A demo that fetched any URL a visitor typed would be an open proxy into whatever network the site runs in. Both the spec read and the tool call happen in the browser, so CORS is the only boundary and the page can explain it in one sentence. The cost is real and stated in the UI: an API that refuses cross-origin requests cannot be run from the playground.
One UI, one state mapping, one request planner.
dashboardStateandbuildToolRequestmoved out ofdev/server.tsintodev/state.tsanddev/request.ts, exported together from a new@webmcp-stack/codegen/devsubpath. Both hosts import them, which is what keeps the hosted demo from becoming a lookalike.dashboardHtmlgainedmode: "playground"for the five lines whose meaning depends on where the dashboard runs (edits saved or not, calls server-side or browser-side).A bug this surfaced. The dashboard's run-it test resolved
/pet/{id}against the spec's server withnew URL(path, base), which drops a base path: the Petstore spec shipsservers: ["/api/v3"], so every test call 404'd. GeneratedcallApi(...)concatenates and keeps it. The planner now concatenates too, and a spec loaded from a URL resolves its relative server URLs against its own location (what OpenAPI says a relative server means).Verification
pnpm lint,pnpm typecheck,pnpm test,pnpm buildall pass. Package tests: 240. Site tests: 11 (new).GET https://petstore3.swagger.io/api/v3/pet/findByStatus?status=availableand the real API answers 200 with JSON.site/lib/dashboard-mount.test.ts). happy-dom does not evaluate runtime-appended scripts, so the test runs the script explicitly, with a comment saying why.New test infrastructure (worth a look)
sitehad no test script. This addsvitest.config.ts(happy-dom) and atestscript, following the codegen package's pattern of resolving vitest from the workspace root. Turbo'stesttask now runs the site tests in CI. Happy to drop this if you would rather keep the site test-free.Also in here
site/lib/demo-data.tsregenerated: it had drifted from the generator (legacy box-drawing markers, notitleorconsequentialHint, pre-fetch*helper bodies). The landing demo was showing generated source users no longer get.site/public/demo/so the playground can load the same file the landing demo is built from.docs/notes/2026-09-18-hosted-playground.md. Changeset: minor on@webmcp-stack/codegen(new subpath).Follow-ups, not in this PR
/playgroundis not insitemap.ts(a tool, not a page to rank).