create-patties 0.0.6 → 0.0.8

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +53 -0
  3. package/bin/create-patties.ts +7 -1
  4. package/package.json +7 -3
  5. package/src/index.ts +143 -25
  6. package/src/probes.ts +28 -0
  7. package/src/prompts.ts +98 -0
  8. package/src/readme.ts +67 -0
  9. package/templates/_claude/.claude/hooks/biome-check.sh +17 -0
  10. package/templates/_claude/.claude/rules/build-time-discovery.md +17 -0
  11. package/templates/_claude/.claude/rules/bun-native.md +28 -0
  12. package/templates/_claude/.claude/rules/filesystem-routing.md +31 -0
  13. package/templates/_claude/.claude/rules/islands.md +32 -0
  14. package/templates/_claude/.claude/rules/optional-ai.md +15 -0
  15. package/templates/_claude/.claude/rules/web-standards-boundary.md +25 -0
  16. package/templates/_claude/.claude/settings.json +18 -1
  17. package/templates/_claude/.claude/skills/patties-cli/SKILL.md +113 -0
  18. package/templates/_claude/CLAUDE.md +16 -51
  19. package/templates/_codex/.codex/README.md +10 -0
  20. package/templates/_codex/.codex/rules/build-time-discovery.md +17 -0
  21. package/templates/_codex/.codex/rules/bun-native.md +28 -0
  22. package/templates/_codex/.codex/rules/filesystem-routing.md +31 -0
  23. package/templates/_codex/.codex/rules/islands.md +32 -0
  24. package/templates/_codex/.codex/rules/optional-ai.md +15 -0
  25. package/templates/_codex/.codex/rules/patties-cli.md +113 -0
  26. package/templates/_codex/.codex/rules/web-standards-boundary.md +25 -0
  27. package/templates/_codex/AGENTS.md +21 -41
  28. package/templates/default/README-template.md +160 -6
  29. package/templates/default/app/islands/TodoApp.tsx +83 -0
  30. package/templates/default/app/routes/index.tsx +14 -3
  31. package/templates/default/app/server.ts +25 -0
  32. package/templates/default/app/islands/Counter.tsx +0 -12
@@ -1,48 +1,28 @@
1
- # {{PROJECT_NAME}}
1
+ # {{name}}
2
2
 
3
- Built with Patties — Bun-native full-stack meta-framework.
3
+ Built with Patties — a Bun-native full-stack meta-framework.
4
4
 
5
- > This file is read by Codex CLI and other AGENTS.md-aware tools. Patties also
6
- > auto-regenerates a live inventory `AGENTS.md` on `patties build` trust the
7
- > generated inventory for routes/islands/agents/tools, and this file for rules
8
- > and conventions.
5
+ > Codex reads this file. The conventions below are split into focused
6
+ > files under `.codex/rules/`; treat the links here as authoritative
7
+ > open each one when its topic is in scope for the task at hand.
9
8
 
10
- ## Stack
9
+ ## Conventions
11
10
 
12
- Bun runtime · `Bun.serve({ routes })` dispatcher · React renderer (`react-dom/server` + `react-dom/client`) · `{{DEPLOY_TARGET}}` deploy.
11
+ - [Bun-native](.codex/rules/bun-native.md) reach for Bun primitives, not Node-era replacements.
12
+ - [Web-standards boundary](.codex/rules/web-standards-boundary.md) — handlers use standard Request / Response; `PattiesContext` stays thin.
13
+ - [Filesystem routing](.codex/rules/filesystem-routing.md) — how `app/routes/` becomes URLs.
14
+ - [Islands](.codex/rules/islands.md) — when and how to use `app/islands/*.tsx`.
15
+ - [Build-time discovery](.codex/rules/build-time-discovery.md) — discovery happens at build time, not at request time.
16
+ - [Optional AI dependency](.codex/rules/optional-ai.md) — keep `@anthropic-ai/sdk` import-disjoint from non-AI code paths.
17
+ - [Patties CLI](.codex/rules/patties-cli.md) — `patties dev / build / start / deploy / secret`.
13
18
 
14
- ## File conventions
19
+ ## Live inventory
15
20
 
16
- | Path | Becomes |
17
- |---|---|
18
- | `app/routes/index.tsx` | `/` |
19
- | `app/routes/about.tsx` | `/about` |
20
- | `app/routes/hotels/[city].tsx` | `/hotels/:city` |
21
- | `app/routes/api/revenue.ts` | `/api/revenue` |
22
- | `app/islands/counter.tsx` | interactive island `Counter` |
23
- | `app/agents/booking.ts` | agent `booking` |
24
- | `app/tools/search.ts` | MCP tool `search` |
25
- | `app/middleware.ts` | global middleware |
26
- | `patties.config.ts` | framework config |
21
+ The block below is regenerated by `patties build` from the actual
22
+ contents of `app/`. Hand-edited content above the
23
+ `<!-- patties:generated -->` marker is preserved across regenerations;
24
+ everything below it is owned by the generator.
27
25
 
28
- Files starting with `_` are private and never routed. The URL prefix `/__patties_*` and output directory `/_patties/*` are reserved.
29
-
30
- ## Critical rules
31
-
32
- 1. Never import from `"next"`.
33
- 2. Never use Node.js `http`, `fs.watch`, or `chokidar`. Use `Bun.serve` and `bun --watch`.
34
- 3. Never use webpack or vite. Use `Bun.build`.
35
- 4. Use React for rendering. Server: `react-dom/server.renderToReadableStream`. Client: `react-dom/client.hydrateRoot`. Never `renderToPipeableStream` or `renderToString`. Never `hono/jsx` or `hono/jsx/dom`.
36
- 5. `tsconfig.json` sets `"jsx": "react-jsx"` and `"jsxImportSource": "react"` — no manual `import React` in user code.
37
- 6. All routes are plain `(req: Request, ctx: PattiesContext) => Response | Promise<Response>`. Never import from `"hono"`.
38
- 7. Islands live in `app/islands/` — no exceptions.
39
- 8. API routes export named `GET`, `POST`, `PUT`, `DELETE` functions. Default exports are reserved for page components.
40
- 9. Middleware default-exports a `Middleware = (req, ctx, next) => Promise<Response>`. Never `MiddlewareHandler` from Hono.
41
- 10. Use Bun primitives for I/O: `Bun.file`, `Bun.write`, `Bun.spawn`, `Bun.CryptoHasher`, `Bun.env`, `Bun.password`, `bun:sqlite`, `Bun.sql`, `Bun.RedisClient`, `Bun.S3Client`. `node:fs` only when no Bun built-in exists.
42
-
43
- ## How to run
44
-
45
- - `bun install`
46
- - `bun dev` — start the dev server
47
- - `bun build` — build for production
48
- - `bun test`
26
+ <!-- patties:generated -->
27
+ <!-- The block below is rewritten by `patties build`. Do not edit by hand. -->
28
+ <!-- /patties:generated -->
@@ -1,16 +1,170 @@
1
- # Patties app
1
+ # {{name}}
2
2
 
3
- Bun-native full-stack app. Generated by `create-patties`.
3
+ Built with [Patties](https://github.com/bihaviour-ai/bun-patties-framework) a
4
+ Bun-native full-stack meta-framework.
4
5
 
5
- ## Develop
6
+ <!-- if:scaffold=demo -->
7
+ ## What you got
6
8
 
9
+ An interactive todo demo:
10
+
11
+ - `app/routes/index.tsx` — server-rendered page that mounts the island.
12
+ - `app/islands/TodoApp.tsx` — `useState`-based todo list, hydrated in the
13
+ browser.
14
+ - `app/server.ts` — dev entry that wires the router into `Bun.serve`.
15
+
16
+ ## Run it
17
+
18
+ ```sh
19
+ bun install # if you used --no-install
20
+ bun dev # → http://localhost:3000
21
+ ```
22
+
23
+ > **Heads up — dev mode currently only does SSR.** The todo list will render
24
+ > but the buttons won't react to clicks under `bun dev`. To see the island
25
+ > hydrate and the demo actually work, build and serve:
26
+ >
27
+ > ```sh
28
+ > bun run build
29
+ > bun start
30
+ > ```
31
+ >
32
+ > Full dev-mode hydration is tracked under framework spec 18 and will land
33
+ > in a future Patties release — at that point `bun dev` will be enough.
34
+
35
+ ## Try editing
36
+
37
+ 1. Open `app/routes/index.tsx`, change the heading text, save. The browser
38
+ reloads (HMR).
39
+ 2. Open `app/islands/TodoApp.tsx`, change the initial todo list or input
40
+ placeholder, save, rebuild with `bun run build && bun start`, and try it.
41
+
42
+ ## Remove the demo when you're ready
43
+
44
+ The todo demo exists to show you state hydration. When you start your real
45
+ app, delete it:
46
+
47
+ ```sh
48
+ rm app/islands/TodoApp.tsx
7
49
  ```
8
- bun install
9
- bun dev
50
+
51
+ Then replace `app/routes/index.tsx` with whatever your landing page should
52
+ be — a minimal version:
53
+
54
+ ```tsx
55
+ export default function Index(): JSX.Element {
56
+ return <main><h1>Hello from {{name}}</h1></main>;
57
+ }
58
+ ```
59
+
60
+ If you don't need any islands at all, you can also delete the empty
61
+ `app/islands/` directory. You can re-scaffold without the demo at any time
62
+ using `bunx create-patties@latest <new-name> --blank`.
63
+ <!-- /if -->
64
+ <!-- if:scaffold=blank -->
65
+ ## What you got
66
+
67
+ A minimal hello-world Patties app:
68
+
69
+ - `app/routes/index.tsx` — server-rendered landing page.
70
+ - `app/server.ts` — dev entry that wires the router into `Bun.serve`.
71
+
72
+ ## Run it
73
+
74
+ ```sh
75
+ bun install # if you used --no-install
76
+ bun dev # → http://localhost:3000
10
77
  ```
11
78
 
12
- ## Build
79
+ ## Add your first interactive feature
80
+
81
+ Create `app/islands/` and drop in a component that uses `useState` or
82
+ `useEffect`. Import it from a route file under `app/routes/`. Islands hydrate
83
+ on the client; everything else runs server-only.
84
+
85
+ > Note: full dev-mode island hydration is tracked under framework spec 18
86
+ > and lands in a future Patties release. Until then, build + start to see
87
+ > islands react: `bun run build && bun start`.
88
+ <!-- /if -->
13
89
 
90
+ ## Project layout
91
+
92
+ ```
93
+ app/
94
+ routes/ # filesystem-routed pages and API handlers
95
+ islands/ # interactive client components
96
+ server.ts # dev entry — wires the router into Bun.serve
97
+ patties.config.ts
98
+ package.json
99
+ tsconfig.json
14
100
  ```
101
+
102
+ ## Build for production
103
+
104
+ ```sh
15
105
  bun run build
16
106
  ```
107
+
108
+ Build artifacts land in `.patties/`. Run the server bundle with:
109
+
110
+ ```sh
111
+ bun .patties/server/server-entry.js
112
+ ```
113
+
114
+ <!-- if:deploy=cloudflare -->
115
+ ## Deploy
116
+
117
+ This project is configured for **Cloudflare** deployment. See the
118
+ `@patties/deploy-cloudflare` plugin docs for the next steps.
119
+ <!-- /if -->
120
+ <!-- if:deploy=vercel -->
121
+ ## Deploy
122
+
123
+ This project is configured for **Vercel** deployment. See the
124
+ `@patties/deploy-vercel` plugin docs for the next steps.
125
+ <!-- /if -->
126
+ <!-- if:deploy=deno -->
127
+ ## Deploy
128
+
129
+ This project is configured for **Deno Deploy**. See the
130
+ `@patties/deploy-deno` plugin docs for the next steps.
131
+ <!-- /if -->
132
+ <!-- if:deploy=netlify -->
133
+ ## Deploy
134
+
135
+ This project is configured for **Netlify Edge**. See the
136
+ `@patties/deploy-netlify` plugin docs for the next steps.
137
+ <!-- /if -->
138
+ <!-- if:deploy=bun -->
139
+ ## Deploy
140
+
141
+ This project ships as a standalone Bun bundle. Run `bun run build` then
142
+ deploy the contents of `.patties/` to any host that runs Bun.
143
+ <!-- /if -->
144
+
145
+ <!-- if:agent=claude -->
146
+ ## Claude Code is set up
147
+
148
+ `CLAUDE.md` at the project root describes the framework conventions for Claude
149
+ Code. `.claude/settings.json` allow-lists the commands you'll typically need
150
+ (`bun`, `bunx`, `patties`). `.claude/hooks/biome-check.sh` runs Biome after
151
+ every edit if you install it (`bun add -d @biomejs/biome`).
152
+
153
+ Launch a session with `claude` in this directory.
154
+ <!-- /if -->
155
+ <!-- if:agent=codex -->
156
+ ## Codex is set up
157
+
158
+ `AGENTS.md` at the project root describes the framework conventions for
159
+ Codex CLI and other AGENTS.md-aware tools. Patties regenerates this file on
160
+ `patties build` while preserving sections you mark with
161
+ `<!-- patties:user --> ... <!-- /patties:user -->`.
162
+
163
+ Launch a session with `codex` in this directory.
164
+ <!-- /if -->
165
+
166
+ ## Learn more
167
+
168
+ - Patties docs: https://bun-patties.com
169
+ - Bun: https://bun.sh
170
+ - React 19: https://react.dev
@@ -0,0 +1,83 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+
5
+ interface Todo {
6
+ id: number;
7
+ text: string;
8
+ done: boolean;
9
+ }
10
+
11
+ export default function TodoApp(): JSX.Element {
12
+ const [todos, setTodos] = useState<Todo[]>([
13
+ { id: 1, text: "edit app/routes/index.tsx", done: false },
14
+ { id: 2, text: "edit app/islands/TodoApp.tsx", done: false },
15
+ { id: 3, text: "delete this demo when you're ready", done: false },
16
+ ]);
17
+ const [draft, setDraft] = useState("");
18
+
19
+ function add(): void {
20
+ const text = draft.trim();
21
+ if (!text) return;
22
+ setTodos([...todos, { id: Date.now(), text, done: false }]);
23
+ setDraft("");
24
+ }
25
+
26
+ function toggle(id: number): void {
27
+ setTodos(todos.map((t) => (t.id === id ? { ...t, done: !t.done } : t)));
28
+ }
29
+
30
+ function remove(id: number): void {
31
+ setTodos(todos.filter((t) => t.id !== id));
32
+ }
33
+
34
+ return (
35
+ <section aria-label="Todo demo">
36
+ <form
37
+ onSubmit={(e) => {
38
+ e.preventDefault();
39
+ add();
40
+ }}
41
+ >
42
+ <input
43
+ type="text"
44
+ value={draft}
45
+ onChange={(e) => setDraft(e.target.value)}
46
+ placeholder="What needs doing?"
47
+ aria-label="New todo"
48
+ />
49
+ <button type="submit">Add</button>
50
+ </form>
51
+ <ul>
52
+ {todos.map((t) => (
53
+ <li key={t.id}>
54
+ <label>
55
+ <input
56
+ type="checkbox"
57
+ checked={t.done}
58
+ onChange={() => toggle(t.id)}
59
+ />
60
+ <span
61
+ style={{ textDecoration: t.done ? "line-through" : "none" }}
62
+ >
63
+ {t.text}
64
+ </span>
65
+ </label>
66
+ <button
67
+ type="button"
68
+ onClick={() => remove(t.id)}
69
+ aria-label="Remove"
70
+ >
71
+ ×
72
+ </button>
73
+ </li>
74
+ ))}
75
+ </ul>
76
+ <p>
77
+ <small>
78
+ {todos.filter((t) => !t.done).length} of {todos.length} remaining
79
+ </small>
80
+ </p>
81
+ </section>
82
+ );
83
+ }
@@ -1,10 +1,21 @@
1
- import Counter from "../islands/Counter.tsx";
1
+ import TodoApp from "../islands/TodoApp.tsx";
2
2
 
3
3
  export default function Index(): JSX.Element {
4
4
  return (
5
5
  <main>
6
- <h1>Hello from Patties</h1>
7
- <Counter />
6
+ <h1>Welcome to Patties</h1>
7
+ <p>
8
+ This page is server-rendered. The list below is a client island —{" "}
9
+ <code>app/islands/TodoApp.tsx</code> — hydrated in the browser.
10
+ </p>
11
+ <TodoApp />
12
+ <hr />
13
+ <p>
14
+ <small>
15
+ When you're ready to start your real app, see the "Remove the demo"
16
+ section of <code>README.md</code>.
17
+ </small>
18
+ </p>
8
19
  </main>
9
20
  );
10
21
  }
@@ -0,0 +1,25 @@
1
+ import type { DevServer } from "patties/dev";
2
+ import { createRenderer } from "patties/render";
3
+ import { createRouter } from "patties/router";
4
+ import { startServer } from "patties/server";
5
+
6
+ interface StartOpts {
7
+ devServer: DevServer;
8
+ port: number;
9
+ host: string;
10
+ appDir: string;
11
+ }
12
+
13
+ export default async function start(opts: StartOpts): Promise<void> {
14
+ const renderer = createRenderer({ dev: true });
15
+ const router = await createRouter({ appDir: opts.appDir, renderer });
16
+
17
+ startServer({
18
+ port: opts.port,
19
+ hostname: opts.host,
20
+ dev: true,
21
+ devServer: opts.devServer,
22
+ routes: router.routes,
23
+ fallback: router.fallback,
24
+ });
25
+ }
@@ -1,12 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
-
5
- export default function Counter(): JSX.Element {
6
- const [n, setN] = useState(0);
7
- return (
8
- <button type="button" onClick={() => setN(n + 1)}>
9
- clicked {n} times
10
- </button>
11
- );
12
- }