runner: migrate example installs to pnpm#41
Merged
demtario merged 16 commits intoJul 15, 2026
Merged
Conversation
…andsontable-18 examples: modernize Handsontable 18 examples
b51ae74 to
f4277a3
Compare
The message named only Vue/Angular from when those were the only container-engine examples; it now covers react-js, ant-design, mui, and base-web too, and was masking real session-start errors behind confusing wording.
pnpm (10.33-10.34), unlike npm, does not strip the -- separator when the target script resolves to a real binary — it forwards a literal "--" as the script's first argument. Vite's CLI treats that as "stop parsing options," so --host/--port silently become inert positional args instead of flags, and the dev server never actually binds where the readiness probe expects it (stuck "Booting preview..." forever). Switch react-js/ant-design/mui/base-web/remix to `pnpm exec <bin> <flags>`, matching vue's already-correct invocation.
wrangler.jsonc sets PREVIEW_HOST to demos.handsontable.com unconditionally (vars apply to both wrangler dev and wrangler deploy), a real public wildcard that routes to the deployed worker, not the local one. Container preview sessions started via local wrangler dev were getting a previewUrl on that domain, so the iframe hit prod and got INVALID_TOKEN for a session/token prod never issued. Overriding PREVIEW_HOST="" in .dev.vars falls back to the request host, resolving as *.localhost:8787 (RFC 6761) back to the local worker.
When routes are declared in wrangler.jsonc, wrangler dev simulates the first route's host on every request (request.url and Host both become demos.handsontable.com regardless of the actual request hostname; only the pathname passes through). That destroys the <port>-<sandboxId>-<token>.* preview hostnames the Sandbox SDK's proxyToSandbox() routes by, so Tier-2 local preview could never work — no PREVIEW_HOST value could fix it. There is no config key or CLI flag to disable the simulation (wrangler gates it on inferOriginFromRoutes, which only the programmatic startWorker API can set). Declare no routes in wrangler.jsonc and attach the production routes via `wrangler deploy --routes …` in the deploy script instead. With no routes, wrangler dev passes the real Host through verbatim, so *.localhost:8787 preview URLs (PREVIEW_HOST="localhost:8787" in .dev.vars) flow through the exact same proxyToSandbox() path as production — HTML, assets, and the HMR WebSocket all verified working locally, including two concurrent sessions and token rejection. Also corrects the local-dev docs from the previous commit: an empty-string PREVIEW_HOST override is silently ignored by wrangler; it must be set to a real value, and removing routes from the dev config is the other required half of the recipe. Caveat: the --routes flags cannot carry zone_name; wrangler infers the zone on real deploys (dry-run validated the flags but not inference) — watch the first production deploy.
Records why wrangler.jsonc must not declare routes (wrangler dev simulates the first route's host on every request, destroying the preview hostnames proxyToSandbox routes by), corrects ADR-0011's local-dev claim, and documents the rejected path-based-proxy alternative and the deploy-time zone-inference caveat.
f85528c to
f544a0c
Compare
nuxt's CLI has no -H alias (host is --host/-h), so `nuxt dev -H 0.0.0.0` made citty treat -H as a boolean flag and swallow 0.0.0.0 as the positional rootDir: the dev server served an empty auto-created /app/0.0.0.0 project — Nuxt's default welcome page instead of the demo. Present since the original scaffold (ee4110f) but never observable until local preview started working. Next.js keeps -H; that alias is valid there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On a fresh Tier-2 session's first load, the Remix vite plugin discovers handsontable/plugins, handsontable/cellTypes and @handsontable/react-wrapper one-by-one during hydration; each discovery re-runs the dep optimizer, and the page ends up importing chunks from mixed optimizer generations — two React copies, "Invalid hook call", and a hydration crash (reload recovered, but every new session crashed on first load). Prebundling the three imports keeps the first optimizer pass complete, so first loads are clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
examples/angular had a local .angular/ CLI build cache on disk, and the catalog importer's EXCLUDE_DIRS (.next/.nuxt/.output/.astro/...) did not cover it, so 12 .angular/cache/** files leaked into the angular starter — visible in the authoring editor's file tree and written into every session container. Add .angular and .vite to the exclusions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
019d267 ("chore: Updated pnpm version to latest v10") deleted the runner workspace lockfile, leaving runner installs non-deterministic. The restored file is byte-identical to the pre-deletion version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ba9be44 to
728b940
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 728b940. Configure here.
The angular devCommand in frameworks.json and import-docs.mjs still carried the `pnpm run start -- --flags` pattern this branch documents as broken (pnpm forwards the literal `--`, so --host/--port go inert). Nothing executes devCommand — container sessions run the generated FRAMEWORK_DEV cmd from prepare-container.mjs — but catalog and docs-example metadata shouldn't advertise a known-broken invocation. Flagged by Bugbot on #41. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
budnix
approved these changes
Jul 15, 2026
0b4545d
into
feature/dev-2025-modernize-handsontable-18
1 check passed
Contributor
Author
|
Merged to master in commit |
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.

Task: https://app.clickup.com/t/9015210959/DEV-2025
Summary
Migrates the runner's example installs to pnpm and unbreaks Tier-2 local preview. Diff vs base is runner-scoped only (27 files).
pnpm migration
installCommands switch fromnpm installtopnpm install --frozen-lockfile(config/frameworks.json).pnpm exec <binary> --flagsinstead ofpnpm run dev -- --flags: pnpm (unlike npm) forwards the literal--to the script's binary, which makes Vite's CLI treat--host 0.0.0.0 --port 5173as inert positional args — the dev server bound to the wrong interface and "Booting preview…" hung forever.liveimage: sessions seed immutable bakednode_modulesper framework via hard links (cp -al /baked/<key>/node_modules), then run a fast frozen pnpm reconciliation. A dependency-metadata fingerprint (dependency-metadata.ts) gates fallback: custom package/lock metadata may retry non-frozen; generated starters refuse to mutate their lockfile. This replaces the previous mutable shared dependency cache.Sandbox file-operation hardening
..,node_modules, backslashes, NULs) and validates full file maps before any write; the client runtime normalizes to relative POSIX paths.Tier-2 local preview fixes (previously broken for ALL container frameworks)
routesmoved out ofwrangler.jsoncinto deploy-time--routesflags (pnpm run deploy): with routes declared in config,wrangler devrewrites every request'sHostto the first route's host, destroying the<port>-<sandboxId>-<token>.*preview hostnamesproxyToSandbox()routes by — noPREVIEW_HOSTvalue could fix it. See ADR-0020 (also corrects ADR-0011's local-dev claim).docs/run-and-deploy.md:.dev.varsneedsPREVIEW_HOST="localhost:8787"(empty-string overrides are silently ignored by wrangler).This branch intentionally excludes regenerated artifacts, so
containers/live/Dockerfilehere is still the old npm-based context while the boot script already runs pnpm (Bugbot correctly flagged this). The regenerated contexts (corepack+pnpm Dockerfile, bakedpnpm-lock.yamlfiles,frameworks.generated.ts,catalog.json) live in #42 (feature/runner-pnpm-artifacts, stacked on this branch). Merge order: #42 → this branch → base. Do not deploy from this branch before the artifacts PR merges.Verified locally (end-to-end, with the artifacts branch applied)
wrangler dev; preview URLs (http://5173-<id>-<token>.localhost:8787/) render through the sameproxyToSandbox()path as production.POST /api/session/:id/filehot-update the open page without reload.INVALID_TOKEN).wrangler deploy --routes … --dry-runcompiles with all bindings.Remaining checks
--routesflags can't carryzone_name; wrangler infers the zone at upload (dry-run doesn't exercise this). Errors loudly if inference fails.node scripts/prepare-container.mjs --allregenerates container contexts cleanly🤖 Generated with Claude Code
Note
High Risk
Changes Tier-2 boot, deploy routing, and dependency install paths; production deploy relies on
--routeszone inference and this branch is incomplete without regenerated container artifacts.Overview
Moves the demo runner’s example and container installs from npm to pnpm (
pnpm install --frozen-lockfile), switches Tier-2 dev commands topnpm exec(avoids pnpm forwarding--and breaking--host/--port), and drops per-framework container Dockerfiles in favor of one live image with baked deps plus frozen reconciliation.Tier-2 local preview is fixed by removing
routesfromwrangler.jsoncand attaching them at deploy viapnpm run deploy --routes …(ADR-0020), withPREVIEW_HOST="localhost:8787"documented for.dev.vars. The API validates session file paths and the client sends relative POSIX paths only.Container boot no longer uses the R2 node_modules cache; it seeds
cp -albakednode_modulesand runs pnpm with fingerprint-gated frozen vs non-frozen fallback. Pipeline/import keeps pnpm lockfiles; Remix example gets ViteoptimizeDeps.includefor Handsontable hydration.Note: Regenerated container artifacts (Dockerfile, baked locks,
frameworks.generated.ts) are expected from a stacked PR—do not deploy this branch alone until those land.Reviewed by Cursor Bugbot for commit fc5263c. Bugbot is set up for automated code reviews on this repo. Configure here.