create-nowaki 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "create-nowaki",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Scaffold a new Nowaki app",
5
5
  "license": "MIT",
6
- "author": "Voredge <dev@voredge.com>",
6
+ "author": "VorEdge <dev@voredge.com>",
7
7
  "homepage": "https://nowaki.dev",
8
8
  "repository": {
9
9
  "type": "git",
@@ -0,0 +1,88 @@
1
+ # AGENTS.md — building this Nowaki app
2
+
3
+ Guidance for AI coding agents (Claude Code, Codex, Gemini, Cursor, Copilot, Grok,
4
+ Kimi, …) working in this app. Nowaki is a full-stack framework with a Rust
5
+ toolchain: pages render to HTML on the server, and only the components under
6
+ `islands/` ship JavaScript and hydrate. Full docs: <https://nowaki.dev/docs>.
7
+
8
+ ## Commands
9
+
10
+ ```bash
11
+ npm run dev # nowaki dev — dev server with hot reload (http://localhost:3000)
12
+ npm run build # nowaki build — production build (dist/client + dist/server)
13
+ npm run start # nowaki start — serve the production build
14
+ npm run prerender # nowaki prerender — static export
15
+ ```
16
+
17
+ ## Project layout
18
+
19
+ ```
20
+ routes/ file-based routes (pages + API). _layout.tsx, _middleware.ts,
21
+ _404.tsx, _500.tsx, [slug].tsx, api/*.ts
22
+ islands/ interactive components — THE ONLY things that ship JS and hydrate
23
+ components/ shared server components (no client JS)
24
+ lib/ shared server code
25
+ actions/ "use server" RPC modules (optional)
26
+ nowaki.config.mjs plugins (optional)
27
+ ```
28
+
29
+ ## Rules — follow these when generating code
30
+
31
+ 1. **Preact, not React.** Import hooks from `preact/hooks`
32
+ (`import { useState } from "preact/hooks"`). `react`, `react-dom`, and
33
+ `react/jsx-runtime` are aliased to `preact/compat`, so many React libraries
34
+ work, but write Preact.
35
+ 2. **Interactivity lives in `islands/`.** A component with `useState`, event
36
+ handlers, effects, etc. must be a file under `islands/`. A route or component
37
+ that imports an island stays server-HTML; only the island hydrates. Don't put
38
+ `onClick`/hooks in route or `components/` files.
39
+ 3. **Use explicit file extensions in relative imports**:
40
+ `import Counter from "../islands/Counter.tsx"` (not `"../islands/Counter"`).
41
+ 4. **Routes** are components with an optional server-only `loader` and `action`:
42
+ ```tsx
43
+ // routes/blog/[slug].tsx
44
+ export const loader = async ({ params }) => ({ post: await db.post(params.slug) }); // server-only
45
+ export async function action(ctx) { // runs on non-GET requests
46
+ const form = await ctx.formData();
47
+ return ctx.redirect("/blog"); // Post/Redirect/Get
48
+ }
49
+ export default function Post({ data }) { return <article><h1>{data.post.title}</h1></article>; }
50
+ ```
51
+ 5. **API routes** are `routes/api/*.ts` with per-method exports; return a value
52
+ (JSON-encoded) or a `Response`:
53
+ ```ts
54
+ export const GET = (ctx) => ctx.json({ ok: true });
55
+ export const POST = async (ctx) => ctx.json({ got: await ctx.bodyJson() });
56
+ ```
57
+ 6. **Islands** are default-exported components:
58
+ ```tsx
59
+ // islands/Counter.tsx
60
+ import { useState } from "preact/hooks";
61
+ export default function Counter({ start = 0 }) {
62
+ const [n, setN] = useState(start);
63
+ return <button onClick={() => setN(n + 1)}>count: {n}</button>;
64
+ }
65
+ ```
66
+ 7. **Server functions** — a module with a top-of-file `"use server"` directive
67
+ becomes RPC; the client gets a tiny fetch proxy, the implementation stays on
68
+ the server. Validate arguments; read auth via `getContext()`:
69
+ ```ts
70
+ // actions/todos.ts
71
+ "use server";
72
+ import { getContext } from "@nowaki-dev/runtime/server/functions.mjs";
73
+ export async function addTodo(text: string) { /* runs on the server */ }
74
+ ```
75
+ Call it from an island like a normal async function:
76
+ `import { addTodo } from "../actions/todos.ts";`
77
+ 8. **Jetstream islands** (server-reactive, zero client JS) — give an island
78
+ `export const live = { state, on }`; buttons use `data-live="handler"` instead
79
+ of `onClick`. State lives on the server; the server pushes HTML patches.
80
+
81
+ ## Don't
82
+
83
+ - Don't add a build tool (Vite/webpack/Babel) or a `tsconfig` paths setup — the
84
+ Rust toolchain handles transform/resolve/bundle.
85
+ - Don't import React directly hoping for React internals; it's Preact under the hood.
86
+ - Don't put interactive components outside `islands/`.
87
+ - Don't read secrets on the client. Only `PUBLIC_*` env vars reach the browser;
88
+ everything else is server-only (loaders, actions, server functions).
@@ -0,0 +1,10 @@
1
+ # CLAUDE.md
2
+
3
+ This app's agent guidance is in **[AGENTS.md](./AGENTS.md)** — read it first.
4
+
5
+ TL;DR: Nowaki renders pages to HTML; only components under `islands/` ship JS and
6
+ hydrate. Write **Preact** (hooks from `preact/hooks`), use **explicit file
7
+ extensions** in relative imports, put interactive components in `islands/`, and
8
+ use route `loader`/`action`, `routes/api/*.ts`, `"use server"` modules, or
9
+ Jetstream islands (`export const live`) as needed. Commands: `npm run dev`,
10
+ `npm run build`, `npm run start`. Docs: https://nowaki.dev/docs