git:20261007.c0c0c7f to git:20261007.1b65f46

70 added, 59 removed. Audit A to A.

# AGENTS.md for {{APP_NAME}}
- This is a WebJs app: server-rendered pages, web components for interactivity,
- server actions, Drizzle, and no build step. WebJs is its own framework, not
- React, Next.js or Lit, so write it from the patterns in this file rather than
- from that memory. Read this whole file before you edit anything.
+ This is a WebJs app: AI-first, web-components-first, buildless, and
+ progressively enhanced. Read this whole file before you edit anything, then
+ follow it. The steps here are required, not optional.
- {{PLAYBOOK}}
+ ## Gather context BEFORE you build (required)
- ## Rules that hold everywhere
+ WebJs is its own framework. It is not React, Next, or Lit, so writing code from
+ that muscle memory produces broken WebJs code. Before you write or change
+ anything, gather context from these sources. Do not skip a step to save time.
+ This is what separates a working app from a broken one.
- - Type every boundary from its source: rows are `typeof posts.$inferSelect`
- (into browser code with `import type`), action inputs a named `interface`,
- routing files `PageProps<'/posts/[id]'>` / `LayoutProps`, object props
- `prop<Post>(Object)`. `unknown` only for an untrusted payload
- narrowed on the next line. Never reach for `any`.
- - Never add `'use server'` to a file only server code imports (the DB
- connection, the schema).
- - Store data with Drizzle in the wired-up database, never in a JSON file, an
- in-memory array or localStorage. Every schema change is `npm run db:generate`
- then `npm run db:migrate`, and the migrations are committed.
- - TypeScript is erasable: no `enum`, `namespace`, parameter properties or
- decorators. Never put a backtick inside an `html` template, even in a comment.
- - Descriptive names (`formData`, `values`, `errors`, never `fd`, `v`, `e`) and a
- one-line doc comment on every exported function.
- - `npm run check` and `npm run typecheck` name the file and the fix; do what
- they say.
+ 1. **Read the skill.** Start with `.agents/skills/webjs/SKILL.md`, then load the
+ `references/*.md` files it routes to for the surface you are touching. The
+ skill is the guide to building a WebJs app: it helps you choose the right
+ layer, reach for the right export, and avoid the mistakes Next.js or Lit
+ habits cause. Reading it is never wasted work: it survives the
+ gallery-clearing step in the playbook below.
+ 2. **Study the shipped examples, then build on a clean slate.** The template
+ playbook below says what ships and the exact order to follow. The workflow
+ rules (git, tests, review) are in `.agents/rules/workflow.md`; follow them
+ too.
+ 3. **Read the framework source for exact contracts.** WebJs is 100% buildless
+ native ES modules, so the source you run IS the source you read. When you
+ need a precise API signature or behavior, open the package source under
+ `node_modules/@webjsdev/*` directly (each package ships its own `AGENTS.md`).
+ The full hosted docs are at https://webjs.dev/docs.
- ## Git
+ {{PLAYBOOK}}
- Commit per logical unit (CLAUDE.md has the rule). When you build a whole app
- from a spec in one session, the build is one unit: work on a feature branch
- (commits to `main` are refused), and commit once at the end after the checks
- pass (`git add -A && git commit -m "<imperative subject>"`). Team workflow
- (pull requests, CI, worktrees) is in `.agents/rules/workflow.md`.
+ ## Type everything (all templates)
- ## Before you build these, read the reference first
+ Full-stack type safety is what the `.server.ts` boundary buys you: a client
+ component importing a server action resolves to that action's real signature at
+ type-check time, with no build step and no code generation in between. So
+ DERIVE the type at every boundary instead of widening it:
- This file covers the common app. For any surface below, read the named
- section of `.agents/skills/webjs/references/` BEFORE writing that part (one
- `sed -n '/^## Heading/,/^## /p' <file>` call), because the API is WebJs's own
- and guessing it from another framework is wrong.
+ - A database row: `export type Todo = typeof todos.$inferSelect` in
+ `db/schema.server.ts` (`$inferInsert` for a write), carried into a
+ browser-shipped component with `import type` (erased before it reaches the
+ browser, so it does not trip the server-import boundary).
+ - An action's input: a named `interface`. Its result: `ActionResult<T>`.
+ Narrow with `if (result.success && result.data)`.
+ - Routing files: `PageProps<'/blog/[slug]'>`, `LayoutProps`,
+ `RouteHandlerContext`, all from `@webjsdev/core`. Run `npx webjsdev types`
+ for the typed `Route` union and per-route `params`.
+ - A reactive property: `prop<Student>(Object)`, `prop<Tag[]>(Array)`.
- | Building | Read |
- | --- | --- |
- | Live updates beyond the example above (presence, two-way sockets) | `client-router-and-streaming.md` "WebSockets", `built-ins.md` "Broadcast" |
- | Streaming beyond the example above (Suspense, cancellation) | `client-router-and-streaming.md` "Streaming (Suspense and RPC)" |
- | Refreshing one region, or one element after a write (`<webjs-frame>`, `<webjs-stream>`) | `client-router-and-streaming.md` |
- | File uploads and serving them (`FileStore`, `signedUrl`) | `built-ins.md` "File storage" |
- | Caching, `revalidate`, `cache()`, rate limits | `built-ins.md` "Caching", "Rate limiting" |
- | Middleware (`middleware.ts`, per segment) and JSON API routes (`route.ts`, `route()` adapter, CORS) | `routing-and-pages.md`, `data-and-actions.md` |
- | SEO: `metadata`, `generateMetadata`, sitemap, robots, social images; the app icon | `routing-and-pages.md` "Metadata", "App icon and manifest" |
- | Browser-only code (`window`, `localStorage`, timers) and component lifecycle, slots, context, directives | `components.md` |
- | Optimistic updates | `optimistic-ui.md` |
- | OAuth sign-in, cookie sessions, `forbidden()` / `unauthorized()` | `auth-and-sessions.md` |
- | Env vars and secrets, boot-time code (`instrumentation.ts` `register()`) | `built-ins.md` "Environment variables", "Observability" |
- | Scheduled jobs beyond the timer above | an external cron calling a `route.ts` with a secret |
- | Email, payments, i18n | no built-in: use the provider's SDK from a server-only `.server.ts` utility called by actions; secrets from `process.env` |
- | Browser and e2e tests | `testing.md` |
+ Never reach for `any` or a loose `as any` cast, and do not reach for `unknown`
+ either just because it looks safer. `unknown` is right for a payload nothing
+ has vouched for yet, narrowed on the very next line (a `route.ts` `await
+ req.json()`, an action's `export const validate` or a validator it delegates
+ to, a `catch` binding), and for a parameter of YOUR OWN helper that forwards
+ into an `html` template hole (a hole renders a string, a number, a
+ `TemplateResult`, or an array of those, so `TemplateResult` alone is too
+ narrow). That second case is about a value you accept, never one the framework
+ already types. Everywhere else it is a missing type, not a safe one: `unknown`
+ that survives into a return type, a component prop, a layout's `children`, or
+ an action signature is the shape to fix.
+ Nothing enforces this (both are valid TypeScript, so `webjs check` and `tsc`
+ pass either way), which is exactly why it is written down. The full ladder,
+ with an end-to-end example, is in
+ `.agents/skills/webjs/references/typescript.md`.
- ## When you need more
+ Keep server-only code (database drivers, secrets, `node:*` builtins) in
+ `.server.ts` modules. There are exactly two kinds:
- The reference set is `.agents/skills/webjs/` (`SKILL.md` routes to
- `references/*.md`). Open one only for a surface this file does not show:
- streaming and Suspense (`client-router-and-streaming.md`), optimistic UI
- (`optimistic-ui.md`), caching, rate limits, file uploads, env vars
- (`built-ins.md`), OAuth providers and sessions (`auth-and-sessions.md`),
- browser and e2e tests (`testing.md`), deeper component topics such as slots,
- shadow DOM, context and directives (`components.md`). The exact framework
- source is under `node_modules/@webjsdev/*`, and the hosted docs are at
- https://webjs.dev/docs.
+ - A `.server.ts` file WITH `'use server';` as its first line is a server
+ action: WebJs exposes its exported async functions to browser code as RPC
+ calls, so browser modules may import it directly.
+ - A `.server.ts` file WITHOUT `'use server'` is a server-only utility:
+ importing it from a page, layout, or component CRASHES in the browser at
+ module load. Reach it only from `'use server'` actions, `route.ts` handlers,
+ or middleware. Never add `'use server'` to a file only other server code
+ imports (the DB connection, the schema).
+
+ ## Data (all templates)
+
+ Use the wired-up database (Drizzle) for every piece of data the app stores;
+ the playbook above has the modeling step. Never store app data in a JSON file,
+ an in-memory array, or localStorage.