Skip to content

feat: npx-first scaffold UX (create-webjs + webjsdev + auto-install)#72

Merged
vivek7405 merged 27 commits into
mainfrom
feat/auto-install-and-create-webjs-app
May 22, 2026
Merged

feat: npx-first scaffold UX (create-webjs + webjsdev + auto-install)#72
vivek7405 merged 27 commits into
mainfrom
feat/auto-install-and-create-webjs-app

Conversation

@vivek7405
Copy link
Copy Markdown
Collaborator

@vivek7405 vivek7405 commented May 22, 2026

Summary

Closes the multi-step "install CLI globally → scaffold → install deps → run" flow into a single npx command, matching the npm create <framework>@latest convention 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   # equivalent

Thin wrapper that depends on @webjsdev/cli and dispatches to its scaffoldApp() function. Supports the existing three templates (full-stack default, api, saas) and auto-installs in the new directory with the detected package manager (npm / pnpm / yarn / bun). --no-install opts 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 / scaffolds

The bin is a one-line ESM re-export of @webjsdev/cli/bin/webjs.js, so webjs from a webjsdev install and webjs from an @webjsdev/cli install are identical scripts.

webjs create (the underlying CLI command)

  • Auto-install: runs <detected-pm> install in the new directory by default. --no-install opts out.
  • Next-steps banner reordered: the actionable cd <name> && <pm> run dev line 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.
  • Library default for scaffoldApp(...) stays opt-in (install: true required), so tests + programmatic callers remain side-effect-free. The CLI passes install: !noInstall.

Release workflow lockstep

.github/workflows/release.yml gains a "Lockstep-bump wrappers" step that fires whenever a new changelog/cli/<version>.md lands. The step:

  1. Reads cli's new version
  2. Writes the same version + matching ^X.Y.Z dep range into packages/create-webjs/package.json and packages/webjsdev/package.json
  3. Commits + pushes as github-actions[bot]
  4. Publishes both wrappers to npm

create-webjs and webjsdev are excluded from scripts/backfill-changelog.js's PACKAGES list and from the website's /changelog page, since their releases are pure version mirrors of cli.

Website + docs

  • Homepage hero on website/app/page.ts: npm create webjs@latest my-app as the headline command, with template variants and a global-install alternative below.
  • <copy-cmd> web component at website/components/copy-cmd.ts: hover-revealed copy button next to each install command. Lit-style declarative shape (everything driven from render(), no imperative setAttribute / addEventListener in lifecycle hooks).
  • README + docs sweep: drop redundant npm install from every webjs create quickstart (the auto-install handles it). Use npm run dev / npm run start in user-facing prose, not raw webjs dev / webjs start. Drop Netlify from the PaaS list (frontend-only). Use npx @webjsdev/cli ui add or npx webjsdev ui add for the UI subcommand, never npx webjs ui add (the bare webjs npm name is owned by an unrelated package).
  • README.md "Repo layout" groups packages into framework runtime vs scaffold entry points.

Things attempted and dropped

  • wjs package: blocked by npm's name-similarity filter against existing w-js and w.js. The standalone unscoped CLI mirror name became webjsdev instead.
  • webjscli package: also blocked by npm's similarity filter against existing webjs-cli. We stayed with webjsdev.
  • wjs bin alias inside @webjsdev/cli (shipped briefly in 0.8.2): reverted in 0.8.3. The canonical CLI ships only the webjs bin name.
  • create-webjs-app package (initially published as 0.1.0): renamed to create-webjs to make the npm create <suffix> form read cleanly as npm create webjs@latest. create-webjs-app@0.1.0 is deprecated on npm with a pointer to create-webjs.

What's on npm after merge

  • @webjsdev/cli@0.8.5
  • create-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, transitional wjs bin alias)
  • webjsdev@0.1.0, webjsdev@0.1.1 (deprecated, transitional 3-bin shape)

Follow-ups landed in subsequent PRs

  • #73 fix the pre-commit hook so the bot can commit on main for the lockstep step
  • #74 manual 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)
  • #75 correct placeholder midnight dates on cli 0.8.2-0.8.5
  • #76 regenerate cli 0.8.5 changelog from git history with proper PR + SHA links

vivek7405 added 27 commits May 22, 2026 15:59
`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.
@vivek7405 vivek7405 merged commit 4f13870 into main May 22, 2026
@vivek7405 vivek7405 deleted the feat/auto-install-and-create-webjs-app branch May 22, 2026 14:29
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.
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
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.
@vivek7405 vivek7405 changed the title feat: npx-first scaffold UX (create-webjs-app, wjs alias, auto-install) feat: npx-first scaffold UX (create-webjs + webjsdev + auto-install) 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant