create-patties 0.0.6 → 0.0.9
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/CHANGELOG.md +52 -0
- package/README.md +53 -0
- package/bin/create-patties.ts +9 -1
- package/package.json +12 -3
- package/src/index.ts +194 -25
- package/src/probes.ts +28 -0
- package/src/prompts.ts +98 -0
- package/src/readme.ts +67 -0
- package/templates/_claude/.claude/hooks/biome-check.sh +17 -0
- package/templates/_claude/.claude/rules/build-time-discovery.md +17 -0
- package/templates/_claude/.claude/rules/bun-native.md +28 -0
- package/templates/_claude/.claude/rules/filesystem-routing.md +31 -0
- package/templates/_claude/.claude/rules/islands.md +32 -0
- package/templates/_claude/.claude/rules/optional-ai.md +15 -0
- package/templates/_claude/.claude/rules/web-standards-boundary.md +25 -0
- package/templates/_claude/.claude/settings.json +18 -1
- package/templates/_claude/.claude/skills/patties-cli/SKILL.md +113 -0
- package/templates/_claude/CLAUDE.md +16 -51
- package/templates/_codex/.codex/README.md +10 -0
- package/templates/_codex/.codex/rules/build-time-discovery.md +17 -0
- package/templates/_codex/.codex/rules/bun-native.md +28 -0
- package/templates/_codex/.codex/rules/filesystem-routing.md +31 -0
- package/templates/_codex/.codex/rules/islands.md +32 -0
- package/templates/_codex/.codex/rules/optional-ai.md +15 -0
- package/templates/_codex/.codex/rules/patties-cli.md +113 -0
- package/templates/_codex/.codex/rules/web-standards-boundary.md +25 -0
- package/templates/_codex/AGENTS.md +21 -41
- package/templates/default/README-template.md +160 -6
- package/templates/default/app/islands/TodoApp.tsx +83 -0
- package/templates/default/app/routes/index.tsx +22 -3
- package/templates/default/app/server.ts +28 -0
- package/templates/default/app/islands/Counter.tsx +0 -12
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Build-time discovery rule
|
|
2
|
+
|
|
3
|
+
Routes, islands, agents, and tools are discovered from the filesystem
|
|
4
|
+
at **build time**, not at request time.
|
|
5
|
+
|
|
6
|
+
- `patties build` scans `app/routes/`, `app/islands/`, `app/agents/`,
|
|
7
|
+
`app/tools/`, and `app/jobs/` and inlines the discovered tables into
|
|
8
|
+
the server bundle. The production server never calls `Bun.Glob` /
|
|
9
|
+
`scanRoutes` / `scanIslands`.
|
|
10
|
+
- This is what makes Patties cold-start fast and adapter-portable
|
|
11
|
+
(edge runtimes that disallow filesystem access still work).
|
|
12
|
+
- **Dev mode is the exception.** The dev server re-scans on file
|
|
13
|
+
change to drive HMR.
|
|
14
|
+
- **Don't break the rule:** never write code that calls `Bun.Glob` or
|
|
15
|
+
reads `app/**` at request time. If you find yourself wanting to,
|
|
16
|
+
the answer is probably a build-time macro or a config option in
|
|
17
|
+
`patties.config.ts`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Bun-native rule
|
|
2
|
+
|
|
3
|
+
This project runs on Bun. Reach for Bun primitives first; do not
|
|
4
|
+
reintroduce Node-era replacements just because a familiar library
|
|
5
|
+
provides them.
|
|
6
|
+
|
|
7
|
+
- **HTTP server:** `Bun.serve`. The framework already wires it — do
|
|
8
|
+
not add Express / Fastify / Hono / `node:http`.
|
|
9
|
+
- **Filesystem discovery:** `Bun.Glob`. Do not pull in `fast-glob`,
|
|
10
|
+
`globby`, or `chokidar`.
|
|
11
|
+
- **Bundling:** `Bun.build`. The framework runs it for you at
|
|
12
|
+
`patties build`; you should not add Webpack / Rollup / esbuild /
|
|
13
|
+
Vite / tsup.
|
|
14
|
+
- **File I/O:** `Bun.file(path).text()` / `.json()` / `.bytes()` and
|
|
15
|
+
`Bun.write(path, data)` before reaching for `node:fs`.
|
|
16
|
+
- **Hashing / crypto:** `Bun.CryptoHasher`, `Bun.password`. Avoid
|
|
17
|
+
`crypto` / `bcrypt` unless you have a real reason.
|
|
18
|
+
- **Databases:** `bun:sqlite`, `Bun.sql` (Postgres), `Bun.RedisClient`,
|
|
19
|
+
`Bun.S3Client` before reaching for npm wrappers.
|
|
20
|
+
- **Environment:** `Bun.env`. The framework injects the public subset
|
|
21
|
+
declared in `patties.config.ts#env.public`; secrets live in the OS
|
|
22
|
+
keychain (see `patties-cli` skill).
|
|
23
|
+
- **Tests:** `bun test`. Do not add Jest or Vitest.
|
|
24
|
+
- **Package manager:** `bun` / `bunx`. Do not run `npm` / `npx` /
|
|
25
|
+
`yarn` / `pnpm` in this project.
|
|
26
|
+
|
|
27
|
+
If you genuinely need a Node-only library, that's fine — Bun's Node
|
|
28
|
+
compatibility is strong. But default to Bun primitives.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Filesystem routing rule
|
|
2
|
+
|
|
3
|
+
Routes are discovered from the filesystem under `app/routes/`. Path
|
|
4
|
+
conventions:
|
|
5
|
+
|
|
6
|
+
| File | URL |
|
|
7
|
+
|---|---|
|
|
8
|
+
| `app/routes/index.tsx` | `/` |
|
|
9
|
+
| `app/routes/about.tsx` | `/about` |
|
|
10
|
+
| `app/routes/hotels/index.tsx` | `/hotels` |
|
|
11
|
+
| `app/routes/hotels/[city].tsx` | `/hotels/:city` |
|
|
12
|
+
| `app/routes/api/revenue.ts` | `/api/revenue` |
|
|
13
|
+
| `app/routes/_internal.tsx` | (private — never routed) |
|
|
14
|
+
|
|
15
|
+
- **Page routes** are `.tsx` files that default-export a React
|
|
16
|
+
component. The component receives no props by default; read params
|
|
17
|
+
/ cookies / env from `PattiesContext` via the page's optional
|
|
18
|
+
`loader` (export `loader` if you need server-side data).
|
|
19
|
+
- **API routes** are `.ts` files that export named HTTP-method handlers:
|
|
20
|
+
`GET`, `POST`, `PUT`, `DELETE`, `PATCH`. They return a standard
|
|
21
|
+
`Response`. Default exports in `.ts` files are reserved and will
|
|
22
|
+
error.
|
|
23
|
+
- **Dynamic segments** use `[param]` in the filename. The values land
|
|
24
|
+
in `ctx.params`.
|
|
25
|
+
- **Files starting with `_`** are private — co-located helpers,
|
|
26
|
+
components, or test files. They are never routed.
|
|
27
|
+
- **Reserved URL prefixes:** `/__patties_*` and `/_patties/*` are
|
|
28
|
+
framework-owned. Don't put your own routes under them.
|
|
29
|
+
- **Discovery happens at build time.** The production server bundle
|
|
30
|
+
has the route table inlined; it does not call `Bun.Glob` at runtime.
|
|
31
|
+
Dev mode re-scans on file change (that's where HMR comes from).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Islands rule
|
|
2
|
+
|
|
3
|
+
The default rendering mode is server-side. Use **islands** for the
|
|
4
|
+
parts of a page that need browser-side interactivity (`useState`,
|
|
5
|
+
`useEffect`, event handlers).
|
|
6
|
+
|
|
7
|
+
- **Where they live:** `app/islands/*.tsx`. Files outside this
|
|
8
|
+
directory are server-only and never ship to the browser.
|
|
9
|
+
- **How to mark one:** start the file with `"use client";` and
|
|
10
|
+
default-export a React component. The framework will register it,
|
|
11
|
+
bundle the client code, and inject the hydration script when the
|
|
12
|
+
component is rendered from a route.
|
|
13
|
+
- **How to use one:** import the component from a route file:
|
|
14
|
+
```tsx
|
|
15
|
+
import TodoApp from "../islands/TodoApp.tsx";
|
|
16
|
+
|
|
17
|
+
export default function Index(): JSX.Element {
|
|
18
|
+
return <main><TodoApp /></main>;
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
- **Today's gap (`bun dev`):** dev mode SSRs the island but does not
|
|
22
|
+
yet ship the client bundle. Click handlers are dead under `bun
|
|
23
|
+
dev`. To exercise interactivity right now, run `bun run build &&
|
|
24
|
+
bun start`. Full dev-mode hydration lands with framework spec 18.
|
|
25
|
+
- **Naming:** the island's auto-registered name is the file path
|
|
26
|
+
relative to `app/islands/` with slashes replaced by dashes and the
|
|
27
|
+
extension stripped (e.g. `app/islands/forms/Signup.tsx` →
|
|
28
|
+
`forms-Signup`). Default exports are the only export consulted.
|
|
29
|
+
- **Don't put non-island helpers in `app/islands/`.** Every `.tsx`
|
|
30
|
+
in there is treated as a hydratable component. Put shared
|
|
31
|
+
presentational components in `app/components/` or co-locate them
|
|
32
|
+
under a `_` prefix.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Optional AI dependency rule
|
|
2
|
+
|
|
3
|
+
The Anthropic SDK is an **optional** peer dependency. Apps that do
|
|
4
|
+
not use the `app/agents/`, `app/tools/`, or `app/jobs/` directories
|
|
5
|
+
must still install and run without `@anthropic-ai/sdk` present.
|
|
6
|
+
|
|
7
|
+
- Never `import "@anthropic-ai/sdk"` at the top level of a route or
|
|
8
|
+
middleware file. Wrap it in a dynamic `import()` inside the function
|
|
9
|
+
that needs it, or accept an `AnthropicLike` instance from
|
|
10
|
+
`PattiesContext`.
|
|
11
|
+
- Do not move `@anthropic-ai/sdk` into `dependencies` unless your app
|
|
12
|
+
genuinely requires it at boot. Even then, prefer keeping it as a
|
|
13
|
+
peer + `bun add @anthropic-ai/sdk` step.
|
|
14
|
+
- The auto-generated `AGENTS.md` references AI types, but does not
|
|
15
|
+
require a live SDK at import time.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Web-standards boundary rule
|
|
2
|
+
|
|
3
|
+
The framework stays close to web standards at handler boundaries. Do
|
|
4
|
+
not paper over them with a custom request abstraction.
|
|
5
|
+
|
|
6
|
+
- **Handler signature:** `(req: Request, ctx: PattiesContext) => Response | Promise<Response>`.
|
|
7
|
+
`req` is a standard web `Request`; the handler returns a standard web
|
|
8
|
+
`Response`. Streaming responses use `ReadableStream`.
|
|
9
|
+
- **`PattiesContext` is the only framework-added affordance.** It
|
|
10
|
+
exposes `params`, `cookies`, `env`, `vars`, `url`, and the
|
|
11
|
+
short-circuit helpers `ctx.json(data, init?)`, `ctx.html(body, init?)`,
|
|
12
|
+
`ctx.redirect(to, status?)`. Keep it thin — don't expect a
|
|
13
|
+
Next-style `request.cookies.set(...)` API.
|
|
14
|
+
- **No Hono / Express / Fastify types.** If you find yourself reaching
|
|
15
|
+
for `MiddlewareHandler` from Hono, write the standard
|
|
16
|
+
`Middleware = (req, ctx, next) => Promise<Response>` instead.
|
|
17
|
+
- **React SSR uses `renderToReadableStream`** (the streaming web API).
|
|
18
|
+
Do not use `renderToString` or `renderToPipeableStream`.
|
|
19
|
+
- **Client hydration uses `hydrateRoot`** (React 19). Do not use
|
|
20
|
+
`ReactDOM.render`.
|
|
21
|
+
|
|
22
|
+
If a deployment target needs platform-specific wiring (Vercel edge
|
|
23
|
+
context, Cloudflare bindings, etc.), the framework's adapters under
|
|
24
|
+
`patties/adapters` translate to/from these web-standard handlers — that
|
|
25
|
+
belongs in the adapter, not in your routes.
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
|
-
"allow": [
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(bun:*)",
|
|
5
|
+
"Bash(bunx:*)",
|
|
6
|
+
"Bash(patties:*)",
|
|
7
|
+
"Bash(git status)",
|
|
8
|
+
"Bash(git diff:*)",
|
|
9
|
+
"Bash(git log:*)"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"hooks": {
|
|
13
|
+
"PostToolUse": [
|
|
14
|
+
{
|
|
15
|
+
"matcher": "Edit|Write|MultiEdit",
|
|
16
|
+
"hooks": [
|
|
17
|
+
{ "type": "command", "command": ".claude/hooks/biome-check.sh" }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
4
21
|
}
|
|
5
22
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: patties-cli
|
|
3
|
+
description: Use when running, building, deploying, or managing secrets for a Patties app. Covers `patties dev`, `patties build`, `patties start`, `patties deploy`, and `patties secret`. Trigger phrases include "start the dev server", "build the app", "deploy", "set a secret", "run patties".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# patties CLI
|
|
7
|
+
|
|
8
|
+
`patties` is the project's CLI. It's installed via the `patties` dependency
|
|
9
|
+
and exposed through `package.json#scripts` (`bun dev`, `bun run build`,
|
|
10
|
+
`bun start`). Reach for these commands directly instead of inventing
|
|
11
|
+
ad-hoc Bun invocations.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### `patties dev` — start the dev server
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
bun dev # equivalent to `patties dev`
|
|
19
|
+
patties dev --port 4000
|
|
20
|
+
patties dev --host 0.0.0.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Starts the dev server with HMR over WebSocket. Reads `patties.config.ts`
|
|
24
|
+
for `target`, `port`, env, and secrets. SSR-only today — full island
|
|
25
|
+
hydration in dev lands with framework spec 18. To exercise interactivity
|
|
26
|
+
right now, build and start instead.
|
|
27
|
+
|
|
28
|
+
### `patties build` — produce a production bundle
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
bun run build # equivalent to `patties build`
|
|
32
|
+
patties build --target bun
|
|
33
|
+
patties build --target edge --out-dir dist
|
|
34
|
+
patties build --compile # bun target only; single-binary
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Outputs to `.patties/` by default. The server entry is at
|
|
38
|
+
`.patties/server/server-entry.js`. Build also regenerates `AGENTS.md` at
|
|
39
|
+
the project root.
|
|
40
|
+
|
|
41
|
+
### `patties start` — run the production bundle
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
bun start # equivalent to `patties start`
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Runs the last `patties build` output. If no build exists, prints an
|
|
48
|
+
error directing you to `patties build` first. Use this (after `bun run
|
|
49
|
+
build`) to verify island hydration today, since dev mode only SSRs.
|
|
50
|
+
|
|
51
|
+
### `patties deploy` — build then dispatch to a deploy plugin
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
patties deploy # build + dispatch
|
|
55
|
+
patties deploy --skip-build # reuse the existing `.patties/`
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Requires a deploy plugin declared in `patties.config.ts#plugins`. If no
|
|
59
|
+
plugin is installed, prints the command to run the server bundle
|
|
60
|
+
manually.
|
|
61
|
+
|
|
62
|
+
### `patties secret` — manage dev-time secrets
|
|
63
|
+
|
|
64
|
+
Dev-only. In production, secrets come from the host's secrets surface
|
|
65
|
+
(env vars, Cloudflare bindings, Vercel env, etc.) — not from this CLI.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
patties secret set DATABASE_URL # prompts for value
|
|
69
|
+
patties secret set DATABASE_URL "postgres://..."
|
|
70
|
+
patties secret get DATABASE_URL
|
|
71
|
+
patties secret list
|
|
72
|
+
patties secret rm DATABASE_URL
|
|
73
|
+
patties secret doctor # checks OS keychain access
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Values live in the OS keychain (macOS Keychain, GNOME Keyring, Windows
|
|
77
|
+
Credential Manager). They are loaded into `Bun.env` automatically when
|
|
78
|
+
the dev server reads `config.secrets`.
|
|
79
|
+
|
|
80
|
+
## Global flags
|
|
81
|
+
|
|
82
|
+
- `--cwd <path>` — project root (default `process.cwd()`)
|
|
83
|
+
- `--config <path>` — explicit config file (default: discovery in cwd)
|
|
84
|
+
- `--verbose` — verbose diagnostics, includes stack traces
|
|
85
|
+
- `--version` / `-v` — print version
|
|
86
|
+
- `--help` / `-h` — show help
|
|
87
|
+
|
|
88
|
+
## Common workflows
|
|
89
|
+
|
|
90
|
+
**First-run sanity check after scaffolding:**
|
|
91
|
+
```sh
|
|
92
|
+
bun install
|
|
93
|
+
bun dev # opens http://localhost:3000
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Verify an island actually hydrates today (workaround until spec 18):**
|
|
97
|
+
```sh
|
|
98
|
+
bun run build
|
|
99
|
+
bun start
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Iterate on a deploy config:**
|
|
103
|
+
```sh
|
|
104
|
+
patties build --target edge
|
|
105
|
+
patties deploy --skip-build
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## What this skill does NOT cover
|
|
109
|
+
|
|
110
|
+
- Authoring framework primitives (routes, islands, agents, tools, jobs).
|
|
111
|
+
See the project's `CLAUDE.md` and `.claude/rules/*.md` for those.
|
|
112
|
+
- Bun-the-runtime invocations (`bun add`, `bun upgrade`, `bun pm`).
|
|
113
|
+
Those are upstream Bun commands; check `bun --help` directly.
|
|
@@ -1,56 +1,21 @@
|
|
|
1
|
-
# {{
|
|
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
|
-
|
|
5
|
+
Project conventions live in `.claude/rules/` as small focused files.
|
|
6
|
+
Read each one when it's relevant to the task at hand:
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
- @.claude/rules/bun-native.md — reach for Bun primitives, not Node-era replacements
|
|
9
|
+
- @.claude/rules/web-standards-boundary.md — handlers use standard Request / Response; PattiesContext stays thin
|
|
10
|
+
- @.claude/rules/filesystem-routing.md — how `app/routes/` becomes URLs
|
|
11
|
+
- @.claude/rules/islands.md — when and how to use `app/islands/*.tsx`
|
|
12
|
+
- @.claude/rules/build-time-discovery.md — discovery happens at build, not at request time
|
|
13
|
+
- @.claude/rules/optional-ai.md — keep `@anthropic-ai/sdk` import-disjoint from non-AI code paths
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
The CLI surface (`patties dev/build/start/deploy/secret`) lives in the
|
|
16
|
+
`patties-cli` skill at `.claude/skills/patties-cli/SKILL.md` — it loads
|
|
17
|
+
automatically when CLI work is in scope.
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| `app/routes/about.tsx` | `/about` |
|
|
15
|
-
| `app/routes/hotels/[city].tsx` | `/hotels/:city` |
|
|
16
|
-
| `app/routes/api/revenue.ts` | `/api/revenue` |
|
|
17
|
-
| `app/islands/counter.tsx` | interactive island `Counter` |
|
|
18
|
-
| `app/agents/booking.ts` | agent `booking` |
|
|
19
|
-
| `app/tools/search.ts` | MCP tool `search` |
|
|
20
|
-
| `app/middleware.ts` | global middleware |
|
|
21
|
-
| `patties.config.ts` | framework config |
|
|
22
|
-
|
|
23
|
-
Files starting with `_` are private and never routed. The URL prefix `/__patties_*` and output directory `/_patties/*` are reserved.
|
|
24
|
-
|
|
25
|
-
## Critical rules
|
|
26
|
-
|
|
27
|
-
1. Never import from `"next"`.
|
|
28
|
-
2. Never use Node.js `http`, `fs.watch`, or `chokidar`. Use `Bun.serve` and `bun --watch`.
|
|
29
|
-
3. Never use webpack or vite. Use `Bun.build`.
|
|
30
|
-
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`.
|
|
31
|
-
5. `tsconfig.json` sets `"jsx": "react-jsx"` and `"jsxImportSource": "react"` — no manual `import React` in user code.
|
|
32
|
-
6. All routes are plain `(req: Request, ctx: PattiesContext) => Response | Promise<Response>`. Never import from `"hono"`.
|
|
33
|
-
7. Islands live in `app/islands/` — no exceptions.
|
|
34
|
-
8. API routes export named `GET`, `POST`, `PUT`, `DELETE` functions. Default exports are reserved for page components.
|
|
35
|
-
9. Middleware default-exports a `Middleware = (req, ctx, next) => Promise<Response>`. Never `MiddlewareHandler` from Hono.
|
|
36
|
-
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.
|
|
37
|
-
|
|
38
|
-
## How to run
|
|
39
|
-
|
|
40
|
-
- `bun install`
|
|
41
|
-
- `bun dev` — start the dev server
|
|
42
|
-
- `bun build` — build for production
|
|
43
|
-
- `bun test`
|
|
44
|
-
|
|
45
|
-
## How to add a feature
|
|
46
|
-
|
|
47
|
-
Use the slash commands under `.claude/commands/`:
|
|
48
|
-
|
|
49
|
-
- `/new-route <path>` — page or API route
|
|
50
|
-
- `/new-island <Name>` — interactive island
|
|
51
|
-
- `/new-agent <name>` — agent
|
|
52
|
-
- `/new-tool <name>` — MCP tool
|
|
53
|
-
|
|
54
|
-
## Where to find things
|
|
55
|
-
|
|
56
|
-
`AGENTS.md` (auto-regenerated by `patties build`) is the live inventory of routes, islands, agents, and tools. Trust `AGENTS.md` over this file for inventory questions; trust this file for rules and conventions.
|
|
19
|
+
The live inventory of routes, islands, agents, tools, and jobs is in
|
|
20
|
+
`AGENTS.md` (regenerated by `patties build`). Trust `AGENTS.md` for
|
|
21
|
+
inventory questions; trust the rules files for conventions.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Codex workspace config
|
|
2
|
+
|
|
3
|
+
Codex CLI reads conventions from `AGENTS.md` at the project root — that
|
|
4
|
+
file is the single source of truth for rules, the CLI surface, and the
|
|
5
|
+
auto-regenerated inventory of routes / islands / agents / tools.
|
|
6
|
+
|
|
7
|
+
This directory is reserved for future Codex-specific config (the
|
|
8
|
+
conventions are still evolving — see https://github.com/openai/codex).
|
|
9
|
+
Leave it in place; the scaffolder relies on it as a marker that the
|
|
10
|
+
project opted into the Codex agent overlay.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Build-time discovery rule
|
|
2
|
+
|
|
3
|
+
Routes, islands, agents, and tools are discovered from the filesystem
|
|
4
|
+
at **build time**, not at request time.
|
|
5
|
+
|
|
6
|
+
- `patties build` scans `app/routes/`, `app/islands/`, `app/agents/`,
|
|
7
|
+
`app/tools/`, and `app/jobs/` and inlines the discovered tables into
|
|
8
|
+
the server bundle. The production server never calls `Bun.Glob` /
|
|
9
|
+
`scanRoutes` / `scanIslands`.
|
|
10
|
+
- This is what makes Patties cold-start fast and adapter-portable
|
|
11
|
+
(edge runtimes that disallow filesystem access still work).
|
|
12
|
+
- **Dev mode is the exception.** The dev server re-scans on file
|
|
13
|
+
change to drive HMR.
|
|
14
|
+
- **Don't break the rule:** never write code that calls `Bun.Glob` or
|
|
15
|
+
reads `app/**` at request time. If you find yourself wanting to,
|
|
16
|
+
the answer is probably a build-time macro or a config option in
|
|
17
|
+
`patties.config.ts`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Bun-native rule
|
|
2
|
+
|
|
3
|
+
This project runs on Bun. Reach for Bun primitives first; do not
|
|
4
|
+
reintroduce Node-era replacements just because a familiar library
|
|
5
|
+
provides them.
|
|
6
|
+
|
|
7
|
+
- **HTTP server:** `Bun.serve`. The framework already wires it — do
|
|
8
|
+
not add Express / Fastify / Hono / `node:http`.
|
|
9
|
+
- **Filesystem discovery:** `Bun.Glob`. Do not pull in `fast-glob`,
|
|
10
|
+
`globby`, or `chokidar`.
|
|
11
|
+
- **Bundling:** `Bun.build`. The framework runs it for you at
|
|
12
|
+
`patties build`; you should not add Webpack / Rollup / esbuild /
|
|
13
|
+
Vite / tsup.
|
|
14
|
+
- **File I/O:** `Bun.file(path).text()` / `.json()` / `.bytes()` and
|
|
15
|
+
`Bun.write(path, data)` before reaching for `node:fs`.
|
|
16
|
+
- **Hashing / crypto:** `Bun.CryptoHasher`, `Bun.password`. Avoid
|
|
17
|
+
`crypto` / `bcrypt` unless you have a real reason.
|
|
18
|
+
- **Databases:** `bun:sqlite`, `Bun.sql` (Postgres), `Bun.RedisClient`,
|
|
19
|
+
`Bun.S3Client` before reaching for npm wrappers.
|
|
20
|
+
- **Environment:** `Bun.env`. The framework injects the public subset
|
|
21
|
+
declared in `patties.config.ts#env.public`; secrets live in the OS
|
|
22
|
+
keychain (see `patties-cli` skill).
|
|
23
|
+
- **Tests:** `bun test`. Do not add Jest or Vitest.
|
|
24
|
+
- **Package manager:** `bun` / `bunx`. Do not run `npm` / `npx` /
|
|
25
|
+
`yarn` / `pnpm` in this project.
|
|
26
|
+
|
|
27
|
+
If you genuinely need a Node-only library, that's fine — Bun's Node
|
|
28
|
+
compatibility is strong. But default to Bun primitives.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Filesystem routing rule
|
|
2
|
+
|
|
3
|
+
Routes are discovered from the filesystem under `app/routes/`. Path
|
|
4
|
+
conventions:
|
|
5
|
+
|
|
6
|
+
| File | URL |
|
|
7
|
+
|---|---|
|
|
8
|
+
| `app/routes/index.tsx` | `/` |
|
|
9
|
+
| `app/routes/about.tsx` | `/about` |
|
|
10
|
+
| `app/routes/hotels/index.tsx` | `/hotels` |
|
|
11
|
+
| `app/routes/hotels/[city].tsx` | `/hotels/:city` |
|
|
12
|
+
| `app/routes/api/revenue.ts` | `/api/revenue` |
|
|
13
|
+
| `app/routes/_internal.tsx` | (private — never routed) |
|
|
14
|
+
|
|
15
|
+
- **Page routes** are `.tsx` files that default-export a React
|
|
16
|
+
component. The component receives no props by default; read params
|
|
17
|
+
/ cookies / env from `PattiesContext` via the page's optional
|
|
18
|
+
`loader` (export `loader` if you need server-side data).
|
|
19
|
+
- **API routes** are `.ts` files that export named HTTP-method handlers:
|
|
20
|
+
`GET`, `POST`, `PUT`, `DELETE`, `PATCH`. They return a standard
|
|
21
|
+
`Response`. Default exports in `.ts` files are reserved and will
|
|
22
|
+
error.
|
|
23
|
+
- **Dynamic segments** use `[param]` in the filename. The values land
|
|
24
|
+
in `ctx.params`.
|
|
25
|
+
- **Files starting with `_`** are private — co-located helpers,
|
|
26
|
+
components, or test files. They are never routed.
|
|
27
|
+
- **Reserved URL prefixes:** `/__patties_*` and `/_patties/*` are
|
|
28
|
+
framework-owned. Don't put your own routes under them.
|
|
29
|
+
- **Discovery happens at build time.** The production server bundle
|
|
30
|
+
has the route table inlined; it does not call `Bun.Glob` at runtime.
|
|
31
|
+
Dev mode re-scans on file change (that's where HMR comes from).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Islands rule
|
|
2
|
+
|
|
3
|
+
The default rendering mode is server-side. Use **islands** for the
|
|
4
|
+
parts of a page that need browser-side interactivity (`useState`,
|
|
5
|
+
`useEffect`, event handlers).
|
|
6
|
+
|
|
7
|
+
- **Where they live:** `app/islands/*.tsx`. Files outside this
|
|
8
|
+
directory are server-only and never ship to the browser.
|
|
9
|
+
- **How to mark one:** start the file with `"use client";` and
|
|
10
|
+
default-export a React component. The framework will register it,
|
|
11
|
+
bundle the client code, and inject the hydration script when the
|
|
12
|
+
component is rendered from a route.
|
|
13
|
+
- **How to use one:** import the component from a route file:
|
|
14
|
+
```tsx
|
|
15
|
+
import TodoApp from "../islands/TodoApp.tsx";
|
|
16
|
+
|
|
17
|
+
export default function Index(): JSX.Element {
|
|
18
|
+
return <main><TodoApp /></main>;
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
- **Today's gap (`bun dev`):** dev mode SSRs the island but does not
|
|
22
|
+
yet ship the client bundle. Click handlers are dead under `bun
|
|
23
|
+
dev`. To exercise interactivity right now, run `bun run build &&
|
|
24
|
+
bun start`. Full dev-mode hydration lands with framework spec 18.
|
|
25
|
+
- **Naming:** the island's auto-registered name is the file path
|
|
26
|
+
relative to `app/islands/` with slashes replaced by dashes and the
|
|
27
|
+
extension stripped (e.g. `app/islands/forms/Signup.tsx` →
|
|
28
|
+
`forms-Signup`). Default exports are the only export consulted.
|
|
29
|
+
- **Don't put non-island helpers in `app/islands/`.** Every `.tsx`
|
|
30
|
+
in there is treated as a hydratable component. Put shared
|
|
31
|
+
presentational components in `app/components/` or co-locate them
|
|
32
|
+
under a `_` prefix.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Optional AI dependency rule
|
|
2
|
+
|
|
3
|
+
The Anthropic SDK is an **optional** peer dependency. Apps that do
|
|
4
|
+
not use the `app/agents/`, `app/tools/`, or `app/jobs/` directories
|
|
5
|
+
must still install and run without `@anthropic-ai/sdk` present.
|
|
6
|
+
|
|
7
|
+
- Never `import "@anthropic-ai/sdk"` at the top level of a route or
|
|
8
|
+
middleware file. Wrap it in a dynamic `import()` inside the function
|
|
9
|
+
that needs it, or accept an `AnthropicLike` instance from
|
|
10
|
+
`PattiesContext`.
|
|
11
|
+
- Do not move `@anthropic-ai/sdk` into `dependencies` unless your app
|
|
12
|
+
genuinely requires it at boot. Even then, prefer keeping it as a
|
|
13
|
+
peer + `bun add @anthropic-ai/sdk` step.
|
|
14
|
+
- The auto-generated `AGENTS.md` references AI types, but does not
|
|
15
|
+
require a live SDK at import time.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: patties-cli
|
|
3
|
+
description: Use when running, building, deploying, or managing secrets for a Patties app. Covers `patties dev`, `patties build`, `patties start`, `patties deploy`, and `patties secret`. Trigger phrases include "start the dev server", "build the app", "deploy", "set a secret", "run patties".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# patties CLI
|
|
7
|
+
|
|
8
|
+
`patties` is the project's CLI. It's installed via the `patties` dependency
|
|
9
|
+
and exposed through `package.json#scripts` (`bun dev`, `bun run build`,
|
|
10
|
+
`bun start`). Reach for these commands directly instead of inventing
|
|
11
|
+
ad-hoc Bun invocations.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### `patties dev` — start the dev server
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
bun dev # equivalent to `patties dev`
|
|
19
|
+
patties dev --port 4000
|
|
20
|
+
patties dev --host 0.0.0.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Starts the dev server with HMR over WebSocket. Reads `patties.config.ts`
|
|
24
|
+
for `target`, `port`, env, and secrets. SSR-only today — full island
|
|
25
|
+
hydration in dev lands with framework spec 18. To exercise interactivity
|
|
26
|
+
right now, build and start instead.
|
|
27
|
+
|
|
28
|
+
### `patties build` — produce a production bundle
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
bun run build # equivalent to `patties build`
|
|
32
|
+
patties build --target bun
|
|
33
|
+
patties build --target edge --out-dir dist
|
|
34
|
+
patties build --compile # bun target only; single-binary
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Outputs to `.patties/` by default. The server entry is at
|
|
38
|
+
`.patties/server/server-entry.js`. Build also regenerates `AGENTS.md` at
|
|
39
|
+
the project root.
|
|
40
|
+
|
|
41
|
+
### `patties start` — run the production bundle
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
bun start # equivalent to `patties start`
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Runs the last `patties build` output. If no build exists, prints an
|
|
48
|
+
error directing you to `patties build` first. Use this (after `bun run
|
|
49
|
+
build`) to verify island hydration today, since dev mode only SSRs.
|
|
50
|
+
|
|
51
|
+
### `patties deploy` — build then dispatch to a deploy plugin
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
patties deploy # build + dispatch
|
|
55
|
+
patties deploy --skip-build # reuse the existing `.patties/`
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Requires a deploy plugin declared in `patties.config.ts#plugins`. If no
|
|
59
|
+
plugin is installed, prints the command to run the server bundle
|
|
60
|
+
manually.
|
|
61
|
+
|
|
62
|
+
### `patties secret` — manage dev-time secrets
|
|
63
|
+
|
|
64
|
+
Dev-only. In production, secrets come from the host's secrets surface
|
|
65
|
+
(env vars, Cloudflare bindings, Vercel env, etc.) — not from this CLI.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
patties secret set DATABASE_URL # prompts for value
|
|
69
|
+
patties secret set DATABASE_URL "postgres://..."
|
|
70
|
+
patties secret get DATABASE_URL
|
|
71
|
+
patties secret list
|
|
72
|
+
patties secret rm DATABASE_URL
|
|
73
|
+
patties secret doctor # checks OS keychain access
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Values live in the OS keychain (macOS Keychain, GNOME Keyring, Windows
|
|
77
|
+
Credential Manager). They are loaded into `Bun.env` automatically when
|
|
78
|
+
the dev server reads `config.secrets`.
|
|
79
|
+
|
|
80
|
+
## Global flags
|
|
81
|
+
|
|
82
|
+
- `--cwd <path>` — project root (default `process.cwd()`)
|
|
83
|
+
- `--config <path>` — explicit config file (default: discovery in cwd)
|
|
84
|
+
- `--verbose` — verbose diagnostics, includes stack traces
|
|
85
|
+
- `--version` / `-v` — print version
|
|
86
|
+
- `--help` / `-h` — show help
|
|
87
|
+
|
|
88
|
+
## Common workflows
|
|
89
|
+
|
|
90
|
+
**First-run sanity check after scaffolding:**
|
|
91
|
+
```sh
|
|
92
|
+
bun install
|
|
93
|
+
bun dev # opens http://localhost:3000
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Verify an island actually hydrates today (workaround until spec 18):**
|
|
97
|
+
```sh
|
|
98
|
+
bun run build
|
|
99
|
+
bun start
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Iterate on a deploy config:**
|
|
103
|
+
```sh
|
|
104
|
+
patties build --target edge
|
|
105
|
+
patties deploy --skip-build
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## What this skill does NOT cover
|
|
109
|
+
|
|
110
|
+
- Authoring framework primitives (routes, islands, agents, tools, jobs).
|
|
111
|
+
See the project's `CLAUDE.md` and `.claude/rules/*.md` for those.
|
|
112
|
+
- Bun-the-runtime invocations (`bun add`, `bun upgrade`, `bun pm`).
|
|
113
|
+
Those are upstream Bun commands; check `bun --help` directly.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Web-standards boundary rule
|
|
2
|
+
|
|
3
|
+
The framework stays close to web standards at handler boundaries. Do
|
|
4
|
+
not paper over them with a custom request abstraction.
|
|
5
|
+
|
|
6
|
+
- **Handler signature:** `(req: Request, ctx: PattiesContext) => Response | Promise<Response>`.
|
|
7
|
+
`req` is a standard web `Request`; the handler returns a standard web
|
|
8
|
+
`Response`. Streaming responses use `ReadableStream`.
|
|
9
|
+
- **`PattiesContext` is the only framework-added affordance.** It
|
|
10
|
+
exposes `params`, `cookies`, `env`, `vars`, `url`, and the
|
|
11
|
+
short-circuit helpers `ctx.json(data, init?)`, `ctx.html(body, init?)`,
|
|
12
|
+
`ctx.redirect(to, status?)`. Keep it thin — don't expect a
|
|
13
|
+
Next-style `request.cookies.set(...)` API.
|
|
14
|
+
- **No Hono / Express / Fastify types.** If you find yourself reaching
|
|
15
|
+
for `MiddlewareHandler` from Hono, write the standard
|
|
16
|
+
`Middleware = (req, ctx, next) => Promise<Response>` instead.
|
|
17
|
+
- **React SSR uses `renderToReadableStream`** (the streaming web API).
|
|
18
|
+
Do not use `renderToString` or `renderToPipeableStream`.
|
|
19
|
+
- **Client hydration uses `hydrateRoot`** (React 19). Do not use
|
|
20
|
+
`ReactDOM.render`.
|
|
21
|
+
|
|
22
|
+
If a deployment target needs platform-specific wiring (Vercel edge
|
|
23
|
+
context, Cloudflare bindings, etc.), the framework's adapters under
|
|
24
|
+
`patties/adapters` translate to/from these web-standard handlers — that
|
|
25
|
+
belongs in the adapter, not in your routes.
|