feat: npx-first scaffold UX (create-webjs + webjsdev + auto-install)#72
Merged
Conversation
`webjs create <name>` now runs `<pm> install` inside the new directory by default. Pass `--no-install` to opt out and get the prior behaviour (scaffold only, print manual install in the next-steps banner). The package manager is detected from `npm_config_user_agent`, so pnpm / yarn / bun users get their own. The `<pm> run dev` and prisma-migrate lines in the next-steps banner adapt to the detected PM too. Library-level (`scaffoldApp(...)`) default stays opt-in (`install: true` required) so tests and programmatic callers remain side-effect-free. The CLI entry point flips that default by passing `install: !noInstall`.
Mirror of the create-next-app / create-react-app convention. Users can now scaffold a webjs app without globally installing @webjsdev/cli: npx create-webjs-app@latest my-app npx create-webjs-app@latest my-api --template api npx create-webjs-app@latest my-saas --template saas Under the hood, create-webjs-app depends on @webjsdev/cli and dispatches to its scaffoldApp() function (~60-line wrapper). Behaviour matches `webjs create` exactly, including the auto-install added in the prior commit. Pass `--no-install` to skip. Release-workflow plumbing: - scripts/backfill-changelog.js: introduce an UNSCOPED set and an npmName(pkg) helper so unscoped packages (create-webjs-app, wjs) get a bare `package: "<name>"` frontmatter line, while scoped packages keep `package: "@webjsdev/<name>"`. Update log lines + the emitted frontmatter to use the helper. - scripts/publish-release.js: derive the GitHub Release title from whether the original frontmatter had a scope. Scoped: "@webjsdev/<pkg> <version>". Unscoped: "<pkg> <version>". Tag stays "<pkg>@<version>" in both cases. publish-npm.js needs no change; it already passes the frontmatter's package name through to `npm publish --workspace=<name>`, which npm resolves by the workspace's package.json name field. publish-github-packages.js skips non-@webjsdev/ packages cleanly, so unscoped names just don't go to GitHub Packages (as intended). The package's initial changelog/create-webjs-app/0.1.0.md is hand- written rather than backfill-generated, since the backfill script needs git history of `packages/<pkg>/package.json` version bumps, and a brand-new package has none.
`wjs` is a tiny standalone npm package whose `bin.wjs` is a 1-line ESM re-export of `@webjsdev/cli/bin/webjs.js`. Importing the CLI's entry script transparently dispatches the same command, so `wjs <cmd>` and `webjs <cmd>` behave identically, with no argv manipulation or spawn overhead. npx wjs create my-app npx wjs dev npx wjs test npm i -g wjs && wjs check The point is discoverability + fewer keystrokes. `create-webjs-app` covers the "I want to start a new project" muscle memory (matching `create-next-app` / `create-react-app`), and `wjs` covers all the in-project commands (`dev`, `start`, `test`, `check`, `db`, `ui`) that the long `@webjsdev/cli` install would otherwise expose as `webjs <cmd>`. The two packages overlap only on `create`, by design. `packages/wjs/` is registered as a workspace via the existing `packages/*` glob in the root package.json. Its initial changelog is hand-written for the same reason as create-webjs-app's: backfill needs prior git history of `packages/<pkg>/package.json` bumps, which a brand-new package doesn't have. @webjsdev/cli's bin map intentionally stays as just `webjs` for v1. If users want both binaries on PATH globally, install both packages (`npm i -g @webjsdev/cli wjs`). Adding `wjs` to the cli's bin map can land in a follow-up patch once we see how usage settles.
webjs create (and the new create-webjs-app) now auto-install deps in the new directory, so every quickstart that showed `cd <name> && npm install && npm run dev` had a redundant step. Six files updated: - README.md: hero scaffold block. - docs/app/docs/getting-started/page.ts: "Run it" example. - docs/app/docs/conventions/page.ts: webjs create section. - packages/cli/AGENTS.md: end-to-end scaffold smoke-test recipe. - packages/cli/README.md: global + npx install examples; also adds the create-webjs-app entry point as the preferred no-global path. - website/app/page.ts: homepage install block. The "install once" line (`npm i -g @webjsdev/cli`) is intentionally left in place. That's a separate decision (global CLI vs npx-only) covered in the upcoming homepage-hero PR once create-webjs-app is live on npm.
`webjs create` (and create-webjs-app, which dispatches here) now prints the next step as one chainable shell line, so users can paste it directly instead of assembling pieces from a multi-line list: cd my-app && npm run dev # default cd my-app && npm install && npm run dev # --no-install cd my-saas && npx prisma migrate dev --name init && npm run dev # saas cd my-saas && npm install && npx prisma ... && npm run dev # saas + --no-install cd my-app && pnpm run dev # pnpm user cd my-app && pnpm install && pnpm run dev # pnpm user + --no-install The four segments compose: cd <name> && [<pm> install && ] [npx prisma migrate ... && ] <pm> run dev The `[<pm> install && ]` segment is empty when auto-install already ran (the default). It only appears when the user passed --no-install or the install step failed. The prisma segment only appears for the saas template (it has a required User model that wants the table to exist before first dev-server boot). `npx webjs ui add <name>` is demoted to a single "Optional:" line below the main next-step. The AI-driven-development banner stays unchanged below.
…-points The repo-layout block in README.md now visually separates the framework packages (core, server, cli, ts-plugin, ui) from the scaffold entry-point peers (create-webjs-app, wjs). Reader gets the grouping without us having to physically nest those peers under packages/cli/packages/, which would force backfill-changelog.js to walk multiple roots and would obscure the published-npm-package inventory that the top-level packages/ list naturally surfaces. Also adds the missing ts-plugin, ui, and website entries that were already in the repo but unlisted.
Matches the convention every modern framework's marketing site follows: `npx create-next-app@latest`, `npx remix@next new`, `npm create vite@latest`, `npx create-astro@latest`. One command, no global install, scaffold + auto-install + ready-to-run. Two surfaces updated: - website/app/page.ts (the landing-page install block): hero is now `npx create-webjs-app@latest my-app`, with the SaaS and api template variants shown directly underneath. The global-install path stays visible at the bottom as a single line for users who want repeated `webjs <cmd>` use across many projects. - README.md (Quickstart section): same restructure. Lead with npx, demote global install to "with the CLI installed globally for repeated use". `create-webjs-app` is published to npm by the existing auto-release workflow on push to main, so the homepage command works minutes after this PR merges. The brief window between merge and npm publish is the same race we accept for every framework-package release.
The headline stays `npx create-webjs-app@latest my-app`. The secondary "install the CLI globally for repeated use" line drops from `npm i -g @webjsdev/cli && webjs create my-app` to `npm i -g wjs && wjs create my-app`. Three fewer characters per invocation in the daily flow, binary name matches the package name (less cognitive load), and `wjs` pulls `@webjsdev/cli` along as a transitive dep so all subcommands still work. Users who want the long-form `webjs` binary on PATH can still `npm i -g @webjsdev/cli` directly; that path stays documented in the `wjs` and `@webjsdev/cli` package READMEs.
`npm i -g wjs` now installs two symlinks (`wjs` short, `webjs` canonical). Both point at the same shim, which delegates to `@webjsdev/cli`'s entry script, so behaviour is identical. Homepage + README's global-install line uses `webjs create my-app` post-install to match the canonical name that scaffold scripts / AGENTS.md / agent configs already use. The short `wjs` form stays available for keystroke-conscious users. Note: `@webjsdev/cli` continues to ship `webjs` as its own bin too. If a user installs both packages globally, npm picks one symlink for the colliding name; both implementations run the same script, so the choice is harmless.
Adds `"wjs": "bin/webjs.js"` to the @webjsdev/cli bin map alongside the existing `"webjs"` entry, so `npm i -g @webjsdev/cli` now puts both commands on PATH from a single install. Same script either way, so behaviour is identical between `webjs <cmd>` and `wjs <cmd>`. Mirrors what the standalone `wjs` package now does (its package.json also declares both `wjs` and `webjs` bins). End state: either global-install path puts both names on PATH, no two-step setup required. Bumps @webjsdev/cli from 0.8.1 to 0.8.2 (minor feature: new bin alias, no breaking change).
The previous wording promoted the "what happens if both packages are installed globally" edge case to first-class doc material. In practice nobody intentionally installs both: each package already provides both `wjs` and `webjs` bins from a single install. The only realistic ways to end up with both globally are accidental. Rewrite the wjs README + the wjs 0.1.0 + cli 0.8.2 changelog bodies to describe only the actual feature: one install gives both names on PATH. Drop the "if both are installed, the symlink collision is harmless" language, since that's a non-scenario users shouldn't have to think about. The behaviour-if-collided is still harmless (both bin entries point at scripts that resolve to the same @webjsdev/cli entry point), so there's no regression risk in not documenting it.
Invariant 9 violation in `f4c1d7b`: I put backticks around `wjs` and `webjs` inside the install-block <span class="comment"> on the homepage. That span sits inside the outer html`...` template literal in app/page.ts, so the embedded backticks close the literal at JS-parse time. Result: 500 at localhost:5000 with "Expected ';', got 'ident'". Replace the backticked terms with plain text: before: gives you both `wjs` and `webjs` after: gives you both wjs and webjs commands The other backticks in this file (lines 27 / 30) live inside single- quoted strings in the FEATURES array, where backticks are just plain characters, so they're fine.
The scaffold's own "Next steps:" banner already prints `cd my-app && npm run dev` and the localhost hint after a successful `npx create-webjs-app@latest my-app` (added in the auto-install commit earlier on this branch). Repeating those lines on the homepage adds noise without adding information. After this, the install block leads with the headline npx command and goes straight to the template variants + the optional global install. Users see the next step from the command's own output.
New <copy-cmd> component (`website/components/copy-cmd.ts`) wraps each shell-command line in the homepage install block. Whole component is the click target: clicking the text OR the icon both copy the trimmed text via navigator.clipboard.writeText, and the icon flips to a check mark for 1.5s. Enter / Space on the keyboard does the same. UX details: - `cursor: copy` (not the generic pointer hand) so the platform's native "this click will copy" cursor renders over the whole component. Semantically more accurate. - Copy button is opacity 0 by default and animates to opacity 1 on :hover or :focus-visible of the host. Subtle hint, doesn't compete with the command text when not hovered. - Light DOM with framework <slot> projection. Class selectors are tag-prefixed per invariant 7 (`copy-cmd .copy-cmd-text`, `copy-cmd .copy-cmd-btn`). - The inner <button> is aria-hidden + tabindex=-1 because the host itself carries role="button" / tabindex="0" / aria-label. One focusable target, one keyboard activation per command. Install-block restructure: replaced the inline `<span class="cmd">...</span><br>` pattern with block-level `<copy-cmd>...</copy-cmd>` per command, plus `<div class="install-gap">` spacers for vertical breathing room between groups. Block layout drops the explicit `<br>`s.
Two related fixes for the new <copy-cmd> component: 1. Drop the imperative `setAttribute` / `classList.add` / `addEventListener` calls in connectedCallback. The lit-parity convention (and the webjs convention by extension) is to drive everything from render(): host attrs are HTML attributes in the template, classes are class= strings, events are @click / @keydown bindings. The custom-element host now wraps a single <span role="button"> that carries all the attrs / classes / handlers. connectedCallback is gone; only disconnectedCallback stays to clear the auto-reset timer. 2. Drop the ~40 lines of custom CSS I added to page.ts for `copy-cmd` / `.copy-cmd-text` / `.copy-cmd-btn` / `.install-gap`. Everything moves to Tailwind utilities on the rendered elements (consistent with how theme-toggle is styled in the same site). `group` + `group-hover:opacity-100` / `group-focus-visible:opacity-100` gives the hover-revealed button without any handwritten CSS. The inter-group spacer in the install block becomes `<div class="h-3">` instead of `<div class="install-gap">`. The `cursor: copy` style applies via an inline style on the wrapper (Tailwind v3 doesn't ship a `cursor-copy` utility out of the box, and the website's @theme config doesn't extend it).
npm 403'd `npm publish` for `wjs` with "too similar to existing packages w-js, w.js". The name's effectively unavailable past the typosquatting filter, no matter the tombstone state. Rename the standalone alias package from `wjs` to `webjsdev`. The new name matches the @webjsdev npm org, reads as the canonical brand, and clears npm's similarity check (8 chars vs 3-char short names that hit the filter). The new `webjsdev` package declares three bin entries from one install: `webjsdev`, `webjs`, and `wjs`. So: npx webjsdev create my-app # one-shot scaffolding npm i -g webjsdev # global: all 3 commands on PATH webjs dev / wjs dev / webjsdev dev # all identical, same script Files renamed (git mv, history preserved): - packages/wjs/ → packages/webjsdev/ - packages/wjs/bin/wjs.js → packages/webjsdev/bin/webjsdev.js - changelog/wjs/0.1.0.md → changelog/webjsdev/0.1.0.md Files content-updated: - packages/webjsdev/package.json: name, description, bin map (now 3 entries), repository.directory, dep bump to @webjsdev/cli@^0.8.2 (the already-published version with the wjs bin alias). - packages/webjsdev/README.md: rewritten around the 3-command install. - changelog/webjsdev/0.1.0.md: package field, rewritten body that also notes why the name changed. - scripts/backfill-changelog.js: PACKAGES + UNSCOPED entries `wjs` → `webjsdev`. - README.md + website/app/page.ts: homepage hero global-install line `npm i -g wjs` → `npm i -g webjsdev`, with updated commentary. The `wjs` bin alias inside @webjsdev/cli (added in 0.8.2, already published) stays as-is. That's why `npm i -g @webjsdev/cli` ALSO puts both `wjs` and `webjs` on PATH; users who pick that install path don't need webjsdev. webjsdev exists primarily to power `npx webjsdev <cmd>` for the one-shot npx flow.
Both packages now ship a single `webjs` bin. The wjs / webjsdev command-name aliases briefly introduced in cli 0.8.2 and webjsdev 0.1.0 are removed. Why: - Only one command name (`webjs`) is the canonical user-facing interface. Documentation, scaffold scripts, AI-agent configs, and every code reference already settled on it. - create-webjs-app already covers the "npx-discoverable scaffolder" use case for first-time users (the only place where a short alias matters for keystrokes). - The webjsdev package keeps existing as the unscoped npm name (so `npm i -g webjsdev` works without typing the @webjsdev/ scope), but it ships the same `webjs` bin as @webjsdev/cli, no extra command names. @webjsdev/cli 0.8.2 stays on the registry as a transitional version (its bin map had both `webjs` and `wjs`). Same for webjsdev 0.1.0 (had `webjsdev` + `webjs` + `wjs`). Users on those versions need to switch any `wjs <cmd>` / `webjsdev <cmd>` calls to `webjs <cmd>`; behaviour is identical, only the command name changes. After merge + publish, the user will manually `npm deprecate` 0.8.2 and 0.1.0 to nudge installers onto the new versions. scripts/backfill-changelog.js stays unchanged (the UNSCOPED helper still applies to webjsdev). README.md, website/app/page.ts, and packages/webjsdev/README.md copy updates land in the next commit.
Follow-up to the bin-map narrowing in the previous commit. Updates the three user-facing surfaces that referenced the now-removed `wjs` / `webjsdev` command names: - packages/webjsdev/README.md: rewrite as "the webjs CLI under an unscoped npm name", drop the multi-command example. - README.md: homepage hero comment now reads "webjsdev is the unscoped npm name for @webjsdev/cli; both install the webjs command" instead of the prior "three commands" framing. - website/app/page.ts: same comment swap on the homepage install block. The copy-cmd line still says `npm i -g webjsdev && webjs create my-app`, which is exactly what the new single-bin shape supports.
… publish-release comment Three loose references to the dropped `wjs` command name: - packages/webjsdev/bin/webjsdev.js: JSDoc block was framed around `wjs` as the alias. Rewrite around webjsdev as "the unscoped npm name for @webjsdev/cli". - README.md `## Repo layout`: the bullet under scaffold entry points still said `wjs/ # wjs <cmd> short alias for the @webjsdev/cli webjs binary`. Update to reflect the renamed package and its single-bin shape. - scripts/publish-release.js: an inline comment listing the unscoped packages still said "create-webjs-app, wjs". Swap wjs → webjsdev. `git ls-files | xargs grep -lE '\bwjs\b'` outside changelog/ now returns nothing. Changelog files (changelog/cli/0.8.2.md, changelog/webjsdev/0.1.0.md, changelog/cli/0.8.3.md, changelog/webjsdev/0.1.1.md) intentionally keep the historical `wjs` references that explain the rename / revert path. Per the "never edit published changelog entries" rule, 0.8.2 and 0.1.0 stay sealed; the 0.8.3 and 0.1.1 entries call out the migration.
Previously `webjs create` printed (in this order): 1. File tree 2. npm install output 3. Next steps + run command ← actionable, gets buried 4. AI-driven development banner 5. For-AI-agents bullet list The AI guidance (sections 4 + 5) is ~25 lines of reading material that pushes the actionable `cd <name> && <pm> run dev` line off the visible terminal. The user has to scroll back to find it. New order: 1. File tree 2. AI guidance (long, reads in advance) 3. npm install output 4. Next steps + run command ← LAST, final thing on screen The reorder is implemented by splitting the previously-combined console.log into two: the AI-guidance block prints before runInstall(), and a smaller next-steps block prints after. No content removed; same total information, repositioned. Bumps @webjsdev/cli to 0.8.4. webjsdev re-export needs no bump since its semver range (`@webjsdev/cli: ^0.8.2`) picks up the new version transitively.
Two reasons to rename: 1. `npm create <suffix>` is npm's documented shorthand for `npx create-<suffix>`. With the suffix as `webjs-app`, the homepage hero reads `npm create webjs-app@latest my-app`, which is awkward (the `-app` suffix is redundant alongside the package name `my-app`). Renaming to `create-webjs` lets the hero read as `npm create webjs@latest my-app`, matching Astro's `npm create astro@latest` exactly. 2. The shorter name removes a redundancy. The `-app` in `create-webjs-app` was inherited from the create-next-app precedent, but Astro / Vite / Remix / SvelteKit have all moved to the shorter `create-<framework>` form (`create-astro`, `create-vite`, `create-remix`, `create-svelte`). Joining that newer convention. Files renamed (git mv, history preserved): - packages/create-webjs-app/ → packages/create-webjs/ - packages/create-webjs/bin/create-webjs-app.js → packages/create-webjs/bin/create-webjs.js - changelog/create-webjs-app/0.1.0.md → changelog/create-webjs/0.1.0.md Files content-updated: - packages/create-webjs/package.json: name, bin map, repository.directory, description, dep bump to @webjsdev/cli@^0.8.4 (the current published version with the reorder). - packages/create-webjs/bin/create-webjs.js: rewrite around the `npm create webjs@latest <name>` hero, document the `--` pass-through separator for flags. - packages/create-webjs/README.md: rewrite around `npm create webjs@latest`, show the npx form as the secondary. - changelog/create-webjs/0.1.0.md: package field flip, body notes the rename history and the deprecation path for `create-webjs-app@0.1.0`. - scripts/backfill-changelog.js: PACKAGES + UNSCOPED entries `create-webjs-app` → `create-webjs`. - README.md: homepage hero block now leads with `npm create webjs@latest my-app`. The repo-layout block's package entry is updated too (via replace_all). - website/app/page.ts: homepage install block updated to the `npm create webjs@latest` form for all three templates. The already-published `create-webjs-app@0.1.0` stays on npm. Plan is to `npm deprecate` it after `create-webjs@0.1.0` publishes, with a message pointing users to the new package name.
…UI commands The next-steps banner printed by `webjs create` previously suggested: npx webjs ui add <name> The bare `webjs` npm name is owned by an unrelated package (`webjs@0.6.1`, 31 versions, different project). Outside a scaffolded project context (or when the user's interactive shell doesn't have `./node_modules/.bin` in PATH), `npx webjs <cmd>` fetches that unrelated package, not ours. Switch both occurrences (api-template hint + non-api Optional line) to the explicit scoped form: npx @webjsdev/cli ui add <name> Unambiguous in every shell, every directory. Bumps @webjsdev/cli to 0.8.5. webjsdev (the unscoped CLI mirror) re-resolves transitively on next install since its dep range is `@webjsdev/cli: ^0.8.2`. This is the only `npx webjs <cmd>` reference in the tracked tree; git ls-files | grep confirmed no other surfaces need updating.
…ld banner Drops the verbose scoped form in favour of the unscoped CLI alias. Both forms resolve to the same `webjs` binary (`webjsdev` package's single bin entry is `webjs`, npx's single-bin fallback runs it), but `npx webjsdev ui add <name>` is 13 fewer characters per invocation than `npx @webjsdev/cli ui add <name>` and reads cleanly without the @-scope. Still avoiding the bare `npx webjs <cmd>` form because the `webjs` npm name is owned by an unrelated package, so that one would fetch the wrong package outside a scaffolded project context. @webjsdev/cli version stays at 0.8.5 (unpublished at the moment of this commit). This amends the in-flight fix before the user publishes 0.8.5. Updates the 0.8.5 changelog entry to describe the final form.
create-webjs and webjsdev are version-lockstep mirrors of
@webjsdev/cli. Their per-release notes would mechanically read
"bump to match cli@X.Y.Z" every single time, which adds noise to
the rendered /changelog page on the website (and to GitHub
Releases) without communicating anything users can't already see
in the cli's own release notes.
Three changes:
- Remove the existing wrapper changelog directories:
changelog/create-webjs/0.1.0.md
changelog/webjsdev/0.1.0.md
changelog/webjsdev/0.1.1.md
The already-published versions of those packages stay on npm
with their existing histories. The website's /changelog page
scans the changelog/ directory at SSR time, so dropping these
dirs immediately removes the entries from the rendered output.
- Narrow scripts/backfill-changelog.js's PACKAGES list back to the
five framework packages (core, server, cli, ts-plugin, ui).
Future version bumps of create-webjs / webjsdev (driven by the
release workflow's lockstep step, landing in the next commit)
will not generate changelog files.
- Empty the UNSCOPED set. No framework-side package is currently
unscoped; the set stays as a hook for any future addition that
needs the bare-name frontmatter.
…sdev in lockstep with cli
When a push to main lands a new `changelog/cli/<version>.md` file
(meaning @webjsdev/cli just bumped), the release workflow now also:
1. Reads the new cli version from packages/cli/package.json.
2. Writes that version into packages/create-webjs/package.json and
packages/webjsdev/package.json. Also updates each wrapper's
`@webjsdev/cli` dep range to `^<new version>`.
3. Commits + pushes the bumps as github-actions[bot]. The commit
touches only `packages/*/package.json`, never `changelog/**`,
so it does NOT re-trigger this workflow (the trigger filter
is `paths: ['changelog/**']`).
4. Publishes each wrapper to npm via
`npm publish --workspace=<pkg> --access=public`, with an
idempotency check (skips if the version is already on the
registry, so re-runs after transient failures don't error).
Why the lockstep matters: `create-webjs` and `webjsdev` depend on
@webjsdev/cli at runtime. npx caches one install per
package-version, so a `create-webjs@0.1.0` install cached at
cli@0.8.4 keeps running cli@0.8.4 forever, even after cli@0.8.5
publishes. The reliable way to invalidate every npx cache is to
bump the wrapper's pkg-version too. Matching cli's version exactly
makes that mechanical: cli@X.Y.Z → wrapper@X.Y.Z, always.
No changelog files are created for the wrappers (handled in the
previous commit) and no GitHub Releases are produced for them
(intentional: the cli's GH release covers "what's new"; the
wrappers are pure mirrors).
On the next merge to main this workflow will jump create-webjs
from 0.1.0 → 0.8.5 and webjsdev from 0.1.1 → 0.8.5 (matching the
cli@0.8.5 publish that's queued on this branch). One-time
forward jump, then perfect lockstep going forward.
2 tasks
vivek7405
added a commit
that referenced
this pull request
May 22, 2026
…mps (#73) The release workflow's "Lockstep-bump wrappers" step commits the create-webjs + webjsdev version bumps directly to main as github-actions[bot]. The pre-commit hook's gate 1 (block commits to main) was firing on those bot commits, failing the workflow and leaving the wrappers un-bumped after a cli release. Add an early short-circuit at the top of the hook: when $GITHUB_ACTIONS=true (set automatically by every GitHub Actions runner), skip every gate and exit 0. The bot's commit is a mechanical version-field write to two package.json files; there's nothing to validate. Human commits hit every gate as designed. The exception applies only to environments where Actions is genuinely running. Caught by the failed workflow on the merge of #72 (run 26293696071): cli@0.8.5 published cleanly, but the lockstep wrappers step errored on `git commit -m ...` with "Cannot commit directly to 'main'". After this fix lands and the failed run is re-run, the lockstep step will succeed and publish create-webjs + webjsdev at 0.8.5.
2 tasks
vivek7405
added a commit
that referenced
this pull request
May 22, 2026
…#74) * fix(hook): skip wrapper packages in the changelog-file requirement create-webjs and webjsdev are version-lockstep mirrors of @webjsdev/cli and are explicitly NOT tracked in the framework's changelog system. Bumping their package.json version is intentional (driven by the release workflow's lockstep step, or rarely by a manual recovery commit) and does NOT need a matching changelog/<pkg>/<version>.md file. The hook previously detected ANY packages/*/package.json version bump and demanded a changelog file. For wrappers it would then run scripts/backfill-changelog.js, which doesn't list them in PACKAGES, so no file was generated, and the hook errored "expected file but generator didn't produce it". Add a name-check in the TO_GENERATE loop: skip create-webjs and webjsdev entirely. The framework-package bump-detection logic for core / server / cli / ts-plugin / ui is unchanged. This also un-blocks manual lockstep recoveries (like the 0.8.5 wrapper bumps that follow this commit) on a feature branch without --no-verify. * chore(release): manual lockstep bump create-webjs + webjsdev to 0.8.5 One-time manual sync. The automated lockstep step (added in #72) failed on the cli@0.8.5 release workflow run because the pre-commit hook blocked the bot's commit on main. PR #73 fixed the hook for new workflow runs, but `gh run rerun` replays the workflow at the original commit's SHA (which still has the un-fixed hook), so the re-run failed the same way. Easiest recovery: bump the wrapper package.json files manually in this commit, then publish the new versions out-of-band. Future cli bumps will trigger the workflow against the latest main (which now includes both the GITHUB_ACTIONS short-circuit AND the wrapper-skip in the changelog-file check), so the lockstep step will succeed automatically. No changelog files are touched here, so this push to main does not re-trigger release.yml. After merge, publish manually: cd packages/create-webjs && npm publish cd ../webjsdev && npm publish
2 tasks
vivek7405
added a commit
that referenced
this pull request
May 22, 2026
…kfill script (#76) Following the question "why are the new cli entries missing SHA / PR links?" the honest answer was: I wrote them by hand instead of letting `scripts/backfill-changelog.js` do it. The hook auto-runs that script whenever a version bump is staged, but I pre-created the files in the same commits that bumped the version, so the hook saw the files already exist and skipped regeneration. Recovery: delete the four hand-rolled files (0.8.2 .. 0.8.5) and run the backfill script fresh. Script result: ONE new file regenerated: 0.8.5.md, with proper ([#72](pr-link)) and [`<sha>`](commit-link) markup, body extracted from the PR's squash-merge commit message. The intermediate 0.8.2, 0.8.3, 0.8.4 versions were ephemeral states during PR #72 development (we manually `npm publish`ed each one as we iterated), but the squash- merge of #72 onto main collapsed all intermediate bumps into a single 0.8.1 -> 0.8.5 step. From git's perspective on main, those middle versions never existed as separate bumps, so the backfill cannot recreate per-version entries for them. Result is a small "version gap" on the /changelog page: 0.8.5 sits directly above 0.8.1. The intermediate versions are still on npm (install of @webjsdev/cli@0.8.3 still works) but have no rendered release notes; their changes are covered cumulatively in 0.8.5's entry. Going forward, the standard one-bump-per-PR flow produces 1-to-1 mapping between published versions and changelog entries.
This was referenced May 22, 2026
vivek7405
added a commit
that referenced
this pull request
May 22, 2026
…79) The auto-generated entry from PR #76 was technically correct per the script's rules but content-wrong for users. Three issues: 1. Title referenced intermediate names that didn't ship. "create-webjs-app" was renamed to "create-webjs" later in PR #72, and "wjs alias" was dropped (npm's name-similarity filter blocked the unscoped `wjs` package; we settled on `webjsdev` instead). 2. Body misrepresented what cli@0.8.5 specifically contains. The bullet's body was the first 4 lines of PR #72's squash commit body, which happens to describe the cli@0.8.2 auto-install work. 0.8.5 specifically is the `npx webjsdev` banner fix; the rest of 0.8.2- 0.8.4 work (bin map narrowing, output reorder) was invisible. 3. Single bullet under "Features" miscategorised a mix of feat + fix + breaking work. Rewrite as a multi-section entry covering everything the cli has gained since 0.8.1: Features: - auto-install dependencies after `webjs create` - next-steps banner reordered (run command lands last) Fixes: - banner uses `npx webjsdev ui` instead of broken `npx webjs ui` Breaking: - 0.8.2's `wjs` bin alias reverted in 0.8.3 (migration note) See also: - The new `create-webjs` and `webjsdev` companion packages Underlying cause this got auto-generated wrong: PR #72 bundled four cli version bumps (0.8.2, 0.8.3, 0.8.4, 0.8.5) into one squash-merge commit on main. The backfill script walks main's history and sees one squash commit for the 0.8.1 -> 0.8.5 range, so it produces one bullet from the squash subject + first 4 lines of body. Future releases under the "one-bump-per-PR" cadence will auto-generate accurate entries without this hand-edit. Companion to PR #72 title update on GitHub: the PR's title now reads "feat: npx-first scaffold UX (create-webjs + webjsdev + auto-install)" to match the actual deliverables (`create-webjs` not `create-webjs-app`, `webjsdev` not `wjs`). That edit lives on the PR page only; the squash commit's subject in main's git history is unchanged because editing it would require a force-push to main.
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.
Summary
Closes the multi-step "install CLI globally → scaffold → install deps → run" flow into a single
npxcommand, matching thenpm create <framework>@latestconvention used by Astro, Vite, SvelteKit, Next.js, Remix, etc.End state (which differs from the description this PR opened with; iterated heavily during review):
Two new npm packages
create-webjs(unscoped). Powers the homepage hero:npm create webjs@latest my-app npx create-webjs@latest my-app # equivalentThin wrapper that depends on
@webjsdev/cliand dispatches to itsscaffoldApp()function. Supports the existing three templates (full-stackdefault,api,saas) and auto-installs in the new directory with the detected package manager (npm / pnpm / yarn / bun).--no-installopts out.webjsdev(unscoped CLI mirror). Lets users install the CLI globally without typing the@webjsdev/scope:npm i -g webjsdev webjs create my-app # the binary on PATH is `webjs`, matching docs / scaffoldsThe bin is a one-line ESM re-export of
@webjsdev/cli/bin/webjs.js, sowebjsfrom awebjsdevinstall andwebjsfrom an@webjsdev/cliinstall are identical scripts.webjs create(the underlying CLI command)<detected-pm> installin the new directory by default.--no-installopts out.cd <name> && <pm> run devline is now the LAST thing on screen, after the AI-agent guidance. Single copy-paste line, no more buried below 25 lines of reading material.scaffoldApp(...)stays opt-in (install: truerequired), so tests + programmatic callers remain side-effect-free. The CLI passesinstall: !noInstall.Release workflow lockstep
.github/workflows/release.ymlgains a "Lockstep-bump wrappers" step that fires whenever a newchangelog/cli/<version>.mdlands. The step:^X.Y.Zdep range intopackages/create-webjs/package.jsonandpackages/webjsdev/package.jsongithub-actions[bot]create-webjsandwebjsdevare excluded fromscripts/backfill-changelog.js'sPACKAGESlist and from the website's/changelogpage, since their releases are pure version mirrors of cli.Website + docs
website/app/page.ts:npm create webjs@latest my-appas the headline command, with template variants and a global-install alternative below.<copy-cmd>web component atwebsite/components/copy-cmd.ts: hover-revealed copy button next to each install command. Lit-style declarative shape (everything driven fromrender(), no imperativesetAttribute/addEventListenerin lifecycle hooks).npm installfrom everywebjs createquickstart (the auto-install handles it). Usenpm run dev/npm run startin user-facing prose, not rawwebjs dev/webjs start. Drop Netlify from the PaaS list (frontend-only). Usenpx @webjsdev/cli ui addornpx webjsdev ui addfor the UI subcommand, nevernpx webjs ui add(the barewebjsnpm name is owned by an unrelated package).README.md"Repo layout" groups packages into framework runtime vs scaffold entry points.Things attempted and dropped
wjspackage: blocked by npm's name-similarity filter against existingw-jsandw.js. The standalone unscoped CLI mirror name becamewebjsdevinstead.webjsclipackage: also blocked by npm's similarity filter against existingwebjs-cli. We stayed withwebjsdev.wjsbin alias inside@webjsdev/cli(shipped briefly in0.8.2): reverted in0.8.3. The canonical CLI ships only thewebjsbin name.create-webjs-apppackage (initially published as0.1.0): renamed tocreate-webjsto make thenpm create <suffix>form read cleanly asnpm create webjs@latest.create-webjs-app@0.1.0is deprecated on npm with a pointer tocreate-webjs.What's on npm after merge
@webjsdev/cli@0.8.5create-webjs@0.8.5(lockstep with cli)webjsdev@0.8.5(lockstep with cli)create-webjs-app@0.1.0(deprecated, redirect message)@webjsdev/cli@0.8.2(deprecated, transitionalwjsbin alias)webjsdev@0.1.0,webjsdev@0.1.1(deprecated, transitional 3-bin shape)Follow-ups landed in subsequent PRs
#73fix the pre-commit hook so the bot can commit on main for the lockstep step#74manual lockstep bump for create-webjs + webjsdev to 0.8.5 (initial sync after the 0.8.5 publish that ran before the hook fix was in place)#75correct placeholder midnight dates on cli 0.8.2-0.8.5#76regenerate cli 0.8.5 changelog from git history with proper PR + SHA links