You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implements the decision in #823 and realizes the umbrella #821. Ship an always-on, idiomatic, multi-feature example GALLERY in the scaffold so an AI agent scaffolding a webjs app gains context on every feature by browsing working, densely-commented examples. Structured exactly per webjs conventions (app-thin routing + modules-logic + shared components), no opt-out.
Structure (idiomatic; NOT a single prune-folder)
app/<feature>/page.ts = thin route adapters, one per example, importing from the feature module.
modules/<feature>/ = the real logic (components/, actions/, queries/, utils/, types.ts).
components/ = shared UI primitives used across examples.
Server boundary: /server-actions (a 'use server' action with verb config: GET/POST, validate, cache, tags, invalidates, streaming, cancellation) PLUS a server-only-utility example so the .server.ts vs 'use server' distinction is shown (dogfood: make the .server.ts vs 'use server' distinction unmissable for agents #820), /route-handlers (route.ts), /websockets (WS export).
Data + built-ins: /database (Drizzle read/write with the working .select() pattern, dogfood: close first-pass friction found building a full-stack app #817), /caching (cache(), revalidate/ISR, ETag, asset-hash), /file-storage, /rate-limit, /broadcast, /auth (createAuth + login/signup + protected route + sessions).
Config + platform: /config (the webjs block: headers/CSP/redirects/basePath, mostly config with a commented note), /env (env validation), /typescript (full-stack type safety), /service-worker (opt-in public/sw.js).
Composed app demos: /todo (optimistic + db + PE, the a11y <label for> pattern), /tic-tac-toe (client-only signals, no server).
Per template: full-stack gets the full gallery; api gets the backend-relevant subset (routing, route-handlers, server-actions, database, caching, rate-limit, websockets, env, config, no UI); saas = full-stack + the /auth example promoted.
Comment standard
Every example follows the dense comment standard from #821: each demonstrated pattern gets a comment stating WHAT / WHY / WHEN-to-use-and-when-NOT / the invariant it respects (e.g. the optimistic "use where feasible, not where it hurts" comment, the .server.ts distinction, <label for> association, the typed Metadata import). The comments are the teaching payload; an agent reading only the example files should learn the idiom AND its guardrails.
Prune model
Per-feature, the normal #818 replace-the-example workflow (files AND folders): each example route + its module is marker-gated so webjs check prompts replacement; the agent keeps what the real app needs and removes the rest. NOT a one-folder delete (that would teach non-idiomatic structure, #823).
Default-on, no opt-out
Every scaffold always ships the gallery. No --minimal / --no-examples flag: the scaffold is the AI-first context vehicle, so an agent can never skip gaining the context. The heavier starting app (pruned per-feature) is the accepted cost.
Implementation notes
The current example page/layout are generated INLINE as strings in packages/cli/lib/create.js (~L931/L1134/L787-858). A gallery this size should move to real TEMPLATE FILES under packages/cli/templates/app/** + packages/cli/templates/modules/** (copied at scaffold time) rather than growing the inline strings, so the examples are themselves lintable/testable in the repo and easier to maintain. Decide the template-file vs inline approach as step 1.
Extend the no-scaffold-placeholder marker coverage to the example routes/modules so a fresh scaffold still fails webjs check until the agent replaces/removes them (today it only marks app/page.ts + app/layout.ts).
The gallery must PASS webjs check + webjs typecheck + build in the repo (CI), so the examples are executable, verified docs that cannot silently rot. Add test/scaffolds/* coverage: a fresh scaffold builds, the landing index links all resolve, and each example route returns < 400.
Sync the prose surfaces (scaffold AGENTS.md / CONVENTIONS.md / the three per-agent rule files) to describe the gallery + the per-feature prune, and add/adjust MCP guided prompts (packages/mcp/src/mcp-docs.js) so the MCP points at the gallery examples.
Auth/db/websocket examples need care (SESSION_SECRET, a table, the WS route): keep each self-contained and bootable with no external setup (seeded example table, in-memory where possible).
Invariant 11 (prose punctuation) applies to every comment/doc edit.
Each template ships the idiomatic example gallery (app-thin routes + modules/<feature>/ logic + shared components/), with a landing index linking every example, covering the full feature surface per template.
Implements the decision in #823 and realizes the umbrella #821. Ship an always-on, idiomatic, multi-feature example GALLERY in the scaffold so an AI agent scaffolding a webjs app gains context on every feature by browsing working, densely-commented examples. Structured exactly per webjs conventions (app-thin routing + modules-logic + shared components), no opt-out.
Structure (idiomatic; NOT a single prune-folder)
app/<feature>/page.ts= thin route adapters, one per example, importing from the feature module.modules/<feature>/= the real logic (components/,actions/,queries/,utils/,types.ts).components/= shared UI primitives used across examples.app/api/<x>/route.ts,middleware.ts, metadata routes (app/sitemap.tsetc.), nestederror.ts/loading.ts.db/carries the example tables the data examples use.app/page.ts= landing index (a commented page example) linking every example route.Feature menu (target coverage; the routes on the landing index)
Cover the full webjs surface (source of truth: the root AGENTS.md feature list). Concrete starting set, grouped:
/routing(dynamic[param], catch-all, route groups),/middleware,/error-loading(nestederror.ts+loading.ts+ Suspense),/metadata(generateMetadata+ sitemap/robots/og routes)./components(WebComponent factory +prop+ signals + computed + lifecycle),/optimistic-ui(declarative + imperativeoptimistic()),/async-render(async render()+renderFallback+<webjs-suspense>streaming),/directives(repeat,watch,Task, ...),/forms(no-JS PE<form>+ pageaction)./server-actions(a'use server'action with verb config: GET/POST,validate,cache,tags,invalidates, streaming, cancellation) PLUS a server-only-utility example so the.server.tsvs'use server'distinction is shown (dogfood: make the .server.ts vs 'use server' distinction unmissable for agents #820),/route-handlers(route.ts),/websockets(WSexport)./database(Drizzle read/write with the working.select()pattern, dogfood: close first-pass friction found building a full-stack app #817),/caching(cache(),revalidate/ISR, ETag, asset-hash),/file-storage,/rate-limit,/broadcast,/auth(createAuth+ login/signup + protected route + sessions)./client-router(prefetch,<webjs-frame>, view transitions,<webjs-stream>stream actions)./config(thewebjsblock: headers/CSP/redirects/basePath, mostly config with a commented note),/env(env validation),/typescript(full-stack type safety),/service-worker(opt-inpublic/sw.js)./todo(optimistic + db + PE, the a11y<label for>pattern),/tic-tac-toe(client-only signals, no server).Per template:
full-stackgets the full gallery;apigets the backend-relevant subset (routing, route-handlers, server-actions, database, caching, rate-limit, websockets, env, config, no UI);saas= full-stack + the/authexample promoted.Comment standard
Every example follows the dense comment standard from #821: each demonstrated pattern gets a comment stating WHAT / WHY / WHEN-to-use-and-when-NOT / the invariant it respects (e.g. the optimistic "use where feasible, not where it hurts" comment, the
.server.tsdistinction,<label for>association, the typedMetadataimport). The comments are the teaching payload; an agent reading only the example files should learn the idiom AND its guardrails.Prune model
Per-feature, the normal #818 replace-the-example workflow (files AND folders): each example route + its module is marker-gated so
webjs checkprompts replacement; the agent keeps what the real app needs and removes the rest. NOT a one-folder delete (that would teach non-idiomatic structure, #823).Default-on, no opt-out
Every scaffold always ships the gallery. No
--minimal/--no-examplesflag: the scaffold is the AI-first context vehicle, so an agent can never skip gaining the context. The heavier starting app (pruned per-feature) is the accepted cost.Implementation notes
packages/cli/lib/create.js(~L931/L1134/L787-858). A gallery this size should move to real TEMPLATE FILES underpackages/cli/templates/app/**+packages/cli/templates/modules/**(copied at scaffold time) rather than growing the inline strings, so the examples are themselves lintable/testable in the repo and easier to maintain. Decide the template-file vs inline approach as step 1.no-scaffold-placeholdermarker coverage to the example routes/modules so a fresh scaffold still failswebjs checkuntil the agent replaces/removes them (today it only marksapp/page.ts+app/layout.ts).webjs check+webjs typecheck+ build in the repo (CI), so the examples are executable, verified docs that cannot silently rot. Addtest/scaffolds/*coverage: a fresh scaffold builds, the landing index links all resolve, and each example route returns < 400.AGENTS.md/CONVENTIONS.md/ the three per-agent rule files) to describe the gallery + the per-feature prune, and add/adjust MCP guided prompts (packages/mcp/src/mcp-docs.js) so the MCP points at the gallery examples.Subsumes / relates
modules/gap is solved by shipping real example modules; dogfood: close first-pass friction found building a full-stack app #817's specific first-pass fixes (typedMetadata, the Drizzle.select()read pattern, the MCP prompt updates, optimistic UI, a11y<label for>) become concrete sub-tasks of the gallery examples. Close dogfood: close first-pass friction found building a full-stack app #817 into this or track them as this issue's checklist..server.tsdistinction) and dogfood: split ui registry lib/utils.ts so importing cn() doesn't pin a page to the browser #819 (cn.ts). Builds on research: keep three scaffolds and enrich, not consolidate to saas-as-default #822/research: scaffold ships an always-on idiomatic multi-feature example gallery #823 (keep-3-enrich + gallery decision).Acceptance criteria
modules/<feature>/logic + sharedcomponents/), with a landing index linking every example, covering the full feature surface per template.webjs-scaffold-placeholder-marked; a fresh scaffold failswebjs checkonly on those markers and passeswebjs typecheck; per-feature removal (dogfood: scaffold guidance should prune unused files/folders, not keep everything #818) is documented in the scaffold prose.