import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; import { join, relative } from "node:path"; import console from "node:console"; import process from "node:process"; import { format } from "prettier"; const root = process.cwd(); const json = (path) => JSON.parse(readFileSync(join(root, path), "utf8")); const rootPackage = json("package.json"); const publicApi = json("docs/public-api-0.8.json"); const uiReference = json("packages/ui/component-reference.json"); function walk(dir, extension, out = []) { for (const entry of readdirSync(dir)) { const path = join(dir, entry); const info = statSync(path); if (info.isDirectory() && !["node_modules", "dist", ".wrnexus"].includes(entry)) walk(path, extension, out); else if (path.endsWith(extension)) out.push(path); } return out; } const packageRows = readdirSync(join(root, "packages"), { withFileTypes: true }) .filter((entry) => entry.isDirectory()) .map((entry) => { const manifest = json(`packages/${entry.name}/package.json`); return { name: manifest.name, version: manifest.version, description: manifest.description ?? "—", }; }) .sort((a, b) => a.name.localeCompare(b.name)); const wrnFiles = walk(join(root, "packages"), ".wrn").sort(); const packageBlocks = new Map(); for (const file of wrnFiles) { const packageName = relative(join(root, "packages"), file).split(/[\\/]/)[0]; const list = packageBlocks.get(packageName) ?? []; list.push(relative(root, file).replaceAll("\\", "/")); packageBlocks.set(packageName, list); } const apiPackages = Object.entries(publicApi.packages); const apiSymbolCount = apiPackages.reduce( (total, [, entries]) => total + Object.values(entries).reduce((sum, symbols) => sum + symbols.length, 0), 0, ); const lines = []; const add = (...value) => lines.push(...value); add( "# WRNexusJS complete framework and `.wrn` report", "", `Generated for workspace version **${rootPackage.version}** from the checked-out source and generated references.`, "", "> Scope and source of truth: this report describes the checked-out implementation, not only the prose docs. The parser in `packages/syntax`, compiler/runtime code, package manifests, `docs/public-api-0.8.json`, and `packages/ui/component-reference.json` take precedence when older documents disagree.", "", "## 1. Executive summary", "", `- Workspace framework version: **${rootPackage.version}**. The 48 independently published packages have their own patch versions; see Appendix A.`, "- Architecture: compiler-driven, SSR-first, Bun-native/full-stack, with Node-friendly selected tooling.", "- Static routes retain the zero-framework-JavaScript goal; hydration is selective and islands are loaded only where declared.", "- Current headline features include typed callable API blocks, reactive `if`/`each` control blocks, runtime-scoped state and functions, typed outputs, stores, React islands, HTML-aware editor tooling, package/plugin discovery, generated contracts, security gates, and multi-app RPC.", `- Audited public API baseline: **${apiPackages.length} packages / ${apiSymbolCount} exported symbols** across root and subpath exports.`, `- Audited packaged \`.wrn\` sources: **${wrnFiles.length}**; generated UI reference: **${uiReference.components.length} components**.`, "", "## 2. What a `.wrn` file is", "", "A `.wrn` file is a single compiler-owned source unit combining imports, a root declaration, typed data/state, runtime behavior, HTML view markup, styles, metadata, API handlers/bindings, and realtime handlers. It is parsed into the canonical AST owned by `@wrnexus/syntax`; `@wrnexus/compiler` turns that AST into SSR, browser, route, style, and metadata artifacts.", "", "Valid roots:", "", "| Root | Purpose |", "| --- | --- |", "| `page Name {}` | Routed page. |", "| `component Name {}` | Reusable server-rendered component. |", "| `layout Name {}` | Reusable page wrapper. |", "| `global store Name {}` | Application-wide store. |", "| `page store Name {}` | Page-lifetime store. |", "", "A file may start with static TypeScript imports. Component and layout symbols can be imported explicitly; compatibility discovery remains configurable for upgraded applications.", "", "## 3. Complete `.wrn` block and declaration catalog", "", "| Declaration/block | Shape | Meaning and current behavior |", "| --- | --- | --- |", "| `layout = LayoutSymbol` | root member | Preferred imported layout reference. String layout names remain a compatibility path. |", '| `runtime = "…"` | root member | Targets: `server`, `client`, `universal`, `edge`, `worker`, `service-worker`. |', '| `render = "…"` | root member | Modes: `static`, `server`, `hybrid`, `client`, `partial-static`. |', '| `hydrate = "…"` | root member | `load`, `idle`, `visible`, `interaction`, `none`, or `media:`; legacy `never` normalizes to `none`. |', '| `client = "…"` | root member | Legacy alias for hydration configuration; `client {}` remains a different runtime-mode block. |', "| `types {}` | raw TypeScript | Local type declarations emitted for checking. |", "| `props {}` | typed declarations | Required without default; optional via `?`; defaults supported; legacy `@event name = function` is parsed for compatibility. |", "| `outputs {}` | typed declarations | Canonical child-to-parent callable output contract, zero or one typed payload. |", "| `state name = expr` / `state {}` | reactive data | Shared state; type annotation optional, initializer required. Arrays, objects, and multiline expressions are supported. |", "| `server state {}` / `client state {}` | runtime-scoped data | State visible only in the declared runtime boundary. |", "| `computed name = expr` / `computed {}` | derived data | Dependency-tracked cached values. |", "| `effect {}` | reactive side effect | Runs after batched updates when referenced reactive values change. |", "| `load server {}` / `load client {}` | loader | Runtime-specific loading; named/dependent/deferred forms are represented in the AST. |", "| `action name(args) {}` | action | Named action, optionally schema-backed, exported for adapters. |", "| `view {}` | HTML/template | HTML/component tree with expressions, events, directives, and reactive control blocks. |", "| `style {}` | scoped CSS | Multiple blocks allowed; promoted into the document head with CSP/HMR/navigation support. |", "| `seo {}` | metadata | Key/value SEO metadata. |", "| `security {}` | policy metadata | Auth, CSRF, roles, rate-limit and organization-specific enforcement metadata. |", "| `navigation {}` | navigation metadata | Page navigation policy/configuration consumed by runtime tooling. |", "| `cache {}` | cache metadata | Declarative framework cache policy. |", "| `functions {}` | shared helpers | Legacy/general shared helper body; runtime-specific function grammar is preferred where applicable. |", "| `server { functions {} }` / `client { functions {} }` | mode helper block | Raw helpers scoped to SSR or browser execution. |", "| `[async] server function name(args) {}` | callable function | Explicit server RPC boundary. |", "| `[async] client function name(args) {}` | browser function | Explicit client callable function. |", "| `[async] shared function name(args) {}` | universal helper | Explicit shared function. |", "| `ssr { api … }` | render-time own-route data | Executes during render. Legacy bare response body is supported; sectioned `response`/`error` is supported; request parameters are intentionally forbidden. |", "| `client { api … }` | callable own-route data | Sectioned form creates `api.name(input)` in browser scope; GET uses query parameters, other methods use JSON and CSRF. |", "| `api METHOD /path {}` | route handler | Defines an application API endpoint/handler. Distinct from named data API bindings inside `ssr`/`client`. |", "| `lifecycle { mount/update/unmount {} }` | component lifecycle | Hydrated lifecycle hooks. |", "| `watch stateName {}` | watcher | Runs for changes to the named state. |", "| `realtime name { on event(args) {} }` | websocket behavior | Declares named realtime handlers. |", "| `persist {}` | store persistence | Storage (`memory`, `session`, `local`), included keys, version, migrations, and validation. |", "| `lifecycle { serverInit/clientInit/hydrate/dispose {} }` | store lifecycle | Store-specific lifecycle form. |", "", "### View/template features", "", "- Standard HTML and custom/component tags; HTML void elements follow the platform list.", "- Escaped `{expression}` interpolation. Raw HTML is an explicit security boundary.", "- Browser event attributes: `@click`, `@window:scroll`, `@document:click`, and other event names.", "- Conditional classes through `class:name='expression'`; visibility through `data-show`.", '- Legacy loop attribute: `data-for="item, index in items key item.id"`, with optional `data-key`.', "- Canonical control blocks: `{#if}`, `{:else if}`, `{:else}`, `{/if}` and `{#each list as item, index key expr}`, `{:empty}`, `{/each}`. Initial output is SSR and remains reactive after hydration.", "- JSX-style expression props (`items={items}`, object/array expressions) are current; quoted expressions remain compatible. Literal HTML attributes remain quoted.", "- React/TSX islands use imported `.tsx` components and `client:only`, `client:load`, `client:visible`, or `client:idle`. They are client-only in v1; island props must be JSON-serializable.", "", "### Typed callable API block (latest form)", "", "```wrn", "client {", " api searchUsers POST /api/users {", " request { body { name?: string age?: number } }", " response { return data.users }", " error { return [] }", " }", "}", "```", "", "Call it with `await api.searchUsers({ name })`. GET uses `request { parameters {} }`; non-GET uses `body {}`. Fields are type-only declarations checked against generated route contracts in `app/types/wrnexus.generated.api-checks.ts`. Success binds parsed JSON as `data`. `error {}` converts failure to its returned value; without it, non-2xx, network, and parse failures reject. Targets are restricted to the current app’s `/api/*` routes. External APIs, custom headers, parameterized SSR calls, caching, and deduplication are deferred.", "", "Legacy API binding remains valid: `ssr { api users GET /api/users { return users } }`. Its bare body receives payload fields through the legacy dynamic scope. The sectioned form deliberately uses `data` so TypeScript can check it.", "", "## 4. Runtime, rendering, and data flow", "", "1. `@wrnexus/syntax` tokenizes/parses and emits stable diagnostics and AST nodes.", "2. The compiler resolves imports/components/islands and generates SSR HTML functions, client modules, route/API exports, styles, metadata, and contracts.", "3. Static pages ship no framework JS. Interactive pages receive only the required CSR runtime; island routes lazily receive React/island assets.", "4. State changes batch, invalidate computed values, run effects/watchers, update expressions/classes/visibility, and rerender `if`/`each` regions.", "5. Server functions use the RPC boundary; typed API blocks call same-app API routes; realtime blocks produce websocket handlers; stores bridge SSR and client state.", "6. Generated types validate component props, outputs, functions, routes, and typed API-block request contracts during `tsc` and release checks.", "", "## 5. Framework feature inventory", "", "- Routing and rendering: filesystem pages/layouts, static/request/hybrid/client/partial-static rendering, route analysis, advanced routing, CSR navigation, layouts, streaming/SSR packages.", "- Reactivity: state, computed values, effects, watchers, reactive attributes/events, SSR-to-client control blocks, loaders/actions, explicit hydration.", "- Components/UI: application components, package-owned blocks, generated prop/output references, theming/tokens, 102 audited first-party UI components, app overrides/ejection.", "- Data/backend: database drivers and migrations, repositories, cache, queue, pub/sub, realtime, GraphQL, route APIs, server functions, workspace RPC.", "- Identity/security: auth, authorization, OAuth, JWT/JWKS, MFA/passkeys/recovery, CAPTCHA, encryption, SSRF defenses, CSP/CSRF, request limits, audit/security gates.", "- Product capabilities: AI/RAG/provider adapters, content, i18n, image optimization, uploads, validation, PWA, native/mobile, analytics/tracking, observability.", "- Developer experience: CLI create/dev/build/update/doctor/inspect/generate/eject/db/workspace operations, HMR, dev toolbar, language server, VS Code completion/HTML editing/formatting/diagnostics, playground, MCP, tests/benchmarks/release validation.", "- Deployment: production builds, Docker and platform examples, migrations, package staging/integrity checks, SBOM and security/performance reports.", "", "## 6. Legacy-to-current migration map", "", "| Legacy/earlier approach | Current approach | Compatibility/status |", "| --- | --- | --- |", "| Compiler-owned/internal parsing imports | Canonical `@wrnexus/syntax` lexer/parser/AST/diagnostics | Compiler re-exports remain for compatibility; direct internals are deprecated. |", "| Implicit component discovery everywhere | Explicit imports and generated contracts | Unresolved symbols are reported rather than guessed; there is no compatibility opt-out. |", '| `layout = "PublicLayout"` | Import layout and use `layout = PublicLayout` | String layouts are no longer supported; the config key that toggled them was removed. |', "| `@event changed = function` in props | `outputs { changed(payload: Type) }` | v0.6 migration converts declarations; ambiguous payloads become `unknown`. |", '| `$emit("changed", value)` and `event.detail` | `output.changed(value)` and direct `payload` | Static cases auto-migrated; dynamic emit names require review. |', "| Unclassified functions | `server function`, `client function`, or `shared function` | v0.6 classifies unambiguous cases; the legacy default runtime that preserved ambiguous behavior was removed. |", "| Manually copied CAPTCHA JS/script tags | Package-discovered client runtime/assets | v0.4 removes tags and archives old assets under `.wrnexus/legacy-assets/0.4.0`. |", "| Package components/routes/assets wired manually | Automatic package/plugin discovery and contribution registry | Current CLI/build/dev server inspect and consume contributions. |", "| Only scalar/quoted dynamic props | Native arrays/objects and JSX-style unquoted expressions | Quoted expression attributes remain supported. |", "| `data-for` and older each forms | `{#each …}{:empty}{/each}` | Legacy loop forms remain supported; canonical blocks offer keyed/empty/reactive behavior. |", "| Static server-only `if`/`each` after hydration | Reactive client rerendering of control blocks | Current runtime updates branches/rows after state changes. |", "| Bare `api` binding bodies and hand-written `fetch` for inputs | Sectioned typed callable client API blocks | Bare body stays supported; new form adds inputs, route-contract checking, CSRF, response/error transforms. |", "| Generated API assertions in `.d.ts` | Assertions in real `wrnexus.generated.api-checks.ts` | Changed because `skipLibCheck` made `.d.ts` assertions inert. |", "| Client functions accidentally retaining TypeScript | Compiler strips type syntax before browser-module emission | Fixed and regression-tested. |", "| Markup merely highlighted as embedded HTML | Virtual HTML document plus HTML language service | Current editor adds tag/attribute completion, auto-close/rename, hover, Emmet, and folding; WRN formatter still owns formatting. |", "| Framework-only component ecosystem | Optional React `.tsx` islands | React is isolated and lazy; zero-JS routes remain unchanged; island SSR/Fast Refresh are deferred. |", "| Per-component/global style placement inconsistencies | `style {}` promoted to document head | Current pipeline supports CSP, HMR and CSR navigation. |", "| Manually maintained API/component knowledge | Generated public API and component references plus validation gates | `check:public-api`, generated-type checks, UI visual contract and package audits detect drift. |", "", "`legacyEmit`, `legacyEventProps`, `legacyComponentDiscovery`, `stringLayouts`, and `functions.legacyDefaultRuntime` (and the other pre-1.0 compatibility keys) were removed before the first public release; a config that still sets any of them is rejected by validation rather than honored.", "", "## 7. Diagnostics, security, and correctness guarantees", "", "Stable diagnostics include parse/member/prop/state/hydration/runtime/accessibility codes and feature-specific diagnostics such as island prop or missing-React errors. Compiler, CLI doctor/build, type generation, and editor tooling share syntax ownership to reduce parser drift.", "", "Security properties include escaped output by default, CSP-aware styles/scripts, same-origin API restriction, CSRF on non-GET callable API requests, credential handling via same-origin cookies, safe serialization, SSRF policies, request limits, auth/authz metadata and middleware, secret/audit gates, and application-layer encryption where explicitly needed. Security metadata is declarative input; enforcement still belongs to installed middleware/plugins and route policy.", "", "## 8. Current limitations and deferred work", "", "- Typed API blocks do not target third-party URLs, accept custom author headers, parameterize SSR requests, or provide built-in request caching/deduplication.", "- React islands are client-rendered in v1; island SSR/hydration and React Fast Refresh are deferred.", "- Native compilation does not directly port data API blocks; native screens use generated backend helpers.", "- HTML language features intentionally do not replace the WRN formatter.", "- Generated type checks must stay fresh; `check:generated-types` is the enforcement gate.", "", "## 9. Documentation drift discovered by this audit", "", `- Root ` + "`README.md`" + ` says 0.8.0, while the workspace manifest is ${rootPackage.version}.`, `- ` + "`packages/ui/README.md`" + ` says 85 components and ` + "`docs/UI-COMPONENT-INVENTORY.md`" + ` says 891; the current generated component reference contains ${uiReference.components.length}.`, "- `docs/WRN-LANGUAGE-SPEC-1.0.md` calls itself the 0.3.x contract and predates several implemented roots/members (stores, rendering modes, outputs, runtime-scoped state/functions, React islands, sectioned callable API blocks). Use it as historical baseline, not a complete 0.8.8 reference.", "- Package patch versions are intentionally ahead of the workspace umbrella version in many packages. Consumers should use the actual package manifest/version selected by the release process.", "", "## 10. Recommended release verification", "", "Run `bun run check:production` for the complete production gate. Its chain covers workspace repair, generated types, public API, UI visual contract, 0.8 validation, framework/ASVS security, editor bundle freshness, typecheck, lint, component imports, package tests, formatting, and examples. Additional focused commands include `bun run test:all`, `bun run audit:packages`, `bun run test:package-kits`, `bun run validate:staging`, `bun run sbom`, and `bun run benchmark:framework`.", "", "## Appendix A — package/version inventory", "", "| Package | Version | Purpose |", "| --- | --- | --- |", ); for (const item of packageRows) add(`| \`${item.name}\` | ${item.version} | ${item.description.replaceAll("|", "\\|")} |`); add("", "## Appendix B — complete audited public export inventory", ""); for (const [packageName, entries] of apiPackages) { const count = Object.values(entries).reduce((sum, symbols) => sum + symbols.length, 0); add(`### \`${packageName}\` (${count} symbols)`, ""); for (const [subpath, symbols] of Object.entries(entries)) { add(`- **${subpath}:** ${symbols.map((symbol) => `\`${symbol}\``).join(", ")}`); } add(""); } add("## Appendix C — current UI component/block reference", ""); for (const component of uiReference.components) { const props = component.props.length ? component.props .map( (prop) => `${prop.name}: ${prop.type}${prop.required ? " (required)" : ` = ${prop.default}`}`, ) .join("; ") : "none"; const outputs = component.outputs?.length ? component.outputs.map((output) => `${output.name}(${output.payloadType})`).join("; ") : "none"; const slots = component.slots?.length ? component.slots.join(", ") : "none"; add( `### \`${component.name}\``, "", `- Category: ${component.category}; mount: \`${component.mount}\`; source: \`${component.source}\`.`, `- Purpose: ${component.purpose}`, `- Props: ${props}`, `- Outputs/events: ${outputs}`, `- Slots: ${slots}`, "", ); } add("## Appendix D — all other package-owned `.wrn` blocks", ""); for (const [packageName, files] of [...packageBlocks.entries()].sort(([a], [b]) => a.localeCompare(b), )) { if (packageName === "ui") continue; add( `### \`@wrnexus/${packageName}\` (${files.length})`, "", ...files.map((file) => `- \`${file}\``), "", ); } add( "## Appendix E — authoritative files", "", "- Language parser/AST: `packages/syntax/src/parser.ts`, `v060.ts`, `api-sections.ts`, `spec.ts`.", "- Compiler/runtime: `packages/compiler/src`, `packages/csr/src`, `packages/ssr/src`, `packages/dev-server/src`.", "- Migration registry: `packages/cli/src/update.ts`.", "- Public exports: `docs/public-api-0.8.json` (checked by `scripts/check-public-api.mjs`).", "- UI blocks: `packages/ui/component-reference.json` and `packages/ui/COMPONENTS.md`.", "- Latest feature designs: `docs/superpowers/specs/2026-08-19-typed-api-block-design.md`, `2026-08-18-react-islands-design.md`, and `2026-08-18-wrn-html-editing-design.md`.", "", "---", "", "This report is reproducible: run `node scripts/generate-complete-framework-report.mjs` after implementation or generated-reference changes.", ); const report = await format(`${lines.join("\n")}\n`, { parser: "markdown" }); writeFileSync(join(root, "docs", "WRNEXUS-COMPLETE-FEATURE-REPORT.md"), report, "utf8"); console.log(`Wrote docs/WRNEXUS-COMPLETE-FEATURE-REPORT.md (${lines.length} lines).`);