From 6aa7fccbe24ad23ad59a61b38473d2ed32a332db Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 11 Aug 2026 02:33:31 +0530 Subject: [PATCH] chore: release core 0.7.50, server 0.8.62, cli 0.10.54 and two more Clears every package carrying unreleased user-facing work since 0.7.49. intellisense and the two editor packages picked up nothing in the range, so they stay where they are. core takes the two attribute-reader fixes. A custom converter.fromAttribute never ran during SSR, so an element painted one value and held another the moment it upgraded, and the SSR reader resolved attribute names with its own resolver rather than the set observedAttributes delivers, which disagreed with the browser on four shapes of hand-written markup. Both readers now share one implementation. Each carries a behaviour note in its entry: a converter that touches a browser global now throws server-side, and three attribute shapes read LESS at SSR to match what the browser already did. server takes the boot-time validation of the `webjs` config block, so a typo'd key warns once instead of silently costing a feature its setting, plus the auto-linking of app/icon and app/apple-icon, which closes the gap between shipping the Next-shaped file convention and never referencing it. The fixes cover the headers rules dropped in silence and the production message for a form submission arriving as a GET, which named a cause #1307 had made impossible. cli emits one cross-agent instruction set from `webjs create` instead of a rule file per tool, sources the scaffold gallery from the repo's runnable gallery app (bundled into the tarball at pack time, verified with npm pack), and refuses `webjs check` outside an app, where every rule's one-application premise does not hold. mcp resolves the docs corpus from the app being edited rather than the snapshot frozen into a global install, and says which one it served. ui stops two registry modules doing work at module scope, which cost page elision in every app using the kit, and teaches cn() the Tailwind v4 parenthesis hint spelling. Raises packages/server's declared @webjsdev/core range from ^0.7.49 to ^0.7.50. No new core export is imported statically, but the release PR is the only place that bump is legal, and core carries the earliest date in the batch so it publishes first. The generated notes were curated before committing. #1314 is dropped from server entirely: it added the submitter-needs-bound-form check rule that #1385 then removed in the same range, so the rule never reaches a release, and what remains is the diagnostic message the fix entry describes. Slices that were a docblock, a test, or an export keyword are dropped from the packages that saw only those. --- changelog/cli/0.10.54.md | 37 +++++++++++++++++++++++++ changelog/core/0.7.50.md | 34 +++++++++++++++++++++++ changelog/mcp/0.1.14.md | 25 +++++++++++++++++ changelog/server/0.8.62.md | 52 ++++++++++++++++++++++++++++++++++++ changelog/ui/0.3.13.md | 24 +++++++++++++++++ package-lock.json | 12 ++++----- packages/cli/package.json | 2 +- packages/core/package.json | 2 +- packages/mcp/package.json | 2 +- packages/server/package.json | 4 +-- packages/ui/package.json | 2 +- 11 files changed, 184 insertions(+), 12 deletions(-) create mode 100644 changelog/cli/0.10.54.md create mode 100644 changelog/core/0.7.50.md create mode 100644 changelog/mcp/0.1.14.md create mode 100644 changelog/server/0.8.62.md create mode 100644 changelog/ui/0.3.13.md diff --git a/changelog/cli/0.10.54.md b/changelog/cli/0.10.54.md new file mode 100644 index 000000000..7da73781a --- /dev/null +++ b/changelog/cli/0.10.54.md @@ -0,0 +1,37 @@ +--- +package: "@webjsdev/cli" +version: 0.10.54 +date: 2026-08-10T20:58:38.529Z +commit_count: 3 +--- +## Features + +- **emit one cross-agent instruction set from `webjs create`** ([#1368](https://github.com/webjsdev/webjs/pull/1368)) [`241c961b`](https://github.com/webjsdev/webjs/commit/241c961b) + A scaffolded app carried a per-agent rule file for every tool (`GEMINI.md`, + `.cursorrules`, `.github/copilot-instructions.md`) plus their hook directories, + each a copy that drifts from `AGENTS.md` the first time a rule changes. The + scaffold now emits `AGENTS.md`, `CONVENTIONS.md`, and + `.agents/skills/webjs/` as the single cross-agent source, with `CLAUDE.md` + retained as the thin bridge Claude Code needs because it does not read + `AGENTS.md` natively. +- **source the scaffold gallery from the repo's runnable gallery app** ([#1371](https://github.com/webjsdev/webjs/pull/1371)) [`c60f226e`](https://github.com/webjsdev/webjs/commit/c60f226e) + The feature gallery `webjs create` emits used to live only as template payload + under `packages/cli/templates/`, so nothing ever ran it. It is now the repo's + own `gallery/` application, bundled into the published tarball at pack time, so + every demo a generated app ships is code the framework boots and tests as a + real app. The generated app is unchanged: the copy skips the gallery's own app + shell (root layout, home page, theme toggle, `cn.ts`) so the scaffold keeps + writing its own, which is what carries `displayName`, `cspNonce()`, + `LayoutProps` typing, the `metadata.icons` favicon, and the verbatim + `@webjsdev/ui` registry copy of `cn.ts` that `webjs ui add` depends on. + +## Fixes + +- **`webjs check` refuses to run outside an app** ([#1356](https://github.com/webjsdev/webjs/pull/1356)) [`aeda5c86`](https://github.com/webjsdev/webjs/commit/aeda5c86) + Run at a monorepo root, the command reported 67 violations that were + effectively all false. Every rule assumes ONE application: one module graph, + one custom-element registry, one runtime, and a workspace root is none of + those, so a tag was reported as duplicated across five files that never load + together. The command now exits 1 in any directory with no `app/` directory and + names the workspace member apps to run it in. The rule engine is untouched, so + the rule set inside an app is byte-identical before and after. diff --git a/changelog/core/0.7.50.md b/changelog/core/0.7.50.md new file mode 100644 index 000000000..dfa7e0864 --- /dev/null +++ b/changelog/core/0.7.50.md @@ -0,0 +1,34 @@ +--- +package: "@webjsdev/core" +version: 0.7.50 +date: 2026-08-10T20:58:38.316Z +commit_count: 2 +--- +## Fixes + +- **honour `converter.fromAttribute` in the SSR attribute reader** ([#1359](https://github.com/webjsdev/webjs/pull/1359)) [`e5f5e1c9`](https://github.com/webjsdev/webjs/commit/e5f5e1c9) + A property declaring a custom `converter.fromAttribute` was read one way during + SSR and another way the moment the element upgraded in the browser. + `attributeChangedCallback` tried the converter first, ahead of any type-based + coercion, while the SSR reader dispatched on `def.type` alone and never called + the converter at all, so `` with an upper-casing converter + painted `a` server-side and held `A` after upgrade. Both readers now share one + implementation, the way `@lit-labs/ssr` forwards into the element's own reader. + Migration: a converter that touches `document`, `window`, or `navigator` now + throws during SSR where it did not before, and the component renders its error + state. A throwing converter is deliberately not caught on either side, matching + the rule already stated for `toAttribute`. +- **make the SSR attribute reader see the browser's attribute set** ([#1361](https://github.com/webjsdev/webjs/pull/1361)) [`bcbf2657`](https://github.com/webjsdev/webjs/commit/bcbf2657) + The SSR reader walked the parsed source tag with its own name resolver, while + the browser goes through `observedAttributes` after the parser has lowercased + every attribute name and decoded every character reference. The two disagreed + on four shapes of hand-written markup, so the first paint held one value and + the upgraded element held another with nothing erroring. Both readers now + resolve a name through one resolver, and attribute text is entity-decoded once + per attribute ahead of type coercion, so every branch sees decoded text rather + than only the JSON one. Migration: three shapes now read LESS at SSR, matching + what the browser already did. A `state: true` prop is no longer populated from + a source attribute, a camelCase attribute name in markup no longer resolves, + and an attribute matching no declared property is no longer copied onto the + instance. An app relying on any of the three was already broken after + hydration. diff --git a/changelog/mcp/0.1.14.md b/changelog/mcp/0.1.14.md new file mode 100644 index 000000000..6447b7bea --- /dev/null +++ b/changelog/mcp/0.1.14.md @@ -0,0 +1,25 @@ +--- +package: "@webjsdev/mcp" +version: 0.1.14 +date: 2026-08-10T20:58:38.784Z +commit_count: 1 +--- +## Fixes + +- **serve the app's own docs corpus, and stamp what was served** [`7c21c367`](https://github.com/webjsdev/webjs/commit/7c21c367) + A globally installed server bundled a docs snapshot frozen at publish time and + served it forever, with nothing in the output revealing that. A server + published one day before the client router stopped needing an explicit import + kept teaching that import for months, contradicting the corrected copy sitting + in the app's own `node_modules` the whole time, and following it put a dead + `import '@webjsdev/core/client-router'` into three layouts, each of which the + elision analyser then correctly refused to elide. Corpus resolution gains a + rung above the bundled snapshot: the app's own installed + `@webjsdev/mcp/resources`, which is version-matched to the framework being + edited. `init` now names the corpus it served from its `corpus.json` stamp, + says plainly when it is serving a live checkout, and warns when the app's + installed mcp is strictly newer than the running server, so the human knows to + refresh the global install. Because `appDir` is a per-call tool argument, the + docs deps are resolved per call and memoized by `appDir` rather than built once + at boot, which would have pinned the corpus to the launch directory. An + injected `opts.docsDeps` still wins for every `appDir`. diff --git a/changelog/server/0.8.62.md b/changelog/server/0.8.62.md new file mode 100644 index 000000000..e961e215b --- /dev/null +++ b/changelog/server/0.8.62.md @@ -0,0 +1,52 @@ +--- +package: "@webjsdev/server" +version: 0.8.62 +date: 2026-08-10T20:58:38.401Z +commit_count: 4 +--- +## Features + +- **validate the `webjs` config block at boot** ([#1355](https://github.com/webjsdev/webjs/pull/1355)) [`b4488f43`](https://github.com/webjsdev/webjs/commit/b4488f43) + The published JSON Schema reached users through exactly one wire, the + scaffold's `.vscode` `$ref`, so a typo'd key was caught only for a VS Code user + with `package.json` open. Everywhere else the key was dropped, the feature + stayed at its default, and nothing said so. `createRequestHandler` now runs the + schema once per boot, so dev, prod, and an embedded host all get it from one + call site, and every problem rides one aggregated warning naming each unknown + top-level key, bad `enum` value, and wrong-typed `boolean` or `integer`. It + warns and never throws: a typo costs one feature its setting rather than + costing the app its boot. It does not descend into a nested object, so a + misspelling inside `dev` or `start` is still unreported. +- **auto-link `app/icon` and `app/apple-icon` metadata routes** ([#1379](https://github.com/webjsdev/webjs/pull/1379)) [`e0622b59`](https://github.com/webjsdev/webjs/commit/e0622b59) + An icon metadata route served its bytes and nothing referenced them, so the + file every other framework treats as the favicon produced a blank tab with no + diagnostic. With no `metadata.icons` declared, `app/icon.*` and + `app/apple-icon.*` now emit `` and + ``, base-path prefixed, with no asserted `type` or + `sizes` (the route picks its content type at request time, so declaring one + here could contradict the bytes). A declared `metadata.icons` SUPPRESSES the + routes rather than merging with them, matching Next's precedence for its static + icon files, so an app that outgrows a placeholder route names its real icons + instead of deleting it. The binding is refreshed from the route table at boot + and on each rebuild, so adding or deleting the file takes effect live. + +## Fixes + +- **report the `webjs.headers` rule dropped for having no directives** ([#1362](https://github.com/webjsdev/webjs/pull/1362)) [`c23c4cd3`](https://github.com/webjsdev/webjs/commit/c23c4cd3) + Two silent-config gaps the boot warning pass had left open. A schema-valid + `{ source: "/x", headers: [] }` was dropped with nothing saying so, and a rule + whose every directive was dropped named the directives while never saying the + rule went with them. A `webjs.headers` or `webjs.redirects` value that is + present but not an array now warns too: both readers used to discard the whole + config in silence, and the boot check inspects only boolean, integer, and enum + leaves, so a `"headers": {}` was reported by nothing anywhere. +- **name the real causes when a form submission arrives as a GET** ([#1385](https://github.com/webjsdev/webjs/pull/1385)) [`6a3044e2`](https://github.com/webjsdev/webjs/commit/6a3044e2) + The `WEBJS_FORM_SUBMITTED_AS_GET` production message blamed the submitter's + enclosing form, which #1307 made impossible: a bound submitter carries its own + `formmethod="post"`, and a bound form is refused a `method="get"` outright. It + now points at the two shapes that can actually produce the request, a PLAIN + submitter's own `formmethod="get"` and a hand-authored form carrying the + reserved identity field. The dev logger was already correct, so the two no + longer disagree about one event. The runtime diagnostics themselves are + unchanged: they read the request shape server-side and stay reachable however + the request was made. diff --git a/changelog/ui/0.3.13.md b/changelog/ui/0.3.13.md new file mode 100644 index 000000000..cfe334832 --- /dev/null +++ b/changelog/ui/0.3.13.md @@ -0,0 +1,24 @@ +--- +package: "@webjsdev/ui" +version: 0.3.13 +date: 2026-08-10T20:58:38.735Z +commit_count: 2 +--- +## Fixes + +- **stop registry modules doing work at module scope** ([#1360](https://github.com/webjsdev/webjs/pull/1360)) [`276ca9ec`](https://github.com/webjsdev/webjs/commit/276ca9ec) + Two registry modules ran work at module scope, which the elision analyser + correctly reads as client work, so every page or layout reaching them on a + component-free path shipped whole instead of being elided. `cn` sits under + essentially every kit helper and every scaffolded app runs `webjs ui init`, so + this silently cost page elision in every app using the kit. +- **teach `cn()` the Tailwind v4 parenthesis hint spelling** ([#1357](https://github.com/webjsdev/webjs/pull/1357)) [`12a06669`](https://github.com/webjsdev/webjs/commit/12a06669) + Tailwind v4 added `shadow-(color:--x)` as shorthand for + `shadow-[color:var(--x)]`. `variantPrefix` counted only bracket depth, so the + colon inside the parentheses read as a variant separator and the matcher was + handed a fragment that matches nothing. The utility ended up ungrouped, which + never evicts anything but does stop two utilities setting the identical + property from collapsing, leaving the winner to compiled stylesheet order. + `variantPrefix` now carries a second counter for parens and splits only where + both depths are zero, the hinted-group regex accepts `-(` alongside `-[`, and + the border width fragment reads the paren length hint. diff --git a/package-lock.json b/package-lock.json index 2cfc8dbdf..14cd0b167 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6979,7 +6979,7 @@ }, "packages/cli": { "name": "@webjsdev/cli", - "version": "0.10.53", + "version": "0.10.54", "license": "MIT", "dependencies": { "@webjsdev/mcp": "^0.1.0", @@ -6995,7 +6995,7 @@ }, "packages/core": { "name": "@webjsdev/core", - "version": "0.7.49", + "version": "0.7.50", "license": "MIT", "devDependencies": { "esbuild": "^0.25.0" @@ -7029,7 +7029,7 @@ }, "packages/mcp": { "name": "@webjsdev/mcp", - "version": "0.1.13", + "version": "0.1.14", "license": "MIT", "dependencies": { "@webjsdev/server": "^0.8.0", @@ -7044,10 +7044,10 @@ }, "packages/server": { "name": "@webjsdev/server", - "version": "0.8.61", + "version": "0.8.62", "license": "MIT", "dependencies": { - "@webjsdev/core": "^0.7.49", + "@webjsdev/core": "^0.7.50", "ws": "^8.20.0" }, "engines": { @@ -7080,7 +7080,7 @@ }, "packages/ui": { "name": "@webjsdev/ui", - "version": "0.3.12", + "version": "0.3.13", "license": "MIT", "dependencies": { "commander": "^14.0.0", diff --git a/packages/cli/package.json b/packages/cli/package.json index 598e5fbc4..18ea284a8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/cli", - "version": "0.10.53", + "version": "0.10.54", "type": "module", "description": "The CLI for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Runs the dev and production servers, scaffolds apps, validates conventions, and drives the database. Node 24+ or Bun.", "bin": { diff --git a/packages/core/package.json b/packages/core/package.json index fe18de86a..e08a2553a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/core", - "version": "0.7.49", + "version": "0.7.50", "type": "module", "description": "The runtime for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Ships the html and css template tags, the WebComponent base class, signals, directives, and the isomorphic renderers.", "types": "./index.d.ts", diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 8ecff3e02..ee39b3739 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/mcp", - "version": "0.1.13", + "version": "0.1.14", "type": "module", "description": "The Model Context Protocol server for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Gives AI coding agents live app introspection over routes, actions, components, and convention checks, plus a knowledge layer of docs, recipes, and framework source.", "bin": { diff --git a/packages/server/package.json b/packages/server/package.json index 7b39b0240..426253300 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/server", - "version": "0.8.61", + "version": "0.8.62", "type": "module", "description": "The server for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Provides the file-based router, SSR, server actions, route handlers, middleware, and live reload on Node 24+ or Bun.", "main": "index.js", @@ -28,7 +28,7 @@ "README.md" ], "dependencies": { - "@webjsdev/core": "^0.7.49", + "@webjsdev/core": "^0.7.50", "ws": "^8.20.0" }, "publishConfig": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 9e812d8d8..0c26532dc 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@webjsdev/ui", - "version": "0.3.12", + "version": "0.3.13", "type": "module", "description": "The AI-first component library for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Class-helper functions for visuals, custom elements only where state matters, source-copied into your repo so you own it.", "bin": {