fix: repair main after an unreviewed commit, and record the cause
Three separate problems, all traceable to `git add -A` sweeping up a working
tree I had not inspected.
Commit 69020b25 ("docs: make the component sections executable") committed far
more than docs: 79 files of a half-scaffolded inter-app example, and four of
those files were truncated mid-statement. That broke `bun run typecheck` on
main. The example is reverted to its last green six-file form. The truncated
fragments and the fuller working copy are NOT in this commit -- if any of that
workspace was wanted, it needs to be reconstructed deliberately and committed on
its own, not as a side effect of a docs change.
Separately, `scripts/generate-ui-complete-catalog.mjs` was run while checking
which helper scripts still work. It rewrites components in place, so it
flattened six of them to stubs, deleted 24 more and lower-cased four filenames
before crashing. Contents were restored from HEAD, but the renames survived
that restore: Windows is case-insensitive, so `git status` reported clean while
Card, Container, Divider and Grid sat on disk under the wrong names. The index
now tracks the capitalised names, which is what the components declare and what
ui-redesign-contract.test.ts reads -- that test would have failed on any
case-sensitive checkout.
Documented both as 4.7 and 4.8 in the remediation plan, with the general rule:
no script that rewrites packages/ui/components/ may write in place. Also fixes
the heading level on 4.6, which was rendering outside section 4.
bun run check is green: 1,433 pass, 0 fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
// POST /api/ai { "prompt": "..." } → Claude's reply.
|
||||
// Set ANTHROPIC_API_KEY in your environment (e.g. a .env file) to enable this.
|
||||
import { createAI } from "@wrnexus/ai";
|
||||
import type { Context } from "@wrnexus/core";
|
||||
|
||||
const ai = createAI(); // reads ANTHROPIC_API_KEY; defaults to claude-opus-4-8
|
||||
|
||||
export const POST = async (ctx: Context) => {
|
||||
if (!process.env.ANTHROPIC_API_KEY) {
|
||||
return Response.json({ error: "Set ANTHROPIC_API_KEY to use AI." }, { status: 501 });
|
||||
}
|
||||
const { prompt } = await ctx.req.json().catch(() => ({}));
|
||||
if (!prompt) return Response.json({ error: "Provide a 'prompt'." }, { status: 400 });
|
||||
|
||||
// Stream the reply back as plain text. Use `ai.generate(prompt)` for a one-shot string.
|
||||
return ai.streamResponse(prompt);
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
export const GET = async () => {
|
||||
return Response.json({ message: "Hello API" });
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { Context } from "../../../../../../packages/core/src/index.ts";
|
||||
import {
|
||||
httpTransport,
|
||||
retryingTransport,
|
||||
serviceClient,
|
||||
} from "../../../../../../packages/rpc/src/index.ts";
|
||||
import { catalogService } from "../../../../packages/shared/src/index.ts";
|
||||
|
||||
/** GET /api/product?sku=starter — obtains product data from the admin app. */
|
||||
export async function GET(ctx: Context): Promise<Response> {
|
||||
const sku = new URL(ctx.req.url).searchParams.get("sku")?.trim() || "starter";
|
||||
const catalog = serviceClient(catalogService, {
|
||||
app: "admin",
|
||||
as: ctx,
|
||||
transport: retryingTransport(
|
||||
@@ -1,20 +0,0 @@
|
||||
// A reusable component. Route: none — mounted inside a page with
|
||||
// <div data-component="counter" ...props></div>.
|
||||
//
|
||||
// Components render on the SERVER (with their props applied) and are hydrated in
|
||||
// the browser by the generic reactive runtime — they ship no JS of their own.
|
||||
component Counter {
|
||||
// Props arrive as mount attributes, each coerced to the type of its default
|
||||
// (so start="5" arrives as the number 5).
|
||||
props {
|
||||
start = 0
|
||||
label = "Count"
|
||||
}
|
||||
|
||||
// State can reference props. `count` seeds the reactive scope.
|
||||
state count = start
|
||||
|
||||
view {
|
||||
<button @click="count++" class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition hover:bg-indigo-500 active:scale-[0.98]">{label}: {count}</button>
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Create application tables here.
|
||||
-- Run with: bunx wrnexus db migrate
|
||||
@@ -1,2 +0,0 @@
|
||||
// Add deterministic development seed data here.
|
||||
export async function seed(): Promise<void> {}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Global document layout. The framework renders this once around the selected
|
||||
// page layout and merges SEO metadata, styles, and scripts into <head>/<body>.
|
||||
// Request cookies, resolved theme, language, URL, and pathname are available
|
||||
// as SSR props, so document attributes do not need a client-side correction.
|
||||
layout Document {
|
||||
props {
|
||||
cookies = {}
|
||||
theme = "light"
|
||||
language = "en"
|
||||
url = ""
|
||||
pathname = "/"
|
||||
}
|
||||
|
||||
view {
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<div id="app"><slot /></div>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"common": {
|
||||
"appName": "web",
|
||||
"welcome": "Welcome to web"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { Middleware } from "@wrnexus/core";
|
||||
|
||||
const logger: Middleware = async (ctx, next) => {
|
||||
console.log(ctx.req.method, ctx.url.pathname);
|
||||
return next();
|
||||
};
|
||||
|
||||
export default logger;
|
||||
@@ -1,20 +0,0 @@
|
||||
page About {
|
||||
seo {
|
||||
title = "About"
|
||||
description = "Learn how web is built with WrNexus."
|
||||
}
|
||||
|
||||
view {
|
||||
<main class="min-h-screen bg-white px-6 py-20 text-slate-900 dark:bg-[#0b0f1e] dark:text-slate-100">
|
||||
<article class="mx-auto max-w-2xl">
|
||||
<a href="/" class="text-sm text-indigo-600 hover:underline dark:text-indigo-400">← Home</a>
|
||||
<p class="mt-12 font-mono text-xs uppercase tracking-[0.2em] text-indigo-500">WrNexus application</p>
|
||||
<h1 class="mt-4 text-4xl font-bold tracking-tight">About web</h1>
|
||||
<p class="mt-6 text-lg leading-8 text-slate-600 dark:text-slate-400">
|
||||
This page is server-rendered from <code>app/pages/about.wrn</code>. Add state,
|
||||
events, components, APIs, and data without switching to another UI framework.
|
||||
</p>
|
||||
</article>
|
||||
</main>
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// Home page (route: /). SSR-first: the view is server-rendered, then components
|
||||
// (.wrn files under app/components) hydrate in the browser. Styled with Tailwind.
|
||||
page Home {
|
||||
seo {
|
||||
title = "Home"
|
||||
description = "web — built with WrNexus, an SSR-first Bun framework."
|
||||
}
|
||||
|
||||
view {
|
||||
<main class="relative min-h-screen overflow-hidden bg-white text-slate-900 dark:bg-[#0b0f1e] dark:text-slate-100">
|
||||
<div aria-hidden="true" class="pointer-events-none absolute inset-x-0 -top-40 mx-auto h-96 max-w-2xl rounded-full bg-indigo-500/20 blur-3xl"></div>
|
||||
|
||||
<div class="relative mx-auto flex min-h-screen max-w-3xl flex-col px-6">
|
||||
<header class="flex items-center justify-between py-6">
|
||||
<span class="flex items-center gap-2.5 font-semibold tracking-tight">
|
||||
<span class="grid h-7 w-7 place-items-center rounded-md bg-gradient-to-br from-indigo-500 to-violet-600 text-sm font-bold text-white">W</span>
|
||||
web
|
||||
</span>
|
||||
<button data-wire-theme-toggle class="rounded-md border border-slate-200 px-3 py-1.5 text-sm text-slate-600 transition hover:border-slate-300 hover:text-slate-900 dark:border-white/10 dark:text-slate-400 dark:hover:border-white/20 dark:hover:text-white">
|
||||
Toggle theme
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<section class="flex flex-1 flex-col items-center justify-center py-16 text-center">
|
||||
<p class="font-mono text-xs uppercase tracking-[0.2em] text-indigo-500 dark:text-indigo-400">SSR-first · Bun-native</p>
|
||||
|
||||
<h1 class="mt-5 text-4xl font-bold leading-[1.1] tracking-tight sm:text-6xl">
|
||||
Server-rendered.<br />
|
||||
Instantly <span class="bg-gradient-to-r from-indigo-500 to-violet-500 bg-clip-text text-transparent">interactive</span>.
|
||||
</h1>
|
||||
|
||||
<p class="mt-5 max-w-md text-base leading-relaxed text-slate-600 dark:text-slate-400">
|
||||
web runs on WrNexus — write <code class="rounded bg-slate-100 px-1.5 py-0.5 font-mono text-[0.85em] text-slate-800 dark:bg-white/10 dark:text-slate-200">.wrn</code> components, ship no client boilerplate, and let the server do the work.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||||
<a href="/about" class="rounded-lg bg-slate-900 px-5 py-2.5 text-sm font-medium text-white shadow-sm transition hover:bg-slate-700 dark:bg-white dark:text-slate-900 dark:hover:bg-slate-200">Get started</a>
|
||||
<a href="/api/hello" class="rounded-lg border border-slate-200 px-5 py-2.5 text-sm font-medium text-slate-700 transition hover:border-slate-300 dark:border-white/10 dark:text-slate-300 dark:hover:border-white/20">View API</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-14 w-full max-w-md rounded-2xl border border-slate-200 bg-white p-6 text-left shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||
<div class="flex items-center gap-2 font-mono text-xs text-slate-400">
|
||||
<span class="h-2 w-2 rounded-full bg-emerald-400"></span>
|
||||
live · hydrated on the server
|
||||
</div>
|
||||
<div class="mt-4 flex items-center justify-between gap-4">
|
||||
<div data-component="counter" start="0" label="Clicks"></div>
|
||||
<span class="max-w-[10rem] text-right text-xs leading-snug text-slate-500">This button works. You wrote zero client JavaScript.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-10 font-mono text-xs text-slate-400 dark:text-slate-600">
|
||||
edit <span class="text-slate-600 dark:text-slate-400">app/pages/index.wrn</span> to make it yours
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<footer class="border-t border-slate-100 py-6 text-center text-xs text-slate-400 dark:border-white/5 dark:text-slate-600">
|
||||
Built with <a href="https://www.npmjs.com/package/@wrnexus/cli" class="text-slate-600 underline-offset-2 hover:underline dark:text-slate-400">WrNexus</a>
|
||||
</footer>
|
||||
</div>
|
||||
</main>
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// ws://<host>/realtime/chat — a simple broadcast room.
|
||||
//
|
||||
// The client side is the framework's realtime runtime; a page opts in with
|
||||
// `data-room="chat"`. Here we only handle room events.
|
||||
//
|
||||
// client.send(msg) → just this connection
|
||||
// client.broadcast(msg) → everyone else in the room
|
||||
// client.room.broadcast(msg) → everyone, including the sender
|
||||
import { defineRoom } from "@wrnexus/core";
|
||||
|
||||
export default defineRoom({
|
||||
onConnect(client) {
|
||||
client.send({ type: "system", text: "connected" });
|
||||
},
|
||||
|
||||
onMessage(client, msg) {
|
||||
// Echo each message to the whole room so every tab stays in sync.
|
||||
client.room.broadcast({ type: "message", data: msg });
|
||||
},
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
import { v } from "@wrnexus/validation";
|
||||
|
||||
export const contactSchema = v.object({
|
||||
email: v.string().email(),
|
||||
message: v.string().min(10).max(2_000),
|
||||
});
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Global stylesheet. Tailwind v4 is compiled by the styles.process hook in
|
||||
* wrnexus.config.ts and served at /__wrnexus/styles.css on every page.
|
||||
*
|
||||
* @source tells Tailwind which files to scan for class names.
|
||||
*/
|
||||
@import "tailwindcss";
|
||||
@plugin "@iconify/tailwind4";
|
||||
@source "../**/*.wrn";
|
||||
@source "../**/*.tsx";
|
||||
|
||||
/* Make Tailwind's `dark:` variant follow the framework's data-theme attribute
|
||||
* (set on <html> by the theme system), not the OS setting. Any element with
|
||||
* data-wire-theme-toggle flips it. */
|
||||
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
||||
|
||||
body {
|
||||
font-family: var(--wire-font-sans, "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif);
|
||||
}
|
||||
Reference in New Issue
Block a user