Bring create-launchpad-app into the repo, with framework selection - #152
Open
PaulBratslavsky wants to merge 12 commits into
Open
Bring create-launchpad-app into the repo, with framework selection#152PaulBratslavsky wants to merge 12 commits into
PaulBratslavsky wants to merge 12 commits into
Conversation
The CLI scaffolds this repo and offers a --framework flag, so it carries its own copy of the frontend list: names, ports and dev scripts. It has to be a copy, because the CLI runs before the repo is cloned. Kept in a separate repo, that copy drifts silently. Rename a frontend or change a port here and the CLI keeps offering the old one, then checks the wrong port or calls a dev script that no longer exists — a failure the user hits, not us. In-repo, a test can read the real sources. cli/test/registry-matches-launchpad.test.js checks the CLI's registry against scripts/frontends.mts, the root package.json scripts and the frontend directories themselves. Verified it catches drift: changing astro's port in the CLI fails with "CLI says port 9999, scripts/frontends.mts says 4321". cli/ uses npm rather than yarn. It is published to npm separately and is not part of the yarn setup that installs the frontends, so `yarn cli` and `yarn test:cli` install its dependencies on demand — both work from a fresh clone with no extra step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZNfEU8h231jo1hu7kcviZ
The prompt listed all four frontends regardless of which ref was being
cloned, so choosing Astro against main got you an error explaining that
Astro is not there. Offering a choice and then refusing it is worse than
not offering it.
The clone now happens first and the prompt is built from the frontend
directories found in it. Against main that is next alone, so the prompt is
skipped entirely rather than showing a one-item menu. Against a ref with
all four, all four are offered.
--framework is validated against the same list, and distinguishes a
frontend that exists but is missing from this ref ("try --ref ...") from a
name that is not a frontend at all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZNfEU8h231jo1hu7kcviZ
Three problems, all found by running it. The picker was skipped whenever the clone held a single frontend, which on LaunchPad's default branch is always. Running with no flags chose Next silently and never showed the menu. It now always lists all four. Choosing a frontend that is not on the default branch used to fail with an error telling you to pass --ref. The ref is now derived from the choice: astro, nuxt and tanstack fetch feat/tanstack-frontend and say so, next takes the default branch, and an explicit --ref still wins. `needsRef` in src/frameworks.js carries a note to delete it once the multi-frontend PR merges. The post-clone check stays as a safety net for a stale --ref or a renamed directory. The clone spinner sat motionless for the ~19 seconds LaunchPad's 54MB takes to fetch, which reads as a hang. It now counts elapsed seconds and says what it is waiting for. git's own --progress was tried first and reverted: it emits thousands of carriage-return updates that do not collapse when stdout is not a TTY, which is worse than no feedback at all. Adds --repo, taking a fork URL or a local path. git clones from a path, so testing needs neither the network nor a pushed branch; local sources are rewritten to file:// so --depth still applies. Verified by scaffolding from a local checkout — the clone becomes instant and only yarn install costs time. Checked all four end to end: each resolves to its own dev script and port, next/dev/3000 through tanstack/dev:tanstack/3002. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZNfEU8h231jo1hu7kcviZ
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Scaffolding with --framework astro left CLIENT_URL at http://localhost:3000, so the Preview button in the Strapi admin opened Next while the site being worked on was Astro on 4321. `yarn setup` propagates the shared PREVIEW_SECRET to every frontend but leaves CLIENT_URL alone, because it cannot know which frontend you intend to run. `yarn use <framework>` is the command that sets it, and the CLI knows the answer, so it now runs it after setup. PREVIEW_SECRET was already correct — verified identical across strapi and all four frontends. Only the URL was wrong. Verified per frontend: next 3000, astro 4321, nuxt 3001, tanstack 3002. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZNfEU8h231jo1hu7kcviZ
The port check only ran when the CLI was about to start the servers, so
scaffolding with --no-start said nothing about a conflict. It also did not
work.
`isPortAvailable` bound a socket to decide, with no host. Node then listens
on IPv6 `::`, which on macOS does not collide with Strapi's IPv4 `0.0.0.0`,
so an occupied port reported as free. Astro is worse: it binds `[::1]`
specifically, and on BSD a wildcard bind coexists with a loopback one. No
bind probe covers every combination, so it connects instead — if something
accepts, the port is taken, whatever it bound to. Verified against a live
Strapi and Astro, which both used to report free.
The check now runs as soon as the frontend is known, before cloning, and
reports which directory holds each port. Two LaunchPad checkouts is the
case worth naming: the second one answers on the right port with its own
PREVIEW_SECRET, so the admin's preview fails with "Invalid token" and
nothing points at a port conflict. That is exactly how this was found.
⚠ Port 4321 (Astro) is already in use.
held by: /Users/paul/Desktop/lp-cli-test/my-app/astro
Before starting it stays a hard failure; up front it is a warning, since
--no-start means nothing is about to bind anything.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XZNfEU8h231jo1hu7kcviZ
astro, nuxt and tanstack are on the default branch, so the CLI no longer needs to send those choices to feat/tanstack-frontend. Removes MULTI_FRONTEND_REF, needsRef and resolveRef, along with the notice explaining which branch was being used and why. --ref stays, for forks and for pinning a tag. Verified against a plain clone of main with no flags: all four frontends present, CLIENT_URL on the chosen frontend's port, PREVIEW_SECRET matching between Strapi and that frontend. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
PaulBratslavsky
marked this pull request as ready for review
September 9, 2026 15:38
create-launchpad-app is already published by someone else — an unrelated package, currently at 1.0.38. The README told people to run `npx create-launchpad-app`, which would have installed that instead of this. The name was never available to take. create-strapi-launchpad is free, and says whose LaunchPad it scaffolds. `npm create strapi-launchpad` works as the shorthand. The bin is renamed to match, along with the help examples, both READMEs and AGENTS.md. Verified the way a user gets it rather than through npm link: packed the tarball, installed it globally, ran it from an unrelated directory. Nine files ship, no tests or node_modules among them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
1.0.0 claims a stable interface. The flags are a day old and have already changed twice — --package-manager was removed, and the picker was rebuilt after it turned out to be offering frontends the clone did not have. 0.x says that plainly and leaves room to keep changing them. npm versions cannot be reused once published, so this is worth getting right before the first publish rather than after. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
`yarn dev` is Next for every scaffold, so someone who chose Nuxt and typed
the obvious command gets the wrong frontend. Rather than change what `dev`
means — which would break it for existing contributors — the CLI now prints
the frontend-specific command before the dev servers take over the
terminal:
To restart later: cd my-app && yarn dev:nuxt
It goes before the servers start because their output scrolls past
immediately, and this is what people need after the first Ctrl+C. The
--no-start path already ended with it.
Also corrects a claim repeated in four places: that Corepack refuses npm
because the root package.json pins yarn@4.5.0. It does not. `npm install`
and `npm run dev` both work here; `packageManager` constrains which yarn or
pnpm Corepack shims in, not whether npm may run.
The real reason the CLI drives yarn is duller and true: every directory
ships a yarn.lock and its scripts shell out to yarn. Removing
--package-manager was still right, but for the reason that was actually
tested — `npm setup`, `npm seed` and `npm dev` are all "Unknown command",
since npm accepts bare names only for its own built-ins.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
The command is already shown before the servers start, but by then it is
long gone: a real run buries it under about 280 lines of server output. The
moment it is wanted is right after Ctrl+C, so it now has the last word.
ℹ Stopped.
Restart: cd q2 && yarn dev:astro
Other frontends: yarn dev (Next.js), yarn dev:nuxt, yarn dev:tanstack
`yarn dev` is named as Next explicitly. It is the command people reach for,
and in a scaffold built for another frontend it quietly starts the wrong
one — better said out loud than discovered.
Needs an explicit SIGINT handler. Ctrl+C signals the whole process group, so
Node tears the process down before anything after the await runs. The first
version relied on that and printed nothing, which only showed up by sending
a real SIGINT rather than reading the code. SIGTERM is handled the same way,
and a flag keeps it to once if both the signal and the await fire.
`yarn dev` in the repo and in every scaffold is untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
Two user-facing changes since 0.1.0: - The restart command is printed when the dev servers stop, not only before they start, where about 280 lines of server output bury it. - Corrects the claim that Corepack refuses npm here. It does not; the CLI drives yarn because every LaunchPad directory ships a yarn.lock and its scripts call yarn. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GQSJu9Etpa6qjCny1CPWcc
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.
Moves the
create-launchpad-appCLI into this repository and teaches it toscaffold any of the four frontends.
It asks which frontend you want, then clones, installs, seeds and starts it.
--framework astroskips the question.Draft for review — please do not merge yet.
Why it belongs here
The CLI offers a
--frameworkflag, so it carries its own copy of the frontendlist: names, ports and dev scripts. It has to be a copy, because the CLI runs
before the repo is cloned.
Kept in a separate repository, that copy drifts silently. Rename a frontend or
change a port here and the CLI keeps offering the old one, then checks the
wrong port or calls a dev script that no longer exists — a failure the user
hits, not us.
In-repo, a test can read the real sources.
cli/test/registry-matches-launchpad.test.jschecks the CLI's registry against
scripts/frontends.mts, the rootpackage.jsonscripts and the frontend directories themselves. It is notvacuous — changing astro's port in the CLI fails with:
Bugs fixed along the way
--package-manager npmcould not work, and is removed.npm setupis not avalid npm command — nor are
npm seedornpm dev, which the flag also ran.Each needed
npm run. The flag never worked, so nobody can be relying on it.(An earlier version of this description also claimed Corepack refuses npm here
because the root
package.jsonpinsyarn@4.5.0. That is wrong:npm installand
npm run devboth work fine.packageManagerconstrains which yarn orpnpm Corepack shims in, not whether npm may run. The invalid commands are the
whole reason.)
Also: the port check was hardcoded to 1337/3000 and would have checked the wrong
port for every frontend but Next;
--no-startprintedyarn devregardless ofthe frontend chosen; the version was written out in both
package.jsonandcli.js;TOTAL_STEPSwas a constant while the steps were already conditional;the Node floor was 18, but Nuxt 4 and Astro 6 need 20.19; and the clone stripped
.gitwithout ever runninggit init, leaving the project untracked.Flags
-f, --framework <name>-r, --ref <ref>--repo <url|path>--dry-run--no-seed,--no-start,--no-git--repotakes a path as well as a URL, so testing needs neither the network nora pushed branch — local sources are rewritten to
file://so--depthstillapplies.
One temporary piece to delete on merge
needsRefincli/src/frameworks.jsmakes astro, nuxt and tanstack clonefeat/tanstack-frontend, since they are not on the default branch yet. Itcarries a comment saying to remove it once #150 merges. Until then the picker
can still offer all four and each one works.
Stacking
Targets
feat/tanstack-frontend(#150), because the CLI configures thefrontends that PR adds. Merge #150 first — GitHub will retarget this to
mainautomatically.Verification
10 tests pass. Scaffolded end to end from both GitHub and a local checkout: four
frontends cloned, a git repo initialized with a 563-file commit,
.envfileswritten, dependencies installed. All four resolve to their own dev script and
port,
next/dev/3000 throughtanstack/dev:tanstack/3002.npm packships9 files.
🤖 Generated with Claude Code